]> git.saurik.com Git - apple/ipsec.git/commitdiff
ipsec-92.tar.gz mac-os-x-106 mac-os-x-1061 v92
authorApple <opensource@apple.com>
Thu, 27 Aug 2009 17:56:23 +0000 (17:56 +0000)
committerApple <opensource@apple.com>
Thu, 27 Aug 2009 17:56:23 +0000 (17:56 +0000)
117 files changed:
entitlements.plist [new file with mode: 0644]
ipsec-tools/Common/config.h
ipsec-tools/Common/ipsecMessageTracer.h [new file with mode: 0644]
ipsec-tools/Common/key_debug.c
ipsec-tools/Common/libpfkey.h
ipsec-tools/Common/pfkey.c
ipsec-tools/libipsec/policy_parse.y
ipsec-tools/racoon/Sample/Embedded/racoon.conf [new file with mode: 0644]
ipsec-tools/racoon/Sample/racoon.conf
ipsec-tools/racoon/admin.c
ipsec-tools/racoon/admin.h
ipsec-tools/racoon/algorithm.c
ipsec-tools/racoon/algorithm.h
ipsec-tools/racoon/algorithm_types.h [new file with mode: 0644]
ipsec-tools/racoon/cfparse.y
ipsec-tools/racoon/cfparse_proto.h
ipsec-tools/racoon/cftoken.l
ipsec-tools/racoon/cftoken_proto.h
ipsec-tools/racoon/com.apple.racoon.plist [new file with mode: 0644]
ipsec-tools/racoon/com.apple.racoonembedded.plist [new file with mode: 0644]
ipsec-tools/racoon/crypto_cssm.c
ipsec-tools/racoon/crypto_cssm.h
ipsec-tools/racoon/crypto_openssl.c
ipsec-tools/racoon/debugrm.h
ipsec-tools/racoon/dnssec.c
ipsec-tools/racoon/evt.c
ipsec-tools/racoon/evt.h
ipsec-tools/racoon/gcmalloc.h
ipsec-tools/racoon/getcertsbyname.c
ipsec-tools/racoon/grabmyaddr.c
ipsec-tools/racoon/grabmyaddr.h
ipsec-tools/racoon/gssapi.c
ipsec-tools/racoon/handler.c
ipsec-tools/racoon/handler.h
ipsec-tools/racoon/ike_session.c [new file with mode: 0644]
ipsec-tools/racoon/ike_session.h [new file with mode: 0644]
ipsec-tools/racoon/ipsecConfigTracer.c [new file with mode: 0644]
ipsec-tools/racoon/ipsecConfigTracer.h [new file with mode: 0644]
ipsec-tools/racoon/ipsecSessionTracer.c [new file with mode: 0644]
ipsec-tools/racoon/ipsecSessionTracer.h [new file with mode: 0644]
ipsec-tools/racoon/ipsec_doi.c
ipsec-tools/racoon/ipsec_doi.h
ipsec-tools/racoon/isakmp.c
ipsec-tools/racoon/isakmp.h
ipsec-tools/racoon/isakmp_agg.c
ipsec-tools/racoon/isakmp_base.c
ipsec-tools/racoon/isakmp_cfg.c
ipsec-tools/racoon/isakmp_cfg.h
ipsec-tools/racoon/isakmp_frag.c
ipsec-tools/racoon/isakmp_frag.h
ipsec-tools/racoon/isakmp_ident.c
ipsec-tools/racoon/isakmp_inf.c
ipsec-tools/racoon/isakmp_inf.h
ipsec-tools/racoon/isakmp_newg.c
ipsec-tools/racoon/isakmp_quick.c
ipsec-tools/racoon/isakmp_unity.c
ipsec-tools/racoon/isakmp_unity.h
ipsec-tools/racoon/isakmp_var.h
ipsec-tools/racoon/isakmp_xauth.c
ipsec-tools/racoon/isakmp_xauth.h
ipsec-tools/racoon/kmpstat.c
ipsec-tools/racoon/localconf.c
ipsec-tools/racoon/localconf.h
ipsec-tools/racoon/logger.c
ipsec-tools/racoon/main.c
ipsec-tools/racoon/misc.h
ipsec-tools/racoon/nattraversal.c
ipsec-tools/racoon/nattraversal.h
ipsec-tools/racoon/oakley.c
ipsec-tools/racoon/oakley.h
ipsec-tools/racoon/pfkey.h
ipsec-tools/racoon/pfkey_racoon.c
ipsec-tools/racoon/plainrsa-gen.c
ipsec-tools/racoon/plog.c
ipsec-tools/racoon/plog.h
ipsec-tools/racoon/policy.c
ipsec-tools/racoon/privsep.c
ipsec-tools/racoon/privsep.h
ipsec-tools/racoon/proposal.c
ipsec-tools/racoon/proposal.h
ipsec-tools/racoon/prsa_par.y
ipsec-tools/racoon/prsa_tok.l
ipsec-tools/racoon/racoon.8
ipsec-tools/racoon/racoon.conf.5
ipsec-tools/racoon/racoonctl.8
ipsec-tools/racoon/racoonctl.c
ipsec-tools/racoon/racoonctl.h
ipsec-tools/racoon/remoteconf.c
ipsec-tools/racoon/remoteconf.h
ipsec-tools/racoon/rsalist.c
ipsec-tools/racoon/rsalist.h
ipsec-tools/racoon/safefile.c
ipsec-tools/racoon/safefile.h
ipsec-tools/racoon/sainfo.c
ipsec-tools/racoon/sainfo.h
ipsec-tools/racoon/schedule.c
ipsec-tools/racoon/schedule.h
ipsec-tools/racoon/session.c
ipsec-tools/racoon/session.h
ipsec-tools/racoon/sockmisc.c
ipsec-tools/racoon/sockmisc.h
ipsec-tools/racoon/strnames.c
ipsec-tools/racoon/strnames.h
ipsec-tools/racoon/throttle.c
ipsec-tools/racoon/var.h
ipsec-tools/racoon/vmbuf.c
ipsec-tools/racoon/vmbuf.h
ipsec-tools/racoon/vpn.c [new file with mode: 0644]
ipsec-tools/racoon/vpn.h [new file with mode: 0644]
ipsec-tools/racoon/vpn_control.c
ipsec-tools/racoon/vpn_control.h
ipsec-tools/racoon/vpn_control_var.h
ipsec-tools/setkey/ipsecPolicyTracer.c [new file with mode: 0644]
ipsec-tools/setkey/ipsecPolicyTracer.h [new file with mode: 0644]
ipsec-tools/setkey/setkey.c
ipsec.plist [new file with mode: 0644]
ipsec.xcodeproj/project.pbxproj

diff --git a/entitlements.plist b/entitlements.plist
new file mode 100644 (file)
index 0000000..93abc34
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>keychain-access-groups</key>
+       <array>
+               <string>apple</string>
+       </array>
+</dict>
+</plist>
index be2c9edcc17d1aa15ad52420c744c9bf1583d956..05028dfa68bd511a418341d912f9f564f53f25bf 100644 (file)
@@ -1,4 +1,6 @@
+#include <TargetConditionals.h>
 
+#define __IPSEC_BUILD__ 1
 
 /* If printf doesn't support %zu. */
 #undef BROKEN_PRINTF
@@ -61,7 +63,7 @@
 #undef ENABLE_SAMODE_UNSPECIFIED
 
 /* Enable statictics */
-//#define ENABLE_STATS 1
+/* #define ENABLE_STATS 1*/      /* causes too many logs to syslog */
 
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
@@ -76,7 +78,8 @@
 #define HAVE_GETTIMEOFDAY 1
 
 /* Enable GSS API */
-#define HAVE_GSSAPI 1
+/* %%%%%%% change this back when conflict fixed */
+#undef HAVE_GSSAPI
 
 /* Have iconv using const */
 #define HAVE_ICONV_2ND_CONST 1
@@ -88,7 +91,8 @@
 #undef HAVE_IPSEC_POLICY_T
 
 /* Hybrid authentication uses PAM */
-#define HAVE_LIBPAM 1
+//#define HAVE_LIBPAM 1
+#undef HAVE_LIBPAM
 
 /* Hybrid authentication uses RADIUS */
 #undef HAVE_LIBRADIUS
 /* Define to 1 if you have the <memory.h> header file. */
 #define HAVE_MEMORY_H 1
 
-/* Use <netinet6/ipsec.h> */
+/* Define to 1 if keychain is used */
+#if TARGET_OS_EMBEDDED
+#undef HAVE_KEYCHAIN
+#else
+#define HAVE_KEYCHAIN 1
+#endif
+
+/* Define to 1 if keychain is used */
+#if TARGET_OS_EMBEDDED
+#undef HAVE_SECURITY_FRAMEWORK
+#else
+#define HAVE_SECURITY_FRAMEWORK 1
+#endif
+
+
+/* Define to 1 if Open Dir available */
+#if TARGET_OS_EMBEDDED
+#undef HAVE_OPENDIR
+#else
+#define HAVE_OPENDIR 1
+#endif
+
+#if TARGET_OS_EMBEDDED
+#undef HAVE_LIBLDAP
+#else
+#define HAVE_LIBLDAP 1
+#endif
+
 #define HAVE_NETINET6_IPSEC 1
 
 #define HAVE_GETIFADDRS 1
 #define HAVE_OPENSSL_RC5_H 1
 
 /* Define to 1 if you have the `pam_start' function. */
+#if TARGET_OS_EMBEDDED
+#undef HAVE_PAM_START
+#else
 #define HAVE_PAM_START 1
+#endif
 
 /* Are PF_KEY policy priorities supported? */
 #undef HAVE_PFKEY_POLICY_PRIORITY
 
 /* Define to `unsigned' if <sys/types.h> does not define. */
 #undef size_t
+
+#ifdef __APPLE__
+#define USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS 1
+#endif
diff --git a/ipsec-tools/Common/ipsecMessageTracer.h b/ipsec-tools/Common/ipsecMessageTracer.h
new file mode 100644 (file)
index 0000000..14bafba
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _IPSECMESSAGETRACER_H
+#define _IPSECMESSAGETRACER_H
+
+#define CONSTSTR(str) (const char *)str
+
+#define L2TPIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN                                                             CONSTSTR("com.apple.Networking.ipsec.disconnect.l2tpipsec")
+#define CISCOIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN                                                            CONSTSTR("com.apple.Networking.ipsec.disconnect.ciscoipsec")
+#define BTMMIPSEC_CONNECTION_ESTABLISHED_DOMAIN                                                                        CONSTSTR("com.apple.Networking.ipsec.disconnect.btmm")
+#define PLAINIPSEC_CONNECTION_ESTABLISHED_DOMAIN                                CONSTSTR("com.apple.Networking.ipsec.disconnect.plain")
+#define L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN                           CONSTSTR("com.apple.Networking.ipsec.connect.l2tpipsec")
+#define CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN                          CONSTSTR("com.apple.Networking.ipsec.connect.ciscoipsec")
+#define BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN                              CONSTSTR("com.apple.Networking.ipsec.connect.btmm")
+#define PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN                             CONSTSTR("com.apple.Networking.ipsec.connect.plain")
+#define L2TPIPSECVPN_PHASE_DOMAIN                                               CONSTSTR("com.apple.Networking.ipsec.phasestats.l2tpipsec")
+#define CISCOIPSECVPN_PHASE_DOMAIN                                              CONSTSTR("com.apple.Networking.ipsec.phasestats.ciscoipsec")
+#define BTMMIPSEC_PHASE_DOMAIN                                                  CONSTSTR("com.apple.Networking.ipsec.phasestats.btmm")
+#define PLAINIPSEC_PHASE_DOMAIN                                                 CONSTSTR("com.apple.Networking.ipsec.phasestats.plain")
+#define PLAINIPSECDOMAIN                                                        CONSTSTR("com.apple.Networking.ipsec.main")
+
+#define IPSECCONFIGTRACEREVENT(config, eventCode, message, failure_reason)             ipsecConfigTracerEvent(config, eventCode, message, failure_reason)
+
+#define IPSECPOLICYTRACEREVENT(policy, eventCode, message, failure_reason)             ipsecPolicyTracerEvent(policy, eventCode, message, failure_reason)
+
+#define IPSECSESSIONTRACERSTART(session)                                                                               ipsecSessionTracerStart(session)
+#define IPSECSESSIONTRACEREVENT(session, eventCode, message, failure_reason)   ipsecSessionTracerEvent(session, eventCode, message, failure_reason)
+#define IPSECSESSIONTRACERSTOP(session, is_failure, reason)                                            ipsecSessionTracerStop(session, is_failure, reason)
+#define IPSECSESSIONTRACERESTABLISHED(session)                                  ipsecSessionTracerLogEstablished(session)
+
+static inline double get_percentage (double numerator, double denominator)
+{
+    if (numerator >= denominator || denominator == 0) {
+        return((double)100);
+    }
+    return((numerator/denominator)*100);
+}
+
+#endif /* _IPSECMESSAGETRACER_H */
index 06a9d4b257eb0f8187f1e8a2513a88437ae7f35a..dca4d896a9d489f354e3ad085358f050e6caaedd 100644 (file)
@@ -77,6 +77,8 @@ static void kdebug_sadb_sa __P((struct sadb_ext *));
 static void kdebug_sadb_address __P((struct sadb_ext *));
 static void kdebug_sadb_key __P((struct sadb_ext *));
 static void kdebug_sadb_x_sa2 __P((struct sadb_ext *));
+static void kdebug_sadb_session_id __P((struct sadb_ext *));
+static void kdebug_sadb_sastat __P((struct sadb_ext *));
 static void kdebug_sadb_x_policy __P((struct sadb_ext *ext));
 static void kdebug_sockaddr __P((struct sockaddr *addr));
 
@@ -171,6 +173,12 @@ kdebug_sadb(base)
                case SADB_X_EXT_SA2:
                        kdebug_sadb_x_sa2(ext);
                        break;
+        case SADB_EXT_SESSION_ID:
+            kdebug_sadb_session_id(ext);
+            break;
+        case SADB_EXT_SASTAT:
+            kdebug_sadb_sastat(ext);
+            break;
 #ifdef SADB_X_EXT_NAT_T_TYPE
                case SADB_X_EXT_NAT_T_TYPE:
                        kdebug_sadb_x_nat_t_type(ext);
@@ -423,6 +431,47 @@ kdebug_sadb_x_sa2(ext)
        return;
 }
 
+static void
+kdebug_sadb_session_id(ext)
+struct sadb_ext *ext;
+{
+    struct sadb_session_id *p = (__typeof__(p))ext;
+
+    /* sanity check */
+    if (ext == NULL) {
+        printf("kdebug_sadb_session_id: NULL pointer was passed.\n");
+        return;
+    }
+
+    printf("sadb_session_id{ id0=%llx, id1=%llx}\n",
+           p->sadb_session_id_v[0],
+           p->sadb_session_id_v[1]);
+}
+
+static void
+kdebug_sadb_sastat(ext)
+struct sadb_ext *ext;
+{
+    struct sadb_sastat *p = (__typeof__(p))ext;
+    struct sastat      *stats;
+    int    i;
+
+    /* sanity check */
+    if (ext == NULL) {
+        printf("kdebug_sadb_sastat: NULL pointer was passed.\n");
+        return;
+    }
+
+    printf("sadb_sastat{ dir=%u num=%u\n",
+           p->sadb_sastat_dir, p->sadb_sastat_list_len);
+    stats = (__typeof__(stats))(p + 1);
+    for (i = 0; i < p->sadb_sastat_list_len; i++) {
+        printf("  spi=%x,\n",
+               stats[i].spi);
+    }
+    printf("}\n");
+}
+
 void
 kdebug_sadb_x_policy(ext)
        struct sadb_ext *ext;
index 628c835a9938a667cc217c5ce7d07e01a2ff1087..ef41d0b43c8cfadf564cb3087670313879fc555e 100644 (file)
@@ -154,6 +154,7 @@ struct sadb_msg *pfkey_recv __P((int));
 int pfkey_send __P((int, struct sadb_msg *, int));
 int pfkey_align __P((struct sadb_msg *, caddr_t *));
 int pfkey_check __P((caddr_t *));
+int pfkey_send_getsastats __P((int, u_int32_t, u_int64_t [], u_int32_t, u_int8_t, struct sastat [], u_int32_t));
 
 #ifndef __SYSDEP_SA_LEN__
 #define __SYSDEP_SA_LEN__
index 0e566a43d7f88223de9eead14f9d1103653e8bd7..f4bcb4f493d81adc84cf24f88ffa2409ed4391a4 100644 (file)
@@ -2250,6 +2250,8 @@ pfkey_align(msg, mhp)
                case SADB_EXT_SPIRANGE:
                case SADB_X_EXT_POLICY:
                case SADB_X_EXT_SA2:
+        case SADB_EXT_SESSION_ID:
+        case SADB_EXT_SASTAT:
 #ifdef SADB_X_EXT_NAT_T_TYPE
                case SADB_X_EXT_NAT_T_TYPE:
                case SADB_X_EXT_NAT_T_SPORT:
@@ -2737,3 +2739,118 @@ pfkey_set_natt_frag(buf, lim, type, l_natt_frag)
        return(buf + len);
 }
 #endif
+
+static caddr_t
+pfkey_setsadbsession_id (caddr_t   buf,
+                         caddr_t   lim,
+                         u_int64_t session_ids[],
+                         u_int32_t max_session_ids)
+{
+       struct sadb_session_id *p;
+       u_int len;
+
+    if (!max_session_ids)
+        return NULL;
+
+       p = (void *)buf;
+       len = sizeof(*p);
+
+       if (buf + len > lim)
+               return NULL;
+
+       bzero(p, len);
+       p->sadb_session_id_len = PFKEY_UNIT64(len);
+       p->sadb_session_id_exttype = SADB_EXT_SESSION_ID;
+    p->sadb_session_id_v[0] = session_ids[0];
+    if (max_session_ids > 1)
+        p->sadb_session_id_v[1] = session_ids[1];
+
+       return(buf + len);
+}
+
+static caddr_t
+pfkey_setsadbsastats (caddr_t        buf,
+                      caddr_t        lim,
+                      u_int32_t      dir,
+                      struct sastat *stats,
+                      u_int32_t      max_stats)
+{
+    struct sadb_sastat *p;
+       u_int len, list_len;
+
+    if (!stats || !max_stats)
+        return NULL;
+
+       p = (__typeof__(p))buf;
+    list_len = sizeof(*stats) * max_stats;
+       len = sizeof(*p) + PFKEY_ALIGN8(list_len);
+
+       if (buf + len > lim)
+               return NULL;
+
+       bzero(p, len);
+       p->sadb_sastat_len      = PFKEY_UNIT64(len);
+       p->sadb_sastat_exttype  = SADB_EXT_SASTAT;
+    p->sadb_sastat_dir      = dir;
+    p->sadb_sastat_list_len = max_stats;
+    bcopy(stats, p + 1, list_len);
+
+       return(buf + len);
+}
+
+int
+pfkey_send_getsastats (int            so,
+                       u_int32_t      seq,
+                       u_int64_t     *session_ids,
+                       u_int32_t      max_session_ids,
+                       u_int8_t       dir,
+                       struct sastat *stats,
+                       u_int32_t      max_stats)
+{
+       struct sadb_msg *newmsg;
+       caddr_t ep;
+       int list_len, out_len, len;
+       caddr_t p;
+
+    if (!session_ids || !stats || !max_stats) {
+        return -1;
+    }
+
+    list_len = sizeof(*stats) * max_stats;
+    /* create new sadb_msg to send. */
+    out_len = sizeof(struct sadb_msg) + sizeof(struct sadb_session_id) + sizeof(struct sadb_sastat) + PFKEY_ALIGN8(list_len);
+
+    if ((newmsg = CALLOC((size_t)out_len, struct sadb_msg *)) == NULL) {
+        __ipsec_set_strerror(strerror(errno));
+        return -1;
+    }
+    ep = ((caddr_t)(void *)newmsg) + out_len;
+
+    p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_GETSASTAT, (u_int)out_len, SADB_SATYPE_UNSPEC, seq, getpid());
+    if (!p) {
+        free(newmsg);
+        return -1;
+    }
+
+    p = pfkey_setsadbsession_id(p, ep, session_ids, max_session_ids);
+    if (!p) {
+        free(newmsg);
+        return -1;
+    }
+
+    p = pfkey_setsadbsastats(p, ep, dir, stats, max_stats);
+    if (!p) {
+        free(newmsg);
+        return -1;
+    }
+
+    /* send message */
+    len = pfkey_send(so, newmsg, out_len);
+    free(newmsg);
+
+    if (len < 0)
+        return -1;
+
+    __ipsec_errcode = EIPSEC_NO_ERROR;
+    return len;
+}
index 51fb1159180c0ef790904ababd556e5508677263..74d1e354d49a9079af8f6a1fb9189a9c82e4735f 100644 (file)
@@ -400,26 +400,30 @@ parse_sockaddr(addrbuf, portbuf)
        char *serv = NULL;
        int error;
        struct sockaddr *newaddr = NULL;
+       int addr_len;
+       int serv_len;
 
-       if ((addr = malloc(addrbuf->len + 1)) == NULL) {
+       addr_len = addrbuf->len + 1;
+       if ((addr = malloc(addr_len)) == NULL) {
                yyerror("malloc failed");
                __ipsec_set_strerror(strerror(errno));
                return NULL;
        }
-
-       if (portbuf && ((serv = malloc(portbuf->len + 1)) == NULL)) {
-               free(addr);
-               yyerror("malloc failed");
-               __ipsec_set_strerror(strerror(errno));
-               return NULL;
+       
+       if (portbuf) {
+               serv_len = portbuf->len + 1;
+               if ((serv = malloc(serv_len)) == NULL) {
+                       free(addr);
+                       yyerror("malloc failed");
+                       __ipsec_set_strerror(strerror(errno));
+                       return NULL;
+               }
        }
 
-       strncpy(addr, addrbuf->buf, addrbuf->len);
-       addr[addrbuf->len] = '\0';
+       strlcpy(addr, addrbuf->buf, addr_len);
 
        if (portbuf) {
-               strncpy(serv, portbuf->buf, portbuf->len);
-               serv[portbuf->len] = '\0';
+               strlcpy(serv, portbuf->buf, serv_len);
        }
 
        memset(&hints, 0, sizeof(hints));
diff --git a/ipsec-tools/racoon/Sample/Embedded/racoon.conf b/ipsec-tools/racoon/Sample/Embedded/racoon.conf
new file mode 100644 (file)
index 0000000..6625e1e
--- /dev/null
@@ -0,0 +1,139 @@
+# $KAME: racoon.conf.in,v 1.17 2001/08/14 12:10:22 sakane Exp $
+
+# "path" must be placed before it is used.
+# You can overwrite what you defined, but it should not be used due to confusion.
+path include "/etc/racoon" ;
+
+# search this file for pre_shared_key with various ID key.
+path pre_shared_key "/etc/racoon/psk.txt" ;
+
+# racoon will look for certificate file in the directory,
+# if the certificate/certificate request payload is received.
+path certificate "/etc/cert" ;
+
+# "log" specifies logging level.  It is followed by either "notify", "debug"
+# or "debug2".
+#log debug;
+
+# "padding" defines some parameter of padding.  You should not touch these.
+padding
+{
+       maximum_length 20;      # maximum padding length.
+       randomize off;          # enable randomize length.
+       strict_check off;       # enable strict check.
+       exclusive_tail off;     # extract last one octet.
+}
+
+# if no listen directive is specified, racoon will listen to all
+# available interface addresses.
+listen
+{
+       #isakmp ::1 [7000];
+       #isakmp 202.249.11.124 [500];
+       #admin [7002];          # administrative's port by kmpstat.
+       #strict_address;        # required all addresses must be bound.
+}
+
+# Specification of default various timer.
+timer
+{
+       # These value can be changed per remote node.
+       counter 10;             # maximum trying count to send.
+       interval 3 sec; # interval to resend (retransmit)
+       persend 1;              # the number of packets per a send.
+
+       # timer for waiting to complete each phase.
+       phase1 30 sec;
+       phase2 30 sec;
+
+       # Auto exit delay timer - for use when controlled by VPN socket
+       auto_exit_delay 3 sec;
+}
+
+#
+# anonymous entry is defined in /etc/racoon/remote/anonymous.conf
+#
+#remote anonymous
+#{
+#      #exchange_mode main,aggressive;
+#      exchange_mode aggressive,main;
+#      doi ipsec_doi;
+#      situation identity_only;
+#
+#      #my_identifier address;
+#      my_identifier user_fqdn "macuser@localhost";
+#      peers_identifier user_fqdn "macuser@localhost";
+#      #certificate_type x509 "mycert" "mypriv";
+#
+#      nonce_size 16;
+#      lifetime time 1 min;    # sec,min,hour
+#      initial_contact on;
+#      support_mip6 on;
+#      proposal_check obey;    # obey, strict or claim
+#
+#      proposal {
+#              encryption_algorithm 3des;
+#              hash_algorithm sha1;
+#              authentication_method pre_shared_key ;
+#              dh_group 2 ;
+#      }
+#}
+
+#remote ::1 [8000]
+#{
+#      #exchange_mode main,aggressive;
+#      exchange_mode aggressive,main;
+#      doi ipsec_doi;
+#      situation identity_only;
+#
+#      my_identifier user_fqdn "macuser@localhost";
+#      peers_identifier user_fqdn "macuser@localhost";
+#      #certificate_type x509 "mycert" "mypriv";
+#
+#      nonce_size 16;
+#      lifetime time 1 min;    # sec,min,hour
+#
+#      proposal {
+#              encryption_algorithm 3des;
+#              hash_algorithm sha1;
+#              authentication_method pre_shared_key ;
+#              dh_group 2 ;
+#      }
+#}
+
+#
+# anonymous entry is defined in /etc/racoon/remote/anonymous.conf
+#
+#sainfo anonymous
+#{
+#      pfs_group 1;
+#      lifetime time 30 sec;
+#      encryption_algorithm aes, 3des ;
+#      authentication_algorithm hmac_sha1;
+#      compression_algorithm deflate ;
+#}
+
+# sainfo address 203.178.141.209 any address 203.178.141.218 any
+# {
+#      pfs_group 1;
+#      lifetime time 30 sec;
+#      encryption_algorithm des ;
+#      authentication_algorithm hmac_md5;
+#      compression_algorithm deflate ;
+# }
+
+#sainfo address ::1 icmp6 address ::1 icmp6
+#{
+#      pfs_group 1;
+#      lifetime time 60 sec;
+#      encryption_algorithm 3des, cast128, blowfish 448, des ;
+#      authentication_algorithm hmac_sha1, hmac_md5 ;
+#      compression_algorithm deflate ;
+#}
+
+# Allow third parties the ability to specify remote and sainfo entries
+# by including all files matching /var/run/racoon/*.conf
+# This line should be added at the end of the racoon.conf file
+# so that settings such as timer values will be appropriately applied.
+include "/var/run/racoon/*.conf" ;
+
index 2a6112bfc53311167d62fb644f9f6062522211f0..8b016455938559b1aecddf321a5028b978fbc47f 100644 (file)
@@ -1,13 +1,9 @@
 # $KAME: racoon.conf.in,v 1.17 2001/08/14 12:10:22 sakane Exp $
 
-# "path" must be placed before it should be used.
-# You can overwrite which you defined, but it should not use due to confusing.
+# "path" must be placed before it is used.
+# You can overwrite what you defined, but it should not be used due to confusion.
 path include "/etc/racoon" ;
 
-# Allow third parties the ability to specify remote and sainfo entries
-# by including all files matching /etc/racoon/remote/*.conf
-include "/etc/racoon/remote/*.conf" ;
-
 # search this file for pre_shared_key with various ID key.
 path pre_shared_key "/etc/racoon/psk.txt" ;
 
@@ -135,3 +131,8 @@ sainfo address ::1 icmp6 address ::1 icmp6
        compression_algorithm deflate ;
 }
 
+# Allow third parties the ability to specify remote and sainfo entries
+# by including all files matching /var/run/racoon/*.conf
+# This line should be added at the end of the racoon.conf file
+# so that settings such as timer values will be appropriately applied.
+include "/var/run/racoon/*.conf" ;
index 344e2f4a26f79f35ec725cc27a8ef36f5cfbbe59..ea11b4e462a7117cbe1b0a75637ea5bf78f0a230 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: admin.c,v 1.17.2.4 2005/07/12 11:49:44 manubsd Exp $ */
+/*     $NetBSD: admin.c,v 1.17.6.1 2007/08/01 11:52:19 vanhu Exp $     */
+
+/* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -60,6 +62,9 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
 
 #include "var.h"
 #include "misc.h"
 #include "admin.h"
 #include "admin_var.h"
 #include "isakmp_inf.h"
+#ifdef ENABLE_HYBRID
+#include "isakmp_cfg.h"
+#endif
 #include "session.h"
 #include "gcmalloc.h"
 
+
 #ifdef ENABLE_ADMINPORT
 char *adminsock_path = ADMINSOCK_PATH;
 uid_t adminsock_owner = 0;
@@ -103,7 +112,6 @@ admin_handler()
        socklen_t fromlen = sizeof(from);
        struct admin_com com;
        char *combuf = NULL;
-       pid_t pid = -1;
        int len, error = -1;
 
        so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen);
@@ -150,7 +158,7 @@ admin_handler()
 
        if (com.ac_cmd == ADMIN_RELOAD_CONF) {
                /* reload does not work at all! */
-               signal_handler(SIGHUP);
+               signal_handler(SIGUSR1);
                goto end;
        }
 
@@ -161,10 +169,6 @@ admin_handler()
        if (combuf)
                racoon_free(combuf);
 
-       /* exit if child's process. */
-       if (pid == 0 && !f_foreground)
-               exit(error);
-
        return error;
 }
 
@@ -181,7 +185,7 @@ admin_process(so2, combuf)
        vchar_t *id = NULL;
        vchar_t *key = NULL;
        int idtype = 0;
-       int error = 0;
+       int error = -1;
 
        com->ac_errno = 0;
 
@@ -189,21 +193,28 @@ admin_process(so2, combuf)
        case ADMIN_RELOAD_CONF:
                /* don't entered because of proccessing it in other place. */
                plog(LLV_ERROR, LOCATION, NULL, "should never reach here\n");
-               goto bad;
+               goto out;
 
        case ADMIN_SHOW_SCHED:
        {
-               caddr_t p;
+               caddr_t p = NULL;
                int len;
+
+               com->ac_errno = -1;
+
                if (sched_dump(&p, &len) == -1)
-                       com->ac_errno = -1;
-               buf = vmalloc(len);
-               if (buf == NULL)
-                       com->ac_errno = -1;
-               else
-                       memcpy(buf->v, p, len);
-       }
+                       goto out2;
+
+               if ((buf = vmalloc(len)) == NULL)
+                       goto out2;
+
+               memcpy(buf->v, p, len);
+
+               com->ac_errno = 0;
+out2:
+               racoon_free(p);
                break;
+       }
 
        case ADMIN_SHOW_EVT:
                /* It's not really an error, don't force racoonctl to quit */
@@ -223,7 +234,7 @@ admin_process(so2, combuf)
                                        com->ac_errno = -1;
                                break;
                        case ADMIN_FLUSH_SA:
-                               flushph1();
+                               flushph1(false);
                                break;
                        }
                        break;
@@ -236,7 +247,7 @@ admin_process(so2, combuf)
                                u_int p;
                                p = admin2pfkey_proto(com->ac_proto);
                                if (p == -1)
-                                       goto bad;
+                                       goto out;
                                buf = pfkey_dump_sadb(p);
                                if (buf == NULL)
                                        com->ac_errno = -1;
@@ -256,7 +267,7 @@ admin_process(so2, combuf)
                                        com->ac_errno = error;
                                break;
                        case ADMIN_FLUSH_SA:
-                               /*XXX flushph2();*/
+                               /*XXX flushph2(false);*/
                                com->ac_errno = 0;
                                break;
                        }
@@ -282,16 +293,10 @@ admin_process(so2, combuf)
                        &((struct admin_com_indexes *)
                            ((caddr_t)com + sizeof(*com)))->dst;
 
-               if ((loc = strdup(saddrwop2str(src))) == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL, 
-                           "cannot allocate memory\n");
-                       break;
-               }
-               if ((rem = strdup(saddrwop2str(dst))) == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL, 
-                           "cannot allocate memory\n");
-                       break;
-               }
+               loc = racoon_strdup(saddrwop2str(src));
+               rem = racoon_strdup(saddrwop2str(dst));
+               STRDUP_FATAL(loc);
+               STRDUP_FATAL(rem);
 
                if ((iph1 = getph1byaddrwop(src, dst)) == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL, 
@@ -308,6 +313,27 @@ admin_process(so2, combuf)
                break;
        }
 
+#ifdef ENABLE_HYBRID
+       case ADMIN_LOGOUT_USER: {
+               struct ph1handle *iph1;
+               char *user;
+               int found = 0;
+
+               if (com->ac_len > sizeof(com) + LOGINLEN + 1) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "malformed message (login too long)\n");
+                       break;
+               }
+
+               user = (char *)(com + 1);
+               found = purgeph1bylogin(user);
+               plog(LLV_INFO, LOCATION, NULL, 
+                   "deleted %d SA for user \"%s\"\n", found, user);
+
+               break;
+       }
+#endif
+
        case ADMIN_DELETE_ALL_SA_DST: {
                struct ph1handle *iph1;
                struct sockaddr *dst;
@@ -317,21 +343,15 @@ admin_process(so2, combuf)
                        &((struct admin_com_indexes *)
                            ((caddr_t)com + sizeof(*com)))->dst;
 
-               if ((rem = strdup(saddrwop2str(dst))) == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL, 
-                           "cannot allocate memory\n");
-                       break;
-               }
+               rem = racoon_strdup(saddrwop2str(dst));
+               STRDUP_FATAL(rem);
 
                plog(LLV_INFO, LOCATION, NULL, 
                    "Flushing all SAs for peer %s\n", rem);
 
                while ((iph1 = getph1bydstaddrwop(dst)) != NULL) {
-                       if ((loc = strdup(saddrwop2str(iph1->local))) == NULL) {
-                               plog(LLV_ERROR, LOCATION, NULL, 
-                                   "cannot allocate memory\n");
-                               break;
-                       }
+                       loc = racoon_strdup(saddrwop2str(iph1->local));
+                       STRDUP_FATAL(loc);
 
                        if (iph1->status == PHASE1ST_ESTABLISHED)
                                isakmp_info_send_d1(iph1);
@@ -345,6 +365,75 @@ admin_process(so2, combuf)
                break;
        }
 
+       //%%%%%% test code
+       case ADMIN_ESTABLISH_SA_VPNCONTROL: 
+       {
+               struct admin_com_psk *acp;
+               char *data;
+               struct sockaddr *dst;
+               struct bound_addr *target;
+
+               com->ac_errno = -1;
+
+               acp = (struct admin_com_psk *)
+                   ((char *)com + sizeof(*com) + 
+                   sizeof(struct admin_com_indexes));
+
+               target = (struct bound_addr *)racoon_malloc(sizeof(struct bound_addr));
+               if (target == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "cannot allocate memory: %s\n", 
+                           strerror(errno));
+                       break;
+               }
+
+               if ((id = vmalloc(acp->id_len)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "cannot allocate memory: %s\n", 
+                           strerror(errno));
+                       goto outofhere;
+               }
+               data = (char *)(acp + 1);
+               memcpy(id->v, data, id->l);
+
+               if ((key = vmalloc(acp->key_len)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "cannot allocate memory: %s\n", 
+                           strerror(errno));
+                       vfree(id);
+                       id = NULL;
+                       goto outofhere;
+               }
+               data = (char *)(data + acp->id_len);
+               memcpy(key->v, data, key->l);
+
+               dst = (struct sockaddr *)
+                       &((struct admin_com_indexes *)
+                           ((caddr_t)com + sizeof(*com)))->dst;
+                               
+               // assume IPv4
+               target->address = ((struct sockaddr_in *)dst)->sin_addr.s_addr;
+
+#ifdef ENABLE_HYBRID
+               /* Set the id and key */
+               if (id && key) {
+
+                       target->user_id = id;
+                       target->user_pw = key;
+               }
+#endif
+               vpn_connect(target);
+               com->ac_errno = 0;
+outofhere:
+               if (target->user_id != NULL)
+                       vfree(target->user_id);
+               if (target->user_pw != NULL)
+                       vfree(target->user_pw);
+               if (target != NULL)
+                       racoon_free(target);
+               break;
+       }
+
        case ADMIN_ESTABLISH_SA_PSK: {
                struct admin_com_psk *acp;
                char *data;
@@ -371,6 +460,7 @@ admin_process(so2, combuf)
                            "cannot allocate memory: %s\n", 
                            strerror(errno));
                        vfree(id);
+                       id = NULL;
                        break;
                }
                data = (char *)(data + acp->id_len);
@@ -389,11 +479,13 @@ admin_process(so2, combuf)
                            ((caddr_t)com + sizeof(*com)))->dst;
 
                switch (com->ac_proto) {
-               case ADMIN_PROTO_ISAKMP:
-                   {
+               case ADMIN_PROTO_ISAKMP: {
                        struct remoteconf *rmconf;
-                       struct sockaddr *remote;
-                       struct sockaddr *local;
+                       struct sockaddr *remote = NULL;
+                       struct sockaddr *local = NULL;
+                       u_int16_t port;
+
+                       com->ac_errno = -1;
 
                        /* search appropreate configuration */
                        rmconf = getrmconf(dst);
@@ -401,16 +493,13 @@ admin_process(so2, combuf)
                                plog(LLV_ERROR, LOCATION, NULL,
                                        "no configuration found "
                                        "for %s\n", saddrwop2str(dst));
-                               com->ac_errno = -1;
-                               break;
+                               goto out1;
                        }
 
                        /* get remote IP address and port number. */
-                       remote = dupsaddr(dst);
-                       if (remote == NULL) {
-                               com->ac_errno = -1;
-                               break;
-                       }
+                       if ((remote = dupsaddr(dst)) == NULL)
+                               goto out1;
+
                        switch (remote->sa_family) {
                        case AF_INET:
                                ((struct sockaddr_in *)remote)->sin_port =
@@ -430,58 +519,54 @@ admin_process(so2, combuf)
                                break;
                        }
 
+//                     port = extract_port(rmconf->remote);
+//                     if (set_port(remote, port) == NULL)
+//                             goto out1;
+
                        /* get local address */
-                       local = dupsaddr(src);
-                       if (local == NULL) {
-                               com->ac_errno = -1;
-                               break;
-                       }
-                       switch (local->sa_family) {
-                       case AF_INET:
-                               ((struct sockaddr_in *)local)->sin_port =
-                                       getmyaddrsport(local);
-                               break;
-#ifdef INET6
-                       case AF_INET6:
-                               ((struct sockaddr_in6 *)local)->sin6_port =
-                                       getmyaddrsport(local);
-                               break;
-#endif
-                       default:
-                               plog(LLV_ERROR, LOCATION, NULL,
-                                       "invalid family: %d\n",
-                                       local->sa_family);
-                               com->ac_errno = -1;
-                               break;
-                       }
+                       if ((local = dupsaddr(src)) == NULL)
+                               goto out1;
 
+                       port = ntohs(getmyaddrsport(local));
+                       if (set_port(local, port) == NULL)
+                               goto out1;
+
+#ifdef ENABLE_HYBRID
                        /* Set the id and key */
                        if (id && key) {
-                               if (rmconf->idv != NULL) {
-                                       vfree(rmconf->idv);
-                                       rmconf->idv = NULL;
+                               if (xauth_rmconf_used(&rmconf->xauth) == -1)
+                                       goto out1;
+
+                               if (rmconf->xauth->login != NULL) {
+                                       vfree(rmconf->xauth->login);
+                                       rmconf->xauth->login = NULL;
                                }
-                               if (rmconf->key != NULL) {
-                                       vfree(rmconf->key);
-                                       rmconf->key = NULL;
+                               if (rmconf->xauth->pass != NULL) {
+                                       vfree(rmconf->xauth->pass);
+                                       rmconf->xauth->pass = NULL;
                                }
 
-                               rmconf->idvtype = idtype;
-                               rmconf->idv = id;
-                               rmconf->key = key;
+                               rmconf->xauth->login = id;
+                               rmconf->xauth->pass = key;
                        }
+#endif
  
                        plog(LLV_INFO, LOCATION, NULL,
                                "accept a request to establish IKE-SA: "
                                "%s\n", saddrwop2str(remote));
 
                        /* begin ident mode */
-                       if (isakmp_ph1begin_i(rmconf, remote, local) < 0) {
-                               com->ac_errno = -1;
-                               break;
-                       }
-                   }
+                       if (isakmp_ph1begin_i(rmconf, remote, local, 0) < 0)
+                               goto out1;
+
+                       com->ac_errno = 0;
+out1:
+                       if (local != NULL)
+                               racoon_free(local);
+                       if (remote != NULL)
+                               racoon_free(remote);
                        break;
+               }
                case ADMIN_PROTO_AH:
                case ADMIN_PROTO_ESP:
                        break;
@@ -498,18 +583,15 @@ admin_process(so2, combuf)
                com->ac_errno = -1;
        }
 
-       if (admin_reply(so2, com, buf) < 0)
-               goto bad;
+       if ((error = admin_reply(so2, com, buf)) != 0)
+               goto out;
 
+       error = 0;
+out:
        if (buf != NULL)
                vfree(buf);
 
-       return 0;
-
-    bad:
-       if (buf != NULL)
-               vfree(buf);
-       return -1;
+       return error;
 }
 
 static int
index e07616ddb082d0b6ac5375cc29c81d430be21064..d6ec706b912d27ba44a769782d8db7401b386e85 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: admin.h,v 1.10 2004/12/30 13:45:49 manubsd Exp $ */
+/*     $NetBSD: admin.h,v 1.4 2006/09/09 16:22:09 manu Exp $   */
+
+/* Id: admin.h,v 1.11 2005/06/19 22:37:47 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -75,6 +77,14 @@ struct admin_com {
  */
 #define ADMIN_ESTABLISH_SA_PSK 0x0203
 
+/*
+ * user login follows
+ */
+#define ADMIN_LOGOUT_USER      0x0205  /* Delete SA for a given Xauth user */
+
+//%%%% for test
+#define ADMIN_ESTABLISH_SA_VPNCONTROL 0x0206
+
 /*
  * Range 0x08xx is reserved for privilege separation, see privsep.h 
  */
index 1af0150dafa228d4d3a146e3de167d45cdc323bd..1fdd9e76ff543fc226b1f2a4024418913914d032 100644 (file)
@@ -213,22 +213,46 @@ static struct misc_algorithm ipsec_compdef[] = {
 { "lzs",       algtype_lzs,            IPSECDOI_IPCOMP_LZS, },
 };
 
+/*
+ * In case of asymetric modes (hybrid xauth), what's racoon mode of
+ * operations ; it seems that the proposal should always use the
+ * initiator half (unless a server initiates a connection, which is
+ * not handled, and probably not useful).
+ */
 static struct misc_algorithm oakley_authdef[] = {
-{ "pre_shared_key",    algtype_psk,            OAKLEY_ATTR_AUTH_METHOD_PSKEY, },
-{ "dsssig",    algtype_dsssig,         OAKLEY_ATTR_AUTH_METHOD_DSSSIG, },
-{ "rsasig",    algtype_rsasig,         OAKLEY_ATTR_AUTH_METHOD_RSASIG, },
-{ "rsaenc",    algtype_rsaenc,         OAKLEY_ATTR_AUTH_METHOD_RSAENC, },
-{ "rsarev",    algtype_rsarev,         OAKLEY_ATTR_AUTH_METHOD_RSAREV, },
-{ "gssapi_krb",        algtype_gssapikrb,      OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, },
+{ "pre_shared_key",    algtype_psk,    OAKLEY_ATTR_AUTH_METHOD_PSKEY, },
+{ "dsssig",            algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, },
+{ "rsasig",            algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, },
+{ "rsaenc",            algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, },
+{ "rsarev",            algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, },
+
+{ "gssapi_krb",                algtype_gssapikrb,
+    OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, },
+
 #ifdef ENABLE_HYBRID
-{ "hybrid_rsa_server",        algtype_hybrid_rsa_s,
-       OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, },
-{ "hybrid_dss_server",        algtype_hybrid_dss_s,
-       OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, },
-{ "hybrid_rsa_client",        algtype_hybrid_rsa_c,
-       OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, },
-{ "hybrid_dss_client",        algtype_hybrid_dss_c,
-       OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, },
+{ "hybrid_rsa_server", algtype_hybrid_rsa_s,   
+    OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, },
+
+{ "hybrid_dss_server", algtype_hybrid_dss_s,   
+    OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, },
+
+{ "xauth_psk_server",  algtype_xauth_psk_s,    
+    OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R, },
+
+{ "xauth_rsa_server",  algtype_xauth_rsa_s,    
+    OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R, },
+
+{ "hybrid_rsa_client", algtype_hybrid_rsa_c,   
+    OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, },
+
+{ "hybrid_dss_client", algtype_hybrid_dss_c,   
+    OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, },
+
+{ "xauth_psk_client",  algtype_xauth_psk_c,    
+    OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I, },
+
+{ "xauth_rsa_client",  algtype_xauth_rsa_c,    
+    OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I, },
 #endif
 };
 
@@ -394,7 +418,7 @@ alg_oakley_hmacdef_one(doi, key, buf)
 
 #ifdef ENABLE_STATS
        gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s size=%d): %8.6f", __func__,
+       syslog(LOG_NOTICE, "%s(%s size=%zu): %8.6f", __func__,
                f->name, buf->l, timedelta(&start, &end));
 #endif
 
@@ -506,7 +530,7 @@ alg_oakley_encdef_decrypt(doi, buf, key, iv)
 
 #ifdef ENABLE_STATS
        gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__,
+       syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__,
                f->name, key->l << 3, buf->l, timedelta(&start, &end));
 #endif
        return res;
@@ -535,7 +559,7 @@ alg_oakley_encdef_encrypt(doi, buf, key, iv)
 
 #ifdef ENABLE_STATS
        gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__,
+       syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__,
                f->name, key->l << 3, buf->l, timedelta(&start, &end));
 #endif
        return res;
@@ -594,7 +618,7 @@ alg_ipsec_hmacdef(doi)
        for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++)
                if (doi == ipsec_hmacdef[i].doi) {
                        plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
-                               oakley_hmacdef[i].name);
+                               ipsec_hmacdef[i].name);
                        return &ipsec_hmacdef[i];
                }
        return NULL;
index e4fc1fe126332b425fce502b134ce4c7b6a2261a..3d1d51b027af72b5d5b165f77f9bb50c102ffedd 100644 (file)
 #define _ALGORITHM_H
 
 #include <gnuc.h>
+#include "Algorithm_types.h"
 
-/* algorithm class */
-enum {
-       algclass_ipsec_enc,
-       algclass_ipsec_auth,
-       algclass_ipsec_comp,
-       algclass_isakmp_enc,
-       algclass_isakmp_hash,
-       algclass_isakmp_dh,
-       algclass_isakmp_ameth,  /* authentication method. */
-#define MAXALGCLASS    7
-};
-
-#define ALG_DEFAULT_KEYLEN     64
-
-#define ALGTYPE_NOTHING                0
-
-/* algorithm type */
-enum algtype {
-       algtype_nothing = 0,
-
-       /* enc */
-       algtype_des_iv64,
-       algtype_des,
-       algtype_3des,
-       algtype_rc5,
-       algtype_idea,
-       algtype_cast128,
-       algtype_blowfish,
-       algtype_3idea,
-       algtype_des_iv32,
-       algtype_rc4,
-       algtype_null_enc,
-       algtype_aes,
-       algtype_twofish,
-
-       /* ipsec auth */
-       algtype_hmac_md5,
-       algtype_hmac_sha1,
-       algtype_des_mac,
-       algtype_kpdk,
-       algtype_non_auth,
-       algtype_hmac_sha2_256,
-       algtype_hmac_sha2_384,
-       algtype_hmac_sha2_512,
-
-       /* ipcomp */
-       algtype_oui,
-       algtype_deflate,
-       algtype_lzs,
-
-       /* hash */
-       algtype_md5,
-       algtype_sha1,
-       algtype_tiger,
-       algtype_sha2_256,
-       algtype_sha2_384,
-       algtype_sha2_512,
-
-       /* dh_group */
-       algtype_modp768,
-       algtype_modp1024,
-       algtype_ec2n155,
-       algtype_ec2n185,
-       algtype_modp1536,
-       algtype_modp2048,
-       algtype_modp3072,
-       algtype_modp4096,
-       algtype_modp6144,
-       algtype_modp8192,
-
-       /* authentication method. */
-       algtype_psk,
-       algtype_dsssig,
-       algtype_rsasig,
-       algtype_rsaenc,
-       algtype_rsarev,
-       algtype_gssapikrb,
-#ifdef ENABLE_HYBRID
-       algtype_hybrid_rsa_s,
-       algtype_hybrid_dss_s,
-       algtype_hybrid_rsa_c,
-       algtype_hybrid_dss_c,
-#endif
-};
 
 struct hmac_algorithm {
        char *name;
diff --git a/ipsec-tools/racoon/algorithm_types.h b/ipsec-tools/racoon/algorithm_types.h
new file mode 100644 (file)
index 0000000..aca2f18
--- /dev/null
@@ -0,0 +1,125 @@
+/* $Id: algorithm.h,v 1.8 2004/11/18 15:14:44 ludvigm Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ALGORITHM_TYPES_H
+#define _ALGORITHM_TYPES_H
+
+
+/* algorithm class */
+enum {
+       algclass_ipsec_enc,
+       algclass_ipsec_auth,
+       algclass_ipsec_comp,
+       algclass_isakmp_enc,
+       algclass_isakmp_hash,
+       algclass_isakmp_dh,
+       algclass_isakmp_ameth,  /* authentication method. */
+#define MAXALGCLASS    7
+};
+
+#define ALG_DEFAULT_KEYLEN     64
+
+#define ALGTYPE_NOTHING                0
+
+/* algorithm type */
+enum algtype {
+       algtype_nothing = 0,
+
+       /* enc */
+       algtype_des_iv64,
+       algtype_des,
+       algtype_3des,
+       algtype_rc5,
+       algtype_idea,
+       algtype_cast128,
+       algtype_blowfish,
+       algtype_3idea,
+       algtype_des_iv32,
+       algtype_rc4,
+       algtype_null_enc,
+       algtype_aes,
+       algtype_twofish,
+
+       /* ipsec auth */
+       algtype_hmac_md5,
+       algtype_hmac_sha1,
+       algtype_des_mac,
+       algtype_kpdk,
+       algtype_non_auth,
+       algtype_hmac_sha2_256,
+       algtype_hmac_sha2_384,
+       algtype_hmac_sha2_512,
+
+       /* ipcomp */
+       algtype_oui,
+       algtype_deflate,
+       algtype_lzs,
+
+       /* hash */
+       algtype_md5,
+       algtype_sha1,
+       algtype_tiger,
+       algtype_sha2_256,
+       algtype_sha2_384,
+       algtype_sha2_512,
+
+       /* dh_group */
+       algtype_modp768,
+       algtype_modp1024,
+       algtype_ec2n155,
+       algtype_ec2n185,
+       algtype_modp1536,
+       algtype_modp2048,
+       algtype_modp3072,
+       algtype_modp4096,
+       algtype_modp6144,
+       algtype_modp8192,
+
+       /* authentication method. */
+       algtype_psk,
+       algtype_dsssig,
+       algtype_rsasig,
+       algtype_rsaenc,
+       algtype_rsarev,
+       algtype_gssapikrb,
+#ifdef ENABLE_HYBRID
+       algtype_hybrid_rsa_s,
+       algtype_hybrid_dss_s,
+       algtype_hybrid_rsa_c,
+       algtype_hybrid_dss_c,
+       algtype_xauth_psk_s,
+       algtype_xauth_psk_c,
+       algtype_xauth_rsa_s,
+       algtype_xauth_rsa_c,
+#endif
+};
+
+#endif
\ No newline at end of file
index e19032a0bae4c21bbb67396be0ffe0c79d2f8b1b..ce041c49cf0d653d01a6be724f9c35a9cb2dad94 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: cfparse.y,v 1.37.2.7 2006/02/02 14:37:17 vanhu Exp $ */
+/*     $NetBSD: cfparse.y,v 1.18.4.3 2007/08/01 11:52:19 vanhu Exp $   */
+
+/* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */
 
 %{
 /*
@@ -55,6 +57,7 @@
 #include <netdb.h>
 #include <pwd.h>
 #include <grp.h>
+#include <signal.h>
 
 #include "var.h"
 #include "misc.h"
 #include "isakmp_var.h"
 #include "handler.h"
 #include "isakmp.h"
+#include "nattraversal.h"
+#include "isakmp_frag.h"
 #ifdef ENABLE_HYBRID
+#include "resolv.h"
+#include "isakmp_unity.h"
 #include "isakmp_xauth.h"
 #include "isakmp_cfg.h"
 #endif
@@ -92,6 +99,8 @@
 #endif
 #include "vendorid.h"
 #include "rsalist.h"
+#include "ipsecConfigTracer.h"
+#include "ipsecMessageTracer.h"
 
 
 static int num2dhgroup[] = {
@@ -120,6 +129,7 @@ static struct remoteconf *cur_rmconf;
 static int tmpalgtype[MAXALGCLASS];
 static struct sainfo *cur_sainfo;
 static int cur_algclass;
+static int oldloglevel = LLV_BASE;
 
 static struct proposalspec *newprspec __P((void));
 static void insprspec __P((struct proposalspec *, struct proposalspec **));
@@ -164,9 +174,10 @@ static int fix_lifebyte __P((u_long));
        /* listen */
 %token LISTEN X_ISAKMP X_ISAKMP_NATT X_ADMIN STRICT_ADDRESS ADMINSOCK DISABLED
        /* modecfg */
-%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4
-%token CFG_AUTH_SOURCE CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LOCAL CFG_NONE
-%token CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE
+%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN
+%token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE
+%token CFG_GROUP_SOURCE CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE
+%token CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL CFG_SPLIT_INCLUDE CFG_SPLIT_DNS
 %token CFG_PFS_GROUP CFG_SAVE_PASSWD
        /* timer */
 %token RETRY RETRY_COUNTER RETRY_INTERVAL RETRY_PERSEND
@@ -180,48 +191,54 @@ static int fix_lifebyte __P((u_long));
 %token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE
 %token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE
 %token VERIFY_CERT SEND_CERT SEND_CR
-%token IDENTIFIERTYPE MY_IDENTIFIER PEERS_IDENTIFIER VERIFY_IDENTIFIER
+%token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER 
+%token PEERS_IDENTIFIER VERIFY_IDENTIFIER
 %token SHARED_SECRET SECRETTYPE
 %token OPEN_DIR_AUTH_GROUP IN_KEYCHAIN
 %token CERTIFICATE_VERIFICATION VERIFICATION_MODULE VERIFICATION_OPTION
 %token DNSSEC CERT_X509 CERT_PLAINRSA
 %token NONCE_SIZE DH_GROUP KEEPALIVE PASSIVE INITIAL_CONTACT
-%token NAT_TRAVERSAL NAT_TRAVERSAL_LEVEL NAT_TRAVERSAL_MULTI_USER
+%token NAT_TRAVERSAL REMOTE_FORCE_LEVEL NAT_TRAVERSAL_LEVEL NAT_TRAVERSAL_MULTI_USER NAT_TRAVERSAL_KEEPALIVE 
 %token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL
-%token GENERATE_POLICY SUPPORT_PROXY
+%token GENERATE_POLICY GENERATE_LEVEL SUPPORT_PROXY
 %token PROPOSAL
 %token EXEC_PATH EXEC_COMMAND EXEC_SUCCESS EXEC_FAILURE
 %token GSS_ID GSS_ID_ENC GSS_ID_ENCTYPE
 %token COMPLEX_BUNDLE
-%token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL
-%token XAUTH_LOGIN
+%token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL DPD_ALGORITHM
+%token DISCONNECT_ON_IDLE IDLE_TIMEOUT IDLE_DIRECTION
+%token XAUTH_LOGIN WEAK_PHASE1_CHECK
 
 %token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG
-%token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH
+%token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID
 
 %token SCRIPT PHASE1_UP PHASE1_DOWN
 
 %token NUMBER SWITCH BOOLEAN
-%token HEXSTRING QUOTEDSTRING ADDRSTRING
+%token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE
 %token UNITTYPE_BYTE UNITTYPE_KBYTES UNITTYPE_MBYTES UNITTYPE_TBYTES
 %token UNITTYPE_SEC UNITTYPE_MIN UNITTYPE_HOUR
 %token EOS BOC EOC COMMA
+%token DPD_ALGO_TYPE_DEFAULT DPD_ALGO_TYPE_INBOUND DPD_ALGO_TYPE_BLACKHOLE
+%token IDLE_DIRECTION_IN IDLE_DIRECTION_OUT IDLE_DIRECTION_ANY
 
 %type <num> NUMBER BOOLEAN SWITCH keylength
-%type <num> PATHTYPE IDENTIFIERTYPE LOGLEV GSS_ID_ENCTYPE
+%type <num> PATHTYPE IDENTIFIERTYPE IDENTIFIERQUAL LOGLEV GSS_ID_ENCTYPE
 %type <num> SECRETTYPE
 %type <num> ALGORITHM_CLASS dh_group_num
 %type <num> ALGORITHMTYPE STRENGTHTYPE
 %type <num> PREFIX prefix PORT port ike_port
 %type <num> ul_proto UL_PROTO
 %type <num> EXCHANGETYPE DOITYPE SITUATIONTYPE
-%type <num> CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL NAT_TRAVERSAL_LEVEL
+%type <num> CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL NAT_TRAVERSAL_LEVEL GENERATE_LEVEL
 %type <num> VERIFICATION_MODULE VERIFICATION_OPTION
 %type <num> unittype_time unittype_byte
-%type <val> QUOTEDSTRING HEXSTRING ADDRSTRING sainfo_id
+%type <val> QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id
 %type <val> identifierstring
 %type <saddr> remote_index ike_addrinfo_port
 %type <alg> algorithm
+%type <num> dpd_algo_type
+%type <num> idle_dir_type
 
 %%
 
@@ -259,7 +276,7 @@ privsep_stmt
                        struct passwd *pw;
 
                        if ((pw = getpwnam($2->v)) == NULL) {
-                               yyerror("unkown user \"%s\"", $2->v);
+                               yyerror("unknown user \"%s\"", $2->v);
                                return -1;
                        }
                        lcconf->uid = pw->pw_uid;
@@ -271,7 +288,7 @@ privsep_stmt
                        struct group *gr;
 
                        if ((gr = getgrnam($2->v)) == NULL) {
-                               yyerror("unkown group \"%s\"", $2->v);
+                               yyerror("unknown group \"%s\"", $2->v);
                                return -1;
                        }
                        lcconf->gid = gr->gr_gid;
@@ -295,7 +312,8 @@ path_statement
                                racoon_free(lcconf->pathinfo[$2]);
 
                        /* set new pathinfo */
-                       lcconf->pathinfo[$2] = strdup($3->v);
+                       lcconf->pathinfo[$2] = racoon_strdup($3->v);
+                       STRDUP_FATAL(lcconf->pathinfo[$2]);
                        vfree($3);
                }
                EOS
@@ -332,7 +350,7 @@ gssenc_statement
                }
        ;
 
-       /* self infomation */
+       /* self information */
 identifier_statement
        :       IDENTIFIER identifier_stmt
        ;
@@ -373,11 +391,12 @@ log_level
        |       LOGLEV
                {
                        /*
-                        * set the loglevel by configuration file only when
-                        * the command line did not specify any loglevel.
+                        * set the loglevel to the value specified
+                        * in the configuration file plus the number
+                        * of -d options specified on the command line
                         */
-                       if (loglevel <= LLV_BASE)
-                               loglevel += $1;
+                       loglevel += $1 - oldloglevel;
+                       oldloglevel = $1;
                }
        ;
 
@@ -482,9 +501,10 @@ modecfg_stmt
        :       CFG_NET4 ADDRSTRING
                {
 #ifdef ENABLE_HYBRID
-                if (inet_pton(AF_INET, $2->v,
-                    &isakmp_cfg_config.network4) != 1)
-                       yyerror("bad IPv4 network address.");
+                       if (inet_pton(AF_INET, $2->v,
+                            &isakmp_cfg_config.network4) != 1)
+                               yyerror("bad IPv4 network address.");
+                       vfree($2);
 #else
                        yyerror("racoon not configured with --enable-hybrid");
 #endif
@@ -496,28 +516,47 @@ modecfg_stmt
                        if (inet_pton(AF_INET, $2->v,
                            &isakmp_cfg_config.netmask4) != 1)
                                yyerror("bad IPv4 netmask address.");
+                       vfree($2);
 #else
                        yyerror("racoon not configured with --enable-hybrid");
 #endif
                }
                EOS
-       |       CFG_DNS4 ADDRSTRING
+       |       CFG_DNS4 addrdnslist
+               EOS
+       |       CFG_NBNS4 addrwinslist
+               EOS
+       |       CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist
                {
 #ifdef ENABLE_HYBRID
-                       if (inet_pton(AF_INET, $2->v,
-                           &isakmp_cfg_config.dns4) != 1)
-                               yyerror("bad IPv4 DNS address.");
+                       isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN;
 #else
                        yyerror("racoon not configured with --enable-hybrid");
 #endif
                }
                EOS
-       |       CFG_NBNS4 ADDRSTRING
+       |       CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist
                {
 #ifdef ENABLE_HYBRID
-                       if (inet_pton(AF_INET, $2->v,
-                           &isakmp_cfg_config.nbns4) != 1)
-                               yyerror("bad IPv4 WINS address.");
+                       isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE;
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+               EOS
+       |       CFG_SPLIT_DNS splitdnslist
+               {
+#ifndef ENABLE_HYBRID
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+               EOS
+       |       CFG_DEFAULT_DOMAIN QUOTEDSTRING
+               {
+#ifdef ENABLE_HYBRID
+                       strlcpy(&isakmp_cfg_config.default_domain[0], 
+                           $2->v, sizeof(isakmp_cfg_config.default_domain));
+                       vfree($2);
 #else
                        yyerror("racoon not configured with --enable-hybrid");
 #endif
@@ -553,6 +592,48 @@ modecfg_stmt
 #else /* HAVE_LIBPAM */
                        yyerror("racoon not configured with --with-libpam");
 #endif /* HAVE_LIBPAM */
+#else /* ENABLE_HYBRID */
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif /* ENABLE_HYBRID */
+               }
+               EOS
+       |       CFG_AUTH_SOURCE CFG_LDAP
+               {
+#ifdef ENABLE_HYBRID
+#ifdef HAVE_LIBLDAP
+                       isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_LDAP;
+#else /* HAVE_LIBLDAP */
+                       yyerror("racoon not configured with --with-libldap");
+#endif /* HAVE_LIBLDAP */
+#else /* ENABLE_HYBRID */
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif /* ENABLE_HYBRID */
+               }
+               EOS
+       |       CFG_AUTH_GROUPS authgrouplist
+               {
+#ifndef ENABLE_HYBRID
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+               EOS
+       |       CFG_GROUP_SOURCE CFG_SYSTEM
+               {
+#ifdef ENABLE_HYBRID
+                       isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+               EOS
+       |       CFG_GROUP_SOURCE CFG_LDAP
+               {
+#ifdef ENABLE_HYBRID
+#ifdef HAVE_LIBLDAP
+                       isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_LDAP;
+#else /* HAVE_LIBLDAP */
+                       yyerror("racoon not configured with --with-libldap");
+#endif /* HAVE_LIBLDAP */
 #else /* ENABLE_HYBRID */
                        yyerror("racoon not configured with --enable-hybrid");
 #endif /* ENABLE_HYBRID */
@@ -564,6 +645,15 @@ modecfg_stmt
                        isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
 #else
                        yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+               EOS
+       |       CFG_ACCOUNTING CFG_SYSTEM
+               {
+#ifdef ENABLE_HYBRID
+                       isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM;
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
 #endif
                }
                EOS
@@ -596,15 +686,8 @@ modecfg_stmt
        |       CFG_POOL_SIZE NUMBER
                {
 #ifdef ENABLE_HYBRID
-                       size_t len;
-
-                       isakmp_cfg_config.pool_size = $2;
-
-                       len = $2 * sizeof(*isakmp_cfg_config.port_pool);
-                       isakmp_cfg_config.port_pool = racoon_malloc(len);
-                       if (isakmp_cfg_config.port_pool == NULL)
+                       if (isakmp_cfg_resize_pool($2) != 0)
                                yyerror("cannot allocate memory for pool");
-                       bzero(isakmp_cfg_config.port_pool, len);
 #else /* ENABLE_HYBRID */
                        yyerror("racoon not configured with --enable-hybrid");
 #endif /* ENABLE_HYBRID */
@@ -654,6 +737,19 @@ modecfg_stmt
 #else /* HAVE_LIBRADIUS */
                        yyerror("racoon not configured with --with-libradius");
 #endif /* HAVE_LIBRADIUS */
+#else /* ENABLE_HYBRID */
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif /* ENABLE_HYBRID */
+               }
+               EOS
+       |       CFG_CONF_SOURCE CFG_LDAP
+               {
+#ifdef ENABLE_HYBRID
+#ifdef HAVE_LIBLDAP
+                       isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LDAP;
+#else /* HAVE_LIBLDAP */
+                       yyerror("racoon not configured with --with-libldap");
+#endif /* HAVE_LIBLDAP */
 #else /* ENABLE_HYBRID */
                        yyerror("racoon not configured with --enable-hybrid");
 #endif /* ENABLE_HYBRID */
@@ -662,8 +758,7 @@ modecfg_stmt
        |       CFG_MOTD QUOTEDSTRING
                {
 #ifdef ENABLE_HYBRID
-                       strncpy(&isakmp_cfg_config.motd[0], $2->v, MAXPATHLEN);
-                       isakmp_cfg_config.motd[MAXPATHLEN] = '\0';
+                       strlcpy(&isakmp_cfg_config.motd[0], $2->v, sizeof(isakmp_cfg_config.motd));
                        vfree($2);
 #else
                        yyerror("racoon not configured with --enable-hybrid");
@@ -672,6 +767,150 @@ modecfg_stmt
                EOS
        ;
 
+addrdnslist
+       :       addrdns
+       |       addrdns COMMA addrdnslist
+       ;
+addrdns
+       :       ADDRSTRING
+               {
+#ifdef ENABLE_HYBRID
+                       struct isakmp_cfg_config *icc = &isakmp_cfg_config;
+
+                       if (icc->dns4_index > MAXNS)
+                               yyerror("No more than %d DNS", MAXNS);
+                       if (inet_pton(AF_INET, $1->v,
+                           &icc->dns4[icc->dns4_index++]) != 1)
+                               yyerror("bad IPv4 DNS address.");
+
+                       vfree($1);
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+       ;
+
+addrwinslist
+       :       addrwins
+       |       addrwins COMMA addrwinslist
+       ;
+addrwins
+       :       ADDRSTRING
+               {
+#ifdef ENABLE_HYBRID
+                       struct isakmp_cfg_config *icc = &isakmp_cfg_config;
+
+                       if (icc->nbns4_index > MAXWINS)
+                               yyerror("No more than %d WINS", MAXWINS);
+                       if (inet_pton(AF_INET, $1->v,
+                           &icc->nbns4[icc->nbns4_index++]) != 1)
+                               yyerror("bad IPv4 WINS address.");
+
+                       vfree($1);
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+       ;
+
+splitnetlist
+       :       splitnet
+       |       splitnetlist COMMA splitnet
+       ;
+splitnet
+       :       ADDRSTRING PREFIX
+               {
+#ifdef ENABLE_HYBRID
+                       struct isakmp_cfg_config *icc = &isakmp_cfg_config;
+                       struct unity_network network;
+
+                       if (inet_pton(AF_INET, $1->v, &network.addr4) != 1)
+                               yyerror("bad IPv4 SPLIT address.");
+
+                       /* Turn $2 (the prefix) into a subnet mask */
+                       network.mask4.s_addr = ($2) ? htonl(~((1 << (32 - $2)) - 1)) : 0;
+
+                       /* add the network to our list */ 
+                       if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count))
+                               yyerror("Unable to allocate split network");
+
+                       vfree($1);
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+       ;
+
+authgrouplist
+       :       authgroup
+       |       authgroup COMMA authgrouplist
+       ;
+authgroup
+       :       QUOTEDSTRING
+               {
+#ifdef ENABLE_HYBRID
+                       char * groupname = NULL;
+                       char ** grouplist = NULL;
+                       struct isakmp_cfg_config *icc = &isakmp_cfg_config;
+
+                       grouplist = racoon_realloc(icc->grouplist,
+                                       sizeof(char**)*(icc->groupcount+1));
+                       if (grouplist == NULL)
+                               yyerror("unable to allocate auth group list");
+
+                       groupname = racoon_malloc($1->l+1);
+                       if (groupname == NULL)
+                               yyerror("unable to allocate auth group name");
+
+                       memcpy(groupname,$1->v,$1->l);
+                       groupname[$1->l]=0;
+                       grouplist[icc->groupcount]=groupname;
+                       icc->grouplist = grouplist;
+                       icc->groupcount++;
+
+                       vfree($1);
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+       ;
+
+splitdnslist
+       :       splitdns
+       |       splitdns COMMA splitdnslist
+       ;
+splitdns
+       :       QUOTEDSTRING
+               {
+#ifdef ENABLE_HYBRID
+                       struct isakmp_cfg_config *icc = &isakmp_cfg_config;
+
+                       if (!icc->splitdns_len)
+                       {
+                               icc->splitdns_list = racoon_malloc($1->l);
+                               if(icc->splitdns_list == NULL)
+                                       yyerror("error allocating splitdns list buffer");
+                               memcpy(icc->splitdns_list,$1->v,$1->l);
+                               icc->splitdns_len = $1->l;
+                       }
+                       else
+                       {
+                               int len = icc->splitdns_len + $1->l + 1;
+                               icc->splitdns_list = racoon_realloc(icc->splitdns_list,len);
+                               if(icc->splitdns_list == NULL)
+                                       yyerror("error allocating splitdns list buffer");
+                               icc->splitdns_list[icc->splitdns_len] = ',';
+                               memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l);
+                               icc->splitdns_len = len;
+                       }
+                       vfree($1);
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+#endif
+               }
+       ;
+
+
        /* timer */
 timer_statement
        :       RETRY BOC timer_stmts EOC
@@ -734,7 +973,7 @@ sainfo_statement
                                return -1;
                        }
                }
-               sainfo_name sainfo_peer BOC sainfo_specs
+               sainfo_name sainfo_param BOC sainfo_specs
                {
                        struct sainfo *check;
 
@@ -774,6 +1013,16 @@ sainfo_name
                        cur_sainfo->idsrc = NULL;
                        cur_sainfo->iddst = NULL;
                }
+       |       ANONYMOUS sainfo_id
+               {
+                       cur_sainfo->idsrc = NULL;
+                       cur_sainfo->iddst = $2;
+               }
+       |       sainfo_id ANONYMOUS
+               {
+                       cur_sainfo->idsrc = $1;
+                       cur_sainfo->iddst = NULL;
+               }
        |       sainfo_id sainfo_id
                {
                        cur_sainfo->idsrc = $1;
@@ -806,14 +1055,8 @@ sainfo_id
                                        return -1;
                                }
                                $$ = ipsecdoi_sockaddr2id(saddr,
-#if 0
-                                       $3 == (sizeof(struct in_addr) << 3) &&
-                                               $1 == IDTYPE_ADDRESS
-                                         ? ~0 : $3,
-#else
-                                       $3 == ~0 ? (sizeof(struct in_addr) << 3): $3,
-#endif
-                                       $5);
+                                                                                 $3 == ~0 ? (sizeof(struct in_addr) << 3): $3,
+                                                                                 $5);
                                break;
 #ifdef INET6
                        case AF_INET6:
@@ -822,15 +1065,9 @@ sainfo_id
                                        racoon_free(saddr);
                                        return -1;
                                }
-                               $$ = ipsecdoi_sockaddr2id(saddr,
-#if 0
-                                       $3 == (sizeof(struct in6_addr) << 3) &&
-                                               $1 == IDTYPE_ADDRESS
-                                         ? ~0 : $3,
-#else
-                               $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3,
-#endif
-                                       $5);
+                               $$ = ipsecdoi_sockaddr2id(saddr, 
+                                                                                 $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3,
+                                                                                 $5);
                                break;
 #endif
                        default:
@@ -842,6 +1079,71 @@ sainfo_id
                        if ($$ == NULL)
                                return -1;
                }
+       |       IDENTIFIERTYPE ADDRSTRING ADDRRANGE prefix port ul_proto
+               {
+                       char portbuf[10];
+                       struct sockaddr *laddr = NULL, *haddr = NULL;
+                       char *cur = NULL;
+
+                       if (($6 == IPPROTO_ICMP || $6 == IPPROTO_ICMPV6)
+                        && ($5 != IPSEC_PORT_ANY || $5 != IPSEC_PORT_ANY)) {
+                               yyerror("port number must be \"any\".");
+                               return -1;
+                       }
+
+                       snprintf(portbuf, sizeof(portbuf), "%lu", $5);
+                       
+                       laddr = str2saddr($2->v, portbuf);
+                       if (laddr == NULL) {
+                           return -1;
+                       }
+                       vfree($2);
+                       haddr = str2saddr($3->v, portbuf);
+                       if (haddr == NULL) {
+                           racoon_free(laddr);
+                           return -1;
+                       }
+                       vfree($3);
+
+                       switch (laddr->sa_family) {
+                       case AF_INET:
+                               if ($6 == IPPROTO_ICMPV6) {
+                                   yyerror("upper layer protocol mismatched.\n");
+                                   if (laddr)
+                                       racoon_free(laddr);
+                                   if (haddr)
+                                       racoon_free(haddr);
+                                   return -1;
+                               }
+                                $$ = ipsecdoi_sockrange2id(laddr, haddr, 
+                                                          $6);
+                               break;
+#ifdef INET6
+                       case AF_INET6:
+                               if ($6 == IPPROTO_ICMP) {
+                                       yyerror("upper layer protocol mismatched.\n");
+                                       if (laddr)
+                                           racoon_free(laddr);
+                                       if (haddr)
+                                           racoon_free(haddr);
+                                       return -1;
+                               }
+                               $$ = ipsecdoi_sockrange2id(laddr, haddr, 
+                                                              $6);
+                               break;
+#endif
+                       default:
+                               yyerror("invalid family: %d", laddr->sa_family);
+                               $$ = NULL;
+                               break;
+                       }
+                       if (laddr)
+                           racoon_free(laddr);
+                       if (haddr)
+                           racoon_free(haddr);
+                       if ($$ == NULL)
+                               return -1;
+               }
        |       IDENTIFIERTYPE QUOTEDSTRING
                {
                        struct ipsecdoi_id_b *id_b;
@@ -869,7 +1171,7 @@ sainfo_id
                        memcpy($$->v + sizeof(*id_b), $2->v, $2->l);
                }
        ;
-sainfo_peer
+sainfo_param
        :       /* nothing */
                {
                        cur_sainfo->id_i = NULL;
@@ -900,6 +1202,18 @@ sainfo_peer
                               idv->v, idv->l);
                        vfree(idv);
                }
+       |       GROUP QUOTEDSTRING
+               {
+#ifdef ENABLE_HYBRID
+                       if ((cur_sainfo->group = vdup($2)) == NULL) {
+                               yyerror("failed to set sainfo xauth group.\n");
+                               return -1;
+                       }
+#else
+                       yyerror("racoon not configured with --enable-hybrid");
+                       return -1;
+#endif
+               }
        ;
 sainfo_specs
        :       /* nothing */
@@ -1201,7 +1515,11 @@ remote_spec
                        yywarn("This directive without certtype will be removed!\n");
                        yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v);
                        cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
-                       cur_rmconf->peerscertfile = strdup($2->v);
+
+                       if (cur_rmconf->peerscertfile != NULL)
+                               racoon_free(cur_rmconf->peerscertfile);
+                       cur_rmconf->peerscertfile = racoon_strdup($2->v);
+                       STRDUP_FATAL(cur_rmconf->peerscertfile);
                        vfree($2);
                }
                EOS
@@ -1209,14 +1527,20 @@ remote_spec
                {
                        cur_rmconf->cacerttype = $2;
                        cur_rmconf->getcacert_method = ISAKMP_GETCERT_LOCALFILE;
-                       cur_rmconf->cacertfile = strdup($3->v);
+                       if (cur_rmconf->cacertfile != NULL)
+                               racoon_free(cur_rmconf->cacertfile);
+                       cur_rmconf->cacertfile = racoon_strdup($3->v);
+                       STRDUP_FATAL(cur_rmconf->cacertfile);
                        vfree($3);
                }
                EOS
        |       PEERS_CERTFILE CERT_X509 QUOTEDSTRING
                {
                        cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
-                       cur_rmconf->peerscertfile = strdup($3->v);
+                       if (cur_rmconf->peerscertfile != NULL)
+                               racoon_free(cur_rmconf->peerscertfile);
+                       cur_rmconf->peerscertfile = racoon_strdup($3->v);
+                       STRDUP_FATAL(cur_rmconf->peerscertfile);
                        vfree($3);
                }
                EOS
@@ -1278,7 +1602,7 @@ remote_spec
                EOS
        |       OPEN_DIR_AUTH_GROUP QUOTEDSTRING 
                { 
-#ifdef __APPLE__
+#if defined(__APPLE__) && HAVE_OPENDIR
                        cur_rmconf->open_dir_auth_group = $2; 
 #else
                        yyerror("Apple specific features not compiled in.");
@@ -1296,16 +1620,28 @@ remote_spec
                        cur_rmconf->idvtype = $2;
                }
                EOS
+       |       MY_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
+               {
+                       if (set_identifier_qual(&cur_rmconf->idv, $2, $4, $3) != 0) {
+                               yyerror("failed to set identifer.\n");
+                               return -1;
+                       }
+                       cur_rmconf->idvtype = $2;
+               }
+               EOS
        |       XAUTH_LOGIN identifierstring
                {
 #ifdef ENABLE_HYBRID
                        /* formerly identifier type login */
-                       cur_rmconf->idvtype = IDTYPE_LOGIN;
-                       if (set_identifier(&cur_rmconf->idv, IDTYPE_LOGIN, $2) != 0) {
+                       if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) {
+                               yyerror("failed to allocate xauth state\n");
+                               return -1;
+                       }
+                       if ((cur_rmconf->xauth->login = vdup($2)) == NULL) {
                                yyerror("failed to set identifer.\n");
                                return -1;
                        }
-                       /* cur_rmconf->use_xauth = 1; */
+                       vfree($2);      //%%% BUG FIX - memory leak
 #else
                        yyerror("racoon not configured with --enable-hybrid");
 #endif
@@ -1330,6 +1666,23 @@ remote_spec
                        genlist_append (cur_rmconf->idvl_p, id);
                }
                EOS
+       |       PEERS_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
+               {
+                       struct idspec  *id;
+                       id = newidspec();
+                       if (id == NULL) {
+                               yyerror("failed to allocate idspec");
+                               return -1;
+                       }
+                       if (set_identifier_qual(&id->id, $2, $4, $3) != 0) {
+                               yyerror("failed to set identifer.\n");
+                               racoon_free(id);
+                               return -1;
+                       }
+                       id->idtype = $2;
+                       genlist_append (cur_rmconf->idvl_p, id);
+               }
+               EOS
        |       VERIFY_IDENTIFIER SWITCH { cur_rmconf->verify_identifier = $2; } EOS
        |       SHARED_SECRET SECRETTYPE QUOTEDSTRING 
                {
@@ -1364,23 +1717,37 @@ remote_spec
                dh_group_num EOS
        |       PASSIVE SWITCH { cur_rmconf->passive = $2; } EOS
        |       IKE_FRAG SWITCH { cur_rmconf->ike_frag = $2; } EOS
+       |       IKE_FRAG REMOTE_FORCE_LEVEL { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } EOS
        |       ESP_FRAG NUMBER { 
 #ifdef SADB_X_EXT_NAT_T_FRAG
-                       cur_rmconf->esp_frag = $2; 
+                       if (libipsec_opt & LIBIPSEC_OPT_FRAG)
+                               cur_rmconf->esp_frag = $2; 
+                       else
+                               yywarn("libipsec lacks IKE frag support");
 #else
                        yywarn("Your kernel does not support esp_frag");
 #endif
                } EOS
        |       SCRIPT QUOTEDSTRING PHASE1_UP { 
+                       if (cur_rmconf->script[SCRIPT_PHASE1_UP] != NULL)
+                               vfree(cur_rmconf->script[SCRIPT_PHASE1_UP]);
+
                        cur_rmconf->script[SCRIPT_PHASE1_UP] = 
                            script_path_add(vdup($2));
                } EOS
        |       SCRIPT QUOTEDSTRING PHASE1_DOWN { 
+                       if (cur_rmconf->script[SCRIPT_PHASE1_DOWN] != NULL)
+                               vfree(cur_rmconf->script[SCRIPT_PHASE1_DOWN]);
+
                        cur_rmconf->script[SCRIPT_PHASE1_DOWN] = 
                            script_path_add(vdup($2));
                } EOS
        |       MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS
+       |       WEAK_PHASE1_CHECK SWITCH {
+                       cur_rmconf->weak_phase1_check = $2;
+               } EOS
        |       GENERATE_POLICY SWITCH { cur_rmconf->gen_policy = $2; } EOS
+       |       GENERATE_POLICY GENERATE_LEVEL { cur_rmconf->gen_policy = $2; } EOS
        |       SUPPORT_PROXY SWITCH { cur_rmconf->support_proxy = $2; } EOS
        |       INITIAL_CONTACT SWITCH { cur_rmconf->ini_contact = $2; } EOS
        |       NAT_TRAVERSAL SWITCH
@@ -1411,7 +1778,19 @@ remote_spec
                        yyerror("NAT-T support not compiled in.");
 #endif
                } EOS
-       |       DPD SWITCH
+       |       NAT_TRAVERSAL_KEEPALIVE SWITCH
+       {
+#ifdef ENABLE_NATT
+#ifdef __APPLE__
+                       cur_rmconf->natt_keepalive = $2;
+#else
+                       yyerror("Apple specific features not compiled in.");
+#endif
+#else
+                       yyerror("NAT-T support not compiled in.");
+#endif
+       } EOS
+|      DPD SWITCH
                {
 #ifdef ENABLE_DPD
                        cur_rmconf->dpd = $2;
@@ -1446,6 +1825,21 @@ remote_spec
 #endif
                }
                EOS
+    |  DPD_ALGORITHM dpd_algo_type
+        {
+#ifdef ENABLE_DPD
+            cur_rmconf->dpd_algo = $2;
+#else
+            yyerror("DPD support not compiled in.");
+#endif
+        }
+        EOS
+    |  DISCONNECT_ON_IDLE IDLE_TIMEOUT NUMBER IDLE_DIRECTION idle_dir_type
+        {
+            cur_rmconf->idle_timeout     = $3;
+            cur_rmconf->idle_timeout_dir = $5;
+        }
+               EOS
        |       LIFETIME LIFETYPE_TIME NUMBER unittype_time
                {
                        cur_rmconf->prhead->lifetime = $3 * $4;
@@ -1484,7 +1878,7 @@ exchange_types
                        struct etypes *new;
                        new = racoon_malloc(sizeof(struct etypes));
                        if (new == NULL) {
-                               yyerror("filed to allocate etypes");
+                               yyerror("failed to allocate etypes");
                                return -1;
                        }
                        new->type = $2;
@@ -1505,9 +1899,15 @@ cert_spec
        :       CERT_X509 QUOTEDSTRING QUOTEDSTRING
                {
                        cur_rmconf->certtype = $1;
-                       cur_rmconf->mycertfile = strdup($2->v);
+                       if (cur_rmconf->mycertfile != NULL)
+                               racoon_free(cur_rmconf->mycertfile);
+                       cur_rmconf->mycertfile = racoon_strdup($2->v);
+                       STRDUP_FATAL(cur_rmconf->mycertfile);
                        vfree($2);
-                       cur_rmconf->myprivfile = strdup($3->v);
+                       if (cur_rmconf->myprivfile != NULL)
+                               racoon_free(cur_rmconf->myprivfile);
+                       cur_rmconf->myprivfile = racoon_strdup($3->v);
+                       STRDUP_FATAL(cur_rmconf->myprivfile);
                        vfree($3);
                }
                EOS
@@ -1615,7 +2015,11 @@ isakmpproposal_spec
                                yyerror("wrong Vendor ID for gssapi_id");
                                return -1;
                        }
-                       cur_rmconf->prhead->spspec->gssid = strdup($2->v);
+                       if (cur_rmconf->prhead->spspec->gssid != NULL)
+                               racoon_free(cur_rmconf->prhead->spspec->gssid);
+                       cur_rmconf->prhead->spspec->gssid = 
+                           racoon_strdup($2->v);
+                       STRDUP_FATAL(cur_rmconf->prhead->spspec->gssid);
                }
                EOS
        |       ALGORITHM_CLASS ALGORITHMTYPE keylength
@@ -1726,6 +2130,16 @@ unittype_byte
        |       UNITTYPE_MBYTES { $$ = (1024 * 1024); }
        |       UNITTYPE_TBYTES { $$ = (1024 * 1024 * 1024); }
        ;
+dpd_algo_type
+    :  DPD_ALGO_TYPE_DEFAULT   { $$ = DPD_ALGO_DEFAULT; }
+    |  DPD_ALGO_TYPE_INBOUND   { $$ = DPD_ALGO_INBOUND_DETECT; }
+    |  DPD_ALGO_TYPE_BLACKHOLE { $$ = DPD_ALGO_BLACKHOLE_DETECT; }
+    ;
+idle_dir_type
+    :  IDLE_DIRECTION_ANY      { $$ = IPSEC_DIR_ANY; }
+    |  IDLE_DIRECTION_IN       { $$ = IPSEC_DIR_INBOUND; }
+    |  IDLE_DIRECTION_OUT      { $$ = IPSEC_DIR_OUTBOUND; }
+    ;
 %%
 
 static struct proposalspec *
@@ -1962,7 +2376,11 @@ expand_isakmpspec(prop_no, trns_no, types,
 #ifdef HAVE_GSSAPI
        if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
                if (gssid != NULL) {
-                       new->gssid = vmalloc(strlen(gssid));
+                       if ((new->gssid = vmalloc(strlen(gssid))) == NULL) {
+                               racoon_free(new);
+                               yyerror("failed to allocate gssid");
+                               return -1;
+                       }
                        memcpy(new->gssid->v, gssid, new->gssid->l);
                        racoon_free(gssid);
                } else {
@@ -2039,8 +2457,16 @@ cfparse()
 
        yycf_init_buffer();
 
-       if (yycf_switch_buffer(lcconf->racoon_conf) != 0)
+       if (yycf_switch_buffer(lcconf->racoon_conf) != 0) {
+        IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf),
+                               IPSECCONFIGEVENTCODE_PARSE_ERROR,
+                               CONSTSTR("could not read configuration file"),
+                               CONSTSTR("cfparse: yycf_switch_buffer erred"));
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "could not read configuration file \"%s\"\n", 
+                   lcconf->racoon_conf);
                return -1;
+       }
 
        error = yyparse();
        if (error != 0) {
@@ -2052,6 +2478,11 @@ cfparse()
                        plog(LLV_ERROR, LOCATION, NULL,
                                "fatal parse failure.\n");
                }
+        IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf),
+                               IPSECCONFIGEVENTCODE_PARSE_ERROR,
+                               CONSTSTR("fatal parse failure"),
+                               CONSTSTR("cfparse: yyparse erred"));
+               yycf_clean_buffer();
                return -1;
        }
 
@@ -2059,6 +2490,11 @@ cfparse()
                plog(LLV_ERROR, LOCATION, NULL,
                        "parse error is nothing, but yyerrorcount is %d.\n",
                                yyerrorcount);
+        IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf),
+                               IPSECCONFIGEVENTCODE_PARSE_ERROR,
+                               CONSTSTR("ambivalent error code"),
+                               CONSTSTR("cfparse: error == 0 && yerrorcount"));
+               yycf_clean_buffer();
                exit(1);
        }
 
@@ -2070,14 +2506,28 @@ cfparse()
 }
 
 int
-cfreparse()
+cfreparse(int sig)
 {
-       plog(LLV_DEBUG, LOCATION, NULL, "==== Got HUP signal - re-parsing.\n");
-       flushph2();
-       flushph1();
+       int ignore_established_handles = (sig == SIGUSR1);
+
+       if (sig >= 0 && sig < NSIG) {
+               plog(LLV_DEBUG, LOCATION, NULL, "==== Got %s signal - re-parsing.\n", sys_signame[sig]);
+       } else {
+               plog(LLV_ERROR, LOCATION, NULL, "==== Got Unknown signal - re-parsing.\n");
+        IPSECCONFIGTRACEREVENT(CONSTSTR("reparse"),
+                               IPSECCONFIGEVENTCODE_REPARSE_ERROR,
+                               CONSTSTR("Unknown signal"),
+                               CONSTSTR("cfreparse: triggered by unknown signal"));
+       }
+
+       flushph2(ignore_established_handles);
+       flushph1(ignore_established_handles);
        flushrmconf();
        flushsainfo();
        flushlcconf();
+#ifdef HAVE_LIBLDAP
+       xauth_ldap_flush();
+#endif
        check_auto_exit();      /* check/change state of auto exit */
        clean_tmpalgtype();
 
index 73c824ecb3f1db812a4b3ceb20e057067ce73703..010cdcd7a5a6dc32588ac2d74277139e94e66712 100644 (file)
@@ -35,6 +35,6 @@
 /* cfparse.y */
 extern int yyparse __P((void));
 extern int cfparse __P((void));
-extern int cfreparse __P((void));
+extern int cfreparse __P((int));
 
 #endif /* _CFPARSE_PROTO_H */
index 861e836ac7b10844febb440a38652026e754dd93..4d825998fc410df058f7b96fa4feb35d958d3bb9 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: cftoken.l,v 1.31.2.7 2005/11/06 17:18:26 monas Exp $ */
+/*     $NetBSD: cftoken.l,v 1.11.4.1 2007/08/01 11:52:20 vanhu Exp $   */
+
+/* Id: cftoken.l,v 1.53 2006/08/22 18:17:17 manubsd Exp */
 %option noyywrap
 %{
 /*
@@ -75,7 +77,9 @@
 #include "isakmp_var.h"
 #include "isakmp.h"
 #include "ipsec_doi.h"
+#include "policy.h"
 #include "proposal.h"
+#include "remoteconf.h"
 #include "nattraversal.h"
 #ifdef GC
 #include "gcmalloc.h"
@@ -131,6 +135,7 @@ bcl         \{
 ecl            \}
 blcl           \[
 elcl           \]
+hyphen          \-
 percent                \%
 semi           \;
 comment                \#.*
@@ -172,7 +177,7 @@ hexstring   0x{hexdigit}+
                                return(PATHTYPE); }
 <S_PTH>certificate     { YYD; yylval.num = LC_PATHTYPE_CERT;
                                return(PATHTYPE); }
-<S_PTH>script          { YYD; yylval.num = LC_PATHTYPE_SCRIPT;
+<S_PTH>script          { YYD; yylval.num = LC_PATHTYPE_SCRIPT;
                                return(PATHTYPE); }
 <S_PTH>backupsa                { YYD; yylval.num = LC_PATHTYPE_BACKUPSA;
                                return(PATHTYPE); }
@@ -194,12 +199,14 @@ hexstring 0x{hexdigit}+
 
        /* logging */
 <S_INI>log             { BEGIN S_LOG; YYDB; return(LOGGING); }
-<S_LOG>info            { YYD; yywarn("it is obsoleted.  use \"notify\""); yylval.num = 0; return(LOGLEV); }
-<S_LOG>notify          { YYD; yylval.num = 0; return(LOGLEV); }
-<S_LOG>debug           { YYD; yylval.num = 1; return(LOGLEV); }
-<S_LOG>debug2          { YYD; yylval.num = 2; return(LOGLEV); }
-<S_LOG>debug3          { YYD; yywarn("it is osboleted.  use \"debug2\""); yylval.num = 2; return(LOGLEV); }
-<S_LOG>debug4          { YYD; yywarn("it is obsoleted.  use \"debug2\""); yylval.num = 2; return(LOGLEV); }
+<S_LOG>error           { YYD; yylval.num = LLV_ERROR; return(LOGLEV); }
+<S_LOG>warning         { YYD; yylval.num = LLV_WARNING; return(LOGLEV); }
+<S_LOG>notify          { YYD; yylval.num = LLV_NOTIFY; return(LOGLEV); }
+<S_LOG>info            { YYD; yylval.num = LLV_INFO; return(LOGLEV); }
+<S_LOG>debug           { YYD; yylval.num = LLV_DEBUG; return(LOGLEV); }
+<S_LOG>debug2          { YYD; yylval.num = LLV_DEBUG2; return(LOGLEV); }
+<S_LOG>debug3          { YYD; yywarn("it is obsoleted.  use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); }
+<S_LOG>debug4          { YYD; yywarn("it is obsoleted.  use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); }
 <S_LOG>{semi}          { BEGIN S_INI; return(EOS); }
 
        /* padding */
@@ -230,7 +237,10 @@ hexstring  0x{hexdigit}+
 <S_CFG>netmask4                { YYD; return(CFG_MASK4); }
 <S_CFG>dns4            { YYD; return(CFG_DNS4); }
 <S_CFG>wins4           { YYD; return(CFG_NBNS4); }
+<S_CFG>default_domain  { YYD; return(CFG_DEFAULT_DOMAIN); }
 <S_CFG>auth_source     { YYD; return(CFG_AUTH_SOURCE); }
+<S_CFG>auth_groups     { YYD; return(CFG_AUTH_GROUPS); }
+<S_CFG>group_source    { YYD; return(CFG_GROUP_SOURCE); }
 <S_CFG>conf_source     { YYD; return(CFG_CONF_SOURCE); }
 <S_CFG>accounting      { YYD; return(CFG_ACCOUNTING); }
 <S_CFG>system          { YYD; return(CFG_SYSTEM); }
@@ -241,8 +251,13 @@ hexstring  0x{hexdigit}+
 <S_CFG>pool_size       { YYD; return(CFG_POOL_SIZE); }
 <S_CFG>banner          { YYD; return(CFG_MOTD); }
 <S_CFG>auth_throttle   { YYD; return(CFG_AUTH_THROTTLE); }
+<S_CFG>split_network   { YYD; return(CFG_SPLIT_NETWORK); }
+<S_CFG>local_lan       { YYD; return(CFG_SPLIT_LOCAL); }
+<S_CFG>include         { YYD; return(CFG_SPLIT_INCLUDE); }
+<S_CFG>split_dns       { YYD; return(CFG_SPLIT_DNS); }
 <S_CFG>pfs_group       { YYD; return(CFG_PFS_GROUP); }
 <S_CFG>save_passwd     { YYD; return(CFG_SAVE_PASSWD); }
+<S_CFG>{comma}         { YYD; return(COMMA); }
 <S_CFG>{ecl}           { BEGIN S_INI; return(EOC); }
 
        /* timer */
@@ -263,11 +278,13 @@ hexstring 0x{hexdigit}+
 <S_SAINF>{blcl}any{elcl}       { YYD; return(PORTANY); }
 <S_SAINF>any           { YYD; return(ANY); }
 <S_SAINF>from          { YYD; return(FROM); }
+<S_SAINF>group         { YYD; return(GROUP); }
        /* sainfo spec */
 <S_SAINF>{bcl}         { BEGIN S_SAINFS; return(BOC); }
 <S_SAINF>{semi}                { BEGIN S_INI; return(EOS); }
 <S_SAINFS>{ecl}                { BEGIN S_INI; return(EOC); }
 <S_SAINFS>pfs_group    { YYD; return(PFS_GROUP); }
+<S_SAINFS>remoteid     { YYD; return(REMOTEID); }
 <S_SAINFS>identifier   { YYD; yywarn("it is obsoleted.  use \"my_identifier\"."); return(IDENTIFIER); }
 <S_SAINFS>my_identifier        { YYD; return(MY_IDENTIFIER); }
 <S_SAINFS>lifetime     { YYD; return(LIFETIME); }
@@ -306,7 +323,7 @@ hexstring   0x{hexdigit}+
 <S_RMTS>x509           { YYD; yylval.num = ISAKMP_CERT_X509SIGN; return(CERT_X509); }
 <S_RMTS>plain_rsa      { YYD; yylval.num = ISAKMP_CERT_PLAINRSA; return(CERT_PLAINRSA); }
 <S_RMTS>open_dir_auth_group    { 
-#ifdef __APPLE__
+#if defined(__APPLE__) && HAVE_OPENDIR
        YYD; 
        return(OPEN_DIR_AUTH_GROUP); 
 #else
@@ -358,6 +375,14 @@ hexstring  0x{hexdigit}+
        yyerror("Apple specific features not compiled in.");
 #endif 
 }
+<S_RMTS>nat_traversal_keepalive {
+#ifdef __APPLE__
+       YYD; 
+       return(NAT_TRAVERSAL_KEEPALIVE);
+#else
+       yyerror("Apple specific features not compiled in.");
+#endif 
+}
 <S_RMTS>proposal_check { YYD; return(PROPOSAL_CHECK); }
 <S_RMTS>obey           { YYD; yylval.num = PROP_CHECK_OBEY; return(PROPOSAL_CHECK_LEVEL); }
 <S_RMTS>strict         { YYD; yylval.num = PROP_CHECK_STRICT; return(PROPOSAL_CHECK_LEVEL); }
@@ -372,12 +397,17 @@ hexstring 0x{hexdigit}+
 <S_RMTS>dpd_delay      { YYD; return(DPD_DELAY); }
 <S_RMTS>dpd_retry      { YYD; return(DPD_RETRY); }
 <S_RMTS>dpd_maxfail    { YYD; return(DPD_MAXFAIL); }
+<S_RMTS>dpd_algorithm  { YYD; return(DPD_ALGORITHM); }
+<S_RMTS>disconnect_on_idle { YYD; return(DISCONNECT_ON_IDLE); }
+<S_RMTS>idle_timeout { YYD; return(IDLE_TIMEOUT); }
+<S_RMTS>idle_direction { YYD; return(IDLE_DIRECTION); }
 <S_RMTS>ike_frag       { YYD; return(IKE_FRAG); }
 <S_RMTS>esp_frag       { YYD; return(ESP_FRAG); }
 <S_RMTS>script         { YYD; return(SCRIPT); }
 <S_RMTS>phase1_up      { YYD; return(PHASE1_UP); }
 <S_RMTS>phase1_down    { YYD; return(PHASE1_DOWN); }
 <S_RMTS>mode_cfg       { YYD; return(MODE_CFG); }
+<S_RMTS>weak_phase1_check { YYD; return(WEAK_PHASE1_CHECK); }
        /* remote proposal */
 <S_RMTS>proposal       { BEGIN S_RMTP; YYDB; return(PROPOSAL); }
 <S_RMTP>{bcl}          { return(BOC); }
@@ -423,6 +453,19 @@ off                { YYD; yylval.num = FALSE; return(SWITCH); }
                        return(PORT);
                }
 
+       /* address range */
+{hyphen}{addrstring} {
+                        YYD;
+                        yytext++;
+                       yylval.val = vmalloc(yyleng + 1);
+                       if (yylval.val == NULL) {
+                               yyerror("vmalloc failed");
+                               return -1;
+                       }
+                       memcpy(yylval.val->v, yytext, yylval.val->l);
+                        return(ADDRRANGE);
+                } 
+
        /* upper protocol */
 esp            { YYD; yylval.num = IPPROTO_ESP; return(UL_PROTO); }
 ah             { YYD; yylval.num = IPPROTO_AH; return(UL_PROTO); }
@@ -516,6 +559,36 @@ hybrid_dss_client {
 #endif
 }
 
+xauth_psk_server {
+#ifdef ENABLE_HYBRID
+       YYD; yylval.num = algtype_xauth_psk_s; return(ALGORITHMTYPE);
+#else
+       yyerror("racoon not configured with --enable-hybrid");
+#endif
+}
+xauth_psk_client {
+#ifdef ENABLE_HYBRID
+       YYD; yylval.num = algtype_xauth_psk_c; return(ALGORITHMTYPE);
+#else
+       yyerror("racoon not configured with --enable-hybrid");
+#endif
+}
+xauth_rsa_server {
+#ifdef ENABLE_HYBRID
+       YYD; yylval.num = algtype_xauth_rsa_s; return(ALGORITHMTYPE);
+#else
+       yyerror("racoon not configured with --enable-hybrid");
+#endif
+}
+xauth_rsa_client {
+#ifdef ENABLE_HYBRID
+       YYD; yylval.num = algtype_xauth_rsa_c; return(ALGORITHMTYPE);
+#else
+       yyerror("racoon not configured with --enable-hybrid");
+#endif
+}
+
+
 
        /* identifier type */
 vendor_id      { YYD; yywarn("it is obsoleted."); return(VENDORID); }
@@ -556,7 +629,7 @@ key         {
 #endif
 }
 keychain       { 
-#ifdef __APPLE__
+#if defined(__APPLE__) && HAVE_KEYCHAIN
        YYD; 
        yylval.num = SECRETTYPE_KEYCHAIN; 
        return(SECRETTYPE); 
@@ -612,6 +685,10 @@ use_peers_identifier       {
 #endif
 }
 
+       /* identifier qualifier */
+tag            { YYD; yylval.num = IDQUAL_TAG;  return(IDENTIFIERQUAL); }
+file           { YYD; yylval.num = IDQUAL_FILE; return(IDENTIFIERQUAL); }
+
        /* units */
 B|byte|bytes           { YYD; return(UNITTYPE_BYTE); }
 KB                     { YYD; return(UNITTYPE_KBYTES); }
@@ -621,6 +698,14 @@ sec|secs|second|seconds    { YYD; return(UNITTYPE_SEC); }
 min|mins|minute|minutes        { YYD; return(UNITTYPE_MIN); }
 hour|hours             { YYD; return(UNITTYPE_HOUR); }
 
+dpd_default             { YYD; return(DPD_ALGO_TYPE_DEFAULT); }
+dpd_inbound_detect      { YYD; return(DPD_ALGO_TYPE_INBOUND); }
+dpd_blackhole_detect    { YYD; return(DPD_ALGO_TYPE_BLACKHOLE); }
+
+idle_any                { YYD; return(IDLE_DIRECTION_ANY); }
+idle_inbound            { YYD; return(IDLE_DIRECTION_IN); }
+idle_outbound           { YYD; return(IDLE_DIRECTION_OUT); }
+
        /* boolean */
 yes            { YYD; yylval.num = TRUE; return(BOOLEAN); }
 no             { YYD; yylval.num = FALSE; return(BOOLEAN); }
@@ -687,7 +772,6 @@ no          { YYD; yylval.num = FALSE; return(BOOLEAN); }
 
 <<EOF>>                {
                        yy_delete_buffer(YY_CURRENT_BUFFER);
-                       yycf_free_buffer(incstackp);
                        incstackp--;
     nextfile:
                        if (incstack[incstackp].matchon <
@@ -733,7 +817,7 @@ yyerror(char *s, ...)
        snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n",
                incstack[incstackp].path, incstack[incstackp].lineno,
                yytext, s);
-       plogv(LLV_ERROR, LOCATION, NULL, fmt, ap);
+       plogv(LLV_ERROR, LOCATION, NULL, fmt, &ap);
        va_end(ap);
 
        yyerrorcount++;
@@ -753,7 +837,7 @@ yywarn(char *s, ...)
        snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n",
                incstack[incstackp].path, incstack[incstackp].lineno,
                yytext, s);
-       plogv(LLV_WARNING, LOCATION, NULL, fmt, ap);
+       plogv(LLV_WARNING, LOCATION, NULL, fmt, &ap);
        va_end(ap);
 }
 
@@ -772,9 +856,9 @@ yycf_switch_buffer(path)
 
        if (glob(path, GLOB_TILDE, NULL, &incstack[incstackp].matches) != 0 ||
            incstack[incstackp].matches.gl_pathc == 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "glob found no matches for path");
-               return -1;
+               plog(LLV_WARNING, LOCATION, NULL,
+                       "glob found no matches for path \"%s\"\n", path);
+               return 0;
        }
        incstack[incstackp].matchon = 0;
        incstack[incstackp].prevstate = YY_CURRENT_BUFFER;
@@ -814,8 +898,13 @@ yycf_set_buffer(path)
        }
 
        /* initialize */
+       if (incstack[incstackp].path != NULL) {
+               fclose(incstack[incstackp].fp);
+               racoon_free(incstack[incstackp].path);
+       }
        incstack[incstackp].fp = yyin;
-       incstack[incstackp].path = strdup(path);
+       incstack[incstackp].path = racoon_strdup(path);
+       STRDUP_FATAL(incstack[incstackp].path);
        incstack[incstackp].lineno = 1;
        plog(LLV_DEBUG, LOCATION, NULL,
                "reading config file %s\n", path);
@@ -833,22 +922,17 @@ yycf_init_buffer()
        incstackp = 0;
 }
 
-void
-yycf_free_buffer(index)
-       int index;
-{
-       fclose(incstack[index].fp);
-       racoon_free(incstack[index].path);
-       incstack[index].path = NULL;
-}
-
 void
 yycf_clean_buffer()
 {
        int i;
 
-       for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
-               if (incstack[i].path != NULL)
-                       yycf_free_buffer(i);
+       for (i = 0; i < MAX_INCLUDE_DEPTH; i++) {
+               if (incstack[i].path != NULL) {
+                       fclose(incstack[i].fp);
+                       racoon_free(incstack[i].path);
+                       incstack[i].path = NULL;
+               }
+       }
 }
 
index 76156a68cc7b6acb625581bae53c4e99d6b8058b..41cb939d63b199114944f7392645c6c17c55fcde 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: cftoken_proto.h,v 1.3 2004/06/11 16:00:15 ludvigm Exp $ */
+/*     $NetBSD: cftoken_proto.h,v 1.4 2006/09/09 16:22:09 manu Exp $   */
+
+/* Id: cftoken_proto.h,v 1.3 2004/06/11 16:00:15 ludvigm Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -42,6 +44,5 @@ extern int yycf_switch_buffer __P((char *));
 extern int yycf_set_buffer __P((char *));
 extern void yycf_init_buffer __P((void));
 extern void yycf_clean_buffer __P((void));
-extern void yycf_free_buffer __P((int));
 
 #endif /* _CFTOKEN_PROTO_H */
diff --git a/ipsec-tools/racoon/com.apple.racoon.plist b/ipsec-tools/racoon/com.apple.racoon.plist
new file mode 100644 (file)
index 0000000..69412ba
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>Label</key>
+       <string>com.apple.racoon</string>
+       <key>Program</key>
+       <string>/usr/sbin/racoon</string>
+       <key>RunAtLoad</key>
+       <false/>
+       <key>KeepAlive</key>
+       <false/>
+       <key>UserName</key>
+       <string>root</string>
+       <key>Sockets</key>
+       <dict>
+               <key>Listeners</key>
+               <dict>
+                       <key>SockFamily</key>
+                       <string>Unix</string>
+                       <key>SockPathMode</key>
+                       <integer>384</integer>
+                       <key>SockPathName</key>
+                       <string>/var/run/vpncontrol.sock</string>
+               </dict>
+       </dict>
+       <key>EnableTransactions</key>
+       <true/>
+</dict>
+</plist>
diff --git a/ipsec-tools/racoon/com.apple.racoonembedded.plist b/ipsec-tools/racoon/com.apple.racoonembedded.plist
new file mode 100644 (file)
index 0000000..bf9ad81
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>Label</key>
+       <string>com.apple.racoon</string>
+       <key>Program</key>
+       <string>/usr/sbin/racoon</string>
+       <key>RunAtLoad</key>
+       <false/>
+       <key>KeepAlive</key>
+       <false/>
+       <key>UserName</key>
+       <string>root</string>
+       <key>Sockets</key>
+       <dict>
+               <key>Listeners</key>
+               <dict>
+                       <key>SockFamily</key>
+                       <string>Unix</string>
+                       <key>SockPathMode</key>
+                       <integer>384</integer>
+                       <key>SockPathName</key>
+                       <string>/tmp/racoon/vpncontrol.sock</string>
+               </dict>
+       </dict>
+</dict>
+</plist>
index 9b0e3495743955059e9a611158e1db8c07b81429..e5b35d6bdebb914f89e17296223461a7453d05f7 100644 (file)
  * Framework and CSSM
  */
 
-#include <Security/SecBase.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecKey.h>
 #include <Security/SecIdentity.h>
+
+#include <TargetConditionals.h>
+#if TARGET_OS_EMBEDDED
+#include <Security/SecItem.h>
+#else
+#include <Security/SecBase.h>
 #include <Security/SecIdentityPriv.h>
 #include <Security/SecIdentitySearch.h>
 #include <Security/SecKeychain.h>
 #include <Security/SecKeychainItem.h>
 #include <Security/SecKeychainItemPriv.h>
-#include <Security/SecKey.h>
+
 #include <Security/SecKeyPriv.h>
-#include <Security/SecTrust.h>
 #include <Security/oidsalg.h>
 #include <Security/cssmapi.h>
 #include <Security/SecPolicySearch.h>
+#endif
+
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
 #include "plog.h"
 #include "debug.h"
 #include "misc.h"
 
-#include "crypto_cssm.h"
 
+#include "crypto_cssm.h"
 
 
-static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef);
 static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef);
-static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef);
 static const char *GetSecurityErrorString(OSStatus err);
-
+#if !TARGET_OS_EMBEDDED
+static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef);
+static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef);
+#endif
 
 /*
  * Verify cert using security framework
  */
-int crypto_cssm_check_x509cert(vchar_t *cert)
+int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname)
 {
        OSStatus                        status;
-       SecCertificateRef       certRef = 0;
+       SecCertificateRef       certRef = NULL;
+       SecPolicyRef            policyRef = NULL;
+
+#if !TARGET_OS_EMBEDDED
        CSSM_DATA                       certData;
        CSSM_OID                        ourPolicyOID = CSSMOID_APPLE_TP_IP_SEC; 
-       SecPolicyRef            policyRef = 0;
 
        // create cert ref
        certData.Length = cert->l;
@@ -81,15 +92,47 @@ int crypto_cssm_check_x509cert(vchar_t *cert)
        status = FindPolicy(&ourPolicyOID, &policyRef);
        if (status != noErr)
                goto end;
-               
-       // setup policy options ???
        // no options used at present - verification of subjectAltName fields, etc.
        // are done elsewhere in racoon in oakley_check_certid()
+               
+#else
+       CFDataRef cert_data = CFDataCreateWithBytesNoCopy(NULL, cert->v, cert->l, kCFAllocatorNull);
+    if (cert_data) {
+        certRef = SecCertificateCreateWithData(NULL, cert_data);
+        CFRelease(cert_data);
+    }
+
+       if (certRef == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL, 
+                       "unable to create a certRef.\n");
+               status = -1;
+               goto end;
+       }
+
+       if (hostname) {
+               policyRef = SecPolicyCreateSSL(FALSE, hostname);
+               if (policyRef == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                               "unable to create a SSL policyRef.\n");
+                       status = -1;
+                       goto end;
+               }
+       } else
+         {
+               policyRef = SecPolicyCreateBasicX509();
+               if (policyRef == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                               "unable to create a Basic X509 policyRef.\n");
+                       status = -1;
+                       goto end;
+               }
+       }
+       
+#endif
        
        // evaluate cert
        status = EvaluateCert(certRef, policyRef);
        
-       
 end:
 
        if (certRef)
@@ -114,27 +157,29 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash)
 {
 
        OSStatus                                                status;
-       SecCertificateRef                               certificateRef = NULL;
        SecIdentityRef                                  identityRef = NULL;
+       SecKeyRef                                               privateKeyRef = NULL;
+       vchar_t                                                 *sig = NULL;
+
+#if !TARGET_OS_EMBEDDED
+       u_int32_t                                               bytesEncrypted = 0;
+       SecCertificateRef                               certificateRef = NULL;
        SecIdentitySearchRef                    idSearchRef = NULL;
        SecKeychainRef                                  keychainRef = NULL;
-       SecKeyRef                                               privateKeyRef = NULL;
        const CSSM_KEY                                  *cssmKey = NULL;
        CSSM_CSP_HANDLE                                 cspHandle = nil;
        CSSM_CC_HANDLE                                  cssmContextHandle = nil;
        const CSSM_ACCESS_CREDENTIALS   *credentials = NULL;
        //CSSM_SIZE                                             bytesEncrypted = 0;     //%%%%HWR fix this - need new headers on Leopard
-       uint32                                                  bytesEncrypted = 0;
        CSSM_DATA                                               clearData;
        CSSM_DATA                                               cipherData;
        CSSM_DATA                                               remData;
        CSSM_CONTEXT_ATTRIBUTE                  newAttr;
-       vchar_t                                                 *sig = NULL;
 
        remData.Length = 0;
        remData.Data = 0;
 
-       if (persistentCertRef) {                        
+       if (persistentCertRef) {        
                // get cert from keychain
                status = SecKeychainItemCopyFromPersistentReference(persistentCertRef, (SecKeychainItemRef*)&certificateRef);
                if (status != noErr)
@@ -151,6 +196,7 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash)
                        goto end;       
                        
        } else {
+       
                // copy system keychain
                status = CopySystemKeychain(&keychainRef);
                if (status != noErr)
@@ -171,7 +217,6 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash)
                        goto end;
        }
        
-                                       
        // get private key from identity
        status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef);
        if (status != noErr)
@@ -231,20 +276,60 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash)
                
        sig->l = cipherData.Length;
        sig->v = (caddr_t)cipherData.Data;
+
+#else
+
+       CFDictionaryRef         persistFind = NULL;
+       const void                      *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef };
+       const void                      *values_persist[] = { kCFBooleanTrue, persistentCertRef };
+
+       #define SIG_BUF_SIZE 1024
+       
+       /* find identity by persistent ref */
+       persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
+               (sizeof(keys_persist) / sizeof(*keys_persist)), NULL, NULL);
+       if (persistFind == NULL)
+               goto end;
+       
+       status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
+       if (status != noErr)
+               goto end;
+               
+       status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef);
+       if (status != noErr)
+               goto end;
+
+       // alloc buffer for result
+       sig = vmalloc(SIG_BUF_SIZE);
+       if (sig == NULL)
+               goto end;
+       
+       status = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1, hash->v,
+               hash->l, sig->v, &sig->l);                              
+
+#endif 
+                                       
                
 end:
-       if (certificateRef)
-               CFRelease(certificateRef);
-       if (keychainRef)
-               CFRelease(keychainRef);
        if (identityRef)
                CFRelease(identityRef);
        if (privateKeyRef)
                CFRelease(privateKeyRef);
+               
+#if !TARGET_OS_EMBEDDED
+       if (certificateRef)
+               CFRelease(certificateRef);
+       if (keychainRef)
+               CFRelease(keychainRef);
        if (idSearchRef)
                CFRelease(idSearchRef);
        if (cssmContextHandle)
                CSSM_DeleteContext(cssmContextHandle);
+#else
+       if (persistFind)
+               CFRelease(persistFind);
+#endif
+       
        if (status != noErr) {
                if (sig) {
                        vfree(sig);
@@ -269,13 +354,14 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
 {
 
        OSStatus                                status;
-       CSSM_DATA                               cssmData;
        vchar_t                                 *cert = NULL;
        SecIdentityRef                  identityRef = NULL;
-       SecIdentitySearchRef    idSearchRef = NULL;
-       SecKeychainRef                  keychainRef = NULL;
        SecCertificateRef               certificateRef = NULL;
 
+#if !TARGET_OS_EMBEDDED
+       CSSM_DATA                               cssmData;       
+       SecIdentitySearchRef    idSearchRef = NULL;
+       SecKeychainRef                  keychainRef = NULL;
 
        // get cert ref
        if (persistentCertRef) {
@@ -303,7 +389,7 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
                        goto end;
                
        }
-               
+
        // get certificate data
        cssmData.Length = 0;
        cssmData.Data = NULL;
@@ -321,17 +407,62 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
        // cssmData struct just points to the data
        // data must be copied to be returned
        memcpy(cert->v, cssmData.Data, cssmData.Length);        
+       
+#else
+               
+       CFDictionaryRef         persistFind = NULL;
+       const void                      *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef };
+       const void                      *values_persist[] = { kCFBooleanTrue, persistentCertRef };
+       size_t                          dataLen;
+       CFDataRef                       certData = NULL;
+       
+       /* find identity by persistent ref */
+       persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
+               (sizeof(keys_persist) / sizeof(*keys_persist)), NULL, NULL);
+       if (persistFind == NULL)
+               goto end;
+       
+       status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
+       if (status != noErr)
+               goto end;
+
+       status = SecIdentityCopyCertificate(identityRef, &certificateRef);
+       if (status != noErr)
+               goto end;
+
+       certData = SecCertificateCopyData(certificateRef);
+       if (certData == NULL)
+               goto end;
+       
+       dataLen = CFDataGetLength(certData);
+       if (dataLen == 0)
+               goto end;
+       
+       cert = vmalloc(dataLen);
+       if (cert == NULL)
+               goto end;       
+       
+       CFDataGetBytes(certData, CFRangeMake(0, dataLen), cert->v); 
+                               
+#endif
                
 end:
        if (certificateRef)
                CFRelease(certificateRef);
        if (identityRef)
                CFRelease(identityRef);
+#if !TARGET_OS_EMBEDDED
        if (idSearchRef)
                CFRelease(idSearchRef);
        if (keychainRef)
                CFRelease(keychainRef);
-
+#else
+       if (persistFind)
+               CFRelease(persistFind);
+       if (certData)
+               CFRelease(certData);
+#endif
+       
        if (status != noErr && status != -1) {
                plog(LLV_ERROR, LOCATION, NULL, 
                        "error %d %s.\n", status, GetSecurityErrorString(status));
@@ -341,7 +472,7 @@ end:
 
 }
 
-
+#if !TARGET_OS_EMBEDDED
 /*
  * Find a policy ref by OID
  */
@@ -368,7 +499,7 @@ end:
        }                       
        return status;
 }
-               
+#endif         
 
 /*
  * Evaluate the trust of a cert using the policy provided
@@ -381,8 +512,8 @@ static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef)
        
        SecCertificateRef                       evalCertArray[1] = { cert };
        
-       CFArrayRef                      cfCertRef = CFArrayCreate((CFAllocatorRef) NULL, (void*)evalCertArray, 1,
-                                                                               &kCFTypeArrayCallBacks);
+       CFArrayRef      cfCertRef = CFArrayCreate((CFAllocatorRef) NULL, (void*)evalCertArray, 1,
+                                                               &kCFTypeArrayCallBacks);
                                                                                
        if (!cfCertRef) {
                plog(LLV_ERROR, LOCATION, NULL, 
@@ -419,7 +550,7 @@ end:
        return status;
 }
 
-
+#if !TARGET_OS_EMBEDDED
 /*
  * Copy the system keychain
  */
@@ -444,7 +575,7 @@ end:
        return status;
 
 }
-
+#endif
 
 /* 
  * Return string representation of Security-related OSStatus.
@@ -465,6 +596,7 @@ GetSecurityErrorString(OSStatus err)
                /* SecBase.h: */
                case errSecNotAvailable:
                        return "errSecNotAvailable";
+#if !TARGET_OS_EMBEDDED
                case errSecReadOnly:
                        return "errSecReadOnly";
                case errSecAuthFailed:
@@ -479,10 +611,6 @@ GetSecurityErrorString(OSStatus err)
                        return "errSecDuplicateCallback";
                case errSecInvalidCallback:
                        return "errSecInvalidCallback";
-               case errSecDuplicateItem:
-                       return "errSecDuplicateItem";
-               case errSecItemNotFound:
-                       return "errSecItemNotFound";
                case errSecBufferTooSmall:
                        return "errSecBufferTooSmall";
                case errSecDataTooLarge:
@@ -529,6 +657,11 @@ GetSecurityErrorString(OSStatus err)
                        return "errSecNoAccessForItem";
                case errSecInvalidOwnerEdit:
                        return "errSecInvalidOwnerEdit";
+#endif
+               case errSecDuplicateItem:
+                       return "errSecDuplicateItem";
+               case errSecItemNotFound:
+                       return "errSecItemNotFound";
                default:
                        return "<unknown>";
     }
index 615277051d89f6f0dca83759b60fcc66d52fa8c9..e7c94c36be5d9166fb22c6db1d9ff1c6adf6b1f3 100644 (file)
  */
 
 #include "vmbuf.h"
+#include <CoreFoundation/CoreFoundation.h>
 
 
-extern int crypto_cssm_check_x509cert(vchar_t *cert);
+extern int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname);
 extern vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash);
 extern vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef);
 
index 39e96b797cc2974fb70ee3f9d1a11d22f3d00c1d..ae184d7976aacd029a27a2ac843d2f06049767cf 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: crypto_openssl.c,v 1.40.4.5 2005/07/12 11:50:15 manubsd Exp $ */
+/*     $NetBSD: crypto_openssl.c,v 1.11.6.1 2006/12/18 10:18:10 vanhu Exp $    */
+
+/* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -60,6 +62,7 @@
 #ifdef __APPLE__
 #include <CommonCrypto/CommonDigest.h>
 #include <CommonCrypto/CommonHMAC.h>
+#include <CommonCrypto/CommonCryptor.h>
 #else
 #include <openssl/md5.h>
 #include <openssl/sha.h>
@@ -141,7 +144,7 @@ eay_str2asn1dn(str, len)
        char *buf;
        char *field, *value;
        int i, j;
-       vchar_t *ret;
+       vchar_t *ret = NULL;
        caddr_t p;
 
        if (len == -1)
@@ -149,7 +152,7 @@ eay_str2asn1dn(str, len)
 
        buf = racoon_malloc(len + 1);
        if (!buf) {
-               printf("failed to allocate buffer\n");
+               plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
                return NULL;
        }
        memcpy(buf, str, len);
@@ -226,6 +229,8 @@ eay_str2asn1dn(str, len)
                racoon_free(buf);
        if (name)
                X509_NAME_free(name);
+       if (ret)
+               vfree(ret);
        return NULL;
 }
 
@@ -253,7 +258,7 @@ eay_hex2asn1dn(const char *hex, int len)
        binlen = BN_num_bytes(bn);
        ret = vmalloc(binlen);
        if (!ret) {
-               printf("failed to allocate buffer\n");
+               plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
                return NULL;
        }
        binbuf = ret->v;
@@ -502,7 +507,7 @@ eay_check_x509cert(cert, CApath, CAfile, local)
 
 end:
        if (error)
-               printf("%s\n", eay_strerror());
+               plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror());
        if (cert_ctx != NULL)
                X509_STORE_free(cert_ctx);
        if (x509 != NULL)
@@ -606,37 +611,36 @@ eay_get_x509asn1subjectname(cert)
        u_char *bp;
        vchar_t *name = NULL;
        int len;
-       int error = -1;
 
        bp = (unsigned char *) cert->v;
 
        x509 = mem2x509(cert);
        if (x509 == NULL)
-               goto end;
+               goto error;
 
        /* get the length of the name */
        len = i2d_X509_NAME(x509->cert_info->subject, NULL);
        name = vmalloc(len);
        if (!name)
-               goto end;
+               goto error;
        /* get the name */
        bp = (unsigned char *) name->v;
        len = i2d_X509_NAME(x509->cert_info->subject, &bp);
 
-       error = 0;
+       X509_free(x509);
 
-   end:
-       if (error) {
-               plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
-               if (name) {
-                       vfree(name);
-                       name = NULL;
-               }
-       }
-       if (x509)
+       return name;
+
+error:
+       plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
+
+       if (name != NULL) 
+               vfree(name);
+
+       if (x509 != NULL)
                X509_free(x509);
 
-       return name;
+       return NULL;
 }
 
 #ifdef __APPLE__
@@ -689,7 +693,7 @@ eay_get_x509subjectaltname(cert, altname, type, pos, len)
 {
        X509 *x509 = NULL;
        int i;
-       GENERAL_NAMES   *gens;
+       GENERAL_NAMES   *gens = NULL;
        GENERAL_NAME    *gen;
        int error = -1;
 
@@ -763,6 +767,9 @@ eay_get_x509subjectaltname(cert, altname, type, pos, len)
                printf("%s\n", eay_strerror());
 #endif
        }
+       if (gens)
+               /* free the whole stack. */
+               sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
        if (x509)
                X509_free(x509);
 
@@ -1042,12 +1049,14 @@ eay_check_x509sign(source, sig, cert)
        evp = X509_get_pubkey(x509);
        if (! evp) {
                plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror());
+               X509_free(x509);
                return -1;
        }
 
        res = eay_rsa_verify(source, sig, evp->pkey.rsa);
 
        EVP_PKEY_free(evp);
+       X509_free(x509);
 
        return res;
 }
@@ -1389,6 +1398,45 @@ evp_keylen(int len, const EVP_CIPHER *e)
        return EVP_CIPHER_key_length(e) << 3;
 }
 
+vchar_t *
+eay_CCCrypt(CCOperation  oper,
+                       CCAlgorithm  algo,
+                       CCOptions    opts,
+                       vchar_t     *data,
+                       vchar_t     *key,
+                       vchar_t     *iv)
+{
+    vchar_t         *res;
+    size_t           res_len = 0;
+    CCCryptorStatus  status;
+
+    /* allocate buffer for result */
+    if ((res = vmalloc(data->l)) == NULL)
+        return NULL;
+
+    status = CCCrypt(oper,
+                     algo,
+                     opts,
+                     key->v, key->l,
+                     iv->v,
+                     data->v, data->l,
+                     res->v, res->l, &res_len);
+    if (status == kCCSuccess) {
+        if (res->l != res_len) {
+            plog(LLV_ERROR, LOCATION, NULL,
+                 "crypt %d %d length mismatch. expected: %zd. got: %zd.\n",
+                 oper, algo, res->l, res_len);
+        }
+        return res;
+    } else {
+        plog(LLV_ERROR, LOCATION, NULL,
+             "crypt %d %d error. status %d.\n",
+             oper, algo, (int)status);
+    }
+    vfree(res);
+    return NULL;
+}
+
 /*
  * DES-CBC
  */
@@ -1396,14 +1444,22 @@ vchar_t *
 eay_des_encrypt(data, key, iv)
        vchar_t *data, *key, *iv;
 {
+#ifdef __APPLE__
+    return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv));
+#else
        return evp_crypt(data, key, iv, EVP_des_cbc(), 1);
+#endif /* __APPLE__ */
 }
 
 vchar_t *
 eay_des_decrypt(data, key, iv)
        vchar_t *data, *key, *iv;
 {
+#ifdef __APPLE__
+    return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv));
+#else
        return evp_crypt(data, key, iv, EVP_des_cbc(), 0);
+#endif /* __APPLE__ */
 }
 
 int
@@ -1421,7 +1477,17 @@ int
 eay_des_keylen(len)
        int len;
 {
+#ifdef __APPLE__
+    /* CommonCrypto return lengths in bytes, ipsec-tools
+     * uses lengths in bits, therefore conversion is required.
+     */
+    if (len != 0 && len != (kCCKeySizeDES << 3))
+        return -1;
+
+    return kCCKeySizeDES << 3;      
+#else
        return evp_keylen(len, EVP_des_cbc());
+#endif /* __APPLE__ */
 }
 
 #ifdef HAVE_OPENSSL_IDEA_H
@@ -1594,14 +1660,22 @@ vchar_t *
 eay_3des_encrypt(data, key, iv)
        vchar_t *data, *key, *iv;
 {
+#ifdef __APPLE__
+    return(eay_CCCrypt(kCCEncrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv));
+#else
        return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1);
+#endif /* __APPLE__ */
 }
 
 vchar_t *
 eay_3des_decrypt(data, key, iv)
        vchar_t *data, *key, *iv;
 {
+#ifdef __APPLE__
+    return(eay_CCCrypt(kCCDecrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv));
+#else
        return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0);
+#endif /* __APPLE__ */
 }
 
 int
@@ -1626,9 +1700,19 @@ int
 eay_3des_keylen(len)
        int len;
 {
+#ifdef __APPLE__
+    /* CommonCrypto return lengths in bytes, ipsec-tools
+     * uses lengths in bits, therefore conversion is required.
+     */
+    if (len != 0 && len != (kCCKeySize3DES << 3))
+        return -1;
+
+    return kCCKeySize3DES << 3;
+#else
        if (len != 0 && len != 192)
                return -1;
        return 192;
+#endif /* __APPLE__ */
 }
 
 /*
@@ -1669,6 +1753,41 @@ eay_cast_keylen(len)
 /*
  * AES(RIJNDAEL)-CBC
  */
+#ifdef __APPLE__
+vchar_t *
+eay_aes_encrypt(data, key, iv)
+vchar_t *data, *key, *iv;
+{
+    return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
+}
+
+vchar_t *
+eay_aes_decrypt(data, key, iv)
+vchar_t *data, *key, *iv;
+{
+    return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
+}
+
+int
+eay_aes_keylen(len)
+int len;
+{
+    /* CommonCrypto return lengths in bytes, ipsec-tools
+     * uses lengths in bits, therefore conversion is required.
+     */
+    if (len != 0) {
+        if (len != (kCCKeySizeAES128 << 3) &&
+            len != (kCCKeySizeAES192 << 3) &&
+            len != (kCCKeySizeAES256 << 3))
+            return -1;
+    } else {
+        return kCCKeySizeAES128 << 3;
+    }
+    return len;
+}
+
+#else
+
 #ifndef HAVE_OPENSSL_AES_H
 vchar_t *
 eay_aes_encrypt(data, key, iv)
@@ -1761,14 +1880,7 @@ eay_aes_decrypt(data, key, iv)
 {
        return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0);
 }
-#endif
-
-int
-eay_aes_weakkey(key)
-       vchar_t *key;
-{
-       return 0;
-}
+#endif /* HAVE_OPENSSL_AES_H */
 
 int
 eay_aes_keylen(len)
@@ -1780,6 +1892,14 @@ eay_aes_keylen(len)
                return -1;
        return len;
 }
+#endif /* __APPLE__ */
+
+int
+eay_aes_weakkey(key)
+       vchar_t *key;
+{
+       return 0;
+}
 
 /* for ipsec part */
 int
@@ -2740,15 +2860,18 @@ base64_decode(char *in, long inlen)
 {
        BIO *bio=NULL, *b64=NULL;
        vchar_t *res = NULL;
-       char out[inlen*2];
+       char *outb;
        long outlen;
 
+       outb = malloc(inlen * 2);
+       if (outb == NULL)
+               goto out;
        bio = BIO_new_mem_buf(in, inlen);
        b64 = BIO_new(BIO_f_base64());
        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
        bio = BIO_push(b64, bio);
 
-       outlen = BIO_read(bio, out, inlen * 2);
+       outlen = BIO_read(bio, outb, inlen * 2);
        if (outlen <= 0) {
                plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
                goto out;
@@ -2758,9 +2881,11 @@ base64_decode(char *in, long inlen)
        if (!res)
                goto out;
 
-       memcpy(res->v, out, outlen);
+       memcpy(res->v, outb, outlen);
 
 out:
+       if (outb)
+               free(outb);
        if (bio)
                BIO_free_all(bio);
 
index 3dec6cd04b2d63062be1ee4a88e93095f93dd49f..960c3a52ae9409ba7118d307f9bee0f8932747da 100644 (file)
@@ -47,6 +47,9 @@
 #ifndef racoon_free
 #define        racoon_free(p)          free((p))
 #endif
+#ifndef racoon_strdup
+#define        racoon_strdup(p)        strdup((p))
+#endif
 #else /*!NONEED_DRM*/
 #ifndef racoon_malloc
 #define        racoon_malloc(sz)       \
 #define        racoon_free(p)          \
        DRM_free(__FILE__, __LINE__, __func__, (p))
 #endif
+#ifndef racoon_strdup
+#define        racoon_strdup(p)        \
+       DRM_strdup(__FILE__, __LINE__, __func__, (p))
+#endif
 #endif /*NONEED_DRM*/
 
 extern void DRM_init __P((void));
@@ -72,6 +79,7 @@ extern void *DRM_malloc __P((char *, int, char *, size_t));
 extern void *DRM_calloc __P((char *, int, char *, size_t, size_t));
 extern void *DRM_realloc __P((char *, int, char *, void *, size_t));
 extern void DRM_free __P((char *, int, char *, void *));
+extern char *DRM_strdup __P((char *, int, char *, const char *));
 
 #ifndef NONEED_DRM
 #define        vmalloc(sz)     \
index 2f1dc258e752a2e27991afa00d628ba5199689bd..bd4cd000866ed58135983bcae95d9d004d5e9824 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: dnssec.c,v 1.4 2006/09/09 16:22:09 manu Exp $  */
+
 /*     $KAME: dnssec.c,v 1.2 2001/08/05 18:46:07 itojun Exp $  */
 
 /*
@@ -94,7 +96,7 @@ dnssec_getcert(id)
                        "impropper ID type passed %s "
                        "though getcert method is dnssec.\n",
                        s_ipsecdoi_ident(id_b->type));
-               return NULL;
+               goto err;
        }
 
        /* check response */
@@ -143,7 +145,10 @@ end:
 err:
        if (name)
                racoon_free(name);
-       if (cert)
+       if (cert) {
                oakley_delcert(cert);
+               cert = NULL;
+       }
+
        goto end;
 }
index e21a82b5469ec49a1a0e8a7fccb5d759781bdf5d..fc65b20e6b49b5f4efdb9f55e11e974b515f8ec0 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: evt.c,v 1.2.4.1 2005/09/26 17:49:38 manubsd Exp $ */
+/*     $NetBSD: evt.c,v 1.5 2006/09/09 16:22:09 manu Exp $     */
+
+/* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
 #include "vmbuf.h"
 #include "plog.h"
 #include "misc.h"
+#include "admin.h"
 #include "gcmalloc.h"
 #include "evt.h"
 
-
+#ifdef ENABLE_ADMINPORT
 struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
 int evtlist_len = 0;
 
@@ -61,6 +64,10 @@ evt_push(src, dst, type, optdata)
        struct evt *evt;
        size_t len;
 
+       /* If admin socket is disabled, silently discard anything */
+       if (adminsock_path == NULL)
+               return;
+
        /* If we are above the limit, don't record anything */
        if (evtlist_len > EVTLIST_MAX) {
                plog(LLV_DEBUG, LOCATION, NULL, 
@@ -147,3 +154,5 @@ evt_dump(void) {
 
        return buf;
 }
+
+#endif /* ENABLE_ADMINPORT */
index 209c854adfb73cb7290547279dd32d27a6443102..88ee366df38e25760ca93a7430b5adeb22736137 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: evt.h,v 1.3 2004/11/29 23:30:39 manubsd Exp $ */
+/*     $NetBSD: evt.h,v 1.4 2006/09/09 16:22:09 manu Exp $     */
+
+/* Id: evt.h,v 1.5 2006/01/19 10:24:09 fredsen Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
@@ -59,6 +61,8 @@ struct evtdump {
 #define EVTT_XAUTH_FAILED      11
 #define EVTT_OVERFLOW          12      /* Event queue overflowed */
 #define EVTT_PEERPH1AUTH_FAILED        13
+#define EVTT_PEERPH1_NOPROP    14      /* NO_PROPOSAL_CHOSEN & friends */
+#define EVTT_NO_ISAKMP_CFG     15      /* no need to wait for mode_cfg */
 
 struct evt {
        struct evtdump *dump;
index ca085287d6c085e2b918074f594def0b018ff41e..acdf7fa50b7067a4e56f026250104b888395d28c 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: gcmalloc.h,v 1.4 2006/09/09 16:22:09 manu Exp $        */
+
 /*     $KAME: gcmalloc.h,v 1.4 2001/11/16 04:34:57 sakane Exp $        */
 
 /*
@@ -77,12 +79,20 @@ free(void *ptr)
 
        GC_FREE(ptr);
 }
+
+char *
+strdup(const char *str)
+{
+
+       return (GC_STRDUP(str));
+}
 #endif /* RACOON_MAIN_PROGRAM */
 
 #define        racoon_malloc(sz)       GC_debug_malloc(sz, GC_EXTRAS)
 #define        racoon_calloc(cnt, sz)  GC_debug_malloc(cnt * sz, GC_EXTRAS)
 #define        racoon_realloc(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS)
 #define        racoon_free(p)          GC_debug_free(p)
+#define        racoon_strdup(str)      GC_debug_strdup(str)
 
 #endif /* GC */
 
@@ -109,6 +119,9 @@ free(void *ptr)
 #ifndef racoon_free
 #define        racoon_free(p)          free((p))
 #endif
+#ifndef racoon_strdup
+#define        racoon_strdup(s)        strdup((s))
+#endif
 #endif /* DEBUG_RECORD_MALLOCATION */
 
 #endif /* _GCMALLOC_H_DEFINED */
index 890f067cb5a84d935d11c06a4eb5bf07cc297a68..6ce6be1c3529160e0795b1c2fd1bf9b2cf1049b3 100644 (file)
@@ -29,9 +29,6 @@
  * SUCH DAMAGE.
  */
 
-//%%%HWR Do we need this?
-#define BIND_8_COMPAT
-
 #include "config.h"
 
 #include <sys/types.h>
@@ -39,7 +36,7 @@
 #include <sys/socket.h>
 
 #include <netinet/in.h>
-#include <arpa/nameser.h>
+#include <arpa/nameser_compat.h>
 #include <resolv.h>
 #ifdef HAVE_LWRES_GETRRSETBYNAME
 #include <lwres/netdb.h>
index 98f2d4c1b7fc59cb7c7904181d34bbb1602cec52..6afc4ef724d36f288c42bcab1fb50e5576f3f466 100644 (file)
 #ifndef HAVE_GETIFADDRS
 static unsigned int if_maxindex __P((void));
 #endif
-#ifdef __APPLE__
-static struct myaddrs *find_myaddr __P((struct myaddrs *, struct sockaddr *, int));
-#else
-static struct myaddrs *find_myaddr __P((struct myaddrs *, struct myaddrs *));
-#endif
+
 static int suitable_ifaddr __P((const char *, const struct sockaddr *));
 #ifdef INET6
 static int suitable_ifaddr6 __P((const char *, const struct sockaddr *));
@@ -300,9 +296,7 @@ clear_myaddr()
        for (p = lcconf->myaddrs; p; p = next) {
                next = p->next;
 
-               if (p->addr)
-                       racoon_free(p->addr);
-               racoon_free(p);
+               delmyaddr(p);   
        }
 
        lcconf->myaddrs = NULL;
@@ -310,9 +304,8 @@ clear_myaddr()
 }
 
 
-static struct myaddrs *
-find_myaddr(db, addr, udp_encap)
-       struct myaddrs *db;
+struct myaddrs *
+find_myaddr(addr, udp_encap)
        struct sockaddr *addr;
        int udp_encap;
 {
@@ -323,7 +316,7 @@ find_myaddr(db, addr, udp_encap)
            NI_NUMERICHOST | niflags) != 0)
                return NULL;
 
-       for (q = db; q; q = q->next) {
+       for (q = lcconf->myaddrs; q; q = q->next) {
                if (!q->addr)
                        continue;
                if (q->udp_encap && !udp_encap
@@ -379,18 +372,18 @@ grab_myaddrs()
                        continue;
 
                if (!suitable_ifaddr(ifap->ifa_name, ifap->ifa_addr)) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(LLV_DEBUG2, LOCATION, NULL,
                                "unsuitable address: %s %s\n",
                                ifap->ifa_name,
                                saddrwop2str(ifap->ifa_addr));
                        continue;
                }
 
-               p = find_myaddr(lcconf->myaddrs, ifap->ifa_addr, 0);
+               p = find_myaddr(ifap->ifa_addr, 0);
                if (p) {
                        p->in_use = 1;
 #ifdef ENABLE_NATT
-                       q = find_myaddr(lcconf->myaddrs, ifap->ifa_addr, 1);
+                       q = find_myaddr(ifap->ifa_addr, 1);
                        if (q)
                                q->in_use = 1;
 #endif                         
@@ -409,6 +402,14 @@ grab_myaddrs()
                                exit(1);
                                /*NOTREACHED*/
                        }
+                       p->ifname = racoon_strdup(ifap->ifa_name);
+                       if (p->ifname == NULL) {
+                               plog(LLV_ERROR2, LOCATION, NULL,
+                                       "unable to duplicate ifname.\n");
+                               exit(1);
+                               /*NOTREACHED*/
+                       }
+                               
                        p->sock = -1;
                        p->in_use = 1;
 
@@ -497,7 +498,7 @@ suitable_ifaddr6(ifname, ifaddr)
        }
 
        memset(&ifr6, 0, sizeof(ifr6));
-       strncpy(ifr6.ifr_name, ifname, strlen(ifname));
+       strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
 
        ifr6.ifr_addr = *(const struct sockaddr_in6 *)ifaddr;
 
@@ -678,6 +679,9 @@ newmyaddr()
 
        new->next = NULL;
        new->addr = NULL;
+#ifdef __APPLE_
+       new->ifname = NULL;
+#endif
 
        return new;
 }
@@ -703,6 +707,17 @@ dupmyaddr(struct myaddrs *old)
                racoon_free(new);
                return NULL;
        }
+       if (old->ifname) {
+               new->ifname = racoon_strdup(old->ifname);
+               if (new->ifname == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "failed to allocate buffer for duplicate ifname.\n");
+                       racoon_free(new->addr);
+                       racoon_free(new);
+                       return NULL;
+               }
+       }
+                       
        new->next = old->next;
        old->next = new;
 
@@ -724,6 +739,10 @@ delmyaddr(myaddr)
 {
        if (myaddr->addr)
                racoon_free(myaddr->addr);
+#ifdef __APPLE__
+       if (myaddr->ifname)
+               racoon_free(myaddr->ifname);
+#endif
        racoon_free(myaddr);
 }
 
index a237cb51b5c2e4c038582134d6033bd40da89f6c..22fc0a20f0435a6e3218ff7d336edc0077e08889 100644 (file)
@@ -39,6 +39,7 @@ struct myaddrs {
        int udp_encap;
 #ifdef __APPLE__
        int     in_use;
+       char *ifname;
 #endif
 };
 
@@ -53,5 +54,7 @@ extern void insmyaddr __P((struct myaddrs *, struct myaddrs **));
 extern void delmyaddr __P((struct myaddrs *));
 extern int initmyaddr __P((void));
 extern int getsockmyaddr __P((struct sockaddr *));
+extern struct myaddrs *find_myaddr __P((struct sockaddr *, int));
+
 
 #endif /* _GRABMYADDR_H */
index 0a11f83a5b6625a5b40938d486bbf748feab2271..a2cce3c60ef289b7b2ebf6638bb1376069e042f6 100644 (file)
@@ -79,7 +79,7 @@ gssapi_error(OM_uint32 status_code, const char *where,
        va_list ap;
 
        va_start(ap, fmt);
-       plogv(LLV_ERROR, where, NULL, fmt, ap);
+       plogv(LLV_ERROR, where, NULL, fmt, &ap);
        va_end(ap);
 
        message_context = 0;
@@ -153,6 +153,7 @@ gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service)
 {
        char name[NI_MAXHOST];
        struct sockaddr *sa;
+       char* buf = NULL;
        gss_buffer_desc name_token;
        OM_uint32 min_stat, maj_stat;
 
@@ -161,8 +162,9 @@ gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service)
        if (getnameinfo(sa, sysdep_sa_len(sa), name, NI_MAXHOST, NULL, 0, 0) != 0)
                return -1;
 
-       name_token.length = asprintf((char **)&name_token.value,
-           "%s@%s", GSSAPI_DEF_NAME, name);  
+       name_token.length = asprintf(&buf, "%s@%s", GSSAPI_DEF_NAME, name);
+       name_token.value = buf;
+
        maj_stat = gss_import_name(&min_stat, &name_token,
            GSS_C_NT_HOSTBASED_SERVICE, service);
        if (GSS_ERROR(maj_stat)) {
@@ -288,7 +290,7 @@ gssapi_get_itoken(struct ph1handle *iph1, int *lenp)
        if (iph1->approval != NULL && iph1->approval->gssid != NULL) {
                plog(LLV_DEBUG, LOCATION, NULL,
                    "using provided service '%.*s'\n",
-                   iph1->approval->gssid->l, iph1->approval->gssid->v);
+                   (int)iph1->approval->gssid->l, iph1->approval->gssid->v);
                name_token.length = iph1->approval->gssid->l;
                name_token.value = iph1->approval->gssid->v;
                maj_stat = gss_import_name(&min_stat, &name_token,
@@ -466,7 +468,7 @@ gssapi_get_itokens(struct ph1handle *iph1, vchar_t **tokens)
        *tokens = toks;
 
        plog(LLV_DEBUG, LOCATION, NULL,
-               "%d itokens of length %d\n", gps->gsscnt, (*tokens)->l);
+               "%d itokens of length %zu\n", gps->gsscnt, (*tokens)->l);
 
        return 0;
 }
@@ -547,7 +549,7 @@ gssapi_wraphash(struct ph1handle *iph1)
                return NULL;
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %d olen %d\n",
+       plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %zu olen %zu\n",
            hash_in->length, hash_out->length);
 
        maj_stat = gss_release_buffer(&min_stat, hash_in);
@@ -589,7 +591,7 @@ gssapi_unwraphash(struct ph1handle *iph1)
        hashbuf.length = ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash);
        hashbuf.value = (char *)(iph1->pl_hash + 1);
 
-       plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %d\n",
+       plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %zu\n",
            hashbuf.length);
 
        maj_stat = gss_unwrap(&min_stat, gps->gss_context, hash_in, hash_out,
index 4082bb57054043e6591a609220f88345c1d7f483..a070970d3d8e7c3a5450340bcdcc539cce5bf382 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: handler.c,v 1.13.4.4 2005/07/14 12:00:36 vanhu Exp $ */
+/*     $NetBSD: handler.c,v 1.9.6.6 2007/06/06 09:20:12 vanhu Exp $    */
+
+/* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 #include "sockmisc.h"
 #include "debug.h"
 
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
+
 #include "schedule.h"
 #include "grabmyaddr.h"
 #include "algorithm.h"
@@ -68,6 +74,9 @@
 #include "handler.h"
 #include "gcmalloc.h"
 #include "nattraversal.h"
+#include "ike_session.h"
+
+#include "sainfo.h"
 
 #ifdef HAVE_GSSAPI
 #include "gssapi.h"
@@ -138,14 +147,24 @@ getph1byaddr(local, remote)
 {
        struct ph1handle *p;
 
+       plog(LLV_DEBUG2, LOCATION, NULL, "getph1byaddr: start\n");
+       plog(LLV_DEBUG2, LOCATION, NULL, "local: %s\n", saddr2str(local));
+       plog(LLV_DEBUG2, LOCATION, NULL, "remote: %s\n", saddr2str(remote));
+
        LIST_FOREACH(p, &ph1tree, chain) {
                if (p->status == PHASE1ST_EXPIRED)
                        continue;
+               plog(LLV_DEBUG2, LOCATION, NULL, "p->local: %s\n", saddr2str(p->local));
+               plog(LLV_DEBUG2, LOCATION, NULL, "p->remote: %s\n", saddr2str(p->remote));
                if (CMPSADDR(local, p->local) == 0
-                && CMPSADDR(remote, p->remote) == 0)
+                       && CMPSADDR(remote, p->remote) == 0){
+                       plog(LLV_DEBUG2, LOCATION, NULL, "matched\n");
                        return p;
+               }
        }
 
+       plog(LLV_DEBUG2, LOCATION, NULL, "no match\n");
+
        return NULL;
 }
 
@@ -187,6 +206,24 @@ getph1bydstaddrwop(remote)
        return NULL;
 }
 
+int
+islast_ph1(ph1) 
+       struct ph1handle *ph1;
+{
+       struct ph1handle *p;
+
+       LIST_FOREACH(p, &ph1tree, chain) {
+               if (p->status == PHASE1ST_EXPIRED)
+                       continue;
+               if (CMPSADDR(ph1->remote, p->remote) == 0) {
+                       if (p == ph1)
+                               continue;
+                       return 0;
+               }
+       }
+       return 1;
+}
+
 /*
  * dump isakmp-sa
  */
@@ -246,9 +283,13 @@ newph1()
        iph1->dpd_lastack = 0;
        iph1->dpd_seq = 0;
        iph1->dpd_fails = 0;
+    iph1->peer_sent_ike = 0;
        iph1->dpd_r_u = NULL;
 #endif
-
+#ifdef ENABLE_VPNCONTROL_PORT
+       iph1->ping_sched = NULL;
+#endif
+       iph1->is_dying = 0;
        return iph1;
 }
 
@@ -259,9 +300,11 @@ void
 delph1(iph1)
        struct ph1handle *iph1;
 {
+       if (iph1 == NULL)
+               return;
+
        /* SA down shell script hook */
-       if (iph1 != NULL)
-               script_hook(iph1, SCRIPT_PHASE1_DOWN);
+       script_hook(iph1, SCRIPT_PHASE1_DOWN);
 
        EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
 
@@ -276,10 +319,20 @@ delph1(iph1)
        }
 #endif
 
+#ifdef ENABLE_HYBRID
+       if (iph1->mode_cfg)
+               isakmp_cfg_rmstate(iph1);
+       VPTRINIT(iph1->xauth_awaiting_userinput_msg);
+#endif
+
 #ifdef ENABLE_DPD
        if (iph1->dpd_r_u != NULL)
                SCHED_KILL(iph1->dpd_r_u);
 #endif
+#ifdef ENABLE_VPNCONTROL_PORT
+       if (iph1->ping_sched != NULL)
+               SCHED_KILL(iph1->ping_sched);
+#endif
 
        if (iph1->remote) {
                racoon_free(iph1->remote);
@@ -295,15 +348,11 @@ delph1(iph1)
                iph1->approval = NULL;
        }
 
-#ifdef ENABLE_HYBRID
-       if (iph1->mode_cfg)
-               isakmp_cfg_rmstate(iph1);
-#endif
-
        VPTRINIT(iph1->authstr);
 
        sched_scrub_param(iph1);
        iph1->sce = NULL;
+       iph1->sce_rekey = NULL;
        iph1->scr = NULL;
 
        VPTRINIT(iph1->sendbuf);
@@ -333,6 +382,9 @@ delph1(iph1)
        VPTRINIT(iph1->id);
        VPTRINIT(iph1->id_p);
 
+       if(iph1->approval != NULL)
+               delisakmpsa(iph1->approval);
+
        if (iph1->ivm) {
                oakley_delivm(iph1->ivm);
                iph1->ivm = NULL;
@@ -348,6 +400,16 @@ delph1(iph1)
        gssapi_free_state(iph1);
 #endif
 
+#ifdef __APPLE__
+       if (iph1->parent_session) {
+               ike_session_unlink_ph1_from_session(iph1);
+       }
+       if (iph1->rmconf) {
+               unlink_rmconf_from_ph1(iph1->rmconf);
+               iph1->rmconf = NULL;
+       }
+#endif
+       
        racoon_free(iph1);
 }
 
@@ -380,17 +442,30 @@ remph1(iph1)
  * flush isakmp-sa
  */
 void
-flushph1()
+flushph1(int ignore_established_handles)
 {
        struct ph1handle *p, *next;
-
+       
        for (p = LIST_FIRST(&ph1tree); p; p = next) {
                next = LIST_NEXT(p, chain);
-
+               
                /* send delete information */
-               if (p->status == PHASE1ST_ESTABLISHED) 
+               if (p->status == PHASE1ST_ESTABLISHED) {
+                       if (ignore_established_handles &&
+                           (ike_session_has_negoing_ph2(p->parent_session) ||
+                            p->mode_cfg->flags)) {
+                               plog(LLV_DEBUG2, LOCATION, NULL,
+                                        "skipping ph1 handler that's established... because it's needed by children phase2s\n");
+                           continue;
+                   }
+                       /* send delete information */
+                       plog(LLV_DEBUG2, LOCATION, NULL,
+                                "got a ph1 handler to flush...\n");
                        isakmp_info_send_d1(p);
+               }
 
+               ike_session_stopped_by_controller(p->parent_session,
+                                                                                 ike_session_stopped_by_flush);
                remph1(p);
                delph1(p);
        }
@@ -469,8 +544,21 @@ getph2byid(src, dst, spid)
        LIST_FOREACH(p, &ph2tree, chain) {
                if (spid == p->spid &&
                    CMPSADDR(src, p->src) == 0 &&
-                   CMPSADDR(dst, p->dst) == 0)
-                       return p;
+                   CMPSADDR(dst, p->dst) == 0){
+                       /* Sanity check to detect zombie handlers
+                        * XXX Sould be done "somewhere" more interesting,
+                        * because we have lots of getph2byxxxx(), but this one
+                        * is called by pk_recvacquire(), so is the most important.
+                        */
+                       if(p->status < PHASE2ST_ESTABLISHED &&
+                          p->retry_counter == 0
+                          && p->sce == NULL && p->scr == NULL){
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                        "Zombie ph2 found, expiring it\n");
+                               isakmp_ph2expire(p);
+                       }else
+                               return p;
+               }
        }
 
        return NULL;
@@ -542,6 +630,7 @@ newph2()
                return NULL;
 
        iph2->status = PHASE1ST_SPAWN;
+       iph2->is_dying = 0;
 
        return iph2;
 }
@@ -635,6 +724,16 @@ delph2(iph2)
                iph2->proposal = NULL;
        }
 
+#ifdef __APPLE__
+       if (iph2->parent_session) {
+               ike_session_unlink_ph2_from_session(iph2);
+       }
+       if (iph2->sainfo) {
+               unlink_sainfo_from_ph2(iph2->sainfo);
+               iph2->sainfo = NULL;
+       }
+#endif
+
        racoon_free(iph2);
 }
 
@@ -664,17 +763,33 @@ initph2tree()
 }
 
 void
-flushph2()
+flushph2(int ignore_established_handles)
 {
        struct ph2handle *p, *next;
 
+       plog(LLV_DEBUG2, LOCATION, NULL,
+                "flushing all ph2 handlers...\n");
+
        for (p = LIST_FIRST(&ph2tree); p; p = next) {
                next = LIST_NEXT(p, chain);
-
-               /* send delete information */
-               if (p->status == PHASE2ST_ESTABLISHED) 
+               
+               if (p->status == PHASE2ST_ESTABLISHED){
+                       if (ignore_established_handles) {
+                               plog(LLV_DEBUG2, LOCATION, NULL,
+                                        "skipping ph2 handler that's established...\n");
+                           continue;
+                   }
+                       /* send delete information */
+                       plog(LLV_DEBUG2, LOCATION, NULL,
+                                "got an established ph2 handler to flush...\n");
                        isakmp_info_send_d2(p);
-
+               }else{
+                       plog(LLV_DEBUG2, LOCATION, NULL,
+                                "got a ph2 handler to flush (state %d)\n", p->status);
+               }
+               
+               ike_session_stopped_by_controller(p->parent_session,
+                                                                                 ike_session_stopped_by_flush);
                delete_spd(p);
                unbindph12(p);
                remph2(p);
@@ -699,7 +814,11 @@ deleteallph2(src, dst, proto_id)
                next = LIST_NEXT(iph2, chain);
                if (iph2->proposal == NULL && iph2->approval == NULL)
                        continue;
-               if (iph2->approval != NULL) {
+               if (cmpsaddrwop(src, iph2->src) != 0 ||
+                   cmpsaddrwop(dst, iph2->dst) != 0) {
+            continue;
+        }
+        if (iph2->approval != NULL) {
                        for (pr = iph2->approval->head; pr != NULL;
                             pr = pr->next) {
                                if (proto_id == pr->proto_id)
@@ -714,18 +833,54 @@ deleteallph2(src, dst, proto_id)
                }
                continue;
  zap_it:
+        plog(LLV_DEBUG2, LOCATION, NULL,
+             "deleteallph2: got a ph2 handler...\n");
+        if (iph2->status == PHASE2ST_ESTABLISHED)
+            isakmp_info_send_d2(iph2);
+        ike_session_stopped_by_controller(iph2->parent_session,
+                                          ike_session_stopped_by_flush);
                unbindph12(iph2);
                remph2(iph2);
                delph2(iph2);
        }
 }
 
+/*
+ * Delete all Phase 1 handlers for this src/dst.
+ */
+void
+deleteallph1(src, dst)
+struct sockaddr *src, *dst;
+{
+       struct ph1handle *iph1, *next;
+
+       for (iph1 = LIST_FIRST(&ph1tree); iph1 != NULL; iph1 = next) {
+               next = LIST_NEXT(iph1, chain);
+               if (cmpsaddrwop(src, iph1->local) != 0 ||
+                   cmpsaddrwop(dst, iph1->remote) != 0) {
+                       continue;
+        }
+        plog(LLV_DEBUG2, LOCATION, NULL,
+             "deleteallph1: got a ph1 handler...\n");
+        if (iph1->status == PHASE2ST_ESTABLISHED)
+               isakmp_info_send_d1(iph1);
+
+               ike_session_stopped_by_controller(iph1->parent_session,
+                                                 ike_session_stopped_by_flush);
+               remph1(iph1);
+               delph1(iph1);
+       }
+}
+
 /* %%% */
 void
 bindph12(iph1, iph2)
        struct ph1handle *iph1;
        struct ph2handle *iph2;
 {
+       if (iph2->ph1 && (struct ph1handle *)iph2->ph1bind.le_next == iph1) {
+               plog(LLV_ERROR, LOCATION, NULL, "duplicate %s.\n", __FUNCTION__);               
+       }
        iph2->ph1 = iph1;
        LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
 }
@@ -735,11 +890,37 @@ unbindph12(iph2)
        struct ph2handle *iph2;
 {
        if (iph2->ph1 != NULL) {
+               plog(LLV_DEBUG, LOCATION, NULL, "unbindph12.\n");
                iph2->ph1 = NULL;
                LIST_REMOVE(iph2, ph1bind);
        }
 }
 
+void
+rebindph12(new_ph1, iph2)
+struct ph1handle *new_ph1;
+struct ph2handle *iph2;
+{
+       if (!new_ph1) {
+               return;
+       }
+
+       // reconcile the ph1-to-ph2 binding
+       plog(LLV_DEBUG, LOCATION, NULL, "rebindph12.\n");
+       unbindph12(iph2);
+       bindph12(new_ph1, iph2);
+       // recalculate ivm since ph1 binding has changed
+       if (iph2->ivm != NULL) {
+               oakley_delivm(iph2->ivm);
+               if (new_ph1->status == PHASE1ST_ESTABLISHED) {
+                       iph2->ivm = oakley_newiv2(new_ph1, iph2->msgid);
+                       plog(LLV_DEBUG, LOCATION, NULL, "ph12 binding changed... recalculated ivm.\n");
+               } else {
+                       iph2->ivm = NULL;
+               }
+       }
+}
+
 /* %%% management contacted list */
 /*
  * search contacted list.
@@ -773,6 +954,12 @@ inscontacted(remote)
                return -1;
 
        new->remote = dupsaddr(remote);
+       if (new->remote == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "failed to allocate buffer.\n");
+               racoon_free(new);
+               return -1;
+       }
 
        LIST_INSERT_HEAD(&ctdtree, new, chain);
 
@@ -840,9 +1027,11 @@ check_recvdpkt(remote, local, rbuf)
 
        /*
         * the packet was processed before, but the remote address mismatches.
+         * ignore the port to accomodate port changes (e.g. floating).
         */
-       if (cmpsaddrstrict(remote, r->remote) != 0)
-               return 2;
+       if (cmpsaddrwop(remote, r->remote) != 0) {
+               return 2;
+        }
 
        /*
         * it should not check the local address because the packet
@@ -888,9 +1077,10 @@ check_recvdpkt(remote, local, rbuf)
  * adding a hash of received packet into the received list.
  */
 int
-add_recvdpkt(remote, local, sbuf, rbuf)
+add_recvdpkt(remote, local, sbuf, rbuf, non_esp)
        struct sockaddr *remote, *local;
        vchar_t *sbuf, *rbuf;
+    size_t non_esp;
 {
        struct recvdpkt *new = NULL;
 
@@ -927,13 +1117,30 @@ add_recvdpkt(remote, local, sbuf, rbuf)
                del_recvdpkt(new);
                return -1;
        }
-       new->sendbuf = vdup(sbuf);
-       if (new->sendbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "failed to allocate buffer.\n");
-               del_recvdpkt(new);
-               return -1;
-       }
+
+       if (non_esp) {
+               plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n");
+
+        /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker) 
+         must added just before the packet itself. For this we must 
+         allocate a new buffer and release it at the end. */
+        if ((new->sendbuf = vmalloc (sbuf->l + non_esp)) == NULL) {
+            plog(LLV_ERROR, LOCATION, NULL, 
+                 "failed to allocate extra buf for non-esp\n");
+            del_recvdpkt(new);
+            return -1;
+        }
+        *(u_int32_t *)new->sendbuf->v = 0;
+        memcpy(new->sendbuf->v + non_esp, sbuf->v, sbuf->l);
+    } else {
+        new->sendbuf = vdup(sbuf);
+        if (new->sendbuf == NULL) {
+            plog(LLV_ERROR, LOCATION, NULL,
+                 "failed to allocate buffer.\n");
+            del_recvdpkt(new);
+            return -1;
+        }
+    }
 
        new->retry_counter = lcconf->retry_counter;
        new->time_send = 0;
@@ -1038,3 +1245,129 @@ exclude_cfg_addr(addr)
        return 1;
 }
 #endif
+
+#ifdef ENABLE_HYBRID
+struct ph1handle *
+getph1bylogin(login)
+       char *login;
+{
+       struct ph1handle *p;
+
+       LIST_FOREACH(p, &ph1tree, chain) {
+               if (p->mode_cfg == NULL)
+                       continue;
+               if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0)
+                       return p;
+       }
+
+       return NULL;
+}
+
+int
+purgeph1bylogin(login)
+       char *login;
+{
+       struct ph1handle *p;
+       int found = 0;
+
+       LIST_FOREACH(p, &ph1tree, chain) {
+               if (p->mode_cfg == NULL)
+                       continue;
+               if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) {
+                       if (p->status == PHASE1ST_ESTABLISHED)
+                               isakmp_info_send_d1(p);
+                       purge_remote(p);
+                       found++;
+               }
+       }
+
+       return found;
+}
+
+int
+purgephXbydstaddrwop(remote)
+struct sockaddr *remote;
+{
+       int    found = 0;
+       struct ph1handle *p;
+       
+       LIST_FOREACH(p, &ph1tree, chain) {
+               if (cmpsaddrwop(remote, p->remote) == 0) {
+            plog(LLV_WARNING, LOCATION, NULL,
+                 "in %s... purging phase1 and related phase2s\n", __FUNCTION__);
+            ike_session_purge_ph2s_by_ph1(p);
+                       if (p->status == PHASE1ST_ESTABLISHED)
+                               isakmp_info_send_d1(p);
+            isakmp_ph1expire(p);
+                       found++;
+               }
+       }
+
+       return found;
+}
+
+void
+purgephXbyspid(u_int32_t spid,
+               int       del_boundph1)
+{
+       struct ph2handle *iph2;
+    struct ph1handle *iph1;
+
+    // do ph2's first... we need the ph1s for notifications
+       LIST_FOREACH(iph2, &ph2tree, chain) {
+               if (spid == iph2->spid) {
+            if (iph2->status == PHASE2ST_ESTABLISHED) {
+                isakmp_info_send_d2(iph2);
+            }
+            isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
+            ike_session_stopped_by_controller(iph2->parent_session,
+                                              ike_session_stopped_by_flush);
+        }
+    }
+
+    // do the ph1s last.
+       LIST_FOREACH(iph2, &ph2tree, chain) {
+               if (spid == iph2->spid) {
+            if (del_boundph1 && iph2->parent_session) {
+                for (iph1 = LIST_FIRST(&iph2->parent_session->ikev1_state.ph1tree); iph1; iph1 = LIST_NEXT(iph1, ph1ofsession_chain)) {
+                    if (iph1->status == PHASE1ST_ESTABLISHED) {
+                        isakmp_info_send_d1(iph1);
+                    }
+                    isakmp_ph1expire(iph1);
+                }
+            }
+               }
+       }
+}
+
+#endif
+
+#ifdef ENABLE_DPD
+int
+ph1_force_dpd (struct sockaddr *remote)
+{
+    int status = -1;
+    struct ph1handle *p;
+
+    LIST_FOREACH(p, &ph1tree, chain) {
+        if (cmpsaddrwop(remote, p->remote) == 0) {
+            if (p->status == PHASE1ST_ESTABLISHED &&
+                !p->is_dying &&
+                p->dpd_support &&
+                p->rmconf->dpd_interval) {
+                if(!p->dpd_fails) {
+                    isakmp_info_send_r_u(p);
+                    status = 0;
+                } else {
+                    plog(LLV_DEBUG2, LOCATION, NULL, "skipping forced-DPD for phase1 (dpd already in progress).\n");
+                }
+            } else {
+                plog(LLV_DEBUG2, LOCATION, NULL, "skipping forced-DPD for phase1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
+                     p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval);
+            }
+        }
+    }
+
+       return status;
+}
+#endif
index 2d5bfb432d940a65ab1d366534d821b06a37ce0e..9dcfdbd341c4b818772e74dd778ea31071f24db6 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: handler.h,v 1.11.4.3 2005/05/07 17:26:05 manubsd Exp $ */
+/*     $NetBSD: handler.h,v 1.9 2006/09/09 16:22:09 manu Exp $ */
+
+/* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -40,6 +42,8 @@
 #include "isakmp_var.h"
 #include "oakley.h"
 
+typedef struct ike_session ike_session_t;
+
 /* Phase 1 handler */
 /*
  * main mode:
@@ -112,6 +116,7 @@ struct ph1handle {
 
        int status;                     /* status of this SA */
        int side;                       /* INITIATOR or RESPONDER */
+       int started_by_api;             /* connection started by VPNControl API */
 
        struct sockaddr *remote;        /* remote address to negosiate ph1 */
        struct sockaddr *local;         /* local address to negosiate ph1 */
@@ -128,15 +133,18 @@ struct ph1handle {
        u_int8_t etype;                 /* Exchange type actually for use */
        u_int8_t flags;                 /* Flags */
        u_int32_t msgid;                /* message id */
-
+       
+#ifdef ENABLE_NATT
        struct ph1natt_options *natt_options;   /* Selected NAT-T IKE version */
        u_int32_t natt_flags;           /* NAT-T related flags */
+#endif
 #ifdef ENABLE_FRAG
        int frag;                       /* IKE phase 1 fragmentation */
        struct isakmp_frag_item *frag_chain;    /* Received fragments */
 #endif
 
        struct sched *sce;              /* schedule for expire */
+       struct sched *sce_rekey; /* schedule for rekey */
 
        struct sched *scr;              /* schedule for resend */
        int retry_counter;              /* for resend. */
@@ -165,7 +173,7 @@ struct ph1handle {
        struct genlist *rsa_candidates; /* possible candidates for peer's RSA key */
        vchar_t *id;                    /* ID minus gen header */
        vchar_t *id_p;                  /* partner's ID minus general header */
-                                       /* i.e. strut ipsecdoi_id_b*. */
+                                       /* i.e. struct ipsecdoi_id_b*. */
        struct isakmp_ivm *ivm;         /* IVs */
 
        vchar_t *sa;                    /* whole SA payload to send/to be sent*/
@@ -191,12 +199,19 @@ struct ph1handle {
        struct timeval end;
 #endif
 
+#ifdef ENABLE_DPD
        int             dpd_support;    /* Does remote supports DPD ? */
        time_t          dpd_lastack;    /* Last ack received */
        u_int16_t       dpd_seq;                /* DPD seq number to receive */
        u_int8_t        dpd_fails;              /* number of failures */
+    u_int8_t         peer_sent_ike;
        struct sched    *dpd_r_u;
+#endif
 
+#ifdef ENABLE_VPNCONTROL_PORT
+       struct sched *ping_sched;       /* for sending pings to keep FW open */
+#endif
+       
        u_int32_t msgid2;               /* msgid counter for Phase 2 */
        int ph2cnt;     /* the number which is negotiated by this phase 1 */
        LIST_HEAD(_ph2ofph1_, ph2handle) ph2tree;
@@ -204,8 +219,16 @@ struct ph1handle {
        LIST_ENTRY(ph1handle) chain;
 #ifdef ENABLE_HYBRID
        struct isakmp_cfg_state *mode_cfg;      /* ISAKMP mode config state */
-#endif       
-
+       u_int8_t pended_xauth_id;                       /* saved id for reply from vpn control socket */
+       u_int8_t xauth_awaiting_userinput;      /* indicates we are waiting for user input */
+        vchar_t *xauth_awaiting_userinput_msg; /* tracks the last packet that triggered XAUTH */
+#endif
+#ifdef __APPLE__
+       int                    is_rekey:1;
+       int                    is_dying:1;
+       ike_session_t         *parent_session;
+       LIST_ENTRY(ph1handle)  ph1ofsession_chain;
+#endif
 };
 
 /* Phase 2 handler */
@@ -311,7 +334,13 @@ struct ph2handle {
        struct timeval end;
 #endif
        struct ph1handle *ph1;  /* back pointer to isakmp status */
-
+#ifdef __APPLE__
+       int                    is_rekey:1;
+       int                    is_dying:1;
+       ike_session_t         *parent_session;
+       LIST_ENTRY(ph2handle)  ph2ofsession_chain;
+#endif
+       
        LIST_ENTRY(ph2handle) chain;
        LIST_ENTRY(ph2handle) ph1bind;  /* chain to ph1handle */
 };
@@ -424,12 +453,21 @@ extern struct ph1handle *getph1byaddr __P((struct sockaddr *,
 extern struct ph1handle *getph1byaddrwop __P((struct sockaddr *,
        struct sockaddr *));
 extern struct ph1handle *getph1bydstaddrwop __P((struct sockaddr *));
+extern int islast_ph1 __P((struct ph1handle *));
+       struct ph1handle *ph1;
+#ifdef ENABLE_HYBRID
+struct ph1handle *getph1bylogin __P((char *));
+int purgeph1bylogin __P((char *));
+#endif
+extern int purgephXbydstaddrwop __P((struct sockaddr *));
+extern void purgephXbyspid __P((u_int32_t, int));
+
 extern vchar_t *dumpph1 __P((void));
 extern struct ph1handle *newph1 __P((void));
 extern void delph1 __P((struct ph1handle *));
 extern int insph1 __P((struct ph1handle *));
 extern void remph1 __P((struct ph1handle *));
-extern void flushph1 __P((void));
+extern void flushph1 __P((int));
 extern void initph1tree __P((void));
 
 extern struct ph2handle *getph2byspidx __P((struct policyindex *));
@@ -447,12 +485,14 @@ extern void initph2 __P((struct ph2handle *));
 extern void delph2 __P((struct ph2handle *));
 extern int insph2 __P((struct ph2handle *));
 extern void remph2 __P((struct ph2handle *));
-extern void flushph2 __P((void));
+extern void flushph2 __P((int));
 extern void deleteallph2 __P((struct sockaddr *, struct sockaddr *, u_int));
+extern void deleteallph1 __P((struct sockaddr *, struct sockaddr *));
 extern void initph2tree __P((void));
 
 extern void bindph12 __P((struct ph1handle *, struct ph2handle *));
 extern void unbindph12 __P((struct ph2handle *));
+extern void rebindph12 __P((struct ph1handle *, struct ph2handle *));
 
 extern struct contacted *getcontacted __P((struct sockaddr *));
 extern int inscontacted __P((struct sockaddr *));
@@ -462,7 +502,7 @@ extern void initctdtree __P((void));
 extern int check_recvdpkt __P((struct sockaddr *,
        struct sockaddr *, vchar_t *));
 extern int add_recvdpkt __P((struct sockaddr *, struct sockaddr *,
-       vchar_t *, vchar_t *));
+       vchar_t *, vchar_t *, size_t));
 extern void clear_recvdpkt __P((void));
 extern void init_recvdpkt __P((void));
 
@@ -470,4 +510,8 @@ extern void init_recvdpkt __P((void));
 extern int exclude_cfg_addr __P((const struct sockaddr *));
 #endif
 
+#ifdef ENABLE_DPD
+extern int  ph1_force_dpd __P((struct sockaddr *));
+#endif
+
 #endif /* _HANDLER_H */
diff --git a/ipsec-tools/racoon/ike_session.c b/ipsec-tools/racoon/ike_session.c
new file mode 100644 (file)
index 0000000..4f688bf
--- /dev/null
@@ -0,0 +1,1355 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include "var.h"
+#include "misc.h"
+#include "vmbuf.h"
+#include "plog.h"
+#include "sockmisc.h"
+#include "debug.h"
+
+#include "isakmp_var.h"
+#include "isakmp.h"
+#include "ike_session.h"
+#include "handler.h"
+#include "gcmalloc.h"
+#include "nattraversal.h"
+#include "schedule.h"
+#include "pfkey.h"
+#include "ipsec_doi.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
+#include "isakmp_inf.h"
+#include "localconf.h"
+#include "remoteconf.h"
+#include "vpn_control.h"
+
+const char *ike_session_stopped_by_vpn_disconnect = "Stopped by VPN disconnect";
+const char *ike_session_stopped_by_flush          = "Stopped by Flush";
+const char *ike_session_stopped_by_idle           = "Stopped by Idle";
+const char *ike_session_stopped_by_xauth_timeout  = "Stopped by XAUTH timeout";
+
+static LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree;
+
+static ike_session_t *
+new_ike_session (ike_session_id_t *id)
+{
+       ike_session_t *session;
+
+       if (!id) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return NULL;
+       }
+
+       plog(LLV_DEBUG, LOCATION, NULL, "new parent session.\n");
+       session = racoon_calloc(1, sizeof(*session));
+       if (session) {
+               bzero(session, sizeof(*session));
+               memcpy(&session->session_id, id, sizeof(*id));
+               LIST_INIT(&session->ikev1_state.ph1tree);
+               LIST_INIT(&session->ikev1_state.ph2tree);       
+               LIST_INSERT_HEAD(&ike_session_tree, session, chain);
+               session->version = IKE_VERSION_1; // hard-coded for now
+               IPSECSESSIONTRACERSTART(session);
+       }
+       return session;
+}
+
+static void
+free_ike_session (ike_session_t *session)
+{
+    int is_failure = TRUE;
+       if (session) {
+        SCHED_KILL(session->traffic_monitor.sc_mon);
+        SCHED_KILL(session->traffic_monitor.sc_idle);
+        SCHED_KILL(session->sc_xauth);
+               if (session->start_timestamp.tv_sec || session->start_timestamp.tv_usec) {
+                       if (!(session->stop_timestamp.tv_sec || session->start_timestamp.tv_usec)) {
+                               gettimeofday(&session->stop_timestamp, NULL);
+                       }
+            if (session->term_reason != ike_session_stopped_by_vpn_disconnect ||
+                session->term_reason != ike_session_stopped_by_flush ||
+                session->term_reason != ike_session_stopped_by_idle) {
+                is_failure = FALSE;
+            }
+                       IPSECSESSIONTRACERSTOP(session,
+                                                                  is_failure,
+                                                                  session->term_reason);
+               }
+               // do MessageTracer cleanup here
+               plog(LLV_DEBUG, LOCATION, NULL,
+                        "Freeing IKE-Session to %s.\n",
+                        saddr2str((struct sockaddr *)&session->session_id.remote));
+               LIST_REMOVE(session, chain);
+               racoon_free(session);
+       }
+}
+
+struct ph1handle *
+ike_session_get_established_or_negoing_ph1 (ike_session_t *session)
+{
+       struct ph1handle *p, *iph1 = NULL;
+
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return NULL;
+       }
+
+       // look for the most mature ph1 under the session
+       for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) {
+               if (!p->is_dying && p->status >= PHASE1ST_START && p->status <= PHASE1ST_ESTABLISHED) {
+                       if (!iph1 || p->status > iph1->status) {
+                               iph1 = p;
+                       } else if (iph1 && p->status == iph1->status) {
+                               // TODO: pick better one based on farthest rekey/expiry remaining
+                       }
+               }
+       }
+
+       return iph1;
+}
+
+struct ph1handle *
+ike_session_get_established_ph1 (ike_session_t *session)
+{
+       struct ph1handle *p;
+    
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return NULL;
+       }
+    
+       for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) {
+               if (!p->is_dying && p->status == PHASE1ST_ESTABLISHED) {
+            return p;
+               }
+       }
+    
+       return NULL;
+}
+
+void
+ike_session_init (void)
+{
+       LIST_INIT(&ike_session_tree);
+}
+
+u_int
+ike_session_get_rekey_lifetime (int local_spi_is_higher, u_int expiry_lifetime)
+{
+       u_int rekey_lifetime = expiry_lifetime / 10;
+
+       if (rekey_lifetime) {
+               if (local_spi_is_higher) {
+                       return (rekey_lifetime * 9);
+               } else {
+                       return (rekey_lifetime * 8);
+               }
+       } else {
+               if (local_spi_is_higher) {
+                       rekey_lifetime = expiry_lifetime - 1;
+               } else {
+                       rekey_lifetime = expiry_lifetime - 2;
+               }
+       }
+       if (rekey_lifetime < expiry_lifetime) {
+               return (rekey_lifetime);
+       }
+       return(0);
+}
+
+// TODO: optimize this mess later
+ike_session_t *
+ike_session_get_session (struct sockaddr *local,
+                                                struct sockaddr *remote,
+                                                int              alloc_if_absent)
+{
+       ike_session_t    *p;
+       ike_session_id_t  id;
+       ike_session_id_t  id_default;
+       ike_session_id_t  id_floated_default;
+       ike_session_id_t  id_wop;
+       ike_session_t    *best_match = NULL;
+       u_int16_t         remote_port;
+       int               is_isakmp_remote_port;
+
+       if (!local || !remote) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return NULL;
+       }
+
+       remote_port = extract_port(remote);
+       if (remote_port && remote_port != PORT_ISAKMP && remote_port != PORT_ISAKMP_NATT) {
+               is_isakmp_remote_port = 0;
+       } else {
+               is_isakmp_remote_port = 1;
+       }
+
+       /* we will try a couple of matches first: if the exact id isn't found, then we'll try for an id that has zero'd ports */
+       bzero(&id, sizeof(id));
+       bzero(&id_default, sizeof(id_default));
+       bzero(&id_floated_default, sizeof(id_floated_default));
+       bzero(&id_wop, sizeof(id_wop));
+       if (local->sa_family == AF_INET) {
+               memcpy(&id.local, local, sizeof(struct sockaddr_in));
+               memcpy(&id_default.local, local, sizeof(struct sockaddr_in));
+               memcpy(&id_floated_default.local, local, sizeof(struct sockaddr_in));
+               memcpy(&id_wop.local, local, sizeof(struct sockaddr_in));
+       } else if (local->sa_family == AF_INET6) {
+               memcpy(&id.local, local, sizeof(struct sockaddr_in6));
+               memcpy(&id_default.local, local, sizeof(struct sockaddr_in6));
+               memcpy(&id_floated_default.local, local, sizeof(struct sockaddr_in6));
+               memcpy(&id_wop.local, local, sizeof(struct sockaddr_in6));
+       }
+       set_port((struct sockaddr *)&id_default.local, PORT_ISAKMP);
+       set_port((struct sockaddr *)&id_floated_default.local, PORT_ISAKMP_NATT);
+       set_port((struct sockaddr *)&id_wop.local, 0);
+       if (remote->sa_family == AF_INET) {
+               memcpy(&id.remote, remote, sizeof(struct sockaddr_in));
+               memcpy(&id_default.remote, remote, sizeof(struct sockaddr_in));
+               memcpy(&id_floated_default.remote, remote, sizeof(struct sockaddr_in));
+               memcpy(&id_wop.remote, remote, sizeof(struct sockaddr_in));
+       } else if (remote->sa_family == AF_INET6) {
+               memcpy(&id.remote, remote, sizeof(struct sockaddr_in6));
+               memcpy(&id_default.remote, remote, sizeof(struct sockaddr_in6));
+               memcpy(&id_floated_default.remote, remote, sizeof(struct sockaddr_in6));
+               memcpy(&id_wop.remote, remote, sizeof(struct sockaddr_in6));
+       }
+       set_port((struct sockaddr *)&id_default.remote, PORT_ISAKMP);
+       set_port((struct sockaddr *)&id_floated_default.remote, PORT_ISAKMP_NATT);
+       set_port((struct sockaddr *)&id_wop.remote, 0);
+
+       plog(LLV_DEBUG, LOCATION, local,
+                "start search for IKE-Session. target %s.\n",
+                saddr2str(remote));                    
+
+       for (p = LIST_FIRST(&ike_session_tree); p; p = LIST_NEXT(p, chain)) {
+               plog(LLV_DEBUG, LOCATION, local,
+                        "still search for IKE-Session. this %s.\n",
+                        saddr2str((struct sockaddr *)&p->session_id.remote));
+
+               if (memcmp(&p->session_id, &id, sizeof(id)) == 0) {
+                       plog(LLV_DEBUG, LOCATION, local,
+                                "Pre-existing IKE-Session to %s. case 1.\n",
+                                saddr2str(remote));                    
+                       return p;
+               } else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_default, sizeof(id_default)) == 0) {
+                       plog(LLV_DEBUG, LOCATION, local,
+                                "Pre-existing IKE-Session to %s. case 2.\n",
+                                saddr2str(remote));    
+                       return p;
+               } else if (is_isakmp_remote_port && p->ports_floated && memcmp(&p->session_id, &id_floated_default, sizeof(id_floated_default)) == 0) {
+                       plog(LLV_DEBUG, LOCATION, local,
+                                "Pre-existing IKE-Session to %s. case 3.\n",
+                                saddr2str(remote));                    
+                       return p;
+               } else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_wop, sizeof(id_wop)) == 0) {
+                       best_match = p;
+               }
+       }
+       if (best_match) {
+               plog(LLV_DEBUG, LOCATION, local,
+                        "Best-match IKE-Session to %s.\n",
+                        saddr2str((struct sockaddr *)&best_match->session_id.remote));
+               return best_match;
+       }
+       if (alloc_if_absent) {
+               plog(LLV_DEBUG, LOCATION, local,
+                        "New IKE-Session to %s.\n",
+                        saddr2str((struct sockaddr *)&id.remote));                     
+               return new_ike_session(&id);
+       } else {
+               return NULL;
+       }
+}
+
+void
+ike_session_init_traffic_cop_params (struct ph1handle *iph1)
+{
+    if (!iph1 ||
+        !iph1->rmconf ||
+        (!iph1->rmconf->idle_timeout && !iph1->rmconf->dpd_interval)) {
+        return;
+    }
+
+    if (!iph1->parent_session->traffic_monitor.interv_idle) {
+        iph1->parent_session->traffic_monitor.interv_idle = iph1->rmconf->idle_timeout;
+    }
+    if (!iph1->parent_session->traffic_monitor.dir_idle) {
+        iph1->parent_session->traffic_monitor.dir_idle = iph1->rmconf->idle_timeout_dir;
+    }
+    
+    if (!iph1->parent_session->traffic_monitor.interv_mon) {
+        int min_period, max_period, sample_period = 0;
+
+        /* calculate the sampling interval... half the smaller interval */
+        if (iph1->rmconf->dpd_interval &&
+            (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT ||
+             iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT)) {
+            // when certain types of dpd are enabled
+            min_period = MIN(iph1->rmconf->dpd_interval, iph1->rmconf->idle_timeout);
+            max_period = MAX(iph1->rmconf->dpd_interval, iph1->rmconf->idle_timeout);
+        } else if (iph1->rmconf->idle_timeout) {
+            min_period = max_period = MIN(0, iph1->rmconf->idle_timeout);
+        } else {
+            // DPD_ALGO_DEFAULT is configured and there's no idle timeout... we don't need to monitor traffic
+            return;
+        }
+        if (min_period) {
+            sample_period = min_period >> 1;
+            if (!sample_period)
+                sample_period = 1; // bad
+        } else {
+            sample_period = max_period >> 1;
+            if (!sample_period)
+                sample_period = 1; // bad
+        }
+        iph1->parent_session->traffic_monitor.interv_mon = sample_period;
+    }
+}
+
+int
+ike_session_link_ph1_to_session (struct ph1handle *iph1)
+{
+       ike_session_t *session;
+
+       if (!iph1) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return -1;
+       }
+
+       session = ike_session_get_session(iph1->local, iph1->remote, TRUE);
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "failed to get session in %s.\n", __FUNCTION__);
+               return -1;
+       }
+
+       // already linked
+       if (iph1->parent_session) {
+               if (session == iph1->parent_session) {
+                       return 0;
+               }
+               // undo previous session
+               if (ike_session_unlink_ph1_from_session(iph1) == 0) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "failed to unlink ph1 in %s.\n", __FUNCTION__);
+                       free_ike_session(session);
+                       return -1;
+               }
+       } else {
+               gettimeofday(&session->start_timestamp, NULL);
+       }
+
+
+       if (iph1->started_by_api) {
+               session->is_cisco_ipsec = 1;
+        session->is_l2tpvpn_ipsec = 0;
+        session->is_btmm_ipsec = 0;
+       }
+       iph1->parent_session = session;
+       LIST_INSERT_HEAD(&session->ikev1_state.ph1tree, iph1, ph1ofsession_chain);
+       session->ikev1_state.active_ph1cnt++;
+    if ((!session->ikev1_state.ph1cnt &&
+         iph1->side == INITIATOR) ||
+        iph1->started_by_api) {
+        // client initiates the first phase1 or, is started by controller api
+        session->is_client = 1;
+    }
+       if (session->established &&
+               session->ikev1_state.ph1cnt) {
+               iph1->is_rekey = 1;
+       }
+       session->ikev1_state.ph1cnt++;
+    ike_session_init_traffic_cop_params(iph1);
+
+       return 0;
+}
+
+void
+ike_session_update_mode (struct ph2handle *iph2)
+{
+       if (!iph2 || !iph2->parent_session) {
+               return;
+       }
+
+       // exit early if we already detected cisco-ipsec
+       if (iph2->parent_session->is_cisco_ipsec) {
+               return;
+       }
+
+       if (iph2->approval) {
+               if (!ipsecdoi_any_transportmode(iph2->approval)) {
+                       // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
+                       iph2->parent_session->is_cisco_ipsec = 0;
+                       iph2->parent_session->is_l2tpvpn_ipsec = 0;
+                       iph2->parent_session->is_btmm_ipsec = 1;
+                       return;
+               } else if (ipsecdoi_transportmode(iph2->approval)) {
+                       iph2->parent_session->is_cisco_ipsec = 0;
+                       iph2->parent_session->is_l2tpvpn_ipsec = 1;
+                       iph2->parent_session->is_btmm_ipsec = 0;
+                       return;
+               }
+       } else if (iph2->proposal) {
+               if (!ipsecdoi_any_transportmode(iph2->proposal)) {
+                       // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1)
+                       iph2->parent_session->is_cisco_ipsec = 0;
+                       iph2->parent_session->is_l2tpvpn_ipsec = 0;
+                       iph2->parent_session->is_btmm_ipsec = 1;
+                       return;
+               } else if (ipsecdoi_transportmode(iph2->proposal)) {
+                       iph2->parent_session->is_cisco_ipsec = 0;
+                       iph2->parent_session->is_l2tpvpn_ipsec = 1;
+                       iph2->parent_session->is_btmm_ipsec = 0;
+                       return;
+               }
+       }
+}
+
+static void
+ike_session_cleanup_xauth_timeout (void *arg)
+{
+    ike_session_t *session = (ike_session_t *)arg;
+
+    SCHED_KILL(session->sc_xauth);
+    // if there are no more established ph2s, start a timer to teardown the session
+    if (!ike_session_has_established_ph2(session)) {
+        ike_session_cleanup(session, ike_session_stopped_by_xauth_timeout);
+    } else {
+        session->sc_xauth = sched_new(300 /* 5 mins */,
+                                      ike_session_cleanup_xauth_timeout,
+                                      session);
+    }
+}
+
+int
+ike_session_link_ph2_to_session (struct ph2handle *iph2)
+{
+       struct sockaddr *local;
+       struct sockaddr *remote;
+       ike_session_t   *session;
+
+       if (!iph2) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return -1;
+       }
+
+    local = iph2->src;
+    remote = iph2->dst;
+
+       session = ike_session_get_session(local, remote, TRUE);
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "failed to get session in %s.\n", __FUNCTION__);
+               return -1;
+       }
+
+       // already linked
+       if (iph2->parent_session) {
+               if (session == iph2->parent_session) {
+                       return 0;
+               }
+               // undo previous session
+               if (ike_session_unlink_ph2_from_session(iph2) == 0) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "failed to unlink ph2 in %s.\n", __FUNCTION__);
+                       free_ike_session(session);
+                       return -1;
+               }
+       }
+
+       iph2->parent_session = session;
+       LIST_INSERT_HEAD(&session->ikev1_state.ph2tree, iph2, ph2ofsession_chain);
+       session->ikev1_state.active_ph2cnt++;
+    if (!session->ikev1_state.ph2cnt &&
+        iph2->side == INITIATOR) {
+        // client initiates the first phase2
+        session->is_client = 1;
+    }
+       if (session->established &&
+               session->ikev1_state.ph2cnt) {
+               iph2->is_rekey = 1;
+       }
+       session->ikev1_state.ph2cnt++;
+
+       ike_session_update_mode(iph2);
+
+       return 0;
+}
+
+int
+ike_session_unlink_ph1_from_session (struct ph1handle *iph1)
+{
+       ike_session_t *session;
+       
+       if (!iph1 || !iph1->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return -1;
+       }
+
+    if (LIST_FIRST(&iph1->ph2tree)) {
+        // reparent any phase2 that may be hanging on to this phase1
+        ike_session_update_ph1_ph2tree(iph1);
+    }
+
+       session = iph1->parent_session;
+       LIST_REMOVE(iph1, ph1ofsession_chain);
+       iph1->parent_session = NULL;
+       session->ikev1_state.active_ph1cnt--;
+       if (session->ikev1_state.active_ph1cnt == 0 && session->ikev1_state.active_ph2cnt == 0) {
+               free_ike_session(session);
+       }
+
+       return 0;
+}
+
+int
+ike_session_unlink_ph2_from_session (struct ph2handle *iph2)
+{
+       ike_session_t *session;
+       
+       if (!iph2 || !iph2->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return -1;
+       }
+       
+       LIST_REMOVE(iph2, ph2ofsession_chain);
+       session = iph2->parent_session;
+       iph2->parent_session = NULL;
+       session->ikev1_state.active_ph2cnt--;
+       if (session->ikev1_state.active_ph1cnt == 0 && session->ikev1_state.active_ph2cnt == 0) {
+               free_ike_session(session);
+       }
+       
+       return 0;
+}
+
+int
+ike_session_has_other_established_ph1 (ike_session_t *session, struct ph1handle *iph1)
+{
+       struct ph1handle *p;
+
+       if (!session) {
+               return 0;
+       }
+
+       for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) {
+               if (iph1 != p && !p->is_dying) {
+                       if (p->status == PHASE1ST_ESTABLISHED && p->sce_rekey) {
+                               return 1;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+int
+ike_session_has_other_negoing_ph1 (ike_session_t *session, struct ph1handle *iph1)
+{
+       struct ph1handle *p;
+       
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return 0;
+       }
+       
+       for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) {
+               if (iph1 != p && !p->is_dying) {
+                       if (p->status >= PHASE1ST_START && p->status <= PHASE1ST_ESTABLISHED) {
+                               return 1;
+                       }
+               }
+       }
+       
+       return 0;
+}
+
+int
+ike_session_has_other_established_ph2 (ike_session_t *session, struct ph2handle *iph2)
+{
+       struct ph2handle *p;
+       
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return 0;
+       }
+       
+       for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) {
+               if (iph2 != p && !p->is_dying && iph2->spid == p->spid) {
+                       if (p->status == PHASE2ST_ESTABLISHED) {
+                               return 1;
+                       }
+               }
+       }
+       
+       return 0;
+}
+
+int
+ike_session_has_other_negoing_ph2 (ike_session_t *session, struct ph2handle *iph2)
+{
+       struct ph2handle *p;
+       
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return 0;
+       }
+       
+       for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) {
+               if (iph2 != p && !p->is_dying && iph2->spid == p->spid) {
+                       if (p->status >= PHASE2ST_START && p->status < PHASE2ST_ESTABLISHED) {
+                               return 1;
+                       }
+               }
+       }
+       
+       return 0;
+}
+
+static void
+ike_session_unbindph12_from_ph1 (struct ph1handle *iph1)
+{
+       struct ph2handle *p, *next;
+
+       for (p = LIST_FIRST(&iph1->ph2tree); p; p = next) {
+               // take next pointer now, since unbind and rebind may change the underlying ph2tree list
+               next = LIST_NEXT(p, ph1bind);
+               unbindph12(p);
+       }
+}
+
+static void
+ike_session_rebindph12_from_old_ph1_to_new_ph1 (struct ph1handle *old_iph1,
+                                                                                               struct ph1handle *new_iph1)
+{
+       struct ph2handle *p, *next;
+       
+       if (old_iph1 == new_iph1 || !old_iph1 || !new_iph1) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+       
+       if (old_iph1->parent_session != new_iph1->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent sessions in %s.\n", __FUNCTION__);
+               return;
+       }
+       
+       for (p = LIST_FIRST(&old_iph1->ph2tree); p; p = next) {
+               // take next pointer now, since rebind may change the underlying ph2tree list
+               next = LIST_NEXT(p, ph1bind);
+               if (p->parent_session != new_iph1->parent_session) {
+                       plog(LLV_ERROR, LOCATION, NULL, "mismatched parent session in ph1bind replacement.\n");
+               }
+               if (p->ph1 == new_iph1) {
+                       plog(LLV_ERROR, LOCATION, NULL, "same phase1 in ph1bind replacement in %s.\n",__FUNCTION__);
+               }
+               rebindph12(new_iph1, p);
+       }
+}
+
+int
+ike_session_verify_ph2_parent_session (struct ph2handle *iph2)
+{
+       if (!iph2) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return -1;
+       }
+
+       if (!iph2->parent_session) {
+               plog(LLV_DEBUG, LOCATION, NULL, "NULL parent session.\n");
+               if (ike_session_link_ph2_to_session(iph2)) {
+                       plog(LLV_DEBUG, LOCATION, NULL, "NULL parent session... still failed to link to session.\n");
+                       // failed to bind ph2 to session 
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+struct ph1handle *
+ike_session_update_ph1_ph2tree (struct ph1handle *iph1)
+{
+       struct ph1handle *new_iph1 = NULL;
+
+       if (!iph1) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return NULL;
+       }
+
+       if (iph1->parent_session) {
+               new_iph1 = ike_session_get_established_ph1(iph1->parent_session);
+
+               if (!new_iph1) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "no ph1bind replacement found. NULL ph1.\n");
+                       ike_session_unbindph12_from_ph1(iph1);
+               } else if (iph1 == new_iph1) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "no ph1bind replacement found. same ph1.\n");
+                       ike_session_unbindph12_from_ph1(iph1);
+               } else {
+                       ike_session_rebindph12_from_old_ph1_to_new_ph1(iph1, new_iph1);
+               }
+       } else {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent session in %s.\n", __FUNCTION__);
+       }
+       return new_iph1;
+}
+
+struct ph1handle *
+ike_session_update_ph2_ph1bind (struct ph2handle *iph2)
+{
+       struct ph1handle *iph1;
+       
+       if (!iph2) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return NULL;
+       }
+       
+       iph1 = ike_session_get_established_ph1(iph2->parent_session);
+       if (iph1 && iph2->ph1 && iph1 != iph2->ph1) {
+               rebindph12(iph1, iph2);
+       } else if (iph1 && !iph2->ph1) {
+               bindph12(iph1, iph2);
+       }
+       
+       return iph1;
+}
+
+void
+ike_session_ikev1_float_ports (struct ph1handle *iph1)
+{
+       struct sockaddr  *local, *remote;
+       struct ph2handle *p;
+
+       if (iph1->parent_session) {
+               local  = (struct sockaddr *)&iph1->parent_session->session_id.local;
+               remote = (struct sockaddr *)&iph1->parent_session->session_id.remote;
+
+        set_port(local, extract_port(iph1->local));
+        set_port(remote, extract_port(iph1->remote));
+               iph1->parent_session->ports_floated = 1;
+
+               for (p = LIST_FIRST(&iph1->parent_session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) {
+
+            local  = p->src;
+            remote = p->dst;
+
+            set_port(local, extract_port(iph1->local));
+            set_port(remote, extract_port(iph1->remote));
+               }
+       } else {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent session in %s.\n", __FUNCTION__);
+       }
+}
+
+static void
+ike_session_traffic_cop (void *arg)
+{
+    ike_session_t *session = (__typeof__(session))arg;
+    
+    if (session) {
+        SCHED_KILL(session->traffic_monitor.sc_mon);
+        /* get traffic query from kernel */
+        if (pk_sendget_inbound_sastats(session) < 0) {
+            // log message
+            plog(LLV_DEBUG2, LOCATION, NULL, "pk_sendget_inbound_sastats failed in %s.\n", __FUNCTION__);
+        }
+        if (pk_sendget_outbound_sastats(session) < 0) {
+            // log message
+            plog(LLV_DEBUG2, LOCATION, NULL, "pk_sendget_outbound_sastats failed in %s.\n", __FUNCTION__);
+        }
+        session->traffic_monitor.sc_mon = sched_new(session->traffic_monitor.interv_mon,
+                                                    ike_session_traffic_cop,
+                                                    session);
+    } else {
+        // log message
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+    }
+}
+
+static void
+ike_session_cleanup_idle (void *arg)
+{
+    ike_session_t *session = (ike_session_t *)arg;
+
+    if (session->traffic_monitor.dir_idle == IPSEC_DIR_INBOUND ||
+        session->traffic_monitor.dir_idle == IPSEC_DIR_ANY) {
+        if (session->peer_sent_data_sc_idle) {
+            SCHED_KILL(session->traffic_monitor.sc_idle);
+            session->traffic_monitor.sc_idle = sched_new(session->traffic_monitor.interv_idle,
+                                                         ike_session_cleanup_idle,
+                                                         session);
+            session->peer_sent_data_sc_idle = 0;
+            session->i_sent_data_sc_idle = 0;
+            return;
+        }
+    }
+    if (session->traffic_monitor.dir_idle == IPSEC_DIR_OUTBOUND ||
+        session->traffic_monitor.dir_idle == IPSEC_DIR_ANY) {
+        if (session->i_sent_data_sc_idle) {
+            SCHED_KILL(session->traffic_monitor.sc_idle);
+            session->traffic_monitor.sc_idle = sched_new(session->traffic_monitor.interv_idle,
+                                                         ike_session_cleanup_idle,
+                                                         session);
+            session->peer_sent_data_sc_idle = 0;
+            session->i_sent_data_sc_idle = 0;
+            return;
+        }
+    }
+
+    ike_session_cleanup((ike_session_t *)arg, ike_session_stopped_by_idle);
+}
+
+void
+ike_session_ph2_established (struct ph2handle *iph2)
+{
+       if (!iph2->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+       SCHED_KILL(iph2->parent_session->sc_xauth);
+       if (!iph2->parent_session->established) {
+               gettimeofday(&iph2->parent_session->estab_timestamp, NULL);
+               iph2->parent_session->established = 1;
+        IPSECSESSIONTRACERESTABLISHED(iph2->parent_session);
+        if (iph2->parent_session->traffic_monitor.interv_mon) {
+            iph2->parent_session->traffic_monitor.sc_mon = sched_new(iph2->parent_session->traffic_monitor.interv_mon,
+                                                                     ike_session_traffic_cop,
+                                                                     iph2->parent_session);
+        }
+        if (iph2->parent_session->traffic_monitor.interv_idle) {
+            iph2->parent_session->traffic_monitor.sc_idle = sched_new(iph2->parent_session->traffic_monitor.interv_idle,
+                                                                      ike_session_cleanup_idle,
+                                                                      iph2->parent_session);
+        }
+       }
+    // nothing happening to this session
+    iph2->parent_session->term_reason = NULL;
+
+       ike_session_update_mode(iph2);
+}
+
+void
+ike_session_cleanup_ph1 (struct ph1handle *iph1)
+{
+    if (iph1->status == PHASE1ST_EXPIRED) {
+               // since this got here via ike_session_cleanup_other_established_ph1s, assumes LIST_FIRST(&iph1->ph2tree) == NULL
+               iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
+               return;
+    }
+    
+       /* send delete information */
+       if (iph1->status == PHASE1ST_ESTABLISHED) {
+               isakmp_info_send_d1(iph1);
+    }
+    
+    isakmp_ph1expire(iph1);            
+}
+
+void
+ike_session_cleanup_ph1_stub (void *p)
+{
+    
+       ike_session_cleanup_ph1((struct ph1handle *)p);
+}
+
+void
+ike_session_cleanup_other_established_ph1s (ike_session_t    *session,
+                                                                                       struct ph1handle *new_iph1)
+{
+       struct ph1handle *p, *next;
+       char             *local, *remote;
+
+       if (!session || !new_iph1 || session != new_iph1->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+
+       for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = next) {
+               // take next pointer now, since delete change the underlying ph1tree list
+               next = LIST_NEXT(p, ph1ofsession_chain);
+               /*
+                * TODO: currently, most recently established SA wins. Need to revisit to see if 
+                * alternative selections is better (e.g. largest p->index stays).
+                */
+               if (p != new_iph1) {
+                       SCHED_KILL(p->sce);
+                       SCHED_KILL(p->sce_rekey);
+                       p->is_dying = 1;
+
+                       //log deletion
+                       local  = racoon_strdup(saddr2str(p->local));
+                       remote = racoon_strdup(saddr2str(p->remote));
+                       STRDUP_FATAL(local);
+                       STRDUP_FATAL(remote);
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                                "ISAKMP-SA needs to be deleted %s-%s spi:%s\n",
+                                local, remote, isakmp_pindex(&p->index, 0));
+                       racoon_free(local);
+                       racoon_free(remote);
+
+                       // first rebind the children ph2s of this dying ph1 to the new ph1.
+                       ike_session_rebindph12_from_old_ph1_to_new_ph1 (p, new_iph1);
+
+                       if (p->side == INITIATOR) {
+                               /* everyone deletes old outbound SA */
+                               p->sce = sched_new(5, ike_session_cleanup_ph1_stub, p);
+                       } else {
+                               /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */
+                               p->sce = sched_new(7, ike_session_cleanup_ph1_stub, p);
+                       }
+               }
+       }
+}
+
+void
+ike_session_cleanup_ph2 (struct ph2handle *iph2)
+{
+    if (iph2->status == PHASE2ST_EXPIRED) {
+        return;
+    }
+
+    SCHED_KILL(iph2->sce);
+
+       /* send delete information */
+       if (iph2->status == PHASE2ST_ESTABLISHED) {
+               isakmp_info_send_d2(iph2);
+    }
+    
+    // delete outgoing SAs
+    if (iph2->approval) {
+        struct saproto *pr;
+        
+        for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
+            if (pr->ok) {
+                pfkey_send_delete(lcconf->sock_pfkey,
+                                  ipsecdoi2pfkey_proto(pr->proto_id),
+                                  IPSEC_MODE_ANY,
+                                  iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */);
+            }
+        }
+    }
+    
+    delete_spd(iph2);
+       unbindph12(iph2);
+       remph2(iph2);
+       delph2(iph2);
+}
+
+void
+ike_session_cleanup_ph2_stub (void *p)
+{
+    
+       ike_session_cleanup_ph2((struct ph2handle *)p);
+}
+
+void
+ike_session_cleanup_other_established_ph2s (ike_session_t    *session,
+                                                                                       struct ph2handle *new_iph2)
+{
+       struct ph2handle *p, *next;
+
+       if (!session || !new_iph2 || session != new_iph2->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+
+       for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = next) {
+               // take next pointer now, since delete change the underlying ph2tree list
+               next = LIST_NEXT(p, ph2ofsession_chain);
+               /*
+                * TODO: currently, most recently established SA wins. Need to revisit to see if 
+                * alternative selections is better.
+                */
+               if (p != new_iph2 && p->spid == new_iph2->spid) {
+                       SCHED_KILL(p->sce);
+                       p->is_dying = 1;
+                       
+                       //log deletion
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                                "IPsec-SA needs to be deleted: %s\n",
+                                sadbsecas2str(p->src, p->dst,
+                                                          p->satype, p->spid, 0));
+
+                       if (p->side == INITIATOR) {
+                               /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
+                               p->sce = sched_new(3, ike_session_cleanup_ph2_stub, p);
+                       } else {
+                               /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */
+                               p->sce = sched_new(5, ike_session_cleanup_ph2_stub, p);
+                       }
+               }
+       }
+}
+
+void
+ike_session_stopped_by_controller (ike_session_t *session,
+                                                                  const char    *reason)
+{      
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+       if (session->stop_timestamp.tv_sec ||
+               session->stop_timestamp.tv_usec) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "already stopped %s.\n", __FUNCTION__);
+               return;
+       }
+       session->stopped_by_vpn_controller = 1;
+       gettimeofday(&session->stop_timestamp, NULL);
+       if (!session->term_reason) {
+               session->term_reason = reason;
+       }
+}
+
+void
+ike_sessions_stopped_by_controller (struct sockaddr *remote,
+                                    int              withport,
+                                                                   const char      *reason)
+{
+       ike_session_t *p = NULL;
+
+       if (!remote) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+
+       for (p = LIST_FIRST(&ike_session_tree); p; p = LIST_NEXT(p, chain)) {
+        if (withport && cmpsaddrstrict(&p->session_id.remote, remote) == 0 ||
+            !withport && cmpsaddrwop(&p->session_id.remote, remote) == 0) {
+                ike_session_stopped_by_controller(p, reason);
+               }
+       }
+}
+
+void
+ike_session_purge_ph2s_by_ph1 (struct ph1handle *iph1)
+{
+       struct ph2handle *p, *next;
+
+       if (!iph1 || !iph1->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+
+       for (p = LIST_FIRST(&iph1->parent_session->ikev1_state.ph2tree); p; p = next) {
+               // take next pointer now, since delete change the underlying ph2tree list
+               next = LIST_NEXT(p, ph2ofsession_chain);
+        SCHED_KILL(p->sce);
+        p->is_dying = 1;
+                       
+        //log deletion
+        plog(LLV_DEBUG, LOCATION, NULL,
+             "IPsec-SA needs to be purged: %s\n",
+             sadbsecas2str(p->src, p->dst,
+                           p->satype, p->spid, 0));
+
+        ike_session_cleanup_ph2(p);
+       }
+}
+
+void
+ike_session_update_ph2_ports (struct ph2handle *iph2)
+{
+    struct sockaddr *local;
+    struct sockaddr *remote;
+    
+       if (iph2->parent_session) {
+               local  = (struct sockaddr *)&iph2->parent_session->session_id.local;
+               remote = (struct sockaddr *)&iph2->parent_session->session_id.remote;
+        
+        set_port(iph2->src, extract_port(local));
+        set_port(iph2->dst, extract_port(remote));
+       } else {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent session in %s.\n", __FUNCTION__);
+       }
+}
+
+u_int32_t
+ike_session_get_sas_for_stats (ike_session_t *session,
+                               u_int8_t       dir,
+                               u_int32_t     *seq,
+                               struct sastat *stats,
+                               u_int32_t      max_stats)
+{
+    int               found = 0;
+       struct ph2handle *iph2;
+
+    if (!session || !seq || !stats || !max_stats || (dir != IPSEC_DIR_INBOUND && dir != IPSEC_DIR_OUTBOUND)) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid args in %s.\n", __FUNCTION__);
+        return found;
+    }
+
+    *seq = 0;
+    for (iph2 = LIST_FIRST(&session->ikev1_state.ph2tree); iph2; iph2 = LIST_NEXT(iph2, ph2ofsession_chain)) {
+
+        if (iph2->approval) {
+            struct saproto *pr;
+
+            for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
+                if (pr->ok && pr->proto_id == IPSECDOI_PROTO_IPSEC_ESP) {
+                    if (!*seq) {
+                        *seq = iph2->seq;
+                    }
+                    if (dir == IPSEC_DIR_INBOUND) {
+                        stats[found].spi = pr->spi;
+                    } else {
+                        stats[found].spi = pr->spi_p;
+                    }
+                    if (++found == max_stats) {
+                        return found;
+                    }
+                }
+            }
+        }
+    }
+    return found;
+}
+
+void
+ike_session_update_traffic_idle_status (ike_session_t *session,
+                                        u_int32_t      dir,
+                                        struct sastat *new_stats,
+                                        u_int32_t      max_stats)
+{
+    int i, j, found = 0, idle = 1;
+
+    if (!session || !new_stats || (dir != IPSEC_DIR_INBOUND && dir != IPSEC_DIR_OUTBOUND)) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid args in %s.\n", __FUNCTION__);
+        return;
+    }
+
+    for (i = 0; i < max_stats; i++) {
+        if (dir == IPSEC_DIR_INBOUND) {
+            for (j = 0; j < session->traffic_monitor.num_in_last_poll; j++) {
+                if (new_stats[i].spi != session->traffic_monitor.in_last_poll[j].spi) {
+                    continue;
+                }
+                found = 1;
+                if (new_stats[i].lft_c.sadb_lifetime_bytes != session->traffic_monitor.in_last_poll[j].lft_c.sadb_lifetime_bytes) {
+                    idle = 0;
+                }
+            }
+        } else {
+            for (j = 0; j < session->traffic_monitor.num_out_last_poll; j++) {
+                if (new_stats[i].spi != session->traffic_monitor.out_last_poll[j].spi) {
+                    continue;
+                }
+                found = 1;
+                if (new_stats[i].lft_c.sadb_lifetime_bytes != session->traffic_monitor.out_last_poll[j].lft_c.sadb_lifetime_bytes) {
+                    idle = 0;
+                }
+            }
+        }
+        // new SA.... check for any activity
+        if (!found) {
+            if (new_stats[i].lft_c.sadb_lifetime_bytes) {
+                plog(LLV_DEBUG, LOCATION, NULL, "new SA: dir %d....\n", dir);           
+                idle = 0;
+            }
+        }
+    }
+    if (dir == IPSEC_DIR_INBOUND) {
+        // overwrite old stats
+        bzero(session->traffic_monitor.in_last_poll, sizeof(session->traffic_monitor.in_last_poll));
+        bcopy(new_stats, session->traffic_monitor.in_last_poll, (max_stats * sizeof(*new_stats)));
+        session->traffic_monitor.num_in_last_poll = max_stats;
+        if (!idle) {
+            plog(LLV_DEBUG, LOCATION, NULL, "peer sent data....\n");           
+            session->peer_sent_data_sc_dpd = 1;
+            session->peer_sent_data_sc_idle = 1;
+        }
+    } else {
+        // overwrite old stats
+        bzero(session->traffic_monitor.out_last_poll, sizeof(session->traffic_monitor.out_last_poll));
+        bcopy(new_stats, session->traffic_monitor.out_last_poll, (max_stats * sizeof(*new_stats)));
+        session->traffic_monitor.num_out_last_poll = max_stats;
+        if (!idle) {
+            plog(LLV_DEBUG, LOCATION, NULL, "i sent data....\n");           
+            session->i_sent_data_sc_dpd = 1;
+            session->i_sent_data_sc_idle = 1;
+        }
+    }
+}
+
+void
+ike_session_cleanup (ike_session_t *session,
+                     const char    *reason)
+{
+    struct ph2handle *iph2;
+    struct ph1handle *iph1;
+
+    if (!session)
+        return;
+
+    // do ph2's first... we need the ph1s for notifications
+    for (iph2 = LIST_FIRST(&session->ikev1_state.ph2tree); iph2; iph2 = LIST_NEXT(iph2, ph2ofsession_chain)) {
+        if (iph2->status == PHASE2ST_ESTABLISHED) {
+            isakmp_info_send_d2(iph2);
+        }
+        isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
+        ike_session_stopped_by_controller(session, reason);
+    }
+
+    // do the ph1s last.
+    for (iph1 = LIST_FIRST(&session->ikev1_state.ph1tree); iph1; iph1 = LIST_NEXT(iph1, ph1ofsession_chain)) {
+        if (iph1->status == PHASE1ST_ESTABLISHED) {
+            isakmp_info_send_d1(iph1);
+        }
+        isakmp_ph1expire(iph1);
+    }
+    
+    // send ipsecManager a notification
+    if (reason == ike_session_stopped_by_idle) {
+        u_int32_t address;
+        if (((struct sockaddr *)&session->session_id.remote)->sa_family == AF_INET) {
+            address = ((struct sockaddr_in *)&session->session_id.remote)->sin_addr.s_addr;
+        } else {
+            address = 0;
+        }
+        (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_IDLE_TIMEOUT, FROM_LOCAL, address, 0, NULL);
+    }
+}
+
+int
+ike_session_has_negoing_ph1 (ike_session_t *session)
+{
+       struct ph1handle *p;
+    
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return 0;
+       }
+    
+       for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) {
+               if (!p->is_dying && p->status >= PHASE1ST_START && p->status <= PHASE1ST_ESTABLISHED) {
+                       return 1;
+               }
+       }
+    
+       return 0;
+}
+
+int
+ike_session_has_negoing_ph2 (ike_session_t *session)
+{
+       struct ph2handle *p;
+
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return 0;
+       }
+
+       for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) {
+               if (!p->is_dying && p->status >= PHASE2ST_START && p->status <= PHASE2ST_ESTABLISHED) {
+            return 1;
+               }
+       }
+
+       return 0;
+}
+
+int
+ike_session_has_established_ph2 (ike_session_t *session)
+{
+       struct ph2handle *p;
+    
+       if (!session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return 0;
+       }
+    
+       for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) {
+               if (!p->is_dying && p->status == PHASE2ST_ESTABLISHED) {
+            return 1;
+               }
+       }
+    
+       return 0;
+}
+
+void
+ike_session_cleanup_ph1s_by_ph2 (struct ph2handle *iph2)
+{
+       struct ph1handle *iph1;
+       
+       if (!iph2 || !iph2->parent_session) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__);
+               return;
+       }
+
+       // phase1 is no longer useful
+       for (iph1 = LIST_FIRST(&iph2->parent_session->ikev1_state.ph1tree); iph1; iph1 = LIST_NEXT(iph1, ph1ofsession_chain)) {
+               if (iph1->status == PHASE1ST_ESTABLISHED) {
+                       isakmp_info_send_d1(iph1);
+               }
+               isakmp_ph1expire(iph1);
+       }
+}
+
+int
+ike_session_is_client_ph2_rekey (struct ph2handle *iph2)
+{
+    if (iph2->parent_session &&
+        iph2->parent_session->is_client &&
+        iph2->is_rekey &&
+        iph2->parent_session->is_cisco_ipsec) {
+        return 1;
+    }
+    return 0;
+}
+
+int
+ike_session_is_client_ph1_rekey (struct ph1handle *iph1)
+{
+    if (iph1->parent_session &&
+        iph1->parent_session->is_client &&
+        iph1->is_rekey &&
+        iph1->parent_session->is_cisco_ipsec) {
+        return 1;
+    }
+    return 0;
+}
+
+void
+ike_session_start_xauth_timer (struct ph1handle *iph1)
+{
+    // if there are no more established ph2s, start a timer to teardown the session
+    if (iph1->parent_session &&
+        iph1->parent_session->is_client &&
+        iph1->parent_session->is_cisco_ipsec &&
+        !iph1->parent_session->sc_xauth) {
+        iph1->parent_session->sc_xauth = sched_new(300 /* 5 mins */,
+                                                   ike_session_cleanup_xauth_timeout,
+                                                   iph1->parent_session);
+    }
+}
+
+void
+ike_session_stop_xauth_timer (struct ph1handle *iph1)
+{
+    if (iph1->parent_session) {
+        SCHED_KILL(iph1->parent_session->sc_xauth);
+    }
+}
\ No newline at end of file
diff --git a/ipsec-tools/racoon/ike_session.h b/ipsec-tools/racoon/ike_session.h
new file mode 100644 (file)
index 0000000..ba91e0f
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _IKE_SESSION_H
+#define _IKE_SESSION_H
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#ifdef __APPLE__
+#include <System/net/pfkeyv2.h>
+#else
+#include <net/pfkeyv2.h>
+#endif
+#include <netinet/in.h>
+#include "handler.h"
+#include "ipsecSessionTracer.h"
+
+#define IKE_VERSION_1                                  0x1
+#define IKE_VERSION_2                                  0x2
+
+typedef struct ike_session_id {
+       struct sockaddr_storage local;
+       struct sockaddr_storage remote;
+} ike_session_id_t;
+
+typedef struct ike_session_stats {
+       u_int32_t                                                        counters[IPSECSESSIONEVENTCODE_MAX];
+} ike_session_stats_t;
+
+typedef struct ike_session_ikev1 {
+       /* list of ph1s */
+       int                                  active_ph1cnt;
+       int                                  ph1cnt;    /* the number which is negotiated for this session */
+       LIST_HEAD(_ph1ofsession_, ph1handle) ph1tree;
+       
+       /* list of ph2s */
+       int                                  active_ph2cnt;
+       int                                  ph2cnt;    /* the number which is negotiated for this session */
+       LIST_HEAD(_ph2ofsession_, ph2handle) ph2tree;
+} ike_session_ikev1_t;
+
+typedef struct ike_session_sastats {
+    int                                  interv_mon;
+    int                                  interv_idle;
+    int                                  dir_idle;
+    struct sched                        *sc_mon;
+    struct sched                        *sc_idle;
+
+    u_int32_t                            num_in_curr_req;
+    u_int32_t                            num_in_last_poll;
+    struct sastat                        in_curr_req[8];
+    struct sastat                        in_last_poll[8];
+
+    u_int32_t                            num_out_curr_req;
+    u_int32_t                            num_out_last_poll;
+    struct sastat                        out_curr_req[8];
+    struct sastat                        out_last_poll[8];
+} ike_sesssion_sastats_t;
+
+struct ike_session {
+       u_int8_t                             version;           /* mask of version flags */
+       u_int8_t                                             mode;                      /* mode of protocol, see ipsec.h */
+       u_int16_t                            proto;                     /* IPPROTO_ESP or IPPROTO_AH */
+
+       ike_session_id_t                     session_id;
+
+       int                                  established:1;
+       int                                  ports_floated:1;
+       int                                  is_cisco_ipsec:1;  
+       int                                                                      is_l2tpvpn_ipsec:1;
+       int                                                                      is_btmm_ipsec:1;
+       int                                                                      stopped_by_vpn_controller:1;
+    int                                  peer_sent_data_sc_dpd:1;
+    int                                  peer_sent_data_sc_idle:1;
+    int                                  i_sent_data_sc_dpd:1;
+    int                                  i_sent_data_sc_idle:1;
+    int                                         is_client:1;
+    u_int32_t                            natt_flags;
+       char                                *term_reason;
+
+       struct timeval                                           start_timestamp;
+       struct timeval                                           estab_timestamp;
+       struct timeval                                           stop_timestamp;
+       ike_session_ikev1_t                                      ikev1_state;
+
+       ike_session_stats_t                                      stats;
+
+    ike_sesssion_sastats_t               traffic_monitor;
+    struct sched                        *sc_idle;
+    struct sched                        *sc_xauth;
+
+       LIST_ENTRY(ike_session)              chain;
+};
+
+extern const char *    ike_session_stopped_by_vpn_disconnect;
+extern const char *    ike_session_stopped_by_flush;
+
+extern void               ike_session_init __P((void));
+extern ike_session_t *   ike_session_get_session __P((struct sockaddr *, struct sockaddr *, int));
+extern u_int              ike_session_get_rekey_lifetime __P((int, u_int));
+extern void               ike_session_update_mode __P((struct ph2handle *iph2));
+extern int                ike_session_link_ph1_to_session __P((struct ph1handle *));
+extern int                ike_session_link_ph2_to_session __P((struct ph2handle *));
+extern int                ike_session_unlink_ph1_from_session __P((struct ph1handle *));
+extern int                ike_session_unlink_ph2_from_session __P((struct ph2handle *));
+extern int                ike_session_has_other_established_ph1 __P((ike_session_t *, struct ph1handle *));
+extern int                ike_session_has_other_negoing_ph1 __P((ike_session_t *, struct ph1handle *));
+extern int                ike_session_has_other_established_ph2 __P((ike_session_t *, struct ph2handle *));
+extern int                ike_session_has_other_negoing_ph2 __P((ike_session_t *, struct ph2handle *));
+extern int                ike_session_verify_ph2_parent_session __P((struct ph2handle *));
+extern struct ph1handle * ike_session_update_ph1_ph2tree __P((struct ph1handle *));
+extern struct ph1handle * ike_session_update_ph2_ph1bind __P((struct ph2handle *));
+extern void               ike_session_ikev1_float_ports __P((struct ph1handle *));
+extern void               ike_session_ph2_established __P((struct ph2handle *));
+extern void               ike_session_cleanup_other_established_ph1s __P((ike_session_t *, struct ph1handle *));
+extern void               ike_session_cleanup_other_established_ph2s __P((ike_session_t *, struct ph2handle *));
+extern void                              ike_session_stopped_by_controller __P((ike_session_t *, const char *));
+extern void                              ike_sessions_stopped_by_controller __P((struct sockaddr *, int, const char *));
+extern void               ike_session_purge_ph2s_by_ph1 __P((struct ph1handle *));
+extern struct ph1handle * ike_session_get_established_ph1 __P((ike_session_t *));
+extern void               ike_session_update_ph2_ports __P((struct ph2handle *));
+extern u_int32_t          ike_session_get_sas_for_stats __P((ike_session_t *, u_int8_t, u_int32_t *, struct sastat  *, u_int32_t));
+extern void               ike_session_update_traffic_idle_status __P((ike_session_t *, u_int32_t, struct sastat *, u_int32_t));
+extern void               ike_session_cleanup __P((ike_session_t *, const char *));
+extern int                ike_session_has_negoing_ph1 __P((ike_session_t *));
+extern int                ike_session_has_negoing_ph2 __P((ike_session_t *));
+extern int                ike_session_has_established_ph2 __P((ike_session_t *));
+extern void               ike_session_cleanup_ph1s_by_ph2 __P((struct ph2handle *));
+extern int                ike_session_is_client_ph2_rekey __P((struct ph2handle *));
+extern int                ike_session_is_client_ph1_rekey __P((struct ph1handle *));
+extern void               ike_session_start_xauth_timer __P((struct ph1handle *));
+extern void               ike_session_stop_xauth_timer __P((struct ph1handle *));
+
+#endif /* _IKE_SESSION_H */
diff --git a/ipsec-tools/racoon/ipsecConfigTracer.c b/ipsec-tools/racoon/ipsecConfigTracer.c
new file mode 100644 (file)
index 0000000..ca82dce
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#import         <asl.h>
+#include <sys/types.h>
+#include "ipsecConfigTracer.h"
+#include "ipsecMessageTracer.h"
+
+const char * ipsecConfigTracerFailedString = "Tracer Failed";
+const char * ipsecConfigInvalidEventString = "Invalid Event";
+const char * ipsecConfigString                    = "IPSEC";
+
+const char * const ipsecConfigEventStrings[IPSECCONFIGEVENTCODE_MAX] = {       CONSTSTR("NONE") /* index place holder */,
+                                                                                                                                                       CONSTSTR("Configuration Reparse Error"),
+                                                                                                                                                       CONSTSTR("Configuration Parse Error"),
+                                                                            CONSTSTR("Signal Error"),
+                                                                                                                                               };
+
+const char *
+ipsecConfigEventCodeToString (ipsecConfigEventCode_t eventCode)
+{
+       if (eventCode <= IPSECCONFIGEVENTCODE_NONE || eventCode >= IPSECCONFIGEVENTCODE_MAX)
+               return ipsecConfigInvalidEventString;
+       return(ipsecConfigEventStrings[eventCode]);
+}
+
+static
+void
+ipsecConfigLogEvent (const char *event_msg, const char *failure_signature)
+{
+       aslmsg m;
+    
+       if (!event_msg) {
+               return;
+       }
+
+       m = asl_new(ASL_TYPE_MSG);
+       asl_set(m, ASL_KEY_FACILITY, PLAINIPSECDOMAIN);
+       asl_set(m, ASL_KEY_MSG, ipsecConfigString);
+#if 0   /* <rdar://problem/6468252> is flooding 300000+ events to MessageTracer servers */ 
+    if (failure_signature) {
+        asl_set(m, "com.apple.message.domain", PLAINIPSECDOMAIN);
+        asl_set(m, "com.apple.message.result", "failure");     // failure
+        asl_set(m, "com.apple.message.signature", failure_signature);
+    }
+    asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg);
+#else
+    if (failure_signature) {
+        asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s (failure: %s)", event_msg, failure_signature);
+    } else {
+        asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg);
+    }
+#endif
+       asl_free(m);
+}
+
+void
+ipsecConfigTracerEvent (const char *filename, ipsecConfigEventCode_t eventCode, const char *event, const char *failure_reason)
+{
+       char buf[1024];
+
+       if (filename == NULL) {
+               ipsecConfigLogEvent(CONSTSTR("tracer failed. (Invalid filename)."), ipsecConfigTracerFailedString);
+               return;
+       }
+       if (eventCode <= IPSECCONFIGEVENTCODE_NONE || eventCode >= IPSECCONFIGEVENTCODE_MAX) {
+               ipsecConfigLogEvent(CONSTSTR("tracer failed. (Invalid event code)."), ipsecConfigTracerFailedString);
+               return;
+       }
+       if (event == NULL) {
+               ipsecConfigLogEvent(CONSTSTR("tracer failed. (Invalid event)."), ipsecConfigTracerFailedString);
+               return;
+       }
+       
+       buf[0] = (char)0;
+       snprintf(buf, sizeof(buf), "%s. (%s, filename %s).", ipsecConfigEventCodeToString(eventCode), failure_reason, filename);
+       ipsecConfigLogEvent(CONSTSTR(buf), event);
+}
diff --git a/ipsec-tools/racoon/ipsecConfigTracer.h b/ipsec-tools/racoon/ipsecConfigTracer.h
new file mode 100644 (file)
index 0000000..31492a2
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _IPSECCONFIGTRACER_H
+#define _IPSECCONFIGTRACER_H
+
+typedef enum ipsecConfigEventCode {
+       IPSECCONFIGEVENTCODE_NONE = 0,
+    IPSECCONFIGEVENTCODE_REPARSE_ERROR,
+       IPSECCONFIGEVENTCODE_PARSE_ERROR,
+       IPSECCONFIGEVENTCODE_SIGNAL_ERROR,
+       IPSECCONFIGEVENTCODE_MAX,
+} ipsecConfigEventCode_t;
+
+const char * ipsecConfigEventCodeToString (ipsecConfigEventCode_t);
+void ipsecConfigTracerEvent (const char *, ipsecConfigEventCode_t, const char *, const char *);
+
+#endif /* _IPSECCONFIGTRACER_H */
diff --git a/ipsec-tools/racoon/ipsecSessionTracer.c b/ipsec-tools/racoon/ipsecSessionTracer.c
new file mode 100644 (file)
index 0000000..98308c2
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#import         <asl.h>
+#include <sys/types.h>
+#include "ike_session.h"
+#include "ipsecMessageTracer.h"
+#include "misc.h"
+#include "nattraversal.h"
+
+#define     TRUE       1
+#define                FALSE   0
+const char *ipsecSessionInvalidEventString = "Invalid Event";
+const char *ipsecSessionString                    = "IPSEC";
+
+/* tells us the event's description */
+const char * const ipsecSessionEventStrings[IPSECSESSIONEVENTCODE_MAX] = {     CONSTSTR("NONE") /* index place holder */,
+                                                                                                                                                       CONSTSTR("IKE Packet: transmit success"),
+                                                                                                                                                       CONSTSTR("IKE Packet: transmit failed"),
+                                                                                                                                                       CONSTSTR("IKE Packet: receive success"),
+                                                                                                                                                       CONSTSTR("IKE Packet: receive failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 Initiator: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 Initiator: failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 Initiator: dropped"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 Responder: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 Responder: failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 Responder: drop"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1: maximum retransmits"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 AUTH: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase1 AUTH: failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Dead-Peer-Detection: request transmitted"),
+                                                                                                                                                       CONSTSTR("IKEv1 Dead-Peer-Detection: response received"),
+                                                                                                                                                       CONSTSTR("IKEv1 Dead-Peer-Detection: request retransmitted"),
+                                                                                                                                                       CONSTSTR("IKEv1 Dead-Peer-Detection: request received"),
+                                                                                                                                                       CONSTSTR("IKEv1 Dead-Peer-Detection: response transmitted"),
+                                                                                                                                                       CONSTSTR("IKEv1 Dead-Peer-Detection: response retransmitted"),
+                                                                                                                                                       CONSTSTR("IKEv1 Dead-Peer-Detection: maximum retransmits"),
+                                                                                                                                                       CONSTSTR("IKEv1 Config: retransmited"),
+                                                                                                                                                       CONSTSTR("IKEv1 Mode-Config: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Mode-Config: failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Mode-Config: dropped"),
+                                                                                                                                                       CONSTSTR("IKEv1 XAUTH: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 XAUTH: failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 XAUTH: dropped"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 Initiator: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 Initiator: failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 Initiator: dropped"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 Responder: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 Responder: fail"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 Responder: drop"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2: maximum retransmits"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 AUTH: success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Phase2 AUTH: failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Information-Notice: transmit success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Information-Notice: transmit failed"),
+                                                                                                                                                       CONSTSTR("IKEv1 Information-Notice: receive success"),
+                                                                                                                                                       CONSTSTR("IKEv1 Information-Notice: receive failed"),
+                                                                                                                                               };
+
+/* tells us if we can ignore the failure_reason passed into the event tracer */
+const int const ipsecSessionEventIgnoreReason[IPSECSESSIONEVENTCODE_MAX] = {TRUE/* index place holder */,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       FALSE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       TRUE,
+                                                                                                                                                       };
+
+
+const char *
+ipsecSessionEventCodeToString (ipsecSessionEventCode_t eventCode)
+{
+       if (eventCode <= IPSECSESSIONEVENTCODE_NONE || eventCode >= IPSECSESSIONEVENTCODE_MAX)
+               return ipsecSessionInvalidEventString;
+       return(ipsecSessionEventStrings[eventCode]);
+}
+
+const char *
+ipsecSessionGetConnectionDomain (ike_session_t *session)
+{
+       if (session) {
+               if (session->is_cisco_ipsec) {
+            if (session->established) {
+                return CISCOIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN;
+            } else {
+                return CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
+            }
+               } else if (session->is_l2tpvpn_ipsec) {
+            if (session->established) {
+                return L2TPIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN;
+            } else {
+                return L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
+            }
+               } else if (session->is_btmm_ipsec) {
+            if (session->established) {
+                return BTMMIPSEC_CONNECTION_ESTABLISHED_DOMAIN;
+            } else {
+                return BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
+            }
+               } else {
+            if (session->established) {
+                return PLAINIPSEC_CONNECTION_ESTABLISHED_DOMAIN;
+            } else {
+                return PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
+            }
+        }
+       }
+       return PLAINIPSECDOMAIN;
+}
+
+const char *
+ipsecSessionGetConnectionLessDomain (ike_session_t *session)
+{
+       if (session) {
+               if (session->is_cisco_ipsec) {
+            return CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
+               } else if (session->is_l2tpvpn_ipsec) {
+            return L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN;
+               } else if (session->is_btmm_ipsec) {
+            return BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
+               } else {
+            return PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN;
+        }
+       }
+       return PLAINIPSECDOMAIN;
+}
+
+const char *
+ipsecSessionGetPhaseDomain (ike_session_t *session)
+{
+       if (session) {
+               if (session->is_cisco_ipsec) {
+                       return CISCOIPSECVPN_PHASE_DOMAIN;
+               } else if (session->is_l2tpvpn_ipsec) {
+                       return L2TPIPSECVPN_PHASE_DOMAIN;
+               } else if (session->is_btmm_ipsec) {
+                       return BTMMIPSEC_PHASE_DOMAIN;
+               }
+       }
+       return PLAINIPSEC_PHASE_DOMAIN;
+}
+
+static
+void
+ipsecSessionLogEvent (ike_session_t *session, const char *event_msg)
+{
+       aslmsg m;
+
+       if (!event_msg) {
+               return;
+       }
+
+       m = asl_new(ASL_TYPE_MSG);
+       asl_set(m, ASL_KEY_FACILITY, ipsecSessionGetPhaseDomain(session));
+       asl_set(m, ASL_KEY_MSG, ipsecSessionString);
+       asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg);
+       asl_free(m);
+}
+
+void
+ipsecSessionTracerStart (ike_session_t *session)
+{
+       if (session == NULL) {
+               return;
+       }
+       bzero(&session->stats, sizeof(session->stats));
+       bzero(&session->stop_timestamp, sizeof(session->stop_timestamp));
+       bzero(&session->estab_timestamp, sizeof(session->estab_timestamp));
+       gettimeofday(&session->start_timestamp, NULL);
+       ipsecSessionLogEvent(session, CONSTSTR("Connecting."));
+}
+
+void
+ipsecSessionTracerEvent (ike_session_t *session, ipsecSessionEventCode_t eventCode, const char *event, const char *failure_reason)
+{
+       char buf[1024];
+
+       if (session == NULL) {
+               ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid session)."));
+               return;
+       }
+       if (eventCode <= IPSECSESSIONEVENTCODE_NONE || eventCode >= IPSECSESSIONEVENTCODE_MAX) {
+               ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid event code)."));
+               return;
+       }
+       if (event == NULL) {
+               ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid event)."));
+               return;
+       }
+
+       if (failure_reason) {
+               if (!session->term_reason &&
+            !ipsecSessionEventIgnoreReason[eventCode]) {
+                       session->term_reason = failure_reason;
+               }
+       }
+
+       session->stats.counters[eventCode]++;
+       buf[0] = (char)0;
+       snprintf(buf, sizeof(buf), "%s. (%s).", ipsecSessionEventCodeToString(eventCode), event);
+       ipsecSessionLogEvent(session, CONSTSTR(buf));
+}
+
+static void
+ipsecSessionTracerLogFailureRate (ike_session_t *session, const char *signature, double failure_rate)
+{
+       aslmsg          m;
+       char            buf[128];
+       const char *domain = ipsecSessionGetPhaseDomain(session);
+
+       if (!signature || failure_rate <= 0.001) {
+               return;
+       }
+
+       m = asl_new(ASL_TYPE_MSG);
+       asl_set(m, "com.apple.message.domain", domain);
+       asl_set(m, ASL_KEY_FACILITY, domain);
+       asl_set(m, ASL_KEY_MSG, ipsecSessionString);
+    asl_set(m, "com.apple.message.result", "noop");
+       asl_set(m, "com.apple.message.signature", signature);
+       snprintf(buf, sizeof(buf), "%.3f", failure_rate);
+       asl_set(m, "com.apple.message.value", buf);     // stuff the up time into value
+       asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s. (Failure-Rate = %s).", signature, buf);
+       asl_free(m);
+}
+
+static void
+ipsecSessionTracerLogStop (ike_session_t *session, int caused_by_failure, const char *reason)
+{
+       aslmsg      m;
+       char        nat_buf[128];
+       char        buf[128];
+       const char *domain = (session->established)? ipsecSessionGetConnectionDomain(session) : ipsecSessionGetConnectionLessDomain(session);
+
+       m = asl_new(ASL_TYPE_MSG);
+       asl_set(m, "com.apple.message.domain", domain);
+       asl_set(m, ASL_KEY_FACILITY, domain);
+       asl_set(m, ASL_KEY_MSG, ipsecSessionString);
+    if (caused_by_failure ||
+        (reason && reason != ike_session_stopped_by_flush && reason != ike_session_stopped_by_vpn_disconnect)) {
+        asl_set(m, "com.apple.message.result", CONSTSTR("failure"));   // failure
+    } else {
+        asl_set(m, "com.apple.message.result", CONSTSTR("success"));   // success
+    }
+       if (reason) {
+        if (session->natt_flags & NAT_DETECTED_ME) {
+            snprintf(nat_buf, sizeof(nat_buf), "%s. NAT detected by Me", reason);
+            asl_set(m, "com.apple.message.signature", nat_buf);
+        } else if (session->natt_flags & NAT_DETECTED_PEER) {
+            snprintf(nat_buf, sizeof(nat_buf), "%s. NAT detected by Peer", reason);
+            asl_set(m, "com.apple.message.signature", nat_buf);
+        } else {
+            asl_set(m, "com.apple.message.signature", reason);
+        }
+       } else {
+               // reason was NULL; make sure success/failure have different signature
+               if (caused_by_failure) {
+                       asl_set(m, "com.apple.message.signature", CONSTSTR("Internal/Server-side error"));
+               } else {
+                       asl_set(m, "com.apple.message.signature", CONSTSTR("User/System initiated the disconnect"));
+               }
+       }
+       if (session->established) {
+               snprintf(buf, sizeof(buf), "%8.6f", timedelta(&session->estab_timestamp, &session->stop_timestamp));
+               asl_set(m, "com.apple.message.value", buf);     // stuff the up time into value
+               asl_log(NULL, m, ASL_LEVEL_NOTICE, "Disconnecting. (Connection was up for, %s seconds).", buf);
+       } else {
+               snprintf(buf, sizeof(buf), "%8.6f", timedelta(&session->start_timestamp, &session->stop_timestamp));
+               asl_set(m, "com.apple.message.value2", buf);    /// stuff the negoing time into value2
+               asl_log(NULL, m, ASL_LEVEL_NOTICE, "Disconnecting. (Connection tried to negotiate for, %s seconds).", buf);
+       }
+       asl_free(m);
+}
+
+void
+ipsecSessionTracerStop (ike_session_t *session, int caused_by_failure, const char *reason)
+{
+       if (session == NULL) {
+               return;
+       }
+
+       gettimeofday(&session->stop_timestamp, NULL);
+
+       ipsecSessionTracerLogStop(session, caused_by_failure, reason);
+
+       // go thru counters logging failure-rate events
+       if (session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL]) {
+               ipsecSessionTracerLogFailureRate(session,
+                                                                                CONSTSTR("IKE Packets Transmit Failure-Rate Statistic"),
+                                                                                get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC]));
+       }
+       if (session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL]) {
+               ipsecSessionTracerLogFailureRate(session,
+                                                                                CONSTSTR("IKE Packets Receive Failure-Rate Statistic"),
+                                                                                get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC]));
+       }
+       if (session->version == IKE_VERSION_1) {
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT] ||
+                       session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL] ||
+                       session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase1 Failure-Rate Statistic"),
+                                                                                        get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT] +
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL] + 
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]),
+                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC] +
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC])));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase1 Initiator Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase1 Responder Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase1 Authentication Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Dead-Peer-Detection Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT],
+                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT] +
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ])));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT] ||
+                       session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Dead-Peer-Detect Retransmit-Rate Statistic"),
+                                                                                        get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT] +
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT]),
+                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ] +
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ])));
+               }               
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE MODE-Config Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE XAUTH Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT] ||
+                       session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL] ||
+                       session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase2 Failure-Rate Statistic"),
+                                                                                        get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT] +
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL] + 
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]),
+                                                            (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC] +
+                                                                     session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL])));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase2 Initiator Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase2 Responder Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Phase2 Authentication Failure-Rate Statistics"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_SUCC]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Information-Notice Transmit Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL]));
+               }
+               if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL]) {
+                       ipsecSessionTracerLogFailureRate(session,
+                                                                                        CONSTSTR("IKE Information-Notice Receive Failure-Rate Statistic"),
+                                                                                        get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_SUCC]));
+               }
+       }
+}
+
+void
+ipsecSessionTracerLogEstablished (ike_session_t *session)
+{
+       aslmsg      m;
+       const char *domain = ipsecSessionGetConnectionLessDomain(session);
+
+       m = asl_new(ASL_TYPE_MSG);
+       asl_set(m, "com.apple.message.domain", domain);
+       asl_set(m, ASL_KEY_FACILITY, domain);
+       asl_set(m, ASL_KEY_MSG, ipsecSessionString);
+    asl_set(m, "com.apple.message.result", "success"); // success
+    asl_set(m, "com.apple.message.signature", "success");
+    asl_log(NULL, m, ASL_LEVEL_NOTICE, "Connected.");
+       asl_free(m);
+}
diff --git a/ipsec-tools/racoon/ipsecSessionTracer.h b/ipsec-tools/racoon/ipsecSessionTracer.h
new file mode 100644 (file)
index 0000000..4cb7421
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _IPSECSESSIONTRACER_H
+#define _IPSECSESSIONTRACER_H
+
+typedef enum ipsecSessionEventCode {
+       IPSECSESSIONEVENTCODE_NONE = 0,
+       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_DROP,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_DROP,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ,
+       IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RESP,
+       IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT,
+       IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ,
+       IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RESP,
+       IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT,
+       IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT,
+       IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT,
+       IPSECSESSIONEVENTCODE_IKEV1_MODECFG_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_MODECFG_DROP,
+       IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_DROP,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+       IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_SUCC,
+       IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL,
+       IPSECSESSIONEVENTCODE_MAX,
+} ipsecSessionEventCode_t;
+
+const char * ipsecSessionEventCodeToString (ipsecSessionEventCode_t);
+void ipsecSessionTracerStart (ike_session_t *);
+void ipsecSessionTracerEvent (ike_session_t *, ipsecSessionEventCode_t, const char *, const char *);
+void ipsecSessionTracerStop (ike_session_t *, int, const char *);
+void ipsecSessionTracerLogEstablished (ike_session_t *session);
+
+#endif /* _IPSECSESSIONTRACER_H */
index 18549642baae55f84de7b569d851a8c43b67f503..713ec4cf854d490f41fccb62ba20d1efc046e78b 100644 (file)
@@ -274,10 +274,12 @@ found:
                plog(LLV_WARNING, LOCATION, NULL,
                        "invalid DH parameter found, use default.\n");
                oakley_dhgrp_free(sa->dhgrp);
+               sa->dhgrp=NULL;
        }
 
        if (oakley_setdhgroup(sa->dh_group, &sa->dhgrp) == -1) {
                sa->dhgrp = NULL;
+               racoon_free(sa);
                return NULL;
        }
 
@@ -285,7 +287,7 @@ saok:
 #ifdef HAVE_GSSAPI
        if (sa->gssid != NULL)
                plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n",
-                   sa->gssid->l, sa->gssid->v);
+                   (int)sa->gssid->l, sa->gssid->v);
        if (iph1-> side == INITIATOR) {
                if (iph1->rmconf->proposal->gssid != NULL)
                        iph1->gi_i = vdup(iph1->rmconf->proposal->gssid);
@@ -303,13 +305,17 @@ saok:
        }
        if (iph1->gi_i != NULL)
                plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n",
-                   iph1->gi_i->l, iph1->gi_i->v);
+                   (int)iph1->gi_i->l, iph1->gi_i->v);
        if (iph1->gi_r != NULL)
                plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n",
-                   iph1->gi_r->l, iph1->gi_r->v);
+                   (int)iph1->gi_r->l, iph1->gi_r->v);
 #else
        iph1->approval = sa;
 #endif
+       if(iph1->approval) {
+               plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n",
+                   s_oakley_attr_method(iph1->approval->authmethod));
+       }
 
        newsa = get_sabyproppair(p, iph1);
        if (newsa == NULL) {
@@ -336,6 +342,7 @@ get_ph1approvalx(p, proposal, sap, check_level)
        struct isakmp_pl_t *trns = p->trns;
        struct isakmpsa sa, *s, *tsap;
        int authmethod;
+    int tsap_authmethod;
 
        plog(LLV_DEBUG, LOCATION, NULL,
                        "prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n",
@@ -355,8 +362,10 @@ get_ph1approvalx(p, proposal, sap, check_level)
        for (s = proposal; s != NULL; s = s->next) {
 #ifdef ENABLE_HYBRID
                authmethod = switch_authmethod(s->authmethod);
+        tsap_authmethod = switch_authmethod(tsap->authmethod);
 #else
                authmethod = s->authmethod;
+        tsap_authmethod = tsap->authmethod;
 #endif
                plog(LLV_DEBUG, LOCATION, NULL, "Compared: DB:Peer\n");
                plog(LLV_DEBUG, LOCATION, NULL, "(lifetime = %ld:%ld)\n",
@@ -377,7 +386,7 @@ get_ph1approvalx(p, proposal, sap, check_level)
                                        tsap->hashtype));
                plog(LLV_DEBUG, LOCATION, NULL, "authmethod = %s:%s\n",
                        s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
-                                       authmethod),
+                                       s->authmethod),
                        s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
                                        tsap->authmethod));
                plog(LLV_DEBUG, LOCATION, NULL, "dh_group = %s:%s\n",
@@ -394,7 +403,7 @@ get_ph1approvalx(p, proposal, sap, check_level)
                 * is bigger than mine, it might be accepted.
                 */
                if(tsap->enctype == s->enctype &&
-                   tsap->authmethod == authmethod &&
+                   (tsap->authmethod == authmethod || tsap_authmethod == authmethod) &&
                    tsap->hashtype == s->hashtype &&
                    tsap->dh_group == s->dh_group &&
                    tsap->encklen == s->encklen) {
@@ -435,8 +444,10 @@ get_ph1approvalx(p, proposal, sap, check_level)
        }
 
 found:
-       if (tsap->dhgrp != NULL)
+       if (tsap->dhgrp != NULL){
                oakley_dhgrp_free(tsap->dhgrp);
+               tsap->dhgrp = NULL;
+       }
 
        if ((s = dupisakmpsa(s)) != NULL) {
                switch(check_level) {
@@ -460,8 +471,11 @@ found:
                default:
                        break;
                }
+        // hack to get around cisco rekeys
+        if (tsap->authmethod != authmethod && tsap_authmethod == authmethod) {
+            s->authmethod = tsap->authmethod;
+        }
        }
-
        return s;
 }
 
@@ -531,8 +545,10 @@ print_ph1mismatched(p, proposal)
                }
        }
 
-       if (sa.dhgrp != NULL)
+       if (sa.dhgrp != NULL){
                oakley_dhgrp_free(sa.dhgrp);
+               sa.dhgrp=NULL;
+       }
 }
 
 /*
@@ -740,7 +756,8 @@ t2isakmpsa(trns, sa)
 #ifdef HAVE_GSSAPI
                case OAKLEY_ATTR_GSS_ID:
                {
-                       iconv_t cd;
+                       int error = -1;
+                       iconv_t cd = (iconv_t) -1;
                        size_t srcleft, dstleft, rv;
                        __iconv_const char *src;
                        char *dst;
@@ -753,12 +770,19 @@ t2isakmpsa(trns, sa)
                         * compatible with this behavior.
                         */
                        if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) {
-                               sa->gssid = vmalloc(len);
+                               if ((sa->gssid = vmalloc(len)) == NULL) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                           "failed to allocate memory\n");
+                                       goto out;
+                               }
                                memcpy(sa->gssid->v, d + 1, len);
                                plog(LLV_DEBUG, LOCATION, NULL,
-                                 "received old-style gss id '%.*s' (len %d)\n",
-                                 sa->gssid->l, sa->gssid->v, sa->gssid->l);
-                               break;
+                                   "received old-style gss "
+                                   "id '%.*s' (len %zu)\n",
+                                   (int)sa->gssid->l, sa->gssid->v, 
+                                   sa->gssid->l);
+                               error = 0;
+                               goto out;
                        }
 
                        /*
@@ -775,10 +799,14 @@ t2isakmpsa(trns, sa)
                                    "unable to initialize utf-16le -> latin1 "
                                    "conversion descriptor: %s\n",
                                    strerror(errno));
-                               break;
+                               goto out;
                        }
 
-                       sa->gssid = vmalloc(len / 2);
+                       if ((sa->gssid = vmalloc(len / 2)) == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                   "failed to allocate memory\n");
+                               goto out;
+                       }
 
                        src = (__iconv_const char *)(d + 1);
                        srcleft = len;
@@ -800,19 +828,25 @@ t2isakmpsa(trns, sa)
                                            "be represented in latin1\n",
                                            rv, rv == 1 ? "" : "s");
                                }
-                               (void) iconv_close(cd);
-                               vfree(sa->gssid);
-                               sa->gssid = NULL;
-                               break;
+                               goto out;
                        }
-                       (void) iconv_close(cd);
 
                        /* XXX dstleft should always be 0; assert it? */
                        sa->gssid->l = (len / 2) - dstleft;
 
                        plog(LLV_DEBUG, LOCATION, NULL,
-                           "received gss id '%.*s' (len %d)\n",
-                           sa->gssid->l, sa->gssid->v, sa->gssid->l);
+                           "received gss id '%.*s' (len %zu)\n",
+                           (int)sa->gssid->l, sa->gssid->v, sa->gssid->l);
+
+                       error = 0;
+out:
+                       if (cd != (iconv_t)-1)
+                               (void)iconv_close(cd);
+
+                       if ((error != 0) && (sa->gssid != NULL)) {
+                               vfree(sa->gssid);
+                               sa->gssid = NULL;
+                       }
                        break;
                }
 #endif /* HAVE_GSSAPI */
@@ -1164,7 +1198,8 @@ found:
 
     {
        struct saproto *sp;
-       struct prop_pair *p, *n, *x;
+       struct prop_pair *p, *x;
+       struct prop_pair *n = NULL;
 
        ret = NULL;
 
@@ -1189,7 +1224,7 @@ found:
                        goto err;       /* XXX */
 
                n = racoon_calloc(1, sizeof(struct prop_pair));
-               if (!n) {
+               if (n == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "failed to get buffer.\n");
                        goto err;
@@ -1261,7 +1296,7 @@ get_proppair(sa, mode)
        vchar_t *sa;
        int mode;
 {
-       struct prop_pair **pair;
+       struct prop_pair **pair = NULL;
        int num_p = 0;                  /* number of proposal for use */
        int tlen;
        caddr_t bp;
@@ -1275,22 +1310,22 @@ get_proppair(sa, mode)
        if (sa->l < sizeof(*sab)) {
                plog(LLV_ERROR, LOCATION, NULL,
                        "Invalid SA length = %zu.\n", sa->l);
-               return NULL;
+               goto bad;
        }
 
        /* check DOI */
        if (check_doi(ntohl(sab->doi)) < 0)
-               return NULL;
+               goto bad;
 
        /* check SITUATION */
        if (check_situation(ntohl(sab->sit)) < 0)
-               return NULL;
+               goto bad;
 
        pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair));
        if (pair == NULL) {
                plog(LLV_ERROR, LOCATION, NULL,
                        "failed to get buffer.\n");
-               return NULL;
+               goto bad;
        }
        memset(pair, 0, sizeof(pair));
 
@@ -1305,7 +1340,7 @@ get_proppair(sa, mode)
 
        pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, tlen);
        if (pbuf == NULL)
-               return NULL;
+               goto bad;
 
        for (pa = (struct isakmp_parse_t *)pbuf->v;
             pa->type != ISAKMP_NPTYPE_NONE;
@@ -1315,7 +1350,7 @@ get_proppair(sa, mode)
                        plog(LLV_ERROR, LOCATION, NULL,
                                "Invalid payload type=%u\n", pa->type);
                        vfree(pbuf);
-                       return NULL;
+                       goto bad;
                }
 
                prop = (struct isakmp_pl_p *)pa->ptr;
@@ -1328,7 +1363,7 @@ get_proppair(sa, mode)
                        plog(LLV_ERROR, LOCATION, NULL,
                                "invalid proposal with length %d\n", proplen);
                        vfree(pbuf);
-                       return NULL;
+                       goto bad;
                }
 
                /* check Protocol ID */
@@ -1348,7 +1383,7 @@ get_proppair(sa, mode)
                /* get transform */
                if (get_transform(prop, pair, &num_p) < 0) {
                        vfree(pbuf);
-                       return NULL;
+                       goto bad;
                }
        }
        vfree(pbuf);
@@ -1410,10 +1445,14 @@ get_proppair(sa, mode)
        if (num_p <= 0) {
                plog(LLV_ERROR, LOCATION, NULL,
                        "no Proposal found.\n");
-               return NULL;
+               goto bad;
        }
 
        return pair;
+bad:
+       if (pair != NULL)
+               racoon_free(pair);
+       return NULL;
 }
 
 /*
@@ -1658,8 +1697,8 @@ get_sabysaprop(pp0, sa0)
        struct saprop *pp0;
        vchar_t *sa0;
 {
-       struct prop_pair **pair;
-       vchar_t *newsa;
+       struct prop_pair **pair = NULL;
+       vchar_t *newsa = NULL;
        int newtlen;
        u_int8_t *np_p = NULL;
        struct prop_pair *p = NULL;
@@ -1668,17 +1707,18 @@ get_sabysaprop(pp0, sa0)
        struct satrns *tr;
        int prophlen, trnslen;
        caddr_t bp;
+       int error = -1;
 
        /* get proposal pair */
        pair = get_proppair(sa0, IPSECDOI_TYPE_PH2);
        if (pair == NULL)
-               return NULL;
+               goto out;
 
        newtlen = sizeof(struct ipsecdoi_sa_b);
        for (pp = pp0; pp; pp = pp->next) {
 
                if (pair[pp->prop_no] == NULL)
-                       return NULL;
+                       goto out;
 
                for (pr = pp->head; pr; pr = pr->next) {
                        newtlen += (sizeof(struct isakmp_pl_p)
@@ -1690,7 +1730,7 @@ get_sabysaprop(pp0, sa0)
                                                break;
                                }
                                if (p == NULL)
-                                       return NULL;
+                                       goto out;
 
                                newtlen += ntohs(p->trns->h.len);
                        }
@@ -1700,7 +1740,7 @@ get_sabysaprop(pp0, sa0)
        newsa = vmalloc(newtlen);
        if (newsa == NULL) {
                plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n");
-               return NULL;
+               goto out;
        }
        bp = newsa->v;
 
@@ -1721,7 +1761,7 @@ get_sabysaprop(pp0, sa0)
                                                break;
                                }
                                if (p == NULL)
-                                       return NULL;
+                                       goto out;
 
                                trnslen = ntohs(p->trns->h.len);
 
@@ -1746,6 +1786,18 @@ get_sabysaprop(pp0, sa0)
                }
        }
 
+       error = 0;
+out:
+       if (pair != NULL)
+               racoon_free(pair);
+
+       if (error != 0) {
+               if (newsa != NULL) {
+                       vfree(newsa);
+                       newsa = NULL;
+               }
+       }
+
        return newsa;
 }
 
@@ -2085,20 +2137,32 @@ check_attr_isakmp(trns)
                        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 #ifdef ENABLE_HYBRID
                        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
-#endif  
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+#if 0 /* Clashes with OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB */
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+#endif
+            case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+#endif
                        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
                                break;
                        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
 #ifdef ENABLE_HYBRID
-                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
                        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
                        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
 #endif
                        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
                        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
                                plog(LLV_ERROR, LOCATION, NULL,
-                                       "auth method %d isn't supported.\n",
-                                       lorv);
+                                       "auth method %s isn't supported.\n",
+                                       s_oakley_attr_method(lorv));
                                return -1;
                        default:
                                plog(LLV_ERROR, LOCATION, NULL,
@@ -2804,8 +2868,8 @@ setph1attr(sa, buf)
                else
                        attrlen += sa->gssid->l * 2;
                if (buf) {
-                       plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %d, "
-                           "val '%.*s'\n", sa->gssid->l, sa->gssid->l,
+                       plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %zu, "
+                           "val '%.*s'\n", sa->gssid->l, (int)sa->gssid->l,
                            sa->gssid->v);
                        if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) {
                                p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID,
@@ -3139,7 +3203,7 @@ ipsecdoi_setph2proposal(iph2)
 
 #ifdef __APPLE__
 /*
- * return 1 if all of the given protocols are transport mode.
+ * return 1 if all of the given protocols are tunnel mode.
  */
 int
 ipsecdoi_tunnelmode(iph2)
@@ -3159,6 +3223,27 @@ ipsecdoi_tunnelmode(iph2)
 
        return 1;
 }
+
+/*
+ * return 1 if any of the given protocols are transport mode.
+ */
+int
+ipsecdoi_any_transportmode(pp)
+struct saprop *pp;
+{
+       struct saproto *pr = NULL;
+       
+       for (; pp; pp = pp->next) {
+               for (pr = pp->head; pr; pr = pr->next) {
+                       if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TRNS ||
+                               pr->encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC ||
+                               pr->encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT)
+                               return 1;
+               }
+       }
+       
+       return 0;
+}
 #endif
 
 /*
@@ -3264,6 +3349,259 @@ doi2ipproto(proto)
        return -1;      /* XXX */
 }
 
+/*
+ * Check if a subnet id is valid for comparison
+ * with an address id ( address length mask )
+ * and compare them
+ * Return value
+ * =  0 for match
+ * =  1 for mismatch
+ */
+
+int
+ipsecdoi_subnetisaddr_v4( subnet, address )
+       const vchar_t *subnet;
+       const vchar_t *address;
+{
+       struct in_addr *mask;
+
+       if (address->l != sizeof(struct in_addr))
+               return 1;
+
+       if (subnet->l != (sizeof(struct in_addr)*2))
+               return 1;
+
+       mask = (struct in_addr*)(subnet->v + sizeof(struct in_addr));
+
+       if (mask->s_addr!=0xffffffff)
+               return 1;
+
+       return memcmp(subnet->v,address->v,address->l);
+}
+
+#ifdef INET6
+
+int
+ipsecdoi_subnetisaddr_v6( subnet, address )
+       const vchar_t *subnet;
+       const vchar_t *address;
+{
+       struct in6_addr *mask;
+       int i;
+
+       if (address->l != sizeof(struct in6_addr))
+               return 1;
+
+       if (subnet->l != (sizeof(struct in6_addr)*2))
+               return 1;
+
+       mask = (struct in6_addr*)(subnet->v + sizeof(struct in6_addr));
+
+       for (i=0; i<16; i++)
+               if(mask->s6_addr[i]!=0xff)
+                       return 1;
+
+       return memcmp(subnet->v,address->v,address->l);
+}
+
+#endif
+
+/*
+ * Check and Compare two IDs
+ * - specify 0 for exact if wildcards are allowed
+ * Return value
+ * =  0 for match
+ * =  1 for misatch
+ * = -1 for integrity error
+ */
+
+int
+ipsecdoi_chkcmpids( idt, ids, exact )
+       const vchar_t *idt; /* id cmp target */
+       const vchar_t *ids; /* id cmp source */
+       int exact;
+{
+       struct ipsecdoi_id_b *id_bt;
+       struct ipsecdoi_id_b *id_bs;
+       vchar_t ident_t;
+       vchar_t ident_s;
+       int result;
+
+       /* handle wildcard IDs */
+
+       if (idt == NULL || ids == NULL)
+       {
+               if( !exact )
+               {
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                               "check and compare ids : values matched (ANONYMOUS)\n" );
+                       return 0;
+               }
+               else
+               {
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                               "check and compare ids : value mismatch (ANONYMOUS)\n" );
+                       return -1;
+               }
+       }
+
+       /* make sure the ids are of the same type */
+
+       id_bt = (struct ipsecdoi_id_b *) idt->v;
+       id_bs = (struct ipsecdoi_id_b *) ids->v;
+
+       ident_t.v = idt->v + sizeof(*id_bt);
+       ident_t.l = idt->l - sizeof(*id_bt);
+       ident_s.v = ids->v + sizeof(*id_bs);
+       ident_s.l = ids->l - sizeof(*id_bs);
+
+       if (id_bs->type != id_bt->type)
+       {
+               /*
+                * special exception for comparing
+                 * address to subnet id types when
+                 * the netmask is address length
+                 */
+
+               if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&&
+                   (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) {
+                       result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s);
+                       goto cmpid_result;
+               }
+
+               if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&&
+                   (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) {
+                       result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t);
+                       goto cmpid_result;
+               }
+
+#ifdef INET6
+               if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&&
+                   (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
+                       result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s);
+                       goto cmpid_result;
+               }
+
+               if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&&
+                   (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) {
+                       result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t);
+                       goto cmpid_result;
+               }
+#endif
+               plog(LLV_DEBUG, LOCATION, NULL,
+                       "check and compare ids : id type mismatch %s != %s\n",
+                       s_ipsecdoi_ident(id_bs->type),
+                       s_ipsecdoi_ident(id_bt->type));
+
+               return 1;
+       }
+
+       if(id_bs->proto_id != id_bt->proto_id){
+               plog(LLV_DEBUG, LOCATION, NULL,
+                       "check and compare ids : proto_id mismatch %d != %d\n",
+                       id_bs->proto_id, id_bt->proto_id);
+
+               return 1;
+       }
+
+       /* compare the ID data. */
+
+       switch (id_bt->type) {
+               case IPSECDOI_ID_DER_ASN1_DN:
+               case IPSECDOI_ID_DER_ASN1_GN:
+                       /* compare asn1 ids */
+                       result = eay_cmp_asn1dn(&ident_t, &ident_s);
+                       goto cmpid_result;
+
+               case IPSECDOI_ID_IPV4_ADDR:
+                       /* validate lengths */
+                       if ((ident_t.l != sizeof(struct in_addr))||
+                           (ident_s.l != sizeof(struct in_addr)))
+                               goto cmpid_invalid;
+                       break;
+
+               case IPSECDOI_ID_IPV4_ADDR_SUBNET:
+               case IPSECDOI_ID_IPV4_ADDR_RANGE:
+                       /* validate lengths */
+                       if ((ident_t.l != (sizeof(struct in_addr)*2))||
+                           (ident_s.l != (sizeof(struct in_addr)*2)))
+                               goto cmpid_invalid;
+                       break;
+
+#ifdef INET6
+               case IPSECDOI_ID_IPV6_ADDR:
+                       /* validate lengths */
+                       if ((ident_t.l != sizeof(struct in6_addr))||
+                           (ident_s.l != sizeof(struct in6_addr)))
+                               goto cmpid_invalid;
+                       break;
+
+               case IPSECDOI_ID_IPV6_ADDR_SUBNET:
+               case IPSECDOI_ID_IPV6_ADDR_RANGE:
+                       /* validate lengths */
+                       if ((ident_t.l != (sizeof(struct in6_addr)*2))||
+                           (ident_s.l != (sizeof(struct in6_addr)*2)))
+                               goto cmpid_invalid;
+                       break;
+#endif
+               case IPSECDOI_ID_FQDN:
+               case IPSECDOI_ID_USER_FQDN:
+               case IPSECDOI_ID_KEY_ID:
+                       break;
+
+               default:
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "Unhandled id type %i specified for comparison\n",
+                               id_bt->type);
+                       return -1;
+       }
+
+       /* validate matching data and length */
+       if (ident_t.l == ident_s.l)
+               result = memcmp(ident_t.v,ident_s.v,ident_t.l);
+       else
+               result = 1;
+
+cmpid_result:
+
+       /* debug level output */
+       if(loglevel >= LLV_DEBUG) {
+               char *idstrt = ipsecdoi_id2str(idt);
+               char *idstrs = ipsecdoi_id2str(ids);
+
+               if (!result)
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                               "check and compare ids : values matched (%s)\n",
+                                s_ipsecdoi_ident(id_bs->type) );
+               else
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                               "check and compare ids : value mismatch (%s)\n",
+                                s_ipsecdoi_ident(id_bs->type));
+
+               plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: \'%s\'\n", idstrt );
+               plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: \'%s\'\n", idstrs );
+
+               racoon_free(idstrs);
+               racoon_free(idstrt);
+       }
+
+       /* return result */
+       if( !result )
+               return 0;
+       else
+               return 1;
+
+cmpid_invalid:
+
+       /* id integrity error */
+       plog(LLV_DEBUG, LOCATION, NULL, "check and compare ids : %s integrity error\n",
+               s_ipsecdoi_ident(id_bs->type));
+       plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: length = \'%zu\'\n", ident_t.l );
+       plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: length = \'%zu\'\n", ident_s.l );
+
+       return -1;
+}
+
 /*
  * check the following:
  * - In main mode with pre-shared key, only address type can be used.
@@ -3328,7 +3666,7 @@ ipsecdoi_checkid1(iph1)
        }
 
        /* if phase 1 ID payload conformed RFC2407 4.6.2. */
-       if (id_b->type == IPSECDOI_ID_IPV4_ADDR ||              // %%%% BUG_FIX - should be || not &&
+       if (id_b->type == IPSECDOI_ID_IPV4_ADDR ||
            id_b->type == IPSECDOI_ID_IPV6_ADDR) {
 
                if (id_b->proto_id == 0 && ntohs(id_b->port) != 0) {
@@ -3393,9 +3731,8 @@ ipsecdoi_checkid1(iph1)
 
                        switch (id->idtype) {
                        case IDTYPE_ASN1DN:
-                               ident.v = (caddr_t)(id_b + 1);
-                               ident.l = iph1->id_p->l - 1; /* had ident.l = ident0->l; but why?? */
-                                     /* is the actual packet contents length sometimes wrong? */
+                               ident.v = iph1->id_p->v + sizeof(*id_b);
+                               ident.l = iph1->id_p->l - sizeof(*id_b);
                                if (eay_cmp_asn1dn(ident0, &ident) == 0)
                                        goto matched;
                                break;
@@ -3591,6 +3928,15 @@ int
 set_identifier(vpp, type, value)
        vchar_t **vpp, *value;
        int type;
+{
+       return set_identifier_qual(vpp, type, value, IDQUAL_UNSPEC);
+}
+
+int
+set_identifier_qual(vpp, type, value, qual)
+       vchar_t **vpp, *value;
+       int type;
+       int qual;
 {
        vchar_t *new = NULL;
 
@@ -3625,31 +3971,55 @@ set_identifier(vpp, type, value)
                memcpy(new->v, value->v, new->l);
                break;
        case IDTYPE_KEYID:
-       {
-               FILE *fp;
-               char b[512];
-               int tlen, len;
-
-               fp = fopen(value->v, "r");
-               if (fp == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "can not open %s\n", value->v);
-                       return -1;
+               /* 
+                * If no qualifier is specified: IDQUAL_UNSPEC. It means
+                * to use a file for backward compatibility sake. 
+                */
+               switch(qual) {
+               case IDQUAL_FILE:
+               case IDQUAL_UNSPEC: {
+                       FILE *fp;
+                       char b[512];
+                       int tlen, len;
+
+                       fp = fopen(value->v, "r");
+                       if (fp == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "can not open %s\n", value->v);
+                               return -1;
+                       }
+                       tlen = 0;
+                       while ((len = fread(b, 1, sizeof(b), fp)) != 0) {
+                               new = vrealloc(new, tlen + len);
+                               if (!new) {
+                                       fclose(fp);
+                                       return -1;
+                               }
+                               memcpy(new->v + tlen, b, len);
+                               tlen += len;
+                       }
+                       fclose(fp);
+                       break;
                }
-               tlen = 0;
-               while ((len = fread(b, 1, sizeof(b), fp)) != 0) {
-                       new = vrealloc(new, tlen + len);
-                       if (!new) {
-                               fclose(fp);
+
+               case IDQUAL_TAG:
+                       new = vmalloc(value->l - 1);
+                       if (new == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "can not allocate memory");
                                return -1;
                        }
-                       memcpy(new->v + tlen, b, len);
-                       tlen += len;
+                       memcpy(new->v, value->v, new->l);
+                       break;
+
+               default:
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "unknown qualifier");
+                       return -1;
                }
                break;
-       }
-       case IDTYPE_ADDRESS:
-       {
+       
+       case IDTYPE_ADDRESS: {
                struct sockaddr *sa;
 
                /* length is adjusted since QUOTEDSTRING teminates NULL. */
@@ -3664,9 +4034,12 @@ set_identifier(vpp, type, value)
                }
 
                new = vmalloc(sysdep_sa_len(sa));
-               if (new == NULL)
+               if (new == NULL) {
+                       racoon_free(sa);
                        return -1;
+               }
                memcpy(new->v, sa, new->l);
+               racoon_free(sa);
                break;
        }
        case IDTYPE_ASN1DN:
@@ -3779,13 +4152,7 @@ ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto)
        switch (saddr->sa_family) {
        case AF_INET:
                len1 = sizeof(struct in_addr);
-               if (
-#if 0
-                       prefixlen == ~0
-#else
-                       prefixlen == (sizeof(struct in_addr) << 3)
-#endif
-                       ) {
+               if (prefixlen == (sizeof(struct in_addr) << 3)) {
                        type = IPSECDOI_ID_IPV4_ADDR;
                        len2 = 0;
                } else {
@@ -3798,13 +4165,7 @@ ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto)
 #ifdef INET6
        case AF_INET6:
                len1 = sizeof(struct in6_addr);
-               if (
-#if 0
-               prefixlen == ~0
-#else
-               prefixlen == (sizeof(struct in6_addr) << 3)
-#endif
-                       ) {
+               if (prefixlen == (sizeof(struct in6_addr) << 3)) {
                        type = IPSECDOI_ID_IPV6_ADDR;
                        len2 = 0;
                } else {
@@ -3865,6 +4226,71 @@ ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto)
        return new;
 }
 
+vchar_t *
+ipsecdoi_sockrange2id(laddr, haddr, ul_proto)
+       struct sockaddr *laddr, *haddr;
+       u_int ul_proto;
+{
+       vchar_t *new;
+       int type, len1, len2;
+       u_short port;
+
+       if (laddr->sa_family != haddr->sa_family) {
+           plog(LLV_ERROR, LOCATION, NULL, "Address family mismatch\n");
+           return NULL;
+       }
+
+       switch (laddr->sa_family) {
+       case AF_INET:
+           type = IPSECDOI_ID_IPV4_ADDR_RANGE;
+           len1 = sizeof(struct in_addr);
+           len2 = sizeof(struct in_addr);
+           break;
+#ifdef INET6
+       case AF_INET6:
+               type = IPSECDOI_ID_IPV6_ADDR_RANGE;
+               len1 = sizeof(struct in6_addr);
+               len2 = sizeof(struct in6_addr);
+               break;
+#endif
+       default:
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "invalid family: %d.\n", laddr->sa_family);
+               return NULL;
+       }
+
+       /* get ID buffer */
+       new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2);
+       if (new == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "failed to get ID buffer.\n");
+               return NULL;
+       }
+
+       memset(new->v, 0, new->l);
+       /* set the part of header. */
+       ((struct ipsecdoi_id_b *)new->v)->type = type;
+
+       /* set ul_proto and port */
+       /*
+        * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card
+        * because 0 means port number of 0.  Instead of 0, we use IPSEC_*_ANY.
+        */
+       ((struct ipsecdoi_id_b *)new->v)->proto_id =
+               ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto;
+       port = ((struct sockaddr_in *)(laddr))->sin_port;
+       ((struct ipsecdoi_id_b *)new->v)->port =
+               port == IPSEC_PORT_ANY ? 0 : port;
+       memcpy(new->v + sizeof(struct ipsecdoi_id_b), 
+              (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr, 
+              len1);
+       memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1, 
+              (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr,
+              len2);
+       return new;
+}
+
+
 /*
  * create sockaddr structure from ID payload (buf).
  * buffers (saddr, prefixlen, ul_proto) must be allocated.
@@ -3965,9 +4391,9 @@ ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto)
                        + alen;
 
                for (; *p == 0xff; p++) {
+                       plen += 8;
                        if (plen >= max)
                                break;
-                       plen += 8;
                }
 
                if (plen < max) {
@@ -3997,16 +4423,210 @@ ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto)
 /*
  * make printable string from ID payload except of general header.
  */
-const char *
+char *
 ipsecdoi_id2str(id)
        const vchar_t *id;
 {
-       static char buf[256];
+#define BUFLEN 512
+       char * ret = NULL;
+       int len = 0;
+       char *dat;
+       static char buf[BUFLEN];
+       struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v;
+       struct sockaddr_storage saddr;
+       u_int plen = 0;
+
+    bzero(&saddr, sizeof(saddr));
+
+       switch (id_b->type) {
+       case IPSECDOI_ID_IPV4_ADDR:
+       case IPSECDOI_ID_IPV4_ADDR_SUBNET:
+       case IPSECDOI_ID_IPV4_ADDR_RANGE:
+
+#ifndef __linux__
+               ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in);
+#endif
+               ((struct sockaddr *)&saddr)->sa_family = AF_INET;
+               ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY;
+               memcpy(&((struct sockaddr_in *)&saddr)->sin_addr,
+                       id->v + sizeof(*id_b), sizeof(struct in_addr));
+               break;
+#ifdef INET6
+       case IPSECDOI_ID_IPV6_ADDR:
+       case IPSECDOI_ID_IPV6_ADDR_SUBNET:
+       case IPSECDOI_ID_IPV6_ADDR_RANGE:
+
+#ifndef __linux__
+               ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in6);
+#endif
+               ((struct sockaddr *)&saddr)->sa_family = AF_INET6;
+               ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY;
+               memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr,
+                       id->v + sizeof(*id_b), sizeof(struct in6_addr));
+               break;
+#endif
+       }
+
+       switch (id_b->type) {
+       case IPSECDOI_ID_IPV4_ADDR:
+#ifdef INET6
+       case IPSECDOI_ID_IPV6_ADDR:
+#endif
+               len = snprintf( buf, sizeof(buf), "%s", saddrwop2str((struct sockaddr *)&saddr));
+               break;
 
-       /* XXX */
-       buf[0] = '\0';
+       case IPSECDOI_ID_IPV4_ADDR_SUBNET:
+#ifdef INET6
+       case IPSECDOI_ID_IPV6_ADDR_SUBNET:
+#endif
+           {
+               u_char *p;
+               u_int max;
+               int alen = sizeof(struct in_addr);
 
-       return buf;
+               switch (id_b->type) {
+               case IPSECDOI_ID_IPV4_ADDR_SUBNET:
+                       alen = sizeof(struct in_addr);
+                       break;
+#ifdef INET6
+               case IPSECDOI_ID_IPV6_ADDR_SUBNET:
+                       alen = sizeof(struct in6_addr);
+                       break;
+#endif
+               }
+
+               /* sanity check */
+               if (id->l < alen) {
+                       len = 0;
+                       break;
+               }
+
+               /* get subnet mask length */
+               plen = 0;
+               max = alen <<3;
+
+               p = (unsigned char *) id->v
+                       + sizeof(struct ipsecdoi_id_b)
+                       + alen;
+
+               for (; *p == 0xff; p++) {
+                       plen += 8;
+                       if (plen >= max)
+                               break;
+               }
+
+               if (plen < max) {
+                       u_int l = 0;
+                       u_char b = ~(*p);
+
+                       while (b) {
+                               b >>= 1;
+                               l++;
+                       }
+
+                       l = 8 - l;
+                       plen += l;
+               }
+
+               len = snprintf( buf, sizeof(buf), "%s/%i", saddrwop2str((struct sockaddr *)&saddr), plen);
+           }
+               break;
+
+       case IPSECDOI_ID_IPV4_ADDR_RANGE:
+
+               len = snprintf( buf, sizeof(buf), "%s-", saddrwop2str((struct sockaddr *)&saddr));
+
+#ifndef __linux__
+               ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in);
+#endif
+               ((struct sockaddr *)&saddr)->sa_family = AF_INET;
+               ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY;
+               memcpy(&((struct sockaddr_in *)&saddr)->sin_addr,
+                       id->v + sizeof(*id_b) + sizeof(struct in_addr),
+                       sizeof(struct in_addr));
+
+               if (len >= 0) {
+                   len += snprintf( buf + len, sizeof(buf) - len, "%s", saddrwop2str((struct sockaddr *)&saddr));
+               }
+
+               break;
+
+#ifdef INET6
+       case IPSECDOI_ID_IPV6_ADDR_RANGE:
+
+               len = snprintf( buf, sizeof(buf), "%s-", saddrwop2str((struct sockaddr *)&saddr));
+
+#ifndef __linux__
+               ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in6);
+#endif
+               ((struct sockaddr *)&saddr)->sa_family = AF_INET6;
+               ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY;
+               memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr,
+                       id->v + sizeof(*id_b) + sizeof(struct in6_addr),
+                       sizeof(struct in6_addr));
+
+               if (len >= 0) {
+                   len += snprintf( buf + len, sizeof(buf) - len, "%s", saddrwop2str((struct sockaddr *)&saddr));
+               }
+
+               break;
+#endif
+
+       case IPSECDOI_ID_FQDN:
+       case IPSECDOI_ID_USER_FQDN:
+               len = id->l - sizeof(*id_b);
+               if (len > BUFLEN)
+                       len = BUFLEN;
+               memcpy(buf, id->v + sizeof(*id_b), len);
+               break;
+
+       case IPSECDOI_ID_DER_ASN1_DN:
+       case IPSECDOI_ID_DER_ASN1_GN:
+       {
+               X509_NAME *xn = NULL;
+
+               dat = id->v + sizeof(*id_b);
+               len = id->l - sizeof(*id_b);
+
+               if (d2i_X509_NAME(&xn, (void*) &dat, len) != NULL) {
+                       BIO *bio = BIO_new(BIO_s_mem());
+                       X509_NAME_print_ex(bio, xn, 0, 0);
+                       len = BIO_get_mem_data(bio, &dat);
+                       if (len > BUFLEN)
+                               len = BUFLEN;
+                       memcpy(buf,dat,len);
+                       BIO_free(bio);
+                       X509_NAME_free(xn);
+               } else {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "unable to extract asn1dn from id\n");
+
+                       len = snprintf(buf, sizeof(buf), "<ASN1-DN>");
+               }
+
+               break;
+       }
+
+       /* currently unhandled id types */
+       case IPSECDOI_ID_KEY_ID:
+               len = snprintf( buf, sizeof(buf), "<KEY-ID>");
+               break;
+
+       default:
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unknown ID type %d\n", id_b->type);
+       }
+
+       if (!len)
+               len = snprintf( buf, sizeof(buf), "<?>");
+
+       ret = racoon_malloc(len+1);
+       if (ret != NULL) {
+               memcpy(ret,buf,len);
+               ret[len]=0;
+       }
+
+       return ret;
 }
 
 /*
@@ -4265,9 +4885,6 @@ static int rm_idtype2doi[] = {
        255,    /*                         IDTYPE_ADDRESS, 4 
                 * it expands into 4 types by another function. */
        IPSECDOI_ID_DER_ASN1_DN,        /* IDTYPE_ASN1DN, 5 */
-#ifdef ENABLE_HYBRID
-       255,                            /* IDTYPE_LOGIN, 6 */
-#endif
 };
 
 /*
@@ -4323,16 +4940,16 @@ switch_authmethod(authmethod)
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
                authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I;
                break;
-       /* Those are not implemented */
        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
                authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
                break;
-       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-               authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I;
-               break;
        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
                authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
                break;
+       /* Those are not implemented */
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+               authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I;
+               break;
        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
                authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I;
                break;
index 9d5e7a9168f730f08b4763afb26da04079827f44..ff07bd3bacbf8ba51732f7567d406f0ef0afbd4b 100644 (file)
@@ -200,6 +200,12 @@ struct ipsecdoi_pl_id {
 #define VERIFICATION_OPTION_OPEN_DIR                   2
 #endif
 
+/* qualifiers for KEYID (and maybe others) */
+#define IDQUAL_UNSPEC          0
+#define IDQUAL_FILE            1
+#define IDQUAL_TAG             2
+
+
 /* The use for checking proposal payload. This is not exchange type. */
 #define IPSECDOI_TYPE_PH1      0
 #define IPSECDOI_TYPE_PH2      1
@@ -219,20 +225,25 @@ extern struct prop_pair **get_proppair __P((vchar_t *, int));
 extern vchar_t *get_sabyproppair __P((struct prop_pair *, struct ph1handle *));
 extern int ipsecdoi_updatespi __P((struct ph2handle *iph2));
 extern vchar_t *get_sabysaprop __P((struct saprop *, vchar_t *));
+extern int ipsecdoi_chkcmpids( const vchar_t *, const vchar_t *, int );
 extern int ipsecdoi_checkid1 __P((struct ph1handle *));
 extern int ipsecdoi_setid1 __P((struct ph1handle *));
 extern int set_identifier __P((vchar_t **, int, vchar_t *));
+extern int set_identifier_qual __P((vchar_t **, int, vchar_t *, int));
 extern int ipsecdoi_setid2 __P((struct ph2handle *));
 extern vchar_t *ipsecdoi_sockaddr2id __P((struct sockaddr *, u_int, u_int));
 extern int ipsecdoi_id2sockaddr __P((vchar_t *, struct sockaddr *,
        u_int8_t *, u_int16_t *));
-extern const char *ipsecdoi_id2str __P((const vchar_t *));
+extern char *ipsecdoi_id2str __P((const vchar_t *));
+extern vchar_t *ipsecdoi_sockrange2id __P((    struct sockaddr *,
+       struct sockaddr *, u_int));
 
 extern vchar_t *ipsecdoi_setph1proposal __P((struct isakmpsa *));
 extern int ipsecdoi_setph2proposal __P((struct ph2handle *));
 extern int ipsecdoi_transportmode __P((struct saprop *));
 #ifdef __APPLE__
 extern int ipsecdoi_tunnelmode __P((struct ph2handle *));
+extern int ipsecdoi_any_transportmode __P((struct saprop *));
 #endif
 extern int ipsecdoi_get_defaultlifetime __P((void));
 extern int ipsecdoi_checkalgtypes __P((int, int, int, int));
index dc58420d088965a94ce54a3f0c6148fca89b220a..7d8e24ea4be92e1895060f099527bc776dfdd3da 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp.c,v 1.34.2.21 2006/02/02 10:31:01 vanhu Exp $ */
+/*     $NetBSD: isakmp.c,v 1.20.6.7 2007/08/01 11:52:20 vanhu Exp $    */
+
+/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -67,7 +69,9 @@
 #include <unistd.h>
 #endif
 #include <ctype.h>
-#include <fcntl.h>
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
 
 #include "var.h"
 #include "misc.h"
 #include "vpn_control.h"
 #include "vpn_control_var.h"
 #ifdef ENABLE_HYBRID
+#include "vendorid.h"
 #include "isakmp_xauth.h"
+#include "isakmp_unity.h"
 #include "isakmp_cfg.h"
 #endif
 #ifdef ENABLE_FRAG
 #endif
 #include "strnames.h"
 
+#include <fcntl.h>
+
 #ifdef ENABLE_NATT
 # include "nattraversal.h"
+#endif
+#include "ike_session.h"
 # ifdef __linux__
 #  include <linux/udp.h>
-#include <fcntl.h>
-
+#  include <linux/ip.h>
 #  ifndef SOL_UDP
 #   define SOL_UDP 17
 #  endif
 # endif /* __linux__ */
-# if defined(__NetBSD__) || defined(__FreeBSD__)
+# if defined(__NetBSD__) || defined(__FreeBSD__) ||    \
+  (defined(__APPLE__) && defined(__MACH__))
 #  include <netinet/in.h>
 #  include <netinet/udp.h>
+#  include <netinet/in_systm.h>
+#  include <netinet/ip.h>
 #  define SOL_UDP IPPROTO_UDP
 # endif /* __NetBSD__ / __FreeBSD__ */
-#endif
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
 
 static int nostate1 __P((struct ph1handle *, vchar_t *));
 static int nostate2 __P((struct ph2handle *, vchar_t *));
@@ -162,7 +175,7 @@ static int (*ph2exchange[][2][PHASE2ST_MAX])
        __P((struct ph2handle *, vchar_t *)) = {
  /* error */
  { {}, {}, },
- /* Quick mode for IKE*/
+ /* Quick mode for IKE */
  {
   { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send,
     quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, },
@@ -198,6 +211,13 @@ isakmp_handler(so_isakmp)
        union {
                char            buf[sizeof (isakmp) + 4];
                u_int32_t       non_esp[2];
+               char            lbuf[sizeof(struct udphdr) + 
+#ifdef __linux
+                                    sizeof(struct iphdr) + 
+#else
+                                    sizeof(struct ip) + 
+#endif
+                                    sizeof(isakmp) + 4];
        } x;
        struct sockaddr_storage remote;
        struct sockaddr_storage local;
@@ -228,10 +248,32 @@ isakmp_handler(so_isakmp)
                        plog(LLV_ERROR, LOCATION, NULL,
                            "failed to receive keep alive packet: %s\n",
                            strerror (errno));
-               }
+        }
                goto end;
        }
 
+       /* Lucent IKE in UDP encapsulation */
+       {
+               struct udphdr *udp;
+#ifdef __linux__
+               struct iphdr *ip;
+
+               udp = (struct udphdr *)&x.lbuf[0];
+               if (ntohs(udp->dest) == 501) {
+                       ip = (struct iphdr *)(x.lbuf + sizeof(*udp));
+                       extralen += sizeof(*udp) + ip->ihl;
+               }
+#else
+               struct ip *ip;
+
+               udp = (struct udphdr *)&x.lbuf[0];
+               if (ntohs(udp->uh_dport) == 501) {
+                       ip = (struct ip *)(x.lbuf + sizeof(*udp));
+                       extralen += sizeof(*udp) + ip->ip_hl;
+               }
+#endif
+       }       
+
 #ifdef ENABLE_NATT
        /* we don't know about portchange yet, 
           look for non-esp marker instead */
@@ -309,8 +351,6 @@ isakmp_handler(so_isakmp)
        
        memcpy (buf->v, tmpbuf->v + extralen, buf->l);
 
-       vfree (tmpbuf);
-
        len -= extralen;
        
        if (len != buf->l) {
@@ -370,6 +410,8 @@ isakmp_handler(so_isakmp)
        error = 0;
 
 end:
+       if (tmpbuf != NULL)
+               vfree(tmpbuf);
        if (buf != NULL)
                vfree(buf);
 
@@ -447,6 +489,10 @@ isakmp_main(msg, remote, local)
                /* validity check */
                if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 &&
                    iph1->side == INITIATOR) {
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                       CONSTSTR("malformed or unexpected cookie"),
+                                                                       CONSTSTR("Failed to process packet (malformed/unexpected cookie)"));
                        plog(LLV_DEBUG, LOCATION, remote,
                                "malformed cookie received or "
                                "the initiator's cookies collide.\n");
@@ -463,10 +509,34 @@ isakmp_main(msg, remote, local)
                        /* prevent memory leak */
                        racoon_free(iph1->remote);
                        racoon_free(iph1->local);
+                       iph1->remote = NULL;
+                       iph1->local = NULL;
 
                        /* copy-in new addresses */
                        iph1->remote = dupsaddr(remote);
+                       if (iph1->remote == NULL) {
+                               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                               CONSTSTR("failed to duplicate remote address"),
+                                                                               CONSTSTR("Failed to process phase1 message (can't duplicate remote address"));
+                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                  "phase1 failed: dupsaddr failed.\n");
+                               remph1(iph1);
+                               delph1(iph1);
+                               return -1;
+                       }
                        iph1->local = dupsaddr(local);
+                       if (iph1->local == NULL) {
+                               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                               CONSTSTR("failed to duplicate local address"),
+                                                                               CONSTSTR("Failed to process phase1 message (can't duplicate local address"));
+                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                  "phase1 failed: dupsaddr failed.\n");
+                               remph1(iph1);
+                               delph1(iph1);
+                               return -1;
+                       }
 
                        /* set the flag to prevent further port floating
                           (FIXME: should we allow it? E.g. when the NAT gw 
@@ -487,8 +557,10 @@ isakmp_main(msg, remote, local)
                if (cmpsaddrstrict(iph1->remote, remote) != 0) {
                        char *saddr_db, *saddr_act;
 
-                       saddr_db = strdup(saddr2str(iph1->remote));
-                       saddr_act = strdup(saddr2str(remote));
+                       saddr_db = racoon_strdup(saddr2str(iph1->remote));
+                       saddr_act = racoon_strdup(saddr2str(remote));
+                       STRDUP_FATAL(saddr_db);
+                       STRDUP_FATAL(saddr_act);
 
                        plog(LLV_WARNING, LOCATION, remote,
                                "remote address mismatched. db=%s, act=%s\n",
@@ -504,6 +576,12 @@ isakmp_main(msg, remote, local)
                 */
 
                /* XXX more acceptable check */
+
+#ifdef ENABLE_DPD
+        // received ike packets: update dpd checks 
+        isakmp_reschedule_info_monitor_if_pending(iph1,
+                                                  "ike packets received from peer");
+#endif /* DPD */
        }
 
        switch (isakmp->etype) {
@@ -548,6 +626,10 @@ isakmp_main(msg, remote, local)
 
                        /* it must be the 2nd message from the responder. */
                        if (iph1->side != INITIATOR) {
+                               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                               CONSTSTR("malformed cookie and unexpected side"),
+                                                                               CONSTSTR("Failed to process phase1 message (unexpected side)"));
                                plog(LLV_DEBUG, LOCATION, remote,
                                        "malformed cookie received. "
                                        "it has to be as the initiator.  %s\n",
@@ -562,6 +644,10 @@ isakmp_main(msg, remote, local)
                 * authencication completed.
                 */
                if (iph1->etype != isakmp->etype) {
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                       CONSTSTR("mismatched exchange type"),
+                                                                       CONSTSTR("Failed to process phase1 message (mismatched exchange type)"));
                        plog(LLV_ERROR, LOCATION, iph1->remote,
                                "exchange type is mismatched: "
                                "db=%s packet=%s, ignore it.\n",
@@ -639,7 +725,13 @@ isakmp_main(msg, remote, local)
                                        isakmp->msgid));
                        return -1;
                }
-
+#ifdef ENABLE_HYBRID
+               /* Reinit the IVM if it's still there */                
+               if (iph1->mode_cfg && iph1->mode_cfg->ivm) {
+                       oakley_delivm(iph1->mode_cfg->ivm);
+                       iph1->mode_cfg->ivm = NULL;
+               }
+#endif
 #ifdef ENABLE_FRAG
                if (isakmp->np == ISAKMP_NPTYPE_FRAG)
                        return frag_handler(iph1, msg, remote, local);
@@ -647,6 +739,10 @@ isakmp_main(msg, remote, local)
 
                /* check status of phase 1 whether negotiated or not. */
                if (iph1->status != PHASE1ST_ESTABLISHED) {
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
+                                                                       CONSTSTR("can't start phase2 without valid phase1"),
+                                                                       CONSTSTR("Failed to start phase2 resonder (no established phase1"));
                        plog(LLV_ERROR, LOCATION, remote,
                                "can't start the quick mode, "
                                "there is no valid ISAKMP-SA, %s\n",
@@ -741,9 +837,12 @@ ph1_main(iph1, msg)
        vchar_t *msg;
 {
        int error;
+       int ini_contact = iph1->rmconf->ini_contact;
 #ifdef ENABLE_STATS
        struct timeval start, end;
 #endif
+       int   spi_cmp;
+       u_int rekey_lifetime;
 
        /* ignore a packet */
        if (iph1->status == PHASE1ST_ESTABLISHED)
@@ -756,6 +855,10 @@ ph1_main(iph1, msg)
        if (ph1exchange[etypesw1(iph1->etype)]
                       [iph1->side]
                       [iph1->status] == NULL) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("unavailable function"),
+                                                               CONSTSTR("Failed to process phase1 message (no state function)"));
                plog(LLV_ERROR, LOCATION, iph1->remote,
                        "why isn't the function defined.\n");
                return -1;
@@ -764,6 +867,7 @@ ph1_main(iph1, msg)
                            [iph1->side]
                            [iph1->status])(iph1, msg);
        if (error != 0) {
+
                /* XXX
                 * When an invalid packet is received on phase1, it should
                 * be selected to process this packet.  That is to respond
@@ -772,7 +876,7 @@ ph1_main(iph1, msg)
                 * acting as RESPONDER we must not keep phase 1 handler or else
                 * it will stay forever.
                 */
-        
+
                if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) {
                        plog(LLV_ERROR, LOCATION, iph1->remote,
                             "failed to pre-process packet.\n");
@@ -783,17 +887,19 @@ ph1_main(iph1, msg)
                }       
        }
 
+#ifndef ENABLE_FRAG
        /* free resend buffer */
        if (iph1->sendbuf == NULL) {
                plog(LLV_ERROR, LOCATION, NULL,
                        "no buffer found as sendbuf\n"); 
                return -1;
        }
+#endif
+
        VPTRINIT(iph1->sendbuf);
 
        /* turn off schedule */
-       if (iph1->scr)
-               SCHED_KILL(iph1->scr);
+       SCHED_KILL(iph1->scr);
 
        /* send */
        plog(LLV_DEBUG, LOCATION, NULL, "===\n");
@@ -822,45 +928,80 @@ ph1_main(iph1, msg)
 
 #ifdef ENABLE_VPNCONTROL_PORT  
 
-       if (iph1->side == RESPONDER &&
-               iph1->local->sa_family == AF_INET) {
-               
-               struct redirect *addr;
-               
-               LIST_FOREACH(addr, &lcconf->redirect_addresses, chain) {
-                       if (((struct sockaddr_in *)iph1->local)->sin_addr.s_addr == addr->cluster_address) {
-                               vchar_t *raddr = vmalloc(sizeof(u_int32_t));
+               if (iph1->side == RESPONDER &&
+                       iph1->local->sa_family == AF_INET) {
+                       
+                       struct redirect *addr;
                        
-                               if (raddr == NULL) {
-                                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                                               "failed to send redirect message - memory error.\n");
-                               } else {
-                                       memcpy(raddr->v, &addr->redirect_address, sizeof(u_int32_t));
-                                       (void)isakmp_info_send_n1(iph1, ISAKMP_NTYPE_LOAD_BALANCE, raddr);
-                                       plog(LLV_DEBUG, LOCATION, iph1->remote, "sent redirect notification - address = %x.\n", ntohl(addr->redirect_address));
-                                       vfree(raddr);
-                                       if (addr->force)
-                                               isakmp_ph1delete(iph1);
+                       LIST_FOREACH(addr, &lcconf->redirect_addresses, chain) {
+                               if (((struct sockaddr_in *)iph1->local)->sin_addr.s_addr == addr->cluster_address) {
+                                       vchar_t *raddr = vmalloc(sizeof(u_int32_t));
+                               
+                                       if (raddr == NULL) {
+                                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                                       "failed to send redirect message - memory error.\n");
+                                       } else {
+                                               memcpy(raddr->v, &addr->redirect_address, sizeof(u_int32_t));
+                                               (void)isakmp_info_send_n1(iph1, ISAKMP_NTYPE_LOAD_BALANCE, raddr);
+                                               plog(LLV_DEBUG, LOCATION, iph1->remote, "sent redirect notification - address = %x.\n", ntohl(addr->redirect_address));
+                                               vfree(raddr);
+                                               if (addr->force) {
+                                                       (void)ike_session_update_ph1_ph2tree(iph1);
+                                                       isakmp_ph1delete(iph1);
+                                               }
+                                       }
                                }
+                               return 0;
                        }
-                       return 0;
                }
-       }
 #endif 
                /* save created date. */
                (void)time(&iph1->created);
 
                /* add to the schedule to expire, and save back pointer. */
                iph1->sce = sched_new(iph1->approval->lifetime,
-                   isakmp_ph1expire_stub, iph1);
+                                                         isakmp_ph1expire_stub, iph1);
+
+               if (iph1->rmconf->initiate_ph1rekey) {
+                       if (iph1->side == INITIATOR) {
+                               spi_cmp = memcmp(&iph1->index.i_ck, &iph1->index.r_ck, sizeof(iph1->index.i_ck));
+                               if (spi_cmp == 0)
+                                       spi_cmp = 1;
+                       } else {
+                               spi_cmp = memcmp(&iph1->index.r_ck, &iph1->index.i_ck, sizeof(iph1->index.r_ck));
+                               if (spi_cmp == 0)
+                                       spi_cmp = -1;
+                       }
+                       rekey_lifetime = ike_session_get_rekey_lifetime((spi_cmp > 0),
+                                                                                                                       iph1->approval->lifetime);
+                       if (rekey_lifetime) {
+                               iph1->sce_rekey = sched_new(rekey_lifetime,
+                                                                                       isakmp_ph1rekeyexpire_stub,
+                                                                                       iph1);
+                       } else {
+                               /* iph1->approval->lifetime is too small (e.g. 1) so why bother?
+                                * LOG ERROR
+                                */
+                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                        "failed to get rekey timer - lifetime is too small... probably.\n");
+                       }
+               }
+
 #ifdef ENABLE_HYBRID
-               if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
-                       switch(iph1->approval->authmethod) {
-                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
-                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+               /* ignore xauth if it is a rekey */
+               if (!iph1->is_rekey &&
+                       iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
+                       switch(AUTHMETHOD(iph1)) {
+                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
                                xauth_sendreq(iph1);
                                /* XXX Don't process INITIAL_CONTACT */
-                               iph1->rmconf->ini_contact = 0;
+                               ini_contact = 0;
                                break;
                        default:
                                break;
@@ -874,9 +1015,9 @@ ph1_main(iph1, msg)
 #endif
 
                /* INITIAL-CONTACT processing */
+               /* ignore initial-contact if it is a rekey */
                /* don't send anything if local test mode. */
-               if (!f_local
-                && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
+               if (!iph1->is_rekey && !f_local && ini_contact && !getcontacted(iph1->remote)) {
                        /* send INITIAL-CONTACT */
                        isakmp_info_send_n1(iph1,
                                        ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
@@ -891,19 +1032,37 @@ ph1_main(iph1, msg)
                log_ph1established(iph1);
                plog(LLV_DEBUG, LOCATION, NULL, "===\n");
                
-#ifdef ENABLE_VPNCONTROL_PORT
-               vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
-#endif
-
-
                /* 
-                * SA up shell script hook: do it now,except if
-                * ISAKMP mode config was requested. In the later
+                * SA up shell script hook: do it now for rekeys, otherwise only
+                * if ISAKMP mode config wasn't requested. In the later
                 * case it is done when we receive the configuration.
                 */
                if ((iph1->status == PHASE1ST_ESTABLISHED) &&
-                   !iph1->rmconf->mode_cfg)
-                       script_hook(iph1, SCRIPT_PHASE1_UP);    
+                   (iph1->is_rekey || !iph1->rmconf->mode_cfg)) { 
+                       switch (AUTHMETHOD(iph1)) {
+#ifdef ENABLE_HYBRID
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+                       /* Unimplemeted... */
+                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+                               break;
+#endif
+                       default:
+                               script_hook(iph1, SCRIPT_PHASE1_UP);
+                               break;
+                       }
+               }
+
+               ike_session_cleanup_other_established_ph1s(iph1->parent_session, iph1);
+
+#ifdef ENABLE_VPNCONTROL_PORT
+               vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
+#endif
+
        }
 
        return 0;
@@ -965,8 +1124,7 @@ quick_main(iph2, msg)
        VPTRINIT(iph2->sendbuf);
 
        /* turn off schedule */
-       if (iph2->scr)
-               SCHED_KILL(iph2->scr);
+       SCHED_KILL(iph2->scr);
                
        /* when using commit bit, status will be reached here. */
        if (iph2->status == PHASE2ST_ADDSA)             //%%% BUG FIX - moved to here
@@ -995,9 +1153,10 @@ quick_main(iph2, msg)
 
 /* new negotiation of phase 1 for initiator */
 int
-isakmp_ph1begin_i(rmconf, remote, local)
+isakmp_ph1begin_i(rmconf, remote, local, started_by_api)
        struct remoteconf *rmconf;
        struct sockaddr *remote, *local;
+       int started_by_api;
 {
        struct ph1handle *iph1;
 #ifdef ENABLE_STATS
@@ -1011,7 +1170,19 @@ isakmp_ph1begin_i(rmconf, remote, local)
 
        iph1->status = PHASE1ST_START;
        iph1->rmconf = rmconf;
+#ifdef __APPLE__
+       if (link_rmconf_to_ph1(rmconf) < 0) {
+               plog(LLV_ERROR, LOCATION, remote,
+                        "couldn't link "
+                        "configuration.\n");
+               iph1->rmconf = NULL;
+               /* don't call remph1(iph1) until after insph1(iph1) is called */
+               delph1(iph1);
+               return -1;
+       }
+#endif
        iph1->side = INITIATOR;
+       iph1->started_by_api = started_by_api;
        iph1->version = ISAKMP_VERSION_NUMBER;
        iph1->msgid = 0;
        iph1->flags = 0;
@@ -1020,21 +1191,38 @@ isakmp_ph1begin_i(rmconf, remote, local)
        iph1->gssapi_state = NULL;
 #endif
 #ifdef ENABLE_HYBRID
-       if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL)
+       if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
+               /* don't call remph1(iph1) until after insph1(iph1) is called */
+               delph1(iph1);
                return -1;
+       }
 #endif
 #ifdef ENABLE_FRAG
-       iph1->frag = 0;
+
+       if(rmconf->ike_frag == ISAKMP_FRAG_FORCE)
+               iph1->frag = 1;
+       else
+               iph1->frag = 0;
        iph1->frag_chain = NULL;
 #endif
        iph1->approval = NULL;
 
        /* XXX copy remote address */
-       if (copy_ph1addresses(iph1, rmconf, remote, local) < 0)
+       if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
+               /* don't call remph1(iph1) until after insph1(iph1) is called */
+               delph1(iph1);
                return -1;
+       }
 
        (void)insph1(iph1);
 
+       if (ike_session_link_ph1_to_session(iph1) != 0) {
+               plog(LLV_DEBUG, LOCATION, NULL, "Failed to link ph1 to session\n");
+               remph1(iph1);
+               delph1(iph1);
+               return -1;
+       }
+
        /* start phase 1 exchange */
        iph1->etype = rmconf->etypes->type;
 
@@ -1042,7 +1230,9 @@ isakmp_ph1begin_i(rmconf, remote, local)
     {
        char *a;
 
-       a = strdup(saddr2str(iph1->local));
+       a = racoon_strdup(saddr2str(iph1->local));
+       STRDUP_FATAL(a);
+
        plog(LLV_INFO, LOCATION, NULL,
                "initiate new phase 1 negotiation: %s<=>%s\n",
                a, saddr2str(iph1->remote));
@@ -1123,8 +1313,20 @@ isakmp_ph1begin_r(msg, remote, local, etype)
        memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck));
        iph1->status = PHASE1ST_START;
        iph1->rmconf = rmconf;
+#ifdef __APPLE__
+       if (link_rmconf_to_ph1(rmconf) < 0) {
+               plog(LLV_ERROR, LOCATION, remote,
+                        "couldn't link "
+                        "configuration.\n");
+               iph1->rmconf = NULL;
+               /* don't call remph1(iph1) until after insph1(iph1) is called */
+               delph1(iph1);
+               return -1;
+       }
+#endif
        iph1->flags = 0;
        iph1->side = RESPONDER;
+       iph1->started_by_api = 0;
        iph1->etype = etypeok->type;
        iph1->version = isakmp->v;
        iph1->msgid = 0;
@@ -1132,8 +1334,11 @@ isakmp_ph1begin_r(msg, remote, local, etype)
        iph1->gssapi_state = NULL;
 #endif
 #ifdef ENABLE_HYBRID
-       if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL)
+       if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
+               /* don't call remph1(iph1) until after insph1(iph1) is called */
+               delph1(iph1);
                return -1;
+       }
 #endif
 #ifdef ENABLE_FRAG
        iph1->frag = 0;
@@ -1151,16 +1356,26 @@ isakmp_ph1begin_r(msg, remote, local, etype)
 #endif
 
        /* copy remote address */
-       if (copy_ph1addresses(iph1, rmconf, remote, local) < 0)
+       if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
+               /* don't call remph1(iph1) until after insph1(iph1) is called */
+               delph1(iph1);
                return -1;
-
+       }
        (void)insph1(iph1);
 
+       if (ike_session_link_ph1_to_session(iph1) != 0) {
+               remph1(iph1);
+               delph1(iph1);
+               return -1;
+       }
+
        plog(LLV_DEBUG, LOCATION, NULL, "===\n");
     {
        char *a;
 
-       a = strdup(saddr2str(iph1->local));
+       a = racoon_strdup(saddr2str(iph1->local));
+       STRDUP_FATAL(a);
+
        plog(LLV_INFO, LOCATION, NULL,
                "respond new phase 1 negotiation: %s<=>%s\n",
                a, saddr2str(iph1->remote));
@@ -1173,6 +1388,9 @@ isakmp_ph1begin_r(msg, remote, local, etype)
        gettimeofday(&iph1->start, NULL);
        gettimeofday(&start, NULL);
 #endif
+
+#ifndef ENABLE_FRAG
+
        /* start exchange */
        if ((ph1exchange[etypesw1(iph1->etype)]
                        [iph1->side]
@@ -1186,6 +1404,7 @@ isakmp_ph1begin_r(msg, remote, local, etype)
                delph1(iph1);
                return -1;
        }
+
 #ifdef ENABLE_STATS
        gettimeofday(&end, NULL);
        syslog(LOG_NOTICE, "%s(%s): %8.6f",
@@ -1198,6 +1417,17 @@ isakmp_ph1begin_r(msg, remote, local, etype)
 #endif
 
        return 0;
+
+#else /* ENABLE_FRAG */
+
+       /* now that we have a phase1 handle, feed back into our
+        * main receive function to catch fragmented packets
+        */
+
+       return isakmp_main(msg, remote, local);
+
+#endif /* ENABLE_FRAG */
+
 }
 
 /* new negotiation of phase 2 for initiator */
@@ -1219,7 +1449,9 @@ isakmp_ph2begin_i(iph1, iph2)
        plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
     {
        char *a;
-       a = strdup(saddr2str(iph2->src));
+       a = racoon_strdup(saddr2str(iph2->src));
+       STRDUP_FATAL(a);
+
        plog(LLV_INFO, LOCATION, NULL,
                "initiate new phase 2 negotiation: %s<=>%s\n",
                a, saddr2str(iph2->dst));
@@ -1230,15 +1462,21 @@ isakmp_ph2begin_i(iph1, iph2)
        gettimeofday(&iph2->start, NULL);
 #endif
        /* found isakmp-sa */
-       bindph12(iph1, iph2);
+       if (iph2->ph1 && iph1 != iph2->ph1) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "phase2 already bound in %s.\n",__FUNCTION__);
+               rebindph12(iph1, iph2);
+       } else if (!iph2->ph1) {
+               bindph12(iph1, iph2);
+       }
+       iph2->is_dying = 0;
+       if (ike_session_link_ph2_to_session(iph2) != 0) {
+               return -1;
+       }
        iph2->status = PHASE2ST_STATUS2;
 
        if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
                         [iph2->side]
                         [iph2->status])(iph2, NULL) < 0) {
-               unbindph12(iph2);
-               /* release ipsecsa handler due to internal error. */
-               remph2(iph2);
                return -1;
        }
        
@@ -1340,12 +1578,21 @@ isakmp_ph2begin_r(iph1, msg)
        /* add new entry to isakmp status table */
        insph2(iph2);
        bindph12(iph1, iph2);
-
+       iph2->is_dying = 0;
+       if (ike_session_link_ph2_to_session(iph2) != 0) {
+               unbindph12(iph2);
+               remph2(iph2);
+               delph2(iph2);
+               return -1;
+       }
+       
        plog(LLV_DEBUG, LOCATION, NULL, "===\n");
     {
        char *a;
 
-       a = strdup(saddr2str(iph2->src));
+       a = racoon_strdup(saddr2str(iph2->src));
+       STRDUP_FATAL(a);
+
        plog(LLV_INFO, LOCATION, NULL,
                "respond new phase 2 negotiation: %s<=>%s\n",
                a, saddr2str(iph2->dst));
@@ -1507,6 +1754,7 @@ isakmp_parse(buf)
 }
 
 /* %%% */
+#ifndef __APPLE__
 int
 isakmp_init()
 {
@@ -1515,6 +1763,7 @@ isakmp_init()
        initph2tree();
        initctdtree();
        init_recvdpkt();
+       ike_session_init();
 
        if (isakmp_open() < 0)
                goto err;
@@ -1525,6 +1774,28 @@ err:
        isakmp_close();
        return(-1);
 }
+#else
+int
+isakmp_init(int ignore_phX)
+{
+       /* initialize a isakmp status table */
+       if (!ignore_phX) {
+               initph1tree();
+               initph2tree();
+       }
+       initctdtree();
+       init_recvdpkt();
+
+       if (isakmp_open() < 0)
+               goto err;
+
+       return(0);
+
+err:
+       isakmp_close();
+       return(-1);
+}
+#endif /* __APPLE__ */
 
 void
 isakmp_cleanup()
@@ -1634,6 +1905,10 @@ isakmp_open()
                        goto err_and_next;
                }
 
+               if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1)
+                       plog(LLV_WARNING, LOCATION, NULL,
+                               "failed to put socket in non-blocking mode\n");
+
                /* receive my interface address on inbound packets. */
                switch (p->addr->sa_family) {
                case AF_INET:
@@ -1645,7 +1920,8 @@ isakmp_open()
 #endif
                                        (const void *)&yes, sizeof(yes)) < 0) {
                                plog(LLV_ERROR, LOCATION, NULL,
-                                       "setsockopt (%s)\n", strerror(errno));
+                                       "setsockopt IP_RECVDSTADDR (%s)\n", 
+                                       strerror(errno));
                                goto err_and_next;
                        }
                        break;
@@ -1664,12 +1940,8 @@ isakmp_open()
                                        (const void *)&yes, sizeof(yes)) < 0)
                        {
                                plog(LLV_ERROR, LOCATION, NULL,
-                                       "setsockopt(%d): %s\n",
+                                       "setsockopt IPV6_RECVDSTADDR (%d):%s\n",
                                        pktinfo, strerror(errno));
-               if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1)
-                       plog(LLV_WARNING, LOCATION, NULL,
-                               "failed to put socket in non-blocking mode\n");
-
                                goto err_and_next;
                        }
                        break;
@@ -1681,7 +1953,8 @@ isakmp_open()
                    setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
                    (void *)&yes, sizeof(yes)) < 0) {
                        plog(LLV_ERROR, LOCATION, NULL,
-                           "setsockopt (%s)\n", strerror(errno));
+                           "setsockopt IPV6_USE_MIN_MTU (%s)\n", 
+                           strerror(errno));
                        return -1;
                }
 #endif
@@ -1705,7 +1978,6 @@ isakmp_open()
                                "failed to bind to address %s (%s).\n",
                                saddr2str(p->addr), strerror(errno));
                        close(p->sock);
-                       p->sock = -1;
                        goto err_and_next;
                }
                
@@ -1731,11 +2003,11 @@ isakmp_open()
                                option = UDP_ENCAP_ESPINUDP_NON_IKE;
 #endif
                        if(option != -1){
-                               if (setsockopt (p->sock, SOL_UDP, UDP_ENCAP,
-                                                               &option, sizeof (option)) < 0) {
+                               if (setsockopt (p->sock, SOL_UDP, 
+                                   UDP_ENCAP, &option, sizeof (option)) < 0) {
                                        plog(LLV_WARNING, LOCATION, NULL,
-                                                "setsockopt(%s): %s\n",
-                                                option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE",
+                                           "setsockopt(%s): UDP_ENCAP %s\n",
+                                           option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE",
                                                 strerror(errno));
                                        goto skip_encap;
                                }
@@ -1817,11 +2089,9 @@ isakmp_close_unused()
                if (p->in_use == 0) {   // not in use ?
        
                        if (p->sock >= 0)
-                               close(p->sock);                 
-                       if (p->addr)
-                               racoon_free(p->addr);
+                               close(p->sock);
                        *prev = p->next;
-                       racoon_free(p);
+                       delmyaddr(p);
                } else
                        prev = &(p->next);
        }
@@ -1855,7 +2125,11 @@ isakmp_send(iph1, sbuf)
           must added just before the packet itself. For this we must 
           allocate a new buffer and release it at the end. */
        if (extralen) {
-               vbuf = vmalloc (sbuf->l + extralen);
+               if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                           "vbuf allocation failed\n");
+                       return -1;
+               }
                *(u_int32_t *)vbuf->v = 0;
                memcpy (vbuf->v + extralen, sbuf->v, sbuf->l);
                sbuf = vbuf;
@@ -1906,34 +2180,70 @@ void
 isakmp_ph1resend_stub(p)
        void *p;
 {
-       (void)isakmp_ph1resend((struct ph1handle *)p);
+       struct ph1handle *iph1;
+
+       iph1=(struct ph1handle *)p;
+       if(isakmp_ph1resend(iph1) < 0){
+               if(iph1->scr != NULL){
+                       /* Should not happen...
+                        */
+                       sched_kill(iph1->scr);
+                       iph1->scr=NULL;
+               }
+
+               remph1(iph1);
+               delph1(iph1);
+       }
 }
 
 int
 isakmp_ph1resend(iph1)
        struct ph1handle *iph1;
 {
-       if (iph1->retry_counter < 0) {
+       /* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function
+        */
+       if (iph1->retry_counter <= 0) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT,
+                                                               CONSTSTR("Phase1 Maximum Retransmits"),
+                                                               CONSTSTR("Phase1 negotiation failed (Maximum retransmits)"));
+
                plog(LLV_ERROR, LOCATION, NULL,
                        "phase1 negotiation failed due to time up. %s\n",
                        isakmp_pindex(&iph1->index, iph1->msgid));
                EVT_PUSH(iph1->local, iph1->remote, 
                    EVTT_PEER_NO_RESPONSE, NULL);
-
-               remph1(iph1);
-               delph1(iph1);
+               if (iph1->side == INITIATOR && iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client) {
+                       /* to get around a bug on the peer, in which rekeys to port 4500 are dropped */
+                       if (isakmp_ph1rekeyretry(iph1) == 0)
+                               return 0;
+               }
                return -1;
        }
 
        if (isakmp_send(iph1, iph1->sendbuf) < 0){
-               iph1->retry_counter--;
-
-               iph1->scr = sched_new(iph1->rmconf->retry_interval,
-                                                         isakmp_ph1resend_stub, iph1);
+               if (iph1->rmconf->retry_counter != iph1->retry_counter) {
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                                       CONSTSTR("Phase1 Retransmit"),
+                                                                       CONSTSTR("Failed to retrasmit Phase1"));
+               }
+               plog(LLV_ERROR, LOCATION, iph1->remote,
+                        "phase1 negotiation failed due to send error. %s\n",
+                        isakmp_pindex(&iph1->index, iph1->msgid));
+               EVT_PUSH(iph1->local, iph1->remote, 
+                                EVTT_PEER_NO_RESPONSE, NULL);
                return -1;
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL,
+       if (iph1->rmconf->retry_counter != iph1->retry_counter) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                               CONSTSTR("Phase1 Retransmit"),
+                                                               CONSTSTR(NULL));
+       }
+
+       plog(LLV_DEBUG, LOCATION, iph1->remote,
                "resend phase1 packet %s\n",
                isakmp_pindex(&iph1->index, iph1->msgid));
 
@@ -1950,37 +2260,73 @@ void
 isakmp_ph2resend_stub(p)
        void *p;
 {
+       struct ph2handle *iph2;
+
+       iph2=(struct ph2handle *)p;
 
-       (void)isakmp_ph2resend((struct ph2handle *)p);
+       if(isakmp_ph2resend(iph2) < 0){
+               unbindph12(iph2);
+               remph2(iph2);
+               delph2(iph2);
+       }
 }
 
 int
 isakmp_ph2resend(iph2)
        struct ph2handle *iph2;
 {
-       if (iph2->retry_counter < 0) {
+       /* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function
+        */
+       //%%% BUG FIX - related to commit bit usage - crash happened here
+       if (iph2->ph1 == 0) {
                plog(LLV_ERROR, LOCATION, NULL,
+                       "internal error - attempt to re-send phase2 with no phase1 bound.\n");
+               return -1;
+       }
+
+       if (iph2->ph1->status == PHASE1ST_EXPIRED){
+               IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT,
+                                                               CONSTSTR("Underlying Phase1 expired"),
+                                                               CONSTSTR("Failed to retransmit phase2 (underlying phase1 expired)"));
+               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+                       "phase2 negotiation failed due to phase1 expired. %s\n",
+                               isakmp_pindex(&iph2->ph1->index, iph2->msgid));
+               return -1;
+       }
+
+       if (iph2->retry_counter <= 0) {
+               IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT,
+                                                               CONSTSTR("Phase2 maximum retransmits"),
+                                                               CONSTSTR("Phase2 negotiation failed (maximum retransmits)"));
+               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
                        "phase2 negotiation failed due to time up. %s\n",
                                isakmp_pindex(&iph2->ph1->index, iph2->msgid));
                EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
-               unbindph12(iph2);
-               remph2(iph2);
-               delph2(iph2);
                return -1;
        }
 
-       //%%% BUG FIX - related to commit bit usage - crash happened here
-       if (iph2->ph1 == 0) {
+       if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){
+               if (iph2->ph1->rmconf->retry_counter != iph2->retry_counter) {
+                       IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                                       CONSTSTR("Phase2 Retransmit"),
+                                                                       CONSTSTR("Failed to retransmit Phase2 message"));
+               }
                plog(LLV_ERROR, LOCATION, NULL,
-                       "internal error - attempt to re-send phase2 with no phase1 bound.\n");
-               iph2->retry_counter = -1;
-               remph2(iph2);
-               delph2(iph2);
-               return -1;
-       }
+                       "phase2 negotiation failed due to send error. %s\n",
+                               isakmp_pindex(&iph2->ph1->index, iph2->msgid));
+               EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
 
-       if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
                return -1;
+       }
+       if (iph2->ph1->rmconf->retry_counter != iph2->retry_counter) {
+               IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                               CONSTSTR("Phase2 Retransmit"),
+                                                               CONSTSTR(NULL));
+       }
 
        plog(LLV_DEBUG, LOCATION, NULL,
                "resend phase2 packet %s\n",
@@ -1991,6 +2337,13 @@ isakmp_ph2resend(iph2)
        iph2->scr = sched_new(iph2->ph1->rmconf->retry_interval,
                isakmp_ph2resend_stub, iph2);
 
+#ifdef ENABLE_DPD
+    if (iph2->scr) {
+        isakmp_reschedule_info_monitor_if_pending(iph2->ph1,
+                                                  "phase2 packets sent to peer: retransmit timer armed");
+    }
+#endif /* DPD */
+    
        return 0;
 }
 
@@ -2010,10 +2363,16 @@ isakmp_ph1expire(iph1)
        char *src, *dst;
 
        SCHED_KILL(iph1->sce);
+#ifdef ENABLE_DPD
+    SCHED_KILL(iph1->dpd_r_u);
+#endif
 
        if(iph1->status != PHASE1ST_EXPIRED){
-               src = strdup(saddr2str(iph1->local));
-               dst = strdup(saddr2str(iph1->remote));
+               src = racoon_strdup(saddr2str(iph1->local));
+               dst = racoon_strdup(saddr2str(iph1->remote));
+               STRDUP_FATAL(src);
+               STRDUP_FATAL(dst);
+
                plog(LLV_INFO, LOCATION, NULL,
                         "ISAKMP-SA expired %s-%s spi:%s\n",
                         src, dst,
@@ -2021,6 +2380,7 @@ isakmp_ph1expire(iph1)
                racoon_free(src);
                racoon_free(dst);
                iph1->status = PHASE1ST_EXPIRED;
+               (void)ike_session_update_ph1_ph2tree(iph1);
        }
 
        /*
@@ -2034,6 +2394,143 @@ isakmp_ph1expire(iph1)
        iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
 }
 
+/* called from scheduler */
+void
+isakmp_ph1rekeyexpire_stub(p)
+void *p;
+{
+       
+       isakmp_ph1rekeyexpire((struct ph1handle *)p);
+}
+
+void
+isakmp_ph1rekeyexpire(iph1)
+struct ph1handle *iph1;
+{
+       char              *src, *dst;
+       struct remoteconf *rmconf;
+
+       SCHED_KILL(iph1->sce_rekey);
+
+       // early exit if iph2->sce == NULL, iph2 isn't established or if entire session is going down
+       if (iph1->sce == NULL ||
+               iph1->status != PHASE1ST_ESTABLISHED ||
+               iph1->is_dying) {
+               return;
+       }
+
+       src = racoon_strdup(saddr2str(iph1->local));
+       dst = racoon_strdup(saddr2str(iph1->remote));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
+
+       plog(LLV_INFO, LOCATION, NULL,
+                "ISAKMP-SA rekey-timer expired %s-%s spi:%s\n",
+                src, dst,
+                isakmp_pindex(&iph1->index, 0));
+       racoon_free(src);
+       racoon_free(dst);
+
+       // exit if there is another ph1 that is established (with a pending rekey timer)
+       if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) {
+               plog(LLV_INFO, LOCATION, iph1->remote,
+                        "request for ISAKMP-SA rekey was ignored "
+                        "due to another established ph1.\n");
+               return;
+       }
+
+       // if there is another ph1 that is negotiating, postpone this rekey for a few seconds later
+       if (ike_session_has_other_negoing_ph1(iph1->parent_session, iph1)) {
+               plog(LLV_DEBUG, LOCATION, NULL, "reschedule Phase1 rekey.\n");
+               iph1->sce_rekey = sched_new(1,
+                                                                       isakmp_ph1rekeyexpire_stub,
+                                                                       iph1);
+               return;
+       }
+
+       // get rmconf to initiate rekey with
+       rmconf = iph1->rmconf;
+       if (!rmconf || rmconf->to_delete || rmconf->to_remove) {
+               rmconf = getrmconf(iph1->remote);
+       }
+       if (rmconf) {
+               /* begin quick mode */
+               plog(LLV_DEBUG, LOCATION, NULL, "begin Phase1 rekey.\n");
+
+               /* start phase 1 negotiation as a initiator. */
+               if (isakmp_ph1begin_i(rmconf, iph1->remote, iph1->local, 0) < 0) {
+                       plog(LLV_DEBUG, LOCATION, NULL, "Phase1 rekey Failed.\n");
+               }
+       } else {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "Phase1 rekey failed: no configuration found for %s.\n",
+                        saddrwop2str(iph1->remote));
+       }
+}
+
+int
+isakmp_ph1rekeyretry(iph1)
+struct ph1handle *iph1;
+{
+       char              *src, *dst;
+       struct remoteconf *rmconf;
+
+       // this code path is meant for floated ph1 rekeys that are failing on the first message
+       if (iph1->sce != NULL ||
+               iph1->sce_rekey != NULL ||
+               (iph1->status != PHASE1ST_MSG1SENT || (iph1->natt_flags & NAT_PORTS_CHANGED == 0)) ||
+               (extract_port(iph1->local) != PORT_ISAKMP_NATT && extract_port(iph1->remote) != PORT_ISAKMP_NATT) ||
+               iph1->is_dying) {
+               return -1;
+       }
+
+       src = racoon_strdup(saddr2str(iph1->local));
+       dst = racoon_strdup(saddr2str(iph1->remote));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
+
+       plog(LLV_INFO, LOCATION, NULL,
+                "ISAKMP-SA rekey failed... retrying %s-%s spi:%s\n",
+                src, dst,
+                isakmp_pindex(&iph1->index, 0));
+       racoon_free(src);
+       racoon_free(dst);
+
+       // exit if there is another ph1 that is established (with a pending rekey timer)
+       if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) {
+               plog(LLV_INFO, LOCATION, iph1->remote,
+                        "request to retry ISAKMP-SA rekey was ignored "
+                        "due to another established ph1.\n");
+               return -1;
+       }
+
+       // some servers don't like respond to 4500 for rekeys... try accomodate them
+       if (extract_port(iph1->local) == PORT_ISAKMP_NATT) {
+               set_port(iph1->local, PORT_ISAKMP);
+       }
+       if (extract_port(iph1->remote) == PORT_ISAKMP_NATT) {
+               set_port(iph1->remote, PORT_ISAKMP);
+       }
+       iph1->natt_flags &= ~NAT_PORTS_CHANGED;
+       rmconf = getrmconf(iph1->remote);
+       if (rmconf) {
+               /* begin quick mode */
+               plog(LLV_DEBUG, LOCATION, NULL, "begin Phase1 rekey retry.\n");
+
+               /* start phase 1 negotiation as a initiator. */
+               if (isakmp_ph1begin_i(rmconf, iph1->remote, iph1->local, 0) < 0) {
+                       plog(LLV_DEBUG, LOCATION, NULL, "Phase1 rekey retry Failed.\n");
+                       return -1;
+               }
+       } else {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "Phase1 rekey retry failed: no configuration found for %s.\n",
+                        saddrwop2str(iph1->remote));
+               return -1;
+       }
+       return 0;
+}
+
 /* called from scheduler */
 void
 isakmp_ph1delete_stub(p)
@@ -2049,18 +2546,26 @@ isakmp_ph1delete(iph1)
 {
        char *src, *dst;
 
-       if (iph1->sce)
-               SCHED_KILL(iph1->sce);
+       SCHED_KILL(iph1->sce);
+       SCHED_KILL(iph1->sce_rekey);
+#ifdef ENABLE_DPD
+    SCHED_KILL(iph1->dpd_r_u);
+#endif    
 
        if (LIST_FIRST(&iph1->ph2tree) != NULL) {
                iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
                return;
        }
 
+    isakmp_info_send_d1(iph1);
+
        /* don't re-negosiation when the phase 1 SA expires. */
 
-       src = strdup(saddr2str(iph1->local));
-       dst = strdup(saddr2str(iph1->remote));
+       src = racoon_strdup(saddr2str(iph1->local));
+       dst = racoon_strdup(saddr2str(iph1->remote));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
+
        plog(LLV_INFO, LOCATION, NULL,
                "ISAKMP-SA deleted %s-%s spi:%s\n",
                src, dst, isakmp_pindex(&iph1->index, 0));
@@ -2096,13 +2601,30 @@ isakmp_ph2expire(iph2)
 
        SCHED_KILL(iph2->sce);
 
-       src = strdup(saddrwop2str(iph2->src));
-       dst = strdup(saddrwop2str(iph2->dst));
+       src = racoon_strdup(saddrwop2str(iph2->src));
+       dst = racoon_strdup(saddrwop2str(iph2->dst));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
+
        plog(LLV_INFO, LOCATION, NULL,
                "phase2 sa expired %s-%s\n", src, dst);
        racoon_free(src);
        racoon_free(dst);
 
+       // delete outgoing SAs
+       if (iph2->status == PHASE2ST_ESTABLISHED && iph2->approval) {
+               struct saproto *pr;
+
+               for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
+                       if (pr->ok) {
+                               pfkey_send_delete(lcconf->sock_pfkey,
+                                  ipsecdoi2pfkey_proto(pr->proto_id),
+                                  IPSEC_MODE_ANY,
+                                  iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */);
+                       }
+               }
+       }
+
        iph2->status = PHASE2ST_EXPIRED;
 
        iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2);
@@ -2127,8 +2649,11 @@ isakmp_ph2delete(iph2)
 
        SCHED_KILL(iph2->sce);
 
-       src = strdup(saddrwop2str(iph2->src));
-       dst = strdup(saddrwop2str(iph2->dst));
+       src = racoon_strdup(saddrwop2str(iph2->src));
+       dst = racoon_strdup(saddrwop2str(iph2->dst));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
+
        plog(LLV_INFO, LOCATION, NULL,
                "phase2 sa deleted %s-%s\n", src, dst);
        racoon_free(src);
@@ -2154,6 +2679,8 @@ isakmp_post_acquire(iph2)
 {
        struct remoteconf *rmconf;
        struct ph1handle *iph1 = NULL;
+       
+       plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n");
 
        /* search appropreate configuration with masking port. */
        rmconf = getrmconf(iph2->dst);
@@ -2173,23 +2700,29 @@ isakmp_post_acquire(iph2)
                return 0;
        }
 
-       /* 
-        * Search isakmp status table by address and port 
-        * If NAT-T is in use, consider null ports as a 
-        * wildcard and use IKE ports instead.
-        */
-#ifdef ENABLE_NATT
-       if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
-               if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) {
-                       set_port(iph2->src, extract_port(iph1->local));
-                       set_port(iph2->dst, extract_port(iph1->remote));
-               }
-       } else {
-               iph1 = getph1byaddr(iph2->src, iph2->dst);
+       if (ike_session_verify_ph2_parent_session(iph2)) {
+               plog(LLV_INFO, LOCATION, iph2->dst,
+                        "request for establishing IPsec-SA was ignored "
+                        "because there was a failure verifying parent session.\n");
+               return -1;
        }
-#else
-       iph1 = getph1byaddr(iph2->src, iph2->dst);
-#endif
+
+       // what if there is another ph2 that is negotiating
+       if (ike_session_has_other_negoing_ph2(iph2->parent_session, iph2)) {
+               // TODO: postpone this rekey for a second later
+               plog(LLV_INFO, LOCATION, iph2->dst,
+                        "request for establishing IPsec-SA was ignored "
+                        "due to another negoing ph2.\n");
+               return -1;
+       }
+
+    // if this is a phase2 rekeys (the policy may not have the current port number).
+    // so, use the appropriate ports.
+    if (iph2->is_rekey) {
+        ike_session_update_ph2_ports(iph2);
+    }
+
+       iph1 = ike_session_update_ph2_ph1bind(iph2);
 
        /* no ISAKMP-SA found. */
        if (iph1 == NULL) {
@@ -2203,7 +2736,7 @@ isakmp_post_acquire(iph2)
                        saddrwop2str(iph2->dst));
 
                /* start phase 1 negotiation as a initiator. */
-               if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) < 0) {
+               if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src, 0) < 0) {
                        SCHED_KILL(sc);
                        return -1;
                }
@@ -2288,12 +2821,21 @@ isakmp_chkph1there(iph2)
        struct ph1handle *iph1;
 
        iph2->retry_checkph1--;
-       if (iph2->retry_checkph1 < 0) {
-               plog(LLV_ERROR, LOCATION, iph2->dst,
-                       "phase2 negotiation failed "
-                       "due to time up waiting for phase1. %s\n",
-                       sadbsecas2str(iph2->dst, iph2->src,
-                               iph2->satype, 0, 0));
+       if (iph2->retry_checkph1 < 0 ||
+               ike_session_verify_ph2_parent_session(iph2)) {
+               if (iph2->retry_checkph1 < 0) {
+                       plog(LLV_ERROR, LOCATION, iph2->dst,
+                                "phase2 negotiation failed "
+                                "due to time up waiting for phase1. %s\n",
+                                sadbsecas2str(iph2->dst, iph2->src,
+                                                          iph2->satype, 0, 0));
+               } else {
+                       plog(LLV_ERROR, LOCATION, iph2->dst,
+                                "phase2 negotiation failed "
+                                "due to invalid parent session. %s\n",
+                                sadbsecas2str(iph2->dst, iph2->src,
+                                                          iph2->satype, 0, 0));
+               }
                plog(LLV_INFO, LOCATION, NULL,
                        "delete phase 2 handler.\n");
 
@@ -2307,39 +2849,44 @@ isakmp_chkph1there(iph2)
                return;
        }
 
-       /* 
-        * Search isakmp status table by address and port 
-        * If NAT-T is in use, consider null ports as a 
-        * wildcard and use IKE ports instead.
-        */
-#ifdef ENABLE_NATT
-       if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
-               if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) {
-                       /*
-                        *      cannot set ph2 ports until after switch to natt port
-                        *      otherwise this function will never again find phase 1
-                        */
-                       if (iph1->status == PHASE1ST_ESTABLISHED) {
-                               set_port(iph2->src, extract_port(iph1->local));
-                               set_port(iph2->dst, extract_port(iph1->remote));
-                       }
-               }
-       } else {
-               iph1 = getph1byaddr(iph2->src, iph2->dst);
-       }
-#else
-       iph1 = getph1byaddr(iph2->src, iph2->dst);
-#endif
+       iph1 = ike_session_update_ph2_ph1bind(iph2);
 
        /* XXX Even if ph1 as responder is there, should we not start
         * phase 2 negotiation ? */
        if (iph1 != NULL
         && iph1->status == PHASE1ST_ESTABLISHED) {
                /* found isakmp-sa */
+
+               plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n");
+               plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str(iph1->local));
+               plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str(iph1->remote));
+               plog(LLV_DEBUG2, LOCATION, NULL, "before:\n");
+               plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src));
+               plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst));
+               set_port(iph2->src, extract_port(iph1->local));
+               set_port(iph2->dst, extract_port(iph1->remote));
+               plog(LLV_DEBUG2, LOCATION, NULL, "After:\n");
+               plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src));
+               plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst));
+
                /* begin quick mode */
-               (void)isakmp_ph2begin_i(iph1, iph2);
+               if (isakmp_ph2begin_i(iph1, iph2)) {
+                       unbindph12(iph2);
+                       remph2(iph2);
+                       delph2(iph2);
+               }
                return;
        }
+       if (!ike_session_has_negoing_ph1(iph2->parent_session)) {
+               struct remoteconf *rmconf = getrmconf(iph2->dst);
+               /* start phase 1 negotiation as a initiator. */
+               if (rmconf == NULL ||
+                   isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src, 0) < 0) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established/negoing ph1 handler found... failed to initiate new one\n");
+               }
+       }
+
+       plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n");
 
        /* no isakmp-sa found */
        sched_new(1, isakmp_chkph1there_stub, iph2);
@@ -2907,7 +3454,7 @@ copy_ph1addresses(iph1, rmconf, remote, local)
                port = &((struct sockaddr_in *)iph1->local)->sin_port;
                if (*port)
                        break;
-               *port = ((struct sockaddr_in *)local)->sin_port;
+               *port = ((struct sockaddr_in *)iph1->local)->sin_port;
                if (*port)
                        break;
                *port = getmyaddrsport(iph1->local);
@@ -2917,7 +3464,7 @@ copy_ph1addresses(iph1, rmconf, remote, local)
                port = &((struct sockaddr_in6 *)iph1->local)->sin6_port;
                if (*port)
                        break;
-               *port = ((struct sockaddr_in6 *)local)->sin6_port;
+               *port = ((struct sockaddr_in6 *)iph1->local)->sin6_port;
                if (*port)
                        break;
                *port = getmyaddrsport(iph1->local);
@@ -2965,13 +3512,19 @@ log_ph1established(iph1)
 {
        char *src, *dst;
 
-       src = strdup(saddr2str(iph1->local));
-       dst = strdup(saddr2str(iph1->remote));
+       src = racoon_strdup(saddr2str(iph1->local));
+       dst = racoon_strdup(saddr2str(iph1->remote));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
+
        plog(LLV_INFO, LOCATION, NULL,
                "ISAKMP-SA established %s-%s spi:%s\n",
                src, dst,
                isakmp_pindex(&iph1->index, 0));
        EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL);
+       if(!iph1->rmconf->mode_cfg)
+               EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL);
+
        racoon_free(src);
        racoon_free(dst);
 
@@ -3001,21 +3554,13 @@ isakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_t
 vchar_t * 
 isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
 {
-       struct payload_list *ptr, *first;
+       struct payload_list *ptr = *plist, *first;
        size_t tlen = sizeof (struct isakmp), n = 0;
-       vchar_t *buf;
+       vchar_t *buf = NULL;
        char *p;
 
-       if (plist == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL, 
-                   "in isakmp_plist_set_all: plist == NULL\n");
-               return NULL;
-       }
-
        /* Seek to the first item.  */
-       ptr = *plist;
-       while (ptr->prev)
-               ptr = ptr->prev;
+       while (ptr->prev) ptr = ptr->prev;
        first = ptr;
        
        /* Compute the whole length.  */
@@ -3051,6 +3596,8 @@ isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
 
        return buf;
 end:
+       if (buf != NULL)
+               vfree(buf);
        return NULL;
 }
 
@@ -3091,7 +3638,9 @@ script_hook(iph1, script)
        struct sockaddr_in *sin;
        char **c;
 
-       if (iph1->rmconf->script[script] == -1)
+       if (iph1 == NULL ||
+               iph1->rmconf == NULL ||
+               iph1->rmconf->script[script] == NULL)
                return;
 
 #ifdef ENABLE_HYBRID
@@ -3101,7 +3650,7 @@ script_hook(iph1, script)
        /* local address */
        sin = (struct sockaddr_in *)iph1->local;
        inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
-       snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
+       snprintf(portstr, sizeof(portstr), "%d", ntohs(sin->sin_port));
 
        if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) {
                plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n");
@@ -3114,21 +3663,27 @@ script_hook(iph1, script)
        }
 
        /* Peer address */
-       sin = (struct sockaddr_in *)iph1->remote;
-       inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
-       snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
+       if (iph1->remote != NULL) {
+               sin = (struct sockaddr_in *)iph1->remote;
+               inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
+               snprintf(portstr, sizeof(portstr), "%d", ntohs(sin->sin_port));
 
-       if (script_env_append(&envp, &envc, "REMOTE_ADDR", addrstr) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "Cannot set REMOTE_ADDR\n");
-               goto out;
-       }
+               if (script_env_append(&envp, &envc, 
+                   "REMOTE_ADDR", addrstr) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                           "Cannot set REMOTE_ADDR\n");
+                       goto out;
+               }
 
-       if (script_env_append(&envp, &envc, "REMOTE_PORT", portstr) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "Cannot set REMOTEL_PORT\n");
-               goto out;
+               if (script_env_append(&envp, &envc, 
+                   "REMOTE_PORT", portstr) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                           "Cannot set REMOTEL_PORT\n");
+                       goto out;
+               }
        }
 
-       if (privsep_script_exec(iph1->rmconf->script[script], 
+       if (privsep_script_exec(iph1->rmconf->script[script]->v
            script, envp) != 0) 
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Script %s execution failed\n", script_names[script]);
@@ -3152,21 +3707,23 @@ script_env_append(envp, envc, name, value)
        char *envitem;
        char **newenvp;
        int newenvc;
-       int envitemlen = strlen(name) + 1 + strlen(value) + 1;
+       int envitem_len;
 
-       envitem = racoon_malloc(envitemlen);
+       envitem_len = strlen(name) + 1 + strlen(value) + 1;
+       envitem = racoon_malloc(envitem_len);
        if (envitem == NULL) {
                plog(LLV_ERROR, LOCATION, NULL,
                    "Cannot allocate memory: %s\n", strerror(errno));
                return -1;
        }
-       snprintf(envitem, envitemlen, "%s=%s", name, value);
+       snprintf(envitem, envitem_len, "%s=%s", name, value);
 
        newenvc = (*envc) + 1;
        newenvp = racoon_realloc(*envp, newenvc * sizeof(char *));
        if (newenvp == NULL) {
                plog(LLV_ERROR, LOCATION, NULL,
                    "Cannot allocate memory: %s\n", strerror(errno));
+               racoon_free(envitem);
                return -1;
        }
 
@@ -3180,29 +3737,20 @@ script_env_append(envp, envc, name, value)
 
 int
 script_exec(script, name, envp)
-       int script;
+       char *script;
        int name;
        char *const envp[];
 {
        char *argv[] = { NULL, NULL, NULL };
-       vchar_t **sp;
-
-       if (script_paths == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "privsep_script_exec: script_paths was not initialized\n");
-               return -1;
-       }
 
-       sp = (vchar_t **)(script_paths->v);
-
-       argv[0] = sp[script]->v;
+       argv[0] = script;
        argv[1] = script_names[name];
        argv[2] = NULL;
 
        switch (fork()) { 
        case 0:
                execve(argv[0], argv, envp);
-               plog(LLV_ERROR2, LOCATION, NULL,
+               plog(LLV_ERROR, LOCATION, NULL,
                    "execve(\"%s\") failed: %s\n",
                    argv[0], strerror(errno));
                _exit(1);
@@ -3239,8 +3787,7 @@ purge_remote(iph1)
        /* Mark as expired. */
        iph1->status = PHASE1ST_EXPIRED;
 
-       /* Check if we have another, still valid, phase1 SA. */
-       new_iph1 = getph1byaddr(iph1->local, iph1->remote);
+       new_iph1 = ike_session_update_ph1_ph2tree(iph1);
 
        /*
         * Delete all orphaned or binded to the deleting ph1handle phase2 SAs.
@@ -3289,7 +3836,11 @@ purge_remote(iph1)
                        continue;
                }
 
-               /* check in/outbound SAs */
+               /*
+                * check in/outbound SAs.
+                * Select only SAs where src == local and dst == remote (outgoing)
+                * or src == remote and dst == local (incoming).
+                */
                if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) &&
                        (CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) {
                        msg = next;
@@ -3361,8 +3912,7 @@ purge_remote(iph1)
                 "purged ISAKMP-SA spi=%s.\n",
                 isakmp_pindex(&(iph1->index), iph1->msgid));
 
-       if (iph1->sce)
-               SCHED_KILL(iph1->sce);
+       SCHED_KILL(iph1->sce);
 
        iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
 }
index 06ee511719e91b07f1e07eaeca6a419bc91033c4..8a3936e6ee92a034d273a4ba3947edde68a60b52 100644 (file)
@@ -348,6 +348,8 @@ struct isakmp_pl_n {
 #define ISAKMP_NTYPE_CERTIFICATE_UNAVAILABLE   28
 #define ISAKMP_NTYPE_UNSUPPORTED_EXCHANGE_TYPE 29
 #define ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS   30
+#define ISAKMP_NTYPE_MINERROR                  1
+#define ISAKMP_NTYPE_MAXERROR                  16383
 /* NOTIFY MESSAGES - STATUS TYPES */
 #define ISAKMP_NTYPE_CONNECTED                 16384
 /* 4.6.3 IPSEC DOI Notify Message Types */
@@ -362,6 +364,7 @@ struct isakmp_pl_n {
 #define ISAKMP_NTYPE_LOAD_BALANCE              40501
 #define ISAKMP_NTYPE_HEARTBEAT                 40503
 
+
 /* using only to log */
 #define ISAKMP_LOG_RETRY_LIMIT_REACHED         65530
 
@@ -444,4 +447,15 @@ struct isakmp_pl_lb {
        u_int32_t address;      /* redirect address */
 } __attribute__((__packed__));
 
+/* Responder-Lifetime Notification */
+struct isakmp_pl_resp_lifetime {
+       struct isakmp_gen h;
+       u_int32_t doi;          /* Domain of Interpretation */
+       u_int8_t proto_id;      /* Protocol-Id */
+       u_int8_t spi_size;      /* SPI Size */
+       u_int16_t type;         /* Notify type */
+    /* spi follows next */
+    /* data follows next */
+} __attribute__((__packed__));
+
 #endif /* _ISAKMP_H */
index eea772629fa7a9981be5421cff4438aa13ed022e..7dddea3de5e4d679781b032ef3c3c849fdbd65c4 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_agg.c,v 1.20.2.5 2005/11/21 09:46:23 vanhu Exp $ */
+/*     $NetBSD: isakmp_agg.c,v 1.9 2006/09/30 21:49:37 manu Exp $      */
+
+/* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 #include "schedule.h"
 #include "debug.h"
 
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
+
 #include "localconf.h"
 #include "remoteconf.h"
 #include "isakmp_var.h"
@@ -91,6 +97,8 @@
 
 #include "vpn_control.h"
 #include "vpn_control_var.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
 
 /*
  * begin Aggressive Mode as initiator.
@@ -111,7 +119,7 @@ agg_i1send(iph1, msg)
 {
        struct payload_list *plist = NULL;
        int need_cr = 0;
-       vchar_t *cr = NULL, *gsstoken = NULL;
+       vchar_t *cr = NULL
        int error = -1;
 #ifdef ENABLE_NATT
        vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
@@ -125,6 +133,7 @@ agg_i1send(iph1, msg)
        vchar_t *vid_frag = NULL;
 #endif
 #ifdef HAVE_GSSAPI
+       vchar_t *gsstoken = NULL;
        int len;
 #endif
 #ifdef ENABLE_DPD
@@ -149,13 +158,19 @@ agg_i1send(iph1, msg)
        isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
 
        /* make ID payload into isakmp status */
-       if (ipsecdoi_setid1(iph1) < 0)
+       if (ipsecdoi_setid1(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set ID");
                goto end;
+       }
 
        /* create SA payload for my proposal */
        iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
-       if (iph1->sa == NULL)
+       if (iph1->sa == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set proposal");
                goto end;
+       }
 
        /* consistency check of proposals */
        if (iph1->rmconf->dhgrp == NULL) {
@@ -166,19 +181,30 @@ agg_i1send(iph1, msg)
 
        /* generate DH public value */
        if (oakley_dh_generate(iph1->rmconf->dhgrp,
-                               &iph1->dhpub, &iph1->dhpriv) < 0)
+                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate DH");
                goto end;
+       }
 
        /* generate NONCE value */
        iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
-       if (iph1->nonce == NULL)
+       if (iph1->nonce == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate NONCE");
                goto end;
+       }
 
 #ifdef ENABLE_HYBRID
        /* Do we need Xauth VID? */
-       switch (iph1->rmconf->proposal->authmethod) {
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       switch (RMAUTHMETHOD(iph1)) {
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
                if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
                        plog(LLV_ERROR, LOCATION, NULL, 
                             "Xauth vendor ID generation failed\n");
@@ -211,7 +237,7 @@ agg_i1send(iph1, msg)
                cr = oakley_getcr(iph1);
                if (cr == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to get cr buffer.\n");
+                               "failed to get CR");
                        goto end;
                }
        }
@@ -219,10 +245,8 @@ agg_i1send(iph1, msg)
        plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n",
                s_oakley_attr_method(iph1->rmconf->proposal->authmethod));
 #ifdef HAVE_GSSAPI
-       if (iph1->rmconf->proposal->authmethod ==
-           OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
+       if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
                gssapi_get_itoken(iph1, &len);
-       }
 #endif
 
        /* set SA payload to propose */
@@ -238,11 +262,10 @@ agg_i1send(iph1, msg)
        plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
 
 #ifdef HAVE_GSSAPI
-       if (iph1->rmconf->proposal->authmethod ==
-           OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
+       if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
                gssapi_get_token_to_send(iph1, &gsstoken);
                plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
-       } else
+       }
 #endif
        /* create isakmp CR payload */
        if (need_cr)
@@ -284,18 +307,34 @@ agg_i1send(iph1, msg)
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        iph1->status = PHASE1ST_MSG1SENT;
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Initiator, Aggressive-Mode message 1"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Initiator, Aggressive-Mode Message 1"),
+                                                               CONSTSTR("Failed to transmit Aggressive-Mode Message 1"));
+       }
        if (cr)
                vfree(cr);
+#ifdef HAVE_GSSAPI
        if (gsstoken)
                vfree(gsstoken);
+#endif
 #ifdef ENABLE_FRAG
        if (vid_frag)
                vfree(vid_frag);
@@ -304,16 +343,16 @@ end:
        for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
                vfree(vid_natt[i]);
 #endif
-#ifdef ENABLE_DPD
-       if (vid_dpd != NULL)
-               vfree(vid_dpd);
-#endif
 #ifdef ENABLE_HYBRID
        if (vid_xauth != NULL)
                vfree(vid_xauth);
        if (vid_unity != NULL)
                vfree(vid_unity);
 #endif
+#ifdef ENABLE_DPD
+       if (vid_dpd != NULL)
+               vfree(vid_dpd);
+#endif
 
        return error;
 }
@@ -365,8 +404,11 @@ agg_i2recv(iph1, msg)
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
        pa = (struct isakmp_parse_t *)pbuf->v;
 
        iph1->pl_hash = NULL;
@@ -380,8 +422,11 @@ agg_i2recv(iph1, msg)
                goto end;
        }
 
-       if (isakmp_p2ph(&satmp, pa->ptr) < 0)
+       if (isakmp_p2ph(&satmp, pa->ptr) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to process SA payload");
                goto end;
+       }
        pa++;
 
        for (/*nothing*/;
@@ -390,31 +435,49 @@ agg_i2recv(iph1, msg)
 
                switch (pa->type) {
                case ISAKMP_NPTYPE_KE:
-                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process KE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_NONCE:
-                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process NONCE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_ID:
-                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process ID payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_HASH:
                        iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
                        break;
                case ISAKMP_NPTYPE_CR:
-                       if (oakley_savecr(iph1, pa->ptr) < 0)
+                       if (oakley_savecr(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CR payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_CERT:
-                       if (oakley_savecert(iph1, pa->ptr) < 0)
+                       if (oakley_savecert(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CERT payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_SIG:
-                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process SIG payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_VID:
                        vid_numeric = check_vendorid(pa->ptr);
@@ -451,8 +514,11 @@ agg_i2recv(iph1, msg)
                        break;
 #ifdef HAVE_GSSAPI
                case ISAKMP_NPTYPE_GSS:
-                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
+                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process GSS payload");
                                goto end;
+                       }
                        gssapi_save_received_token(iph1, gsstoken);
                        break;
 #endif
@@ -467,13 +533,19 @@ agg_i2recv(iph1, msg)
                            pa->type == iph1->natt_options->payload_nat_d) {
                                struct natd_payload *natd;
                                natd = (struct natd_payload *)racoon_malloc(sizeof(*natd));
-                               if (!natd)
+                               if (!natd) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                                "failed to pre-process NATD payload");
                                        goto end;
+                               }
 
                                natd->payload = NULL;
 
-                               if (isakmp_p2ph (&natd->payload, pa->ptr) < 0)
+                               if (isakmp_p2ph (&natd->payload, pa->ptr) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                                "failed to process NATD payload");
                                        goto end;
+                               }
 
                                natd->seq = natd_seq++;
 
@@ -564,22 +636,41 @@ agg_i2recv(iph1, msg)
 
        /* compute sharing secret of DH */
        if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
-                               iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
+                                                 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute DH");
                goto end;
+       }
 
        /* generate SKEYIDs & IV & final cipher key */
-       if (oakley_skeyid(iph1) < 0)
+       if (oakley_skeyid(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID");
                goto end;
-       if (oakley_skeyid_dae(iph1) < 0)
+       }
+       if (oakley_skeyid_dae(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID-DAE");
                goto end;
-       if (oakley_compute_enckey(iph1) < 0)
+       }
+       if (oakley_compute_enckey(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate ENCKEY");
                goto end;
-       if (oakley_newiv(iph1) < 0)
+       }
+       if (oakley_newiv(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate IV");
                goto end;
+       }
 
        /* validate authentication value */
        ptype = oakley_validate_auth(iph1);
        if (ptype != 0) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL,
+                                                               CONSTSTR("Initiator, Aggressive-Mode Message 2"),
+                                                               CONSTSTR("Failed to authenticate, Aggressive-Mode Message 2"));
                if (ptype == -1) {
                        /* message printed inner oakley_validate_auth() */
                        goto end;
@@ -589,7 +680,11 @@ agg_i2recv(iph1, msg)
                isakmp_info_send_n1(iph1, ptype, NULL);
                goto end;
        }
-
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC,
+                                                       CONSTSTR("Initiator, Aggressive-Mode Message 2"),
+                                                       CONSTSTR(NULL));
+       
        if (oakley_checkcr(iph1) < 0) {
                /* Ignore this error in order to be interoperability. */
                ;
@@ -604,7 +699,22 @@ agg_i2recv(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Initiator, Aggressive-Mode message 2"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Initiator, Aggressive-Mode Message 2"),
+                                                               CONSTSTR("Failure processing Aggressive-Mode Message 2"));
+       }
+#ifdef HAVE_GSSAPI
+       if (gsstoken)
+               vfree(gsstoken);
+#endif
        if (pbuf)
                vfree(pbuf);
        if (satmp)
@@ -642,6 +752,11 @@ agg_i2send(iph1, msg)
        int need_cert = 0;
        int error = -1;
        vchar_t *gsshash = NULL;
+#ifdef ENABLE_NATT
+       vchar_t *natd[2] = { NULL, NULL };
+#endif
+    vchar_t *notp_unity = NULL;
+    vchar_t *notp_ini = NULL;
 
        /* validity check */
        if (iph1->status != PHASE1ST_MSG2RECEIVED) {
@@ -655,35 +770,50 @@ agg_i2send(iph1, msg)
        iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
        if (iph1->hash == NULL) {
 #ifdef HAVE_GSSAPI
-               if (gssapi_more_tokens(iph1))
+               if (gssapi_more_tokens(iph1) &&
+#ifdef ENABLE_HYBRID
+                   !iph1->rmconf->xauth &&
+#endif
+                   1)
                        isakmp_info_send_n1(iph1,
                            ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
 #endif
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate HASH");
                goto end;
        }
 
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
 #endif  
                /* set HASH payload */
-               plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
+               plist = isakmp_plist_append(plist, 
+                   iph1->hash, ISAKMP_NPTYPE_HASH);
                break;
+
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 #ifdef ENABLE_HYBRID
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
-#endif  
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+#endif
                /* XXX if there is CR or not ? */
 
-               if (oakley_getmycert(iph1) < 0)
+               if (oakley_getmycert(iph1) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to get mycert");
                        goto end;
+               }
 
-               if (oakley_getsign(iph1) < 0)
+               if (oakley_getsign(iph1) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to get sign");
                        goto end;
+               }
 
                if (iph1->cert != NULL && iph1->rmconf->send_cert)
                        need_cert = 1;
@@ -698,13 +828,17 @@ agg_i2send(iph1, msg)
 
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+#endif
                break;
 #ifdef HAVE_GSSAPI
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
                gsshash = gssapi_wraphash(iph1);
                if (gsshash == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to wrap hash\n");
+                               "failed to get GSS hash\n");
                        isakmp_info_send_n1(iph1,
                                ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
                        goto end;
@@ -713,19 +847,11 @@ agg_i2send(iph1, msg)
                plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH);
                break;
 #endif
-       default:
-               plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n",
-                       iph1->approval->authmethod);
-               goto end;
-               break;
        }
 
 #ifdef ENABLE_NATT
        /* generate NAT-D payloads */
-       if (NATT_AVAILABLE(iph1))
-       {
-               vchar_t *natd[2] = { NULL, NULL };
-
+       if (NATT_AVAILABLE(iph1)) {
                plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
                if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
@@ -753,18 +879,24 @@ agg_i2send(iph1, msg)
        }
 #endif
 
-       iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 
+       iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
+       
 #ifdef HAVE_PRINT_ISAKMP_C
        isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
 #endif
 
+
        /* send to responder */
-       if (isakmp_send(iph1, iph1->sendbuf) < 0)
+       if (isakmp_send(iph1, iph1->sendbuf) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -775,9 +907,35 @@ agg_i2send(iph1, msg)
 
        iph1->status = PHASE1ST_ESTABLISHED;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC,
+                                                       CONSTSTR("Initiator, Aggressive-Mode"),
+                                                       CONSTSTR(NULL));
+
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Initiator, Aggressive-Mode message 3"),
+                                                       CONSTSTR(NULL));
+
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Initiator, Aggressive-Mode Message 3"),
+                                                               CONSTSTR("Failed to transmit Aggressive-Mode Message 3"));
+       }
+#ifdef ENABLE_NATT
+       if (natd[0])
+               vfree(natd[0]);
+       if (natd[1])
+               vfree(natd[1]);
+#endif
+       if (notp_unity)
+               vfree(notp_unity);
+       if (notp_ini)
+               vfree(notp_ini);
        if (gsshash)
                vfree(gsshash);
        return error;
@@ -814,8 +972,11 @@ agg_r1recv(iph1, msg)
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
        pa = (struct isakmp_parse_t *)pbuf->v;
 
        /* SA payload is fixed postion */
@@ -826,8 +987,11 @@ agg_r1recv(iph1, msg)
                        pa->type, ISAKMP_NPTYPE_SA);
                goto end;
        }
-       if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
+       if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to process SA payload");
                goto end;
+       }
        pa++;
 
        for (/*nothing*/;
@@ -840,16 +1004,25 @@ agg_r1recv(iph1, msg)
 
                switch (pa->type) {
                case ISAKMP_NPTYPE_KE:
-                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process KE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_NONCE:
-                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process NONCE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_ID:
-                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process ID payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_VID:
                        vid_numeric = check_vendorid(pa->ptr);
@@ -891,14 +1064,20 @@ agg_r1recv(iph1, msg)
                        break;
 
                case ISAKMP_NPTYPE_CR:
-                       if (oakley_savecr(iph1, pa->ptr) < 0)
+                       if (oakley_savecr(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CR payload");
                                goto end;
+                       }
                        break;
 
 #ifdef HAVE_GSSAPI
                case ISAKMP_NPTYPE_GSS:
-                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
+                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process GSS payload");
                                goto end;
+                       }
                        gssapi_save_received_token(iph1, gsstoken);
                        break;
 #endif
@@ -950,7 +1129,22 @@ agg_r1recv(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Responder, Aggressive-Mode message 1"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Responder, Aggressive-Mode Message 1"),
+                                                               CONSTSTR("Failed to process Aggressive-Mode Message 1"));
+       }
+#ifdef HAVE_GSSAPI
+       if (gsstoken)
+               vfree(gsstoken);
+#endif
        if (pbuf)
                vfree(pbuf);
        if (error) {
@@ -982,7 +1176,6 @@ agg_r1send(iph1, msg)
        int need_cr = 0;
        int need_cert = 0;
        vchar_t *cr = NULL;
-       vchar_t *vid = NULL;
        int error = -1;
 #ifdef ENABLE_HYBRID
        vchar_t *xauth_vid = NULL;
@@ -995,11 +1188,15 @@ agg_r1send(iph1, msg)
 #ifdef ENABLE_DPD
        vchar_t *vid_dpd = NULL;
 #endif
+#ifdef ENABLE_FRAG
+       vchar_t *vid_frag = NULL;
+#endif
 
 #ifdef HAVE_GSSAPI
        int gsslen;
        vchar_t *gsstoken = NULL, *gsshash = NULL;
        vchar_t *gss_sa = NULL;
+       int free_gss_sa = 0;
 #endif
 
        /* validity check */
@@ -1013,37 +1210,60 @@ agg_r1send(iph1, msg)
        isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
 
        /* make ID payload into isakmp status */
-       if (ipsecdoi_setid1(iph1) < 0)
+       if (ipsecdoi_setid1(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set ID");
                goto end;
+       }
 
        /* generate DH public value */
        if (oakley_dh_generate(iph1->rmconf->dhgrp,
-                               &iph1->dhpub, &iph1->dhpriv) < 0)
+                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate DH");
                goto end;
+       }
 
        /* generate NONCE value */
        iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
-       if (iph1->nonce == NULL)
+       if (iph1->nonce == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate NONCE");
                goto end;
+       }
 
        /* compute sharing secret of DH */
        if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
-                               iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
+                                                 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute DH");
                goto end;
+       }
 
        /* generate SKEYIDs & IV & final cipher key */
-       if (oakley_skeyid(iph1) < 0)
+       if (oakley_skeyid(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID");
                goto end;
-       if (oakley_skeyid_dae(iph1) < 0)
+       }
+       if (oakley_skeyid_dae(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID-DAE");
                goto end;
-       if (oakley_compute_enckey(iph1) < 0)
+       }
+       if (oakley_compute_enckey(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate ENCKEY");
                goto end;
-       if (oakley_newiv(iph1) < 0)
+       }
+       if (oakley_newiv(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate IV");
                goto end;
+       }
 
 #ifdef HAVE_GSSAPI
-       if (iph1->rmconf->proposal->authmethod ==       
-           OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+       if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
                gssapi_get_rtoken(iph1, &gsslen);
 #endif
 
@@ -1056,6 +1276,8 @@ agg_r1send(iph1, msg)
                        isakmp_info_send_n1(iph1,
                            ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
 #endif
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate GSS HASH");
                goto end;
        }
 
@@ -1067,7 +1289,7 @@ agg_r1send(iph1, msg)
                cr = oakley_getcr(iph1);
                if (cr == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to get cr buffer.\n");
+                               "failed to get CR.\n");
                        goto end;
                }
        }
@@ -1098,9 +1320,23 @@ agg_r1send(iph1, msg)
        if (iph1->dpd_support && iph1->rmconf->dpd)
                vid_dpd = set_vendorid(VENDORID_DPD);
 #endif
+#ifdef ENABLE_FRAG
+       if (iph1->frag) {
+               vid_frag = set_vendorid(VENDORID_FRAG);
+               if (vid_frag != NULL)
+                       vid_frag = isakmp_frag_addcap(vid_frag,
+                           VENDORID_FRAG_AGG);
+               if (vid_frag == NULL)
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Frag vendorID construction failed\n");
+       }
+#endif
 
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+#endif
                /* set SA payload to reply */
                plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA);
 
@@ -1114,11 +1350,8 @@ agg_r1send(iph1, msg)
                plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
 
                /* create isakmp HASH payload */
-               plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
-
-               /* append vendor id, if needed */
-               if (vid)
-                       plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
+               plist = isakmp_plist_append(plist, 
+                   iph1->hash, ISAKMP_NPTYPE_HASH);
 
                /* create isakmp CR payload if needed */
                if (need_cr)
@@ -1127,16 +1360,24 @@ agg_r1send(iph1, msg)
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 #ifdef ENABLE_HYBRID
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
 #endif
                /* XXX if there is CR or not ? */
 
-               if (oakley_getmycert(iph1) < 0)
+               if (oakley_getmycert(iph1) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to get mycert");
                        goto end;
+               }
 
-               if (oakley_getsign(iph1) < 0)
+               if (oakley_getsign(iph1) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to get sign");
                        goto end;
+               }
 
                if (iph1->cert != NULL && iph1->rmconf->send_cert)
                        need_cert = 1;
@@ -1160,12 +1401,78 @@ agg_r1send(iph1, msg)
                /* add SIG payload */
                plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
 
-               /* append vendor id, if needed */
-               if (vid)
-                       plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
+               /* create isakmp CR payload if needed */
+               if (need_cr)
+                       plist = isakmp_plist_append(plist, 
+                           cr, ISAKMP_NPTYPE_CR);
+               break;
+
+       case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
+       case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+#endif
+               break;
+#ifdef HAVE_GSSAPI
+       case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
+                       /* create buffer to send isakmp payload */
+                       gsshash = gssapi_wraphash(iph1);
+                       if (gsshash == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "failed to generate GSS HASH\n");
+                               /*
+                                * This is probably due to the GSS 
+                                * roundtrips not being finished yet. 
+                                * Return this error in the hope that 
+                                * a fallback to main mode will be done.
+                                */
+                               isakmp_info_send_n1(iph1,
+                                   ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
+                               goto end;
+                       }
+                       if (iph1->approval->gssid != NULL)
+                               gss_sa = 
+                                   ipsecdoi_setph1proposal(iph1->approval);  
+                       else
+                               gss_sa = iph1->sa_ret;
+
+                       if (gss_sa != iph1->sa_ret)
+                               free_gss_sa = 1;
+
+                       /* set SA payload to reply */
+                       plist = isakmp_plist_append(plist, 
+                           gss_sa, ISAKMP_NPTYPE_SA);
+
+                       /* create isakmp KE payload */
+                       plist = isakmp_plist_append(plist, 
+                           iph1->dhpub, ISAKMP_NPTYPE_KE);
+
+                       /* create isakmp NONCE payload */
+                       plist = isakmp_plist_append(plist, 
+                           iph1->nonce, ISAKMP_NPTYPE_NONCE);
+
+                       /* create isakmp ID payload */
+                       plist = isakmp_plist_append(plist, 
+                           iph1->id, ISAKMP_NPTYPE_ID);
+
+                       /* create GSS payload */
+                       gssapi_get_token_to_send(iph1, &gsstoken);
+                       plist = isakmp_plist_append(plist, 
+                           gsstoken, ISAKMP_NPTYPE_GSS);
+
+                       /* create isakmp HASH payload */
+                       plist = isakmp_plist_append(plist, 
+                           gsshash, ISAKMP_NPTYPE_HASH);
+
+                       /* append vendor id, if needed */
+                       break;
+#endif
+       }
 
 #ifdef ENABLE_HYBRID
        if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
+               plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
                if ((xauth_vid = set_vendorid(VENDORID_XAUTH)) == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
                            "Cannot create Xauth vendor ID\n");
@@ -1186,68 +1493,6 @@ agg_r1send(iph1, msg)
        }
 #endif
 
-               /* create isakmp CR payload if needed */
-               if (need_cr)
-                       plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
-               break;
-
-       case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
-       case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
-               break;
-#ifdef HAVE_GSSAPI
-       case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
-               /* create buffer to send isakmp payload */
-               gsshash = gssapi_wraphash(iph1);
-               if (gsshash == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to wrap hash\n");
-                       /*
-                        * This is probably due to the GSS roundtrips not
-                        * being finished yet. Return this error in
-                        * the hope that a fallback to main mode will
-                        * be done.
-                        */
-                       isakmp_info_send_n1(iph1,
-                           ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
-                       goto end;
-               }
-               if (iph1->approval->gssid != NULL)
-                       gss_sa = ipsecdoi_setph1proposal(iph1->approval);  
-               else
-                       gss_sa = iph1->sa_ret;
-
-               /* set SA payload to reply */
-               plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA);
-
-               /* create isakmp KE payload */
-               plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
-
-               /* create isakmp NONCE payload */
-               plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
-
-               /* create isakmp ID payload */
-               plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
-
-               /* create GSS payload */
-               gssapi_get_token_to_send(iph1, &gsstoken);
-               plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
-
-               /* create isakmp HASH payload */
-               plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH);
-
-               /* append vendor id, if needed */
-               if (vid)
-                       plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
-
-               break;
-#endif
-       default:
-               plog(LLV_ERROR, LOCATION, NULL, "Invalid authmethod %d\n",
-                       iph1->approval->authmethod);
-               goto end;
-               break;
-       }
-
 #ifdef ENABLE_NATT
        /* append NAT-T payloads */
        if (vid_natt) {
@@ -1267,6 +1512,12 @@ agg_r1send(iph1, msg)
                }
        }
 #endif
+
+#ifdef ENABLE_FRAG
+       if (vid_frag)
+               plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
+#endif
+
 #ifdef ENABLE_DPD
        if (vid_dpd)
                plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
@@ -1280,11 +1531,15 @@ agg_r1send(iph1, msg)
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               plog(LLV_ERROR , LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -1298,11 +1553,20 @@ agg_r1send(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Responder, Aggressive-Mode message 2"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Responder, Aggressive-Mode Message 2"),
+                                                               CONSTSTR("Failed to process Aggressive-Mode Message 2"));
+       }
        if (cr)
                vfree(cr);
-       if (vid)
-               vfree(vid);
 #ifdef ENABLE_HYBRID
        if (xauth_vid)
                vfree(xauth_vid);
@@ -1314,13 +1578,25 @@ end:
                vfree(gsstoken);
        if (gsshash)
                vfree(gsshash);
-       if (gss_sa != iph1->sa_ret)
+       if (free_gss_sa)
                vfree(gss_sa);
 #endif
+#ifdef ENABLE_NATT
+       if (vid_natt)
+               vfree(vid_natt);
+       if (natd[0])
+               vfree(natd[0]);
+       if (natd[1])
+               vfree(natd[1]);
+#endif
 #ifdef ENABLE_DPD
        if (vid_dpd)
                vfree(vid_dpd);
 #endif
+#ifdef ENABLE_FRAG
+       if (vid_frag)
+               vfree(vid_frag);
+#endif
 
        return error;
 }
@@ -1360,15 +1636,21 @@ agg_r2recv(iph1, msg0)
        if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
                msg = oakley_do_decrypt(iph1, msg0,
                                        iph1->ivm->iv, iph1->ivm->ive);
-               if (msg == NULL)
+               if (msg == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to decrypt msg");
                        goto end;
+               }
        } else
                msg = vdup(msg0);
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
 
        iph1->pl_hash = NULL;
 
@@ -1384,12 +1666,18 @@ agg_r2recv(iph1, msg0)
                        (void)check_vendorid(pa->ptr);
                        break;
                case ISAKMP_NPTYPE_CERT:
-                       if (oakley_savecert(iph1, pa->ptr) < 0)
+                       if (oakley_savecert(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CERT payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_SIG:
-                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process SIG payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_N:
                        isakmp_check_notify(pa->ptr, iph1);
@@ -1398,17 +1686,17 @@ agg_r2recv(iph1, msg0)
 #ifdef ENABLE_NATT
                case ISAKMP_NPTYPE_NATD_DRAFT:
                case ISAKMP_NPTYPE_NATD_RFC:
-#ifdef __APPLE__
-               case ISAKMP_NPTYPE_NATD_BADDRAFT:
-#endif
                        if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
                                pa->type == iph1->natt_options->payload_nat_d)
                        {
                                vchar_t *natd_received = NULL;
                                int natd_verified;
                                
-                               if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
+                               if (isakmp_p2ph (&natd_received, pa->ptr) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                                "failed to process NATD payload");
                                        goto end;
+                               }
                                
                                if (natd_seq == 0)
                                        iph1->natt_flags |= NAT_DETECTED;
@@ -1450,6 +1738,10 @@ agg_r2recv(iph1, msg0)
        /* validate authentication value */
        ptype = oakley_validate_auth(iph1);
        if (ptype != 0) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL,
+                                                               CONSTSTR("Responder, Aggressive-Mode Message 3"),
+                                                               CONSTSTR("Failed to authenticate Aggressive-Mode Message 3"));
                if (ptype == -1) {
                        /* message printed inner oakley_validate_auth() */
                        goto end;
@@ -1459,12 +1751,27 @@ agg_r2recv(iph1, msg0)
                isakmp_info_send_n1(iph1, ptype, NULL);
                goto end;
        }
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC,
+                                                       CONSTSTR("Responder, Aggressive-Mode Message 3"),
+                                                       CONSTSTR(NULL));
 
        iph1->status = PHASE1ST_MSG2RECEIVED;
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Responder, Aggressive-Mode message 3"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Responder, Aggressive-Mode Message 3"),
+                                                               CONSTSTR("Failed to process Aggressive-Mode Message 3"));
+       }
        if (pbuf)
                vfree(pbuf);
        if (msg)
@@ -1507,6 +1814,11 @@ agg_r2send(iph1, msg)
 
        iph1->status = PHASE1ST_ESTABLISHED;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC,
+                                                       CONSTSTR("Responder, Aggressive-Mode"),
+                                                       CONSTSTR(NULL));
+       
        error = 0;
 
 end:
index f33b7331d418c45641198ec02f495819481a6917..3ac9e7c7f32878d9ba075dec900cc8e47f010360 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: isakmp_base.c,v 1.7 2006/10/02 21:51:33 manu Exp $     */
+
 /*     $KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane Exp $    */
 
 /*
 #include "schedule.h"
 #include "debug.h"
 
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
+
 #include "localconf.h"
 #include "remoteconf.h"
 #include "isakmp_var.h"
 #ifdef ENABLE_FRAG
 #include "isakmp_frag.h"
 #endif
+#ifdef ENABLE_HYBRID
+#include "isakmp_xauth.h"
+#include "isakmp_cfg.h"
+#endif
 #include "vpn_control.h"
 #include "vpn_control_var.h"
 
@@ -105,6 +115,14 @@ base_i1send(iph1, msg)
 #ifdef ENABLE_FRAG
        vchar_t *vid_frag = NULL;
 #endif
+#ifdef ENABLE_HYBRID
+       vchar_t *vid_xauth = NULL;
+       vchar_t *vid_unity = NULL;
+#endif
+#ifdef ENABLE_DPD
+       vchar_t *vid_dpd = NULL;
+#endif
+
 
        /* validity check */
        if (msg != NULL) {
@@ -136,6 +154,28 @@ base_i1send(iph1, msg)
        if (iph1->nonce == NULL)
                goto end;
 
+#ifdef ENABLE_HYBRID
+        /* Do we need Xauth VID? */
+        switch (RMAUTHMETHOD(iph1)) {
+        case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+                if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
+                        plog(LLV_ERROR, LOCATION, NULL,
+                             "Xauth vendor ID generation failed\n");
+
+                if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
+                        plog(LLV_ERROR, LOCATION, NULL,
+                             "Unity vendor ID generation failed\n");
+                break;
+        default:
+                break;
+        }
+#endif
 #ifdef ENABLE_FRAG
        if (iph1->rmconf->ike_frag) {
                vid_frag = set_vendorid(VENDORID_FRAG);
@@ -184,13 +224,28 @@ base_i1send(iph1, msg)
        if (vid_frag)
                plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
 #endif
+#ifdef ENABLE_HYBRID
+       if (vid_xauth)
+               plist = isakmp_plist_append(plist, 
+                   vid_xauth, ISAKMP_NPTYPE_VID);
+       if (vid_unity)
+               plist = isakmp_plist_append(plist, 
+                   vid_unity, ISAKMP_NPTYPE_VID);
+#endif
+#ifdef ENABLE_DPD
+       if (iph1->rmconf->dpd) {
+               vid_dpd = set_vendorid(VENDORID_DPD);
+               if (vid_dpd != NULL)
+                       plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); 
+       }
+#endif  
 #ifdef ENABLE_NATT
        /* set VID payload for NAT-T */
        for (i = 0; i < vid_natt_i; i++)
                plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID);
-
-       iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 #endif
+       iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
+
 
 #ifdef HAVE_PRINT_ISAKMP_C
        isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
@@ -214,6 +269,16 @@ end:
        for (i = 0; i < vid_natt_i; i++)
                vfree(vid_natt[i]);
 #endif
+#ifdef ENABLE_HYBRID    
+       if (vid_xauth != NULL)
+               vfree(vid_xauth);
+       if (vid_unity != NULL) 
+               vfree(vid_unity);
+#endif 
+#ifdef ENABLE_DPD
+       if (vid_dpd != NULL)    
+               vfree(vid_dpd);
+#endif     
 
        return error;
 }
@@ -235,6 +300,10 @@ base_i2recv(iph1, msg)
        vchar_t *satmp = NULL;
        int error = -1;
        int vid_numeric;
+#ifdef ENABLE_HYBRID
+       vchar_t *unity_vid;
+       vchar_t *xauth_vid;
+#endif
 
        /* validity check */
        if (iph1->status != PHASE1ST_MSG1SENT) {
@@ -279,6 +348,29 @@ base_i2recv(iph1, msg)
 #ifdef ENABLE_NATT
                        if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
                          natt_handle_vendorid(iph1, vid_numeric);
+#endif
+#ifdef ENABLE_HYBRID
+                       switch (vid_numeric) {
+                       case VENDORID_XAUTH:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_XAUTH;
+                               break;
+
+                       case VENDORID_UNITY:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_UNITY;
+                               break;
+
+                       default:
+                               break;
+                       }
+#endif
+#ifdef ENABLE_DPD
+                       if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
+                               iph1->dpd_support=1;
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                        "remote supports DPD\n");
+                       }
 #endif
                        break;
                default:
@@ -376,10 +468,21 @@ base_i2send(iph1, msg)
                goto end;
 
        /* generate SKEYID to compute hash if not signature mode */
-       if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG
-        && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG) {
+       switch (AUTHMETHOD(iph1)) {
+       case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+       case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+#endif
+               break;
+       default:
                if (oakley_skeyid(iph1) < 0)
                        goto end;
+               break;
        }
 
        /* generate HASH to send */
@@ -387,9 +490,13 @@ base_i2send(iph1, msg)
        iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE);
        if (iph1->hash == NULL)
                goto end;
-
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+#endif
                vid = set_vendorid(iph1->approval->vendorid);
 
                /* create isakmp KE payload */
@@ -404,6 +511,10 @@ base_i2send(iph1, msg)
                break;
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+#endif
                /* XXX if there is CR or not ? */
 
                if (oakley_getmycert(iph1) < 0)
@@ -425,16 +536,17 @@ base_i2send(iph1, msg)
                /* add SIG payload */
                plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
                break;
+#ifdef HAVE_GSSAPI
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
                /* ... */
                break;
+#endif
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
-               break;
-       default:
-               plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n",
-                       iph1->approval->authmethod);
-               goto end;
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+#endif
                break;
        }
 
@@ -483,7 +595,8 @@ base_i2send(iph1, msg)
                goto end;
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -632,10 +745,21 @@ base_i3recv(iph1, msg)
                goto end;
 
        /* generate SKEYID to compute hash if signature mode */
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_RSASIG
-        || iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_DSSSIG) {
+       switch (AUTHMETHOD(iph1)) {
+       case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+       case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+#endif
                if (oakley_skeyid(iph1) < 0)
                        goto end;
+               break;
+       default:
+               break;
        }
 
        /* generate SKEYIDs & IV & final cipher key */
@@ -766,6 +890,29 @@ base_r1recv(iph1, msg)
                            (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE))
                                iph1->frag = 1;
 #endif
+#ifdef ENABLE_HYBRID
+                       switch (vid_numeric) {
+                       case VENDORID_XAUTH:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_XAUTH;
+                               break;
+
+                       case VENDORID_UNITY:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_UNITY;
+                               break;
+
+                       default:
+                               break;
+                       }
+#endif
+#ifdef ENABLE_DPD
+                       if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
+                               iph1->dpd_support=1;
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                        "remote supports DPD\n");
+                       }
+#endif 
                        break;
                default:
                        /* don't send information, see ident_r1recv() */
@@ -839,6 +986,16 @@ base_r1send(iph1, msg)
 #ifdef ENABLE_NATT
        vchar_t *vid_natt = NULL;
 #endif
+#ifdef ENABLE_HYBRID    
+        vchar_t *vid_xauth = NULL;
+        vchar_t *vid_unity = NULL;
+#endif  
+#ifdef ENABLE_FRAG
+       vchar_t *vid_frag = NULL;
+#endif
+#ifdef ENABLE_DPD
+       vchar_t *vid_dpd = NULL;
+#endif  
 
        /* validity check */
        if (iph1->status != PHASE1ST_MSG1RECEIVED) {
@@ -875,6 +1032,56 @@ base_r1send(iph1, msg)
        if (vid_natt)
                plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
 #endif
+#ifdef ENABLE_HYBRID
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
+               plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
+               if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Cannot create Xauth vendor ID\n");
+                       goto end;
+               }
+               plist = isakmp_plist_append(plist,
+                   vid_xauth, ISAKMP_NPTYPE_VID);
+       }
+
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) {
+               if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Cannot create Unity vendor ID\n");
+                       goto end;
+               }
+               plist = isakmp_plist_append(plist,
+                   vid_unity, ISAKMP_NPTYPE_VID);
+       }
+#endif
+#ifdef ENABLE_DPD
+       /* 
+        * Only send DPD support if remote announced DPD 
+        * and if DPD support is active 
+        */
+       if (iph1->dpd_support && iph1->rmconf->dpd) {
+               if ((vid_dpd = set_vendorid(VENDORID_DPD)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "DPD vendorID construction failed\n");
+               } else {
+                       plist = isakmp_plist_append(plist, vid_dpd,
+                           ISAKMP_NPTYPE_VID);
+               }
+       }
+#endif
+#ifdef ENABLE_FRAG
+       if (iph1->rmconf->ike_frag) {
+               if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Frag vendorID construction failed\n");
+               } else {
+                       vid_frag = isakmp_frag_addcap(vid_frag,
+                           VENDORID_FRAG_BASE);
+                       plist = isakmp_plist_append(plist,
+                           vid_frag, ISAKMP_NPTYPE_VID);
+               }
+       }
+#endif
 
        iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 
@@ -884,11 +1091,14 @@ base_r1send(iph1, msg)
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               iph1 = NULL;
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -907,8 +1117,23 @@ end:
        if (vid_natt)
                vfree(vid_natt);
 #endif
+#ifdef ENABLE_HYBRID    
+       if (vid_xauth != NULL)
+               vfree(vid_xauth);
+       if (vid_unity != NULL)
+               vfree(vid_unity);
+#endif    
+#ifdef ENABLE_FRAG
+       if (vid_frag)
+               vfree(vid_frag);
+#endif
+#ifdef ENABLE_DPD
+       if (vid_dpd)
+               vfree(vid_dpd);
+#endif
 
-       VPTRINIT(iph1->sa_ret);
+       if (iph1 != NULL)
+               VPTRINIT(iph1->sa_ret);
 
        return error;
 }
@@ -1096,15 +1321,30 @@ base_r2send(iph1, msg)
 
        /* generate HASH to send */
        plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+#endif
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+#endif
                iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
                break;
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+#endif
+#ifdef HAVE_GSSAPI
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
+#endif
                iph1->hash = oakley_ph1hash_base_r(iph1, GENERATE);
                break;
        default:
@@ -1116,8 +1356,11 @@ base_r2send(iph1, msg)
        if (iph1->hash == NULL)
                goto end;
 
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+#endif
                vid = set_vendorid(iph1->approval->vendorid);
 
                /* create isakmp KE payload */
@@ -1132,6 +1375,12 @@ base_r2send(iph1, msg)
                break;
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+#endif
                /* XXX if there is CR or not ? */
 
                if (oakley_getmycert(iph1) < 0)
@@ -1152,23 +1401,23 @@ base_r2send(iph1, msg)
                /* add SIG payload */
                plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
                break;
+#ifdef HAVE_GSSAPI
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
                /* ... */
                break;
+#endif
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
-               break;
-       default:
-               plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n",
-                       iph1->approval->authmethod);
-               goto end;
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+#endif
                break;
        }
 
 #ifdef ENABLE_NATT
        /* generate NAT-D payloads */
-       if (NATT_AVAILABLE(iph1))
-       {
+       if (NATT_AVAILABLE(iph1)) {
                vchar_t *natd[2] = { NULL, NULL };
 
                plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
@@ -1198,7 +1447,7 @@ base_r2send(iph1, msg)
        }
 #endif
 
-       iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
+       iph1->sendbuf = isakmp_plist_set_all(&plist, iph1);
 
 #ifdef HAVE_PRINT_ISAKMP_C
        isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
@@ -1209,7 +1458,8 @@ base_r2send(iph1, msg)
                goto end;
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
index 56e96de02c56a89fb0e66cf6c5efdced4125d783..c72600ac82abd29453a0c91a41fb3e06a5454c37 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_cfg.c,v 1.26.2.7 2006/01/07 23:50:42 manubsd Exp $ */
+/*     $NetBSD: isakmp_cfg.c,v 1.12.6.1 2007/06/07 20:06:34 manu Exp $ */
+
+/* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
 
 /*
  * Copyright (C) 2004-2006 Emmanuel Dreyfus
 #include <sys/socket.h>
 #include <sys/queue.h>
 
+#include <utmpx.h>
+#if defined(__APPLE__) && defined(__MACH__)
+#include <util.h>
+#endif
+
+#ifdef __FreeBSD__
+# include <libutil.h>
+#endif
+#ifdef __NetBSD__
+#  include <util.h>
+#endif
+
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
 #include <ctype.h>
+#include <resolv.h>
 
 #ifdef HAVE_LIBRADIUS
 #include <sys/utsname.h>
@@ -78,6 +96,7 @@
 #include "evt.h"
 #include "throttle.h"
 #include "remoteconf.h"
+#include "localconf.h"
 #include "crypto_openssl.h"
 #include "isakmp_inf.h"
 #include "isakmp_xauth.h"
 #include "strnames.h"
 #include "admin.h"
 #include "privsep.h"
+#include "vpn_control.h"
+#include "vpn_control_var.h"
+#include "ike_session.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
+#include "nattraversal.h"
 
-struct isakmp_cfg_config isakmp_cfg_config = {
-       0x00000000,     /* network4 */
-       0x00000000,     /* netmask4 */
-       0x00000000,     /* dns4 */
-       0x00000000,     /* nbns4 */
-       NULL,           /* pool */
-       ISAKMP_CFG_AUTH_SYSTEM,         /* authsource */
-       ISAKMP_CFG_CONF_LOCAL,          /* confsource */
-       ISAKMP_CFG_ACCT_NONE,           /* accounting */
-       ISAKMP_CFG_MAX_CNX,             /* pool_size */
-       THROTTLE_PENALTY,               /* auth_throttle */
-       ISAKMP_CFG_MOTD,                /* motd */
-       0,                              /* pfs_group */
-       0,                              /* save_passwd */
-};
+struct isakmp_cfg_config isakmp_cfg_config;
 
 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
 static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
@@ -111,6 +122,12 @@ static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
 static vchar_t *isakmp_cfg_addr4(struct ph1handle *, 
                                 struct isakmp_data *, in_addr_t *);
 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
+static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
+                                     struct isakmp_data *, in_addr_t *, int);
+static void isakmp_cfg_appendaddr4(struct isakmp_data *, 
+                                  struct in_addr *, int *, int);
+static void isakmp_cfg_getstring(struct isakmp_data *,char *);
+void isakmp_cfg_iplist_to_str(char *, int, void *, int);
 
 #define ISAKMP_CFG_LOGIN       1
 #define ISAKMP_CFG_LOGOUT      2
@@ -135,17 +152,27 @@ isakmp_cfg_r(iph1, msg)
        int np;
        vchar_t *dmsg;
        struct isakmp_ivm *ivm;
+       struct ph2handle *iph2;
+       int               error = -1;
 
        /* Check that the packet is long enough to have a header */
        if (msg->l < sizeof(*packet)) {
-            plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
-            return;
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("MODE-Config. Unexpected short packet"),
+                                                               CONSTSTR("Failed to process short MODE-Config packet"));
+               plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
+               return;
        }
 
        packet = (struct isakmp *)msg->v;
 
        /* Is it encrypted? It should be encrypted */
        if ((packet->flags & ISAKMP_FLAG_E) == 0) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("MODE-Config. User credentials sent in cleartext"),
+                                                               CONSTSTR("Dropped cleattext User credentials"));
                plog(LLV_ERROR, LOCATION, NULL, 
                    "User credentials sent in cleartext!\n");
                return;
@@ -155,13 +182,18 @@ isakmp_cfg_r(iph1, msg)
         * Decrypt the packet. If this is the beginning of a new
         * exchange, reinitialize the IV
         */
-       if (iph1->mode_cfg->ivm == NULL)
+       if (iph1->mode_cfg->ivm == NULL ||
+           iph1->mode_cfg->last_msgid != packet->msgid )
                iph1->mode_cfg->ivm = 
                    isakmp_cfg_newiv(iph1, packet->msgid);
        ivm = iph1->mode_cfg->ivm;
 
        dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
        if (dmsg == NULL) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("MODE-Config. Failed to decrypt packet"),
+                                                               CONSTSTR("Failed to decrypt MODE-Config packet"));
                plog(LLV_ERROR, LOCATION, NULL, 
                    "failed to decrypt message\n");
                return;
@@ -235,7 +267,7 @@ isakmp_cfg_r(iph1, msg)
                        struct isakmp_pl_attr *attrpl;
 
                        attrpl = (struct isakmp_pl_attr *)ph;
-                       isakmp_cfg_attr_r(iph1, packet->msgid, attrpl);
+                       isakmp_cfg_attr_r(iph1, packet->msgid, attrpl, msg);
 
                        break;
                }
@@ -253,24 +285,47 @@ isakmp_cfg_r(iph1, msg)
                ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
        }
 
+       error = 0;
+       /* find phase 2 in case pkt scheduled for resend */
+       iph2 = getph2bymsgid(iph1, packet->msgid);
+       if (iph2 == NULL)
+               goto out;               /* no resend scheduled */
+       SCHED_KILL(iph2->scr);  /* turn off schedule */
+       unbindph12(iph2);
+       remph2(iph2);
+       delph2(iph2);
+
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("MODE-Config"),
+                                                       CONSTSTR(NULL));
 out:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("MODE-Config"),
+                                                               CONSTSTR("Failed to process Mode-Config packet"));
+       }
        vfree(dmsg);
 }
 
 int
-isakmp_cfg_attr_r(iph1, msgid, attrpl) 
+isakmp_cfg_attr_r(iph1, msgid, attrpl, msg
        struct ph1handle *iph1;
        u_int32_t msgid;
        struct isakmp_pl_attr *attrpl;
+       vchar_t *msg;
 {
        int type = attrpl->type;
 
+       plog(LLV_DEBUG, LOCATION, NULL,
+            "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
        switch (type) {
        case ISAKMP_CFG_ACK:
                /* ignore, but this is the time to reinit the IV */
                oakley_delivm(iph1->mode_cfg->ivm);
                iph1->mode_cfg->ivm = NULL;
-               return 0;
+               return 0;            
                break;
 
        case ISAKMP_CFG_REPLY:
@@ -279,12 +334,12 @@ isakmp_cfg_attr_r(iph1, msgid, attrpl)
 
        case ISAKMP_CFG_REQUEST:
                iph1->msgid = msgid;
-               return isakmp_cfg_request(iph1, attrpl);
+               return isakmp_cfg_request(iph1, attrpl, msg);
                break;
 
        case ISAKMP_CFG_SET:
                iph1->msgid = msgid;
-               return isakmp_cfg_set(iph1, attrpl);
+               return isakmp_cfg_set(iph1, attrpl, msg);
                break;
 
        default:
@@ -307,12 +362,15 @@ isakmp_cfg_reply(iph1, attrpl)
        size_t alen;
        char *npp;
        int type;
-       struct sockaddr_in *sin;
+       int error;
 
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_REPLY)
+               return 0;       /* already received this - duplicate packet */
+               
        tlen = ntohs(attrpl->h.len);
        attr = (struct isakmp_data *)(attrpl + 1);
        tlen -= sizeof(*attrpl);
-       
+
        while (tlen > 0) {
                type = ntohs(attr->type);
 
@@ -321,17 +379,22 @@ isakmp_cfg_reply(iph1, attrpl)
                        type &= ~ISAKMP_GEN_MASK;
 
                        plog(LLV_DEBUG, LOCATION, NULL,
-                            "Short attribute %d = %d\n", 
-                            type, ntohs(attr->lorv));
+                            "Short attribute %s = %d\n", 
+                            s_isakmp_cfg_type(type), ntohs(attr->lorv));
 
-                       switch (type) {
+                       switch (type) {                 
                        case XAUTH_TYPE:
-                               xauth_attr_reply(iph1, attr, ntohs(attrpl->id));
+                               if ((error = xauth_attr_reply(iph1, 
+                                   attr, ntohs(attrpl->id))) != 0)
+                                       return error;
+                               break;
+
                                break;
 
                        default:
                                plog(LLV_WARNING, LOCATION, NULL,
-                                    "Ignored short attribute %d\n", type);
+                                    "Ignored short attribute %s\n",
+                                    s_isakmp_cfg_type(type));
                                break;
                        }
 
@@ -346,12 +409,14 @@ isakmp_cfg_reply(iph1, attrpl)
                /* Check that the attribute fit in the packet */
                if (tlen < alen) {
                        plog(LLV_ERROR, LOCATION, NULL,
-                            "Short attribute %d\n", type);
+                            "Short attribute %s\n",
+                            s_isakmp_cfg_type(type));
                        return -1;
                }
 
                plog(LLV_DEBUG, LOCATION, NULL,
-                    "Attribute %d, len %zu\n", type, alen);
+                    "Attribute %s, len %zu\n", 
+                    s_isakmp_cfg_type(type), alen);
 
                switch(type) {
                case XAUTH_TYPE:
@@ -364,39 +429,67 @@ isakmp_cfg_reply(iph1, attrpl)
                case XAUTH_STATUS:
                case XAUTH_NEXT_PIN:
                case XAUTH_ANSWER:
-                       xauth_attr_reply(iph1, attr, ntohs(attrpl->id));
+                       if ((error = xauth_attr_reply(iph1, 
+                           attr, ntohs(attrpl->id))) != 0)
+                               return error;
                        break;
                case INTERNAL_IP4_ADDRESS:
-                       isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
-                       iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
+                       if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) == 0) {
+                               isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
+                               iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
+                       }
                        break;
                case INTERNAL_IP4_NETMASK:
-                       isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
-                       iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
+                       if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) == 0) {
+                               isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
+                               iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
+                       }
                        break;
                case INTERNAL_IP4_DNS:
-                       isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->dns4);
-                       iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
+                       if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) == 0) {
+                               isakmp_cfg_appendaddr4(attr, 
+                                       &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
+                                       &iph1->mode_cfg->dns4_index, MAXNS);
+                               iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
+                       }
                        break;
                case INTERNAL_IP4_NBNS:
-                       isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->wins4);
-                       iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
+                       if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) == 0) {
+                               isakmp_cfg_appendaddr4(attr, 
+                                       &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
+                                       &iph1->mode_cfg->wins4_index, MAXNS);
+                               iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
+                       }
                        break;
-               case INTERNAL_IP4_SUBNET:
-               case INTERNAL_ADDRESS_EXPIRY:
-               case UNITY_BANNER:
-               case UNITY_SAVE_PASSWD:
                case UNITY_DEF_DOMAIN:
-               case UNITY_SPLITDNS_NAME:
+                       if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) == 0) {
+                               isakmp_cfg_getstring(attr, 
+                                       iph1->mode_cfg->default_domain);
+                               iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
+                       }
+                       break;
                case UNITY_SPLIT_INCLUDE:
+               case UNITY_LOCAL_LAN:
+               case UNITY_SPLITDNS_NAME:
+               case UNITY_BANNER:
+               case UNITY_SAVE_PASSWD:
                case UNITY_NATT_PORT:
-               case UNITY_PFS:
                case UNITY_FW_TYPE:
                case UNITY_BACKUP_SERVERS:
                case UNITY_DDNS_HOSTNAME:
+               case APPLICATION_VERSION:
+               case UNITY_PFS:
+                       isakmp_unity_reply(iph1, attr);
+                       break;
+               case INTERNAL_IP4_SUBNET:
+               case INTERNAL_ADDRESS_EXPIRY:
+                       if (iph1->started_by_api)
+                               break;  /* not actually ignored - don't fall thru */
+                       // else fall thru
                default:
                        plog(LLV_WARNING, LOCATION, NULL,
-                            "Ignored attribute %d\n", type);
+                            "Ignored attribute %s\n",
+                            s_isakmp_cfg_type(type));
                        break;
                }
 
@@ -404,15 +497,49 @@ isakmp_cfg_reply(iph1, attrpl)
                attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
                tlen -= (sizeof(*attr) + alen);
        }
-
+       iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_REPLY;
+       
+       if (iph1->started_by_api || (iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client)) {
+               /* connection was started by API - save attr list for passing to VPN controller */
+               if (iph1->mode_cfg->attr_list != NULL)  /* shouldn't happen */
+                       vfree(iph1->mode_cfg->attr_list);
+               alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
+               if ((iph1->mode_cfg->attr_list = vmalloc(alen)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                            "Cannot allocate memory for mode-cfg attribute list\n");
+                       return -1;
+               }
+               memcpy(iph1->mode_cfg->attr_list->v, attrpl + 1, alen);
+       }
+               
        /* 
         * Call the SA up script hook now that we have the configuration
         * It is done at the end of phase 1 if ISAKMP mode config is not
         * requested.
         */
+       
        if ((iph1->status == PHASE1ST_ESTABLISHED) && 
-           iph1->rmconf->mode_cfg)
-               script_hook(iph1, SCRIPT_PHASE1_UP);
+           iph1->rmconf->mode_cfg) {
+               switch (AUTHMETHOD(iph1)) {
+               case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+               /* Unimplemented */
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: 
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: 
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 
+                       script_hook(iph1, SCRIPT_PHASE1_UP);
+                       break;
+               default:
+                       break;
+               }
+       }
+               
+#ifdef ENABLE_VPNCONTROL_PORT
+       if (iph1->status == PHASE1ST_ESTABLISHED)
+               vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
+#endif
 
 #ifdef ENABLE_ADMINPORT
        {
@@ -435,29 +562,53 @@ isakmp_cfg_reply(iph1, attrpl)
 }
 
 int
-isakmp_cfg_request(iph1, attrpl)
+isakmp_cfg_request(iph1, attrpl, msg)
        struct ph1handle *iph1;
        struct isakmp_pl_attr *attrpl;
+       vchar_t *msg;
 {
        struct isakmp_data *attr;
        int tlen;
        size_t alen;
        char *npp;
-       vchar_t *payload;
+       vchar_t *payload = NULL;
        struct isakmp_pl_attr *reply;
        vchar_t *reply_attr;
        int type;
        int error = -1;
 
+       tlen = ntohs(attrpl->h.len);
+       attr = (struct isakmp_data *)(attrpl + 1);
+       tlen -= sizeof(*attrpl);
+
+       /*
+        * if started_by_api then we are a VPN client and if we receive
+        * a mode-cfg request it needs to go to the VPN controller to
+        * retrieve the appropriate data (name, pw, pin, etc.)
+        */
+       if (iph1->started_by_api || ike_session_is_client_ph1_rekey(iph1)) {            
+               /* 
+                * if we already received this one - ignore it
+                * we are waiting for a reply from the vpn control socket
+                */
+               if (iph1->xauth_awaiting_userinput)                     
+                       return 0;       
+                       
+               /* otherwise - save the msg id and call and send the status notification */
+               iph1->pended_xauth_id = attrpl->id;             /* network byte order */
+               if (vpncontrol_notify_need_authinfo(iph1, attrpl + 1, tlen))
+                       goto end;
+               iph1->xauth_awaiting_userinput = 1;
+               iph1->xauth_awaiting_userinput_msg = vdup(msg); // dup the message for later
+               ike_session_start_xauth_timer(iph1);
+               return 0;
+       }
+
        if ((payload = vmalloc(sizeof(*reply))) == NULL) {
                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
                return -1;
        }
        memset(payload->v, 0, sizeof(*reply));
-
-       tlen = ntohs(attrpl->h.len);
-       attr = (struct isakmp_data *)(attrpl + 1);
-       tlen -= sizeof(*attrpl);
        
        while (tlen > 0) {
                reply_attr = NULL;
@@ -468,8 +619,8 @@ isakmp_cfg_request(iph1, attrpl)
                        type &= ~ISAKMP_GEN_MASK;
 
                        plog(LLV_DEBUG, LOCATION, NULL,
-                            "Short attribute %d = %d\n", 
-                            type, ntohs(attr->lorv));
+                            "Short attribute %s = %d\n", 
+                            s_isakmp_cfg_type(type), ntohs(attr->lorv));
 
                        switch (type) {
                        case XAUTH_TYPE:
@@ -477,7 +628,8 @@ isakmp_cfg_request(iph1, attrpl)
                                break;
                        default:
                                plog(LLV_WARNING, LOCATION, NULL,
-                                    "Ignored short attribute %d\n", type);
+                                    "Ignored short attribute %s\n",
+                                    s_isakmp_cfg_type(type));
                                break;
                        }
 
@@ -491,19 +643,21 @@ isakmp_cfg_request(iph1, attrpl)
 
                        continue;
                }
-
+               
                type = ntohs(attr->type);
                alen = ntohs(attr->lorv);
 
                /* Check that the attribute fit in the packet */
                if (tlen < alen) {
                        plog(LLV_ERROR, LOCATION, NULL,
-                            "Short attribute %d\n", type);
+                            "Short attribute %s\n",
+                            s_isakmp_cfg_type(type));
                        goto end;
                }
 
                plog(LLV_DEBUG, LOCATION, NULL,
-                    "Attribute %d, len %zu\n", type, alen);
+                    "Attribute %s, len %zu\n",
+                    s_isakmp_cfg_type(type), alen);
 
                switch(type) {
                case INTERNAL_IP4_ADDRESS:
@@ -540,6 +694,7 @@ isakmp_cfg_request(iph1, attrpl)
                case UNITY_FW_TYPE:
                case UNITY_SPLITDNS_NAME:
                case UNITY_SPLIT_INCLUDE:
+               case UNITY_LOCAL_LAN:
                case UNITY_NATT_PORT:
                case UNITY_BACKUP_SERVERS:
                        reply_attr = isakmp_unity_req(iph1, attr);
@@ -548,7 +703,8 @@ isakmp_cfg_request(iph1, attrpl)
                case INTERNAL_ADDRESS_EXPIRY:
                default:
                        plog(LLV_WARNING, LOCATION, NULL,
-                            "Ignored attribute %d\n", type);
+                            "Ignored attribute %s\n",
+                            s_isakmp_cfg_type(type));
                        break;
                }
 
@@ -560,7 +716,6 @@ isakmp_cfg_request(iph1, attrpl)
                        payload = buffer_cat(payload, reply_attr);
                        vfree(reply_attr);
                }
-
        }
 
        reply = (struct isakmp_pl_attr *)payload->v;
@@ -568,12 +723,33 @@ isakmp_cfg_request(iph1, attrpl)
        reply->type = ISAKMP_CFG_REPLY;
        reply->id = attrpl->id;
 
+       plog(LLV_DEBUG, LOCATION, NULL, 
+                   "Sending MODE_CFG REPLY\n");
+
        error = isakmp_cfg_send(iph1, payload, 
-           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
+           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
+
+       if (iph1->status == PHASE1ST_ESTABLISHED) {
+               switch (AUTHMETHOD(iph1)) {
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+               /* Unimplemented */
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 
+                       script_hook(iph1, SCRIPT_PHASE1_UP);
+                       break;
+               default:
+                       break;
+               }
+#ifdef ENABLE_VPNCONTROL_PORT
+               vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
+#endif
 
-       /* Reinit the IV */
-       oakley_delivm(iph1->mode_cfg->ivm);
-       iph1->mode_cfg->ivm = NULL;
+       }
+       
 end:
        vfree(payload);
 
@@ -581,9 +757,10 @@ end:
 }
 
 int
-isakmp_cfg_set(iph1, attrpl)
+isakmp_cfg_set(iph1, attrpl, msg)
        struct ph1handle *iph1;
        struct isakmp_pl_attr *attrpl;
+    vchar_t *msg;
 {
        struct isakmp_data *attr;
        int tlen;
@@ -612,18 +789,22 @@ isakmp_cfg_set(iph1, attrpl)
                reply_attr = NULL;
                type = ntohs(attr->type);
 
+               plog(LLV_DEBUG, LOCATION, NULL,
+                    "Attribute %s\n", 
+                    s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
+               
                switch (type & ~ISAKMP_GEN_MASK) {
                case XAUTH_STATUS:
                        reply_attr = isakmp_xauth_set(iph1, attr);
                        break;
                default:
                        plog(LLV_DEBUG, LOCATION, NULL,
-                            "Unexpected SET attribute %d\n", 
-                                type & ~ISAKMP_GEN_MASK);
+                            "Unexpected SET attribute %s\n", 
+                            s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
                        break;
                }
 
-               if ((reply_attr = vmalloc(sizeof(*reply_attr))) != NULL) {
+               if (reply_attr != NULL) {
                        payload = buffer_cat(payload, reply_attr);
                        vfree(reply_attr);
                }
@@ -649,22 +830,25 @@ isakmp_cfg_set(iph1, attrpl)
        reply->type = ISAKMP_CFG_ACK;
        reply->id = attrpl->id;
 
+       plog(LLV_DEBUG, LOCATION, NULL,
+                    "Sending MODE_CFG ACK\n");
+
        error = isakmp_cfg_send(iph1, payload, 
-           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
+           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
 
        if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
                if (iph1->status == PHASE1ST_ESTABLISHED)
                        isakmp_info_send_d1(iph1);
                remph1(iph1);
                delph1(iph1);
+               iph1 = NULL;
        }
-end:
        vfree(payload);
 
        /* 
-        * If required, request ISAKMP mode config information
+        * If required, request ISAKMP mode config information: ignore rekeys
         */
-       if ((iph1->rmconf->mode_cfg) && (error == 0))
+       if ((iph1 != NULL) && (!iph1->is_rekey) && (iph1->rmconf->mode_cfg) && (error == 0))
                error = isakmp_cfg_getconfig(iph1);
 
        return error;
@@ -698,6 +882,7 @@ isakmp_cfg_net(iph1, attr)
        struct isakmp_data *attr;
 {
        int type;
+       int confsource;
        in_addr_t addr4;
 
        type = ntohs(attr->type);
@@ -711,12 +896,30 @@ isakmp_cfg_net(iph1, attr)
                return NULL;
        }
 
+       confsource = isakmp_cfg_config.confsource;
+       /*
+        * If we have to fall back to a local
+        * configuration source, we will jump
+        * back to this point.
+        */
+retry_source:
+
        switch(type) {
        case INTERNAL_IP4_ADDRESS:
-               switch(isakmp_cfg_config.confsource) {
+               switch(confsource) {
+#ifdef HAVE_LIBLDAP
+               case ISAKMP_CFG_CONF_LDAP:
+                       if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
+                           break;
+                       plog(LLV_INFO, LOCATION, NULL, 
+                           "No IP from LDAP, using local pool\n");
+                       /* FALLTHROUGH */
+                       confsource = ISAKMP_CFG_CONF_LOCAL;
+                       goto retry_source;
+#endif
 #ifdef HAVE_LIBRADIUS
                case ISAKMP_CFG_CONF_RADIUS:
-                       if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS)
+                       if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
                            && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
                            /*
                             * -2 is 255.255.255.254, RADIUS uses that
@@ -726,6 +929,8 @@ isakmp_cfg_net(iph1, attr)
                        plog(LLV_INFO, LOCATION, NULL, 
                            "No IP from RADIUS, using local pool\n");
                        /* FALLTHROUGH */
+                       confsource = ISAKMP_CFG_CONF_LOCAL;
+                       goto retry_source;
 #endif
                case ISAKMP_CFG_CONF_LOCAL:
                        if (isakmp_cfg_getport(iph1) == -1) {
@@ -753,14 +958,26 @@ isakmp_cfg_net(iph1, attr)
                break;
 
        case INTERNAL_IP4_NETMASK:
-               switch(isakmp_cfg_config.confsource) {
+               switch(confsource) {
+#ifdef HAVE_LIBLDAP
+               case ISAKMP_CFG_CONF_LDAP:
+                       if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
+                               break;
+                       plog(LLV_INFO, LOCATION, NULL, 
+                           "No mask from LDAP, using local pool\n");
+                       /* FALLTHROUGH */
+                       confsource = ISAKMP_CFG_CONF_LOCAL;
+                       goto retry_source;
+#endif
 #ifdef HAVE_LIBRADIUS
                case ISAKMP_CFG_CONF_RADIUS:
-                       if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_RADIUS)
+                       if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
                                break;
                        plog(LLV_INFO, LOCATION, NULL, 
                            "No mask from RADIUS, using local pool\n");
                        /* FALLTHROUGH */
+                       confsource = ISAKMP_CFG_CONF_LOCAL;
+                       goto retry_source;
 #endif
                case ISAKMP_CFG_CONF_LOCAL:
                        iph1->mode_cfg->mask4.s_addr 
@@ -777,13 +994,15 @@ isakmp_cfg_net(iph1, attr)
                break;
 
        case INTERNAL_IP4_DNS:
-               return isakmp_cfg_addr4(iph1, 
-                   attr, &isakmp_cfg_config.dns4);
+               return isakmp_cfg_addr4_list(iph1, 
+                   attr, &isakmp_cfg_config.dns4[0], 
+                   isakmp_cfg_config.dns4_index);
                break;
 
        case INTERNAL_IP4_NBNS:
-               return isakmp_cfg_addr4(iph1, 
-                   attr, &isakmp_cfg_config.nbns4);
+               return isakmp_cfg_addr4_list(iph1, 
+                   attr, &isakmp_cfg_config.nbns4[0], 
+                   isakmp_cfg_config.nbns4_index);
                break;
 
        case INTERNAL_IP4_SUBNET:
@@ -795,7 +1014,6 @@ isakmp_cfg_net(iph1, attr)
                plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
                break;
        }
-
        return NULL;
 }
 
@@ -868,17 +1086,16 @@ isakmp_cfg_short(iph1, attr, value)
 }
 
 vchar_t *
-isakmp_cfg_string(iph1, attr, string)
+isakmp_cfg_varlen(iph1, attr, string, len)
        struct ph1handle *iph1;
        struct isakmp_data *attr;
        char *string;
+       size_t len;
 {
        vchar_t *buffer;
        struct isakmp_data *new;
-       size_t len;
        char *data;
 
-       len = strlen(string);
        if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
                return NULL;
@@ -894,6 +1111,15 @@ isakmp_cfg_string(iph1, attr, string)
        
        return buffer;
 }
+vchar_t *
+isakmp_cfg_string(iph1, attr, string)
+       struct ph1handle *iph1;
+       struct isakmp_data *attr;
+       char *string;
+{
+       size_t len = strlen(string);
+       return isakmp_cfg_varlen(iph1, attr, string, len);
+}
 
 static vchar_t *
 isakmp_cfg_addr4(iph1, attr, addr)
@@ -920,6 +1146,51 @@ isakmp_cfg_addr4(iph1, attr, addr)
        return buffer;
 }
 
+static vchar_t *
+isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
+       struct ph1handle *iph1;
+       struct isakmp_data *attr;
+       in_addr_t *addr;
+       int nbr;
+{
+       int error = -1;
+       vchar_t *buffer = NULL;
+       vchar_t *bufone = NULL;
+       struct isakmp_data *new;
+       size_t len;
+       int i;
+
+       len = sizeof(*addr);
+       if ((buffer = vmalloc(0)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
+               goto out;
+       }
+       for(i = 0; i < nbr; i++) {
+               if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                           "Cannot allocate memory\n");
+                       goto out;
+               }
+               new = (struct isakmp_data *)bufone->v;
+               new->type = attr->type;
+               new->lorv = htons(len);
+               memcpy(new + 1, &addr[i], len);
+               new += (len + sizeof(*attr));
+               buffer = buffer_cat(buffer, bufone);
+               vfree(bufone);
+       }
+
+       error = 0;
+
+out:
+       if ((error != 0) && (buffer != NULL)) {
+               vfree(buffer);
+               buffer = NULL;
+       }
+
+       return buffer;
+}
+
 struct isakmp_ivm *
 isakmp_cfg_newiv(iph1, msgid)
        struct ph1handle *iph1;
@@ -937,18 +1208,21 @@ isakmp_cfg_newiv(iph1, msgid)
                oakley_delivm(ics->ivm);
 
        ics->ivm = oakley_newiv2(iph1, msgid);
+       ics->last_msgid = msgid;
 
        return ics->ivm;
 }
 
 /* Derived from isakmp_info_send_common */
 int
-isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
+isakmp_cfg_send(iph1, payload, np, flags, new_exchange, retry_count, msg)
        struct ph1handle *iph1;
        vchar_t *payload;
        u_int32_t np;
        int flags;
        int new_exchange;
+       int retry_count;
+    vchar_t *msg;
 {
        struct ph2handle *iph2 = NULL;
        vchar_t *hash = NULL;
@@ -970,22 +1244,40 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
 
        /* add new entry to isakmp status table */
        iph2 = newph2();
-       if (iph2 == NULL)
+       if (iph2 == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to allocate ph2");
                goto end;
+       }
 
        iph2->dst = dupsaddr(iph1->remote);
+       if (iph2->dst == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to duplicate remote address");
+               delph2(iph2);
+               goto end;
+       }
        iph2->src = dupsaddr(iph1->local);
+       if (iph2->src == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to duplicate local address");
+               delph2(iph2);
+               goto end;
+       }
+
        switch (iph1->remote->sa_family) {
        case AF_INET:
-#ifndef ENABLE_NATT
+#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
                ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
                ((struct sockaddr_in *)iph2->src)->sin_port = 0;
 #endif
                break;
 #ifdef INET6
        case AF_INET6:
+#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
                ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
                ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
+#endif
                break;
 #endif
        default:
@@ -1007,6 +1299,8 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
        if (iph1->skeyid_a != NULL) {
                if (new_exchange) {
                        if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to generate IV");
                                delph2(iph2);
                                goto end;
                        }
@@ -1015,6 +1309,8 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
                /* generate HASH(1) */
                hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
                if (hash == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate HASH");
                        delph2(iph2);
                        goto end;
                }
@@ -1076,6 +1372,9 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
 #ifdef HAVE_PRINT_ISAKMP_C
        isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
 #endif
+       
+       plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
+       plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
 
        /* encoding */
        if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
@@ -1084,17 +1383,47 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
                tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, 
                        ics->ivm->ive, ics->ivm->iv);
                VPTRINIT(iph2->sendbuf);
-               if (tmp == NULL)
+               if (tmp == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to encrypt packet");
                        goto err;
+               }
                iph2->sendbuf = tmp;
        }
 
        /* HDR*, HASH(1), ATTR */
+       
+       if (retry_count > 0) {
+               iph2->retry_counter = retry_count;
+               if (isakmp_ph2resend(iph2) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to resend packet");
+                       VPTRINIT(iph2->sendbuf);
+                       goto err;
+               }
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT,
+                                                               CONSTSTR("Mode-Config retransmit"),
+                                                               CONSTSTR(NULL));
+               error = 0;
+               goto end;
+       }
+       
        if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                VPTRINIT(iph2->sendbuf);
                goto err;
        }
-
+       if (msg) {
+               /* the sending message is added to the received-list. */
+               if (add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg,
+                                PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
+                       plog(LLV_ERROR , LOCATION, NULL,
+                            "failed to add a response packet to the tree.\n");
+               }
+       }
+    
        plog(LLV_DEBUG, LOCATION, NULL,
                "sendto mode config %s.\n", s_isakmp_nptype(np));
 
@@ -1105,10 +1434,18 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
        error = 0;
        VPTRINIT(iph2->sendbuf);
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Mode-Config message"),
+                                                       CONSTSTR(NULL));
+       
 err:
-       if (iph2->sendbuf != NULL)
-               vfree(iph2->sendbuf);
-
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Mode-Config message"),
+                                                               CONSTSTR("Failed to transmit Mode-Config message"));
+       }
        unbindph12(iph2);
        remph2(iph2);
        delph2(iph2);
@@ -1131,7 +1468,24 @@ isakmp_cfg_rmstate(iph1)
        if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
                isakmp_cfg_putport(iph1, state->port);  
 
+       /* Delete the IV if it's still there */
+       if(iph1->mode_cfg->ivm) {
+               oakley_delivm(iph1->mode_cfg->ivm);
+               iph1->mode_cfg->ivm = NULL;
+       }
+
+       /* Free any allocated splitnet lists */
+       if(iph1->mode_cfg->split_include != NULL)
+               splitnet_list_free(iph1->mode_cfg->split_include,
+                       &iph1->mode_cfg->include_count);
+       if(iph1->mode_cfg->split_local != NULL)
+               splitnet_list_free(iph1->mode_cfg->split_local,
+                       &iph1->mode_cfg->local_count);
+
        xauth_rmstate(&state->xauth);
+       
+       if (state->attr_list)
+               vfree(state->attr_list);
 
        racoon_free(state);
        iph1->mode_cfg = NULL;
@@ -1251,6 +1605,9 @@ isakmp_cfg_accounting(iph1, inout)
        if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
                return isakmp_cfg_accounting_radius(iph1, inout);
 #endif
+       if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
+               return privsep_accounting_system(iph1->mode_cfg->port,
+                       iph1->remote, iph1->mode_cfg->login, inout);
        return 0;
 }
 
@@ -1452,6 +1809,75 @@ isakmp_cfg_radius_common(radius_state, port)
        return 0;
 }
 #endif
+
+/*
+       Logs the user into the utmp system files.
+*/
+
+int
+isakmp_cfg_accounting_system(port, raddr, usr, inout)
+       int port;
+       struct sockaddr *raddr;
+       char *usr;
+       int inout;
+{
+       int error = 0;
+       struct utmpx ut;
+       char term[_UTX_LINESIZE];
+       char addr[NI_MAXHOST];
+       
+       if (usr == NULL || usr[0]=='\0') {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "system accounting : no login found\n");
+               return -1;
+       }
+
+       snprintf(term, sizeof(term), TERMSPEC, port);
+
+       switch (inout) {
+       case ISAKMP_CFG_LOGIN:
+               strlcpy(ut.ut_user, usr, sizeof(ut.ut_user));
+
+               strlcpy(ut.ut_line, term, sizeof(ut.ut_line));
+
+               GETNAMEINFO_NULL(raddr, addr);
+               strlcpy(ut.ut_host, addr, sizeof(ut.ut_host));
+
+               ut.ut_pid = getpid();
+
+               ut.ut_type = UTMPX_AUTOFILL_MASK | USER_PROCESS;
+
+               gettimeofday(&ut.ut_tv, NULL);
+               plog(LLV_INFO, LOCATION, NULL,
+                       "Accounting : '%s' logging on '%s' from %s.\n",
+                       ut.ut_user, ut.ut_line, ut.ut_host);
+
+               if (pututxline(&ut) == NULL)
+                       return -1;
+
+               break;
+       case ISAKMP_CFG_LOGOUT: 
+
+               plog(LLV_INFO, LOCATION, NULL,
+                       "Accounting : '%s' unlogging from '%s'.\n",
+                       usr, term);
+
+               ut.ut_type = UTMPX_AUTOFILL_MASK | DEAD_PROCESS;
+
+               gettimeofday(&ut.ut_tv, NULL);
+
+               if (pututxline(&ut) == NULL)
+                       return -1;
+
+               break;
+       default:
+               plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
+               break;
+       }
+
+       return 0;
+}
        
 int 
 isakmp_cfg_getconfig(iph1)
@@ -1461,6 +1887,7 @@ isakmp_cfg_getconfig(iph1)
        struct isakmp_pl_attr *attrpl;
        struct isakmp_data *attr;
        size_t len;
+       vchar_t *version = NULL;
        int error;
        int attrcount;
        int i;
@@ -1469,13 +1896,37 @@ isakmp_cfg_getconfig(iph1)
                INTERNAL_IP4_NETMASK,
                INTERNAL_IP4_DNS,
                INTERNAL_IP4_NBNS,
-               UNITY_BANNER,
+               INTERNAL_ADDRESS_EXPIRY,
                APPLICATION_VERSION,
+               UNITY_BANNER,
+               UNITY_DEF_DOMAIN,
+               UNITY_SPLITDNS_NAME,
+               UNITY_SPLIT_INCLUDE,
+               UNITY_LOCAL_LAN,
        };
 
        attrcount = sizeof(attrlist) / sizeof(*attrlist);
        len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
-           
+       
+       if (iph1->started_by_api) {
+               if (iph1->remote->sa_family == AF_INET) {
+                       struct vpnctl_socket_elem *sock_elem;
+                       struct bound_addr *bound_addr;
+                       u_int32_t address;
+
+                       address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
+                       LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
+                               LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
+                                       if (bound_addr->address == address) {
+                                               if (version = bound_addr->version)
+                                                       len += bound_addr->version->l;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+       
        if ((buffer = vmalloc(len)) == NULL) {
                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
                return -1;
@@ -1489,13 +1940,28 @@ isakmp_cfg_getconfig(iph1)
        attr = (struct isakmp_data *)(attrpl + 1);
 
        for (i = 0; i < attrcount; i++) {
-               attr->type = htons(attrlist[i]);
-               attr->lorv = htons(0);
-               attr++;
+               switch (attrlist[i]) {
+                       case APPLICATION_VERSION:
+                               if (version) {
+                                       attr->type = htons(attrlist[i]);
+                                       attr->lorv = htons(version->l);
+                                       memcpy(attr + 1, version->v, version->l);
+                                       attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l);
+                                       break;
+                               } else /* fall thru */;
+                       default:
+                               attr->type = htons(attrlist[i]);
+                               attr->lorv = htons(0);
+                               attr++;
+                               break;
+               }
        }
 
+       plog(LLV_DEBUG, LOCATION, NULL, 
+                   "Sending MODE_CFG REQUEST\n");
+
        error = isakmp_cfg_send(iph1, buffer,
-           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
+           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL);
 
        vfree(buffer);
 
@@ -1521,22 +1987,113 @@ isakmp_cfg_getaddr4(attr, ip)
        return;
 }
 
+static void
+isakmp_cfg_appendaddr4(attr, ip, num, max)
+       struct isakmp_data *attr;
+       struct in_addr *ip;
+       int *num;
+       int max;
+{
+       size_t alen = ntohs(attr->lorv);
+       in_addr_t *addr;
+
+       if (alen != sizeof(*ip)) {
+               plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
+               return;
+       }
+       if (*num == max) {
+               plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
+               return;
+       }
+
+       addr = (in_addr_t *)(attr + 1);
+       ip->s_addr = *addr;
+       (*num)++;
+
+       return;
+}
+
+static void
+isakmp_cfg_getstring(attr, str)
+       struct isakmp_data *attr;
+       char *str;
+{
+       size_t alen = ntohs(attr->lorv);
+       char *src;
+       src = (char *)(attr + 1);
+
+       memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
+
+       return;
+}
+
+#define IP_MAX 40
+
+void
+isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
+       char *dest;
+       int count;
+       void *addr;
+       int withmask;
+{
+       int i;
+       int p;
+       int l;
+       struct unity_network tmp;
+       for(i = 0, p = 0; i < count; i++) {
+               if(withmask == 1)
+                       l = sizeof(struct unity_network);
+               else
+                       l = sizeof(struct in_addr);
+               memcpy(&tmp, addr, l);
+               addr += l;
+               if((uint32_t)tmp.addr4.s_addr == 0)
+                       break;
+       
+               inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
+               p += strlen(dest + p);
+               if(withmask == 1) {
+                       dest[p] = '/';
+                       p++;
+                       inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
+                       p += strlen(dest + p);
+               }
+               dest[p] = ' ';
+               p++;
+       }
+       if(p > 0)
+               dest[p-1] = '\0';
+       else
+               dest[0] = '\0';
+}
+
 int
 isakmp_cfg_setenv(iph1, envp, envc)
        struct ph1handle *iph1; 
        char ***envp;
        int *envc;
 {
-#define IP_MAX 40
        char addrstr[IP_MAX];
+       char addrlist[IP_MAX * MAXNS + MAXNS];
+       char *splitlist = addrlist;
+       char defdom[MAXPATHLEN + 1];
+       int cidr, tmp;
+       char cidrstr[4];
+       int i, p;
+       int test;
+
+       plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
 
        /* 
         * Internal IPv4 address, either if 
         * we are a client or a server.
         */
        if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
+#ifdef HAVE_LIBLDAP
+           (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
+#endif
 #ifdef HAVE_LIBRADIUS
-           (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS) ||
+           (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
 #endif
            (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
                inet_ntop(AF_INET, &iph1->mode_cfg->addr4, 
@@ -1549,6 +2106,15 @@ isakmp_cfg_setenv(iph1, envp, envc)
                return -1;
        }
 
+       if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
+               if (script_env_append(envp, envc, "XAUTH_USER", 
+                   iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                           "Cannot set XAUTH_USER\n");
+                       return -1;
+               }
+       }
+
        /* Internal IPv4 mask */
        if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) 
                inet_ntop(AF_INET, &iph1->mode_cfg->mask4, 
@@ -1556,45 +2122,250 @@ isakmp_cfg_setenv(iph1, envp, envc)
        else
                addrstr[0] = '\0';
 
-       /* 
-       * During several releases, documentation adverised INTERNAL_NETMASK4
-       * while code was using INTERNAL_MASK4. We now do both.
-       */
-       if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
-                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
-                return -1;
-        } 
-
-       if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
-              plog(LLV_ERROR, LOCATION, NULL,  
-                  "Cannot set INTERNAL_NETMASK4\n");
-              return -1;
-       }
+       /*      
+        * During several releases, documentation adverised INTERNAL_NETMASK4
+        * while code was using INTERNAL_MASK4. We now do both.
+        */
 
+       if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { 
+               plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
+               return -1;
+       }
+
+       if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { 
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "Cannot set INTERNAL_NETMASK4\n");
+               return -1;
+       }
+
+       tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
+       for (cidr = 0; tmp != 0; cidr++)
+               tmp <<= 1;
+       snprintf(cidrstr, 3, "%d", cidr);
+
+       if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
+               plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
+               return -1;
+       }
 
        /* Internal IPv4 DNS */
-       if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) 
-               inet_ntop(AF_INET, &iph1->mode_cfg->dns4, 
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
+               /* First Internal IPv4 DNS (for compatibilty with older code */
+               inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0], 
                    addrstr, IP_MAX);
-       else
+
+               /* Internal IPv4 DNS - all */
+               isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
+                       (void *)iph1->mode_cfg->dns4, 0);
+       } else {
                addrstr[0] = '\0';
+               addrlist[0] = '\0';
+       }
 
-       if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) { 
+       if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
                plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
                return -1;
        }
-
+       if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "Cannot set INTERNAL_DNS4_LIST\n");
+               return -1;
+       }
+       
        /* Internal IPv4 WINS */
-       if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) 
-               inet_ntop(AF_INET, &iph1->mode_cfg->wins4, 
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
+               /* 
+                * First Internal IPv4 WINS 
+                * (for compatibilty with older code 
+                */
+               inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0], 
                    addrstr, IP_MAX);
-       else
+
+               /* Internal IPv4 WINS - all */
+               isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
+                       (void *)iph1->mode_cfg->wins4, 0);
+       } else {
                addrstr[0] = '\0';
+               addrlist[0] = '\0';
+       }
 
-       if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) { 
-               plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_WINS4\n");
+       if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "Cannot set INTERNAL_WINS4\n");
+               return -1;
+       }
+       if (script_env_append(envp, envc, 
+           "INTERNAL_WINS4_LIST", addrlist) != 0) {
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "Cannot set INTERNAL_WINS4_LIST\n");
                return -1;
        }
 
+       /* Deault domain */
+       if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) 
+               strlcpy(defdom, 
+                   iph1->mode_cfg->default_domain, 
+                   sizeof(defdom));
+       else
+               defdom[0] = '\0';
+       
+       if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) { 
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "Cannot set DEFAULT_DOMAIN\n");
+               return -1;
+       }
+
+       /* Split networks */
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE)
+               splitlist = splitnet_list_2str(iph1->mode_cfg->split_include);
+       else {
+               splitlist = addrlist;
+               addrlist[0] = '\0';
+       }
+
+       if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
+               plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
+               return -1;
+       }
+       if (splitlist != addrlist)
+               racoon_free(splitlist);
+
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL)
+               splitlist = splitnet_list_2str(iph1->mode_cfg->split_local);
+       else {
+               splitlist = addrlist;
+               addrlist[0] = '\0';
+       }
+
+       if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
+               plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
+               return -1;
+       }
+       if (splitlist != addrlist)
+               racoon_free(splitlist);
+       
        return 0;
 }
+
+int
+isakmp_cfg_resize_pool(size)
+       int size;
+{
+       struct isakmp_cfg_port *new_pool;
+       size_t len;
+       int i;
+
+       if (size == isakmp_cfg_config.pool_size)
+               return 0;
+
+       plog(LLV_INFO, LOCATION, NULL,
+           "Resize address pool from %zu to %d\n",
+           isakmp_cfg_config.pool_size, size);
+
+       /* If a pool already exists, check if we can shrink it */
+       if ((isakmp_cfg_config.port_pool != NULL) &&
+           (size < isakmp_cfg_config.pool_size)) {
+               for (i = isakmp_cfg_config.pool_size; i >= size; --i) {
+                       if (isakmp_cfg_config.port_pool[i].used) {
+                               plog(LLV_ERROR, LOCATION, NULL, 
+                                   "resize pool from %zu to %d impossible "
+                                   "port %d is in use\n", 
+                                   isakmp_cfg_config.pool_size, size, i);
+                               size = i;
+                               break;
+                       }       
+               }
+       }
+
+       len = size * sizeof(*isakmp_cfg_config.port_pool);
+       new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
+       if (new_pool == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "resize pool from %zu to %d impossible: %s",
+                   isakmp_cfg_config.pool_size, size, strerror(errno));
+               return -1;
+       }
+
+       /* If size increase, intialize correctly the new records */
+       if (size > isakmp_cfg_config.pool_size) {
+               size_t unit;
+               size_t old_size;
+
+               unit =  sizeof(*isakmp_cfg_config.port_pool);
+               old_size = isakmp_cfg_config.pool_size;
+
+               bzero((char *)new_pool + (old_size * unit), 
+                   (size - old_size) * unit);
+       }
+
+       isakmp_cfg_config.port_pool = new_pool;
+       isakmp_cfg_config.pool_size = size;
+
+       return 0;
+}
+
+int
+isakmp_cfg_init(cold) 
+       int cold;
+{
+       int i;
+       int error;
+
+       isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
+       isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
+       for (i = 0; i < MAXNS; i++)
+               isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
+       isakmp_cfg_config.dns4_index = 0;
+       for (i = 0; i < MAXWINS; i++)
+               isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
+       isakmp_cfg_config.nbns4_index = 0;
+       if (cold != ISAKMP_CFG_INIT_COLD) {
+               if (isakmp_cfg_config.port_pool) {
+                       racoon_free(isakmp_cfg_config.port_pool);
+               }
+       }
+       isakmp_cfg_config.port_pool = NULL;
+       isakmp_cfg_config.pool_size = 0;
+       isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
+       isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
+       if (cold != ISAKMP_CFG_INIT_COLD) {
+               if (isakmp_cfg_config.grouplist != NULL) {
+                       for (i = 0; i < isakmp_cfg_config.groupcount; i++)
+                               racoon_free(isakmp_cfg_config.grouplist[i]);
+                       racoon_free(isakmp_cfg_config.grouplist);
+               }
+       }
+       isakmp_cfg_config.grouplist = NULL;
+       isakmp_cfg_config.groupcount = 0;
+       isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
+       isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
+       isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
+       strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
+           sizeof(isakmp_cfg_config.default_domain));
+       strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd));
+
+       if (cold != ISAKMP_CFG_INIT_COLD )
+               if (isakmp_cfg_config.splitnet_list != NULL)
+                       splitnet_list_free(isakmp_cfg_config.splitnet_list,
+                               &isakmp_cfg_config.splitnet_count);
+       isakmp_cfg_config.splitnet_list = NULL;
+       isakmp_cfg_config.splitnet_count = 0;
+       isakmp_cfg_config.splitnet_type = 0;
+
+       isakmp_cfg_config.pfs_group = 0;
+       isakmp_cfg_config.save_passwd = 0;
+
+       if (cold != ISAKMP_CFG_INIT_COLD )
+               if (isakmp_cfg_config.splitdns_list != NULL)
+                       racoon_free(isakmp_cfg_config.splitdns_list);
+       isakmp_cfg_config.splitdns_list = NULL;
+       isakmp_cfg_config.splitdns_len = 0;
+
+       if (cold == ISAKMP_CFG_INIT_COLD) {
+               if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
+                       return error;
+       }
+
+       return 0;
+}
+
index ba45ef842ceb4e5fe47f0534b5b779fe904387fd..1a0ce038a73a54ddf0511ad61baadca2e02bdb92 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: isakmp_cfg.h,v 1.6 2006/09/09 16:22:09 manu Exp $      */
+
 /*     $KAME$ */
 
 /*
  */
 
 #ifdef HAVE_LIBPAM
-#ifdef __APPLE__
-#include <pam/pam_appl.h>
-#else
 #include <security/pam_appl.h>
 #endif
-#endif
 
 /* 
  * XXX don't forget to update 
 #define INTERNAL_IP6_SUBNET        15
 
 /* For APPLICATION_VERSION */
-#define ISAKMP_CFG_RACOON_VERSION "KAME/racoon " \
-                                 "+ Hybrid auth Patches <manu@netbsd.org>"
+#define ISAKMP_CFG_RACOON_VERSION "racoon / IPsec-tools"
+
+/* For the wins servers -- XXX find the value somewhere ? */
+#define MAXWINS 4
 
 /* 
  * Global configuration for ISAKMP mode confiration address allocation 
- * Readen from the mode_cfg section of racoon.conf
+ * Read from the mode_cfg section of racoon.conf
  */
 struct isakmp_cfg_port {
        char    used;
@@ -76,34 +76,57 @@ struct isakmp_cfg_port {
 };
 
 struct isakmp_cfg_config {
-       in_addr_t       network4;
-       in_addr_t       netmask4;
-       in_addr_t       dns4;
-       in_addr_t       nbns4;
-       struct isakmp_cfg_port *port_pool;
-       int authsource;
-       int confsource;
-       int accounting;
-       size_t pool_size;
-       int auth_throttle;
-       char motd[MAXPATHLEN + 1];
-       int pfs_group;
-       int save_passwd;
+       in_addr_t               network4;
+       in_addr_t               netmask4;
+       in_addr_t               dns4[MAXNS];
+       int                     dns4_index;
+       in_addr_t               nbns4[MAXWINS];
+       int                     nbns4_index;
+       struct isakmp_cfg_port  *port_pool;
+       int                     authsource;
+       int                     groupsource;
+       char                    **grouplist;
+       int                     groupcount;
+       int                     confsource;
+       int                     accounting;
+       size_t                  pool_size;
+       int                     auth_throttle;
+       /* XXX move this to a unity specific sub-structure */
+       char                    default_domain[MAXPATHLEN + 1];
+       char                    motd[MAXPATHLEN + 1];
+       struct unity_netentry   *splitnet_list;
+       int                     splitnet_count;
+       int                     splitnet_type;
+       char                    *splitdns_list;
+       int                     splitdns_len;
+       int                     pfs_group;
+       int                     save_passwd;
 };
 
+/* For utmp updating */
+#define TERMSPEC       "vpn%d"
+
 /* For authsource */
 #define ISAKMP_CFG_AUTH_SYSTEM 0
 #define ISAKMP_CFG_AUTH_RADIUS 1
 #define ISAKMP_CFG_AUTH_PAM    2
+#define ISAKMP_CFG_AUTH_LDAP   4
+
+/* For groupsource */
+#define ISAKMP_CFG_GROUP_SYSTEM        0
+#define ISAKMP_CFG_GROUP_LDAP  1
 
 /* For confsource */
 #define ISAKMP_CFG_CONF_LOCAL  0
 #define ISAKMP_CFG_CONF_RADIUS 1
+#define ISAKMP_CFG_CONF_LDAP   2
 
 /* For accounting */
 #define ISAKMP_CFG_ACCT_NONE   0
 #define ISAKMP_CFG_ACCT_RADIUS 1
 #define ISAKMP_CFG_ACCT_PAM    2
+#define ISAKMP_CFG_ACCT_LDAP   3
+#define ISAKMP_CFG_ACCT_SYSTEM 4
 
 /* For pool_size */
 #define ISAKMP_CFG_MAX_CNX     255
@@ -111,6 +134,9 @@ struct isakmp_cfg_config {
 /* For motd */
 #define ISAKMP_CFG_MOTD        "/etc/motd"
 
+/* For default domain */
+#define ISAKMP_CFG_DEFAULT_DOMAIN ""
+
 extern struct isakmp_cfg_config isakmp_cfg_config;
 
 /*
@@ -123,18 +149,29 @@ struct isakmp_cfg_state {
        char login[LOGINLEN + 1];       /* login */
        struct in_addr addr4;           /* IPv4 address */
        struct in_addr mask4;           /* IPv4 netmask */
-       struct in_addr dns4;            /* IPv4 DNS (when client only) */
-       struct in_addr wins4;           /* IPv4 WINS (when client only) */
+       struct in_addr dns4[MAXNS];     /* IPv4 DNS (when client only) */
+       int dns4_index;                 /* Number of IPv4 DNS (client only) */
+       struct in_addr wins4[MAXWINS];  /* IPv4 WINS (when client only) */
+       int wins4_index;                /* Number of IPv4 WINS (client only) */
+       char default_domain[MAXPATHLEN + 1];    /* Default domain recieved */
+       struct unity_netentry 
+           *split_include;             /* UNITY_SPLIT_INCLUDE */
+       int include_count;              /* Number of SPLIT_INCLUDES */
+       struct unity_netentry 
+           *split_local;               /* UNITY_LOCAL_LAN */
+       int local_count;                /* Number of SPLIT_LOCAL */
        struct xauth_state xauth;       /* Xauth state, if revelant */          
        struct isakmp_ivm *ivm;         /* XXX Use iph1's ivm? */
+       u_int32_t last_msgid;           /* Last message-ID */
+       vchar_t *attr_list;                     /* list of mode config attributes - used when started by api */
 };
 
 /* flags */
 #define ISAKMP_CFG_VENDORID_XAUTH      0x01    /* Supports Xauth */
 #define ISAKMP_CFG_VENDORID_UNITY      0x02    /* Cisco Unity compliant */
 #define ISAKMP_CFG_PORT_ALLOCATED      0x04    /* Port allocated */
-#define ISAKMP_CFG_ADDR4_RADIUS                0x08    /* Address from RADIUS  */
-#define ISAKMP_CFG_MASK4_RADIUS                0x10    /* Netmask from RADIUS */
+#define ISAKMP_CFG_ADDR4_EXTERN                0x08    /* Address from external config  */
+#define ISAKMP_CFG_MASK4_EXTERN                0x10    /* Netmask from external config */
 #define ISAKMP_CFG_ADDR4_LOCAL         0x20    /* Address from local pool */
 #define ISAKMP_CFG_MASK4_LOCAL         0x40    /* Netmask from local pool */
 #define ISAKMP_CFG_GOT_ADDR4           0x80    /* Client got address */
@@ -142,27 +179,36 @@ struct isakmp_cfg_state {
 #define ISAKMP_CFG_GOT_DNS4            0x200   /* Client got DNS */
 #define ISAKMP_CFG_GOT_WINS4           0x400   /* Client got WINS */
 #define ISAKMP_CFG_DELETE_PH1          0x800   /* phase 1 should be deleted */
+#define ISAKMP_CFG_GOT_DEFAULT_DOMAIN  0x1000  /* Client got default domain */
+#define ISAKMP_CFG_GOT_SPLIT_INCLUDE   0x2000  /* Client got a split network config */
+#define ISAKMP_CFG_GOT_SPLIT_LOCAL     0x4000  /* Client got a split LAN config */
+#define ISAKMP_CFG_GOT_REPLY           0x8000  /* got config data from reply - don't process again */
 
 struct isakmp_pl_attr;
 struct ph1handle;
 struct isakmp_ivm;
 void isakmp_cfg_r(struct ph1handle *, vchar_t *);
-int isakmp_cfg_attr_r(struct ph1handle *, u_int32_t, struct isakmp_pl_attr *);
+int isakmp_cfg_attr_r(struct ph1handle *, u_int32_t, struct isakmp_pl_attr *, vchar_t *);
 int isakmp_cfg_reply(struct ph1handle *, struct isakmp_pl_attr *);
-int isakmp_cfg_request(struct ph1handle *, struct isakmp_pl_attr *);
-int isakmp_cfg_set(struct ph1handle *, struct isakmp_pl_attr *);
-int isakmp_cfg_send(struct ph1handle *, vchar_t *, u_int32_t, int, int);
+int isakmp_cfg_request(struct ph1handle *, struct isakmp_pl_attr *, vchar_t *);
+int isakmp_cfg_set(struct ph1handle *, struct isakmp_pl_attr *, vchar_t *);
+int isakmp_cfg_send(struct ph1handle *, vchar_t *, u_int32_t, int, int, int, vchar_t *);
 struct isakmp_ivm *isakmp_cfg_newiv(struct ph1handle *, u_int32_t);
 void isakmp_cfg_rmstate(struct ph1handle *);
 struct isakmp_cfg_state *isakmp_cfg_mkstate(void);
 vchar_t *isakmp_cfg_copy(struct ph1handle *, struct isakmp_data *);
 vchar_t *isakmp_cfg_short(struct ph1handle *, struct isakmp_data *, int);
+vchar_t *isakmp_cfg_varlen(struct ph1handle *, struct isakmp_data *, char *, size_t);
 vchar_t *isakmp_cfg_string(struct ph1handle *, struct isakmp_data *, char *);
 int isakmp_cfg_getconfig(struct ph1handle *);
 int isakmp_cfg_setenv(struct ph1handle *, char ***, int *);
 
-int isakmp_cfg_getport(struct ph1handle *);       
+int isakmp_cfg_resize_pool(int);
+int isakmp_cfg_getport(struct ph1handle *);
 int isakmp_cfg_putport(struct ph1handle *, unsigned int);
+int isakmp_cfg_init(int);
+#define ISAKMP_CFG_INIT_COLD   1
+#define ISAKMP_CFG_INIT_WARM   0
 
 #ifdef HAVE_LIBRADIUS
 struct rad_handle;
@@ -174,3 +220,5 @@ int isakmp_cfg_radius_common(struct rad_handle *, int);
 int isakmp_cfg_accounting_pam(int, int);
 void cleanup_pam(int);
 #endif
+
+int isakmp_cfg_accounting_system(int, struct sockaddr *, char *, int);
index e728c74cb99aeae354189c4ebb45a0fcac933a32..64228239e9484478975df488bf4c6b09e1732c35 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp $ */
+/*     $NetBSD: isakmp_frag.c,v 1.4 2006/09/09 16:22:09 manu Exp $     */
+
+/* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
@@ -147,10 +149,10 @@ isakmp_sendfrags(iph1, buf)
                memcpy(data, sdata, datalen);
 
                if (isakmp_send(iph1, frag) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL, "isakmp_send failed\n");
+                       plog(LLV_ERROR, LOCATION, iph1->remote, "isakmp_send failed\n");
                        return -1;
                }
-
+               
                vfree(frag);
 
                len -= datalen;
index 52ee10a4251bd73496e5091ed79d67603548ed35..f2d4c335916972391bed4d002d3bce78c1225030 100644 (file)
@@ -1,4 +1,6 @@
-/*     $Id: isakmp_frag.h,v 1.2 2004/10/24 16:51:24 manubsd Exp $ */
+/*     $NetBSD: isakmp_frag.h,v 1.5 2006/09/18 20:32:40 manu Exp $     */
+
+/*     Id: isakmp_frag.h,v 1.3 2005/04/09 16:25:24 manubsd Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus 
  * SUCH DAMAGE.
  */
 
+/* These are the values from parsing "remote {}"
+   block of the config file. */
+#define ISAKMP_FRAG_OFF                FLASE   /* = 0 */
+#define ISAKMP_FRAG_ON         TRUE    /* = 1 */
+#define ISAKMP_FRAG_FORCE      2
+
 /* IKE fragmentation capabilities */
+#define VENDORID_FRAG_IDENT    0x80000000
 #define VENDORID_FRAG_BASE     0x40000000
 #define VENDORID_FRAG_AGG      0x80000000
 
index d9e6cf9bbfdf4292b0557d7c8aea9ddfae907de4..6488207f5b613f48d844371af74c430626584a01 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_ident.c,v 1.13.2.2 2005/11/21 09:46:23 vanhu Exp $ */
+/*     $NetBSD: isakmp_ident.c,v 1.6 2006/10/02 21:41:59 manu Exp $    */
+
+/* Id: isakmp_ident.c,v 1.21 2006/04/06 16:46:08 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 #ifdef HAVE_GSSAPI
 #include "gssapi.h"
 #endif
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#include "isakmp_xauth.h"
+#include "isakmp_cfg.h"
+#endif
+#ifdef ENABLE_FRAG 
+#include "isakmp_frag.h"
+#endif
 
 #include "vpn_control.h"
 #include "vpn_control_var.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
 
 static vchar_t *ident_ir2mx __P((struct ph1handle *));
 static vchar_t *ident_ir3mx __P((struct ph1handle *));
@@ -107,6 +119,13 @@ ident_i1send(iph1, msg)
        vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
        int i;
 #endif
+#ifdef ENABLE_HYBRID  
+       vchar_t *vid_xauth = NULL;
+       vchar_t *vid_unity = NULL;
+#endif
+#ifdef ENABLE_FRAG 
+       vchar_t *vid_frag = NULL;
+#endif 
 #ifdef ENABLE_DPD
        vchar_t *vid_dpd = NULL;
 #endif
@@ -128,8 +147,11 @@ ident_i1send(iph1, msg)
 
        /* create SA payload for my proposal */
        iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
-       if (iph1->sa == NULL)
+       if (iph1->sa == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set proposal");
                goto end;
+       }
 
        /* set SA payload to propose */
        plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
@@ -139,12 +161,53 @@ ident_i1send(iph1, msg)
        if (iph1->rmconf->nat_traversal) 
                plist = isakmp_plist_append_natt_vids(plist, vid_natt);
 #endif
+#ifdef ENABLE_HYBRID
+       /* Do we need Xauth VID? */
+       switch (RMAUTHMETHOD(iph1)) {
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+               if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
+                       plog(LLV_ERROR, LOCATION, NULL,
+                            "Xauth vendor ID generation failed\n");
+               else
+                       plist = isakmp_plist_append(plist,
+                           vid_xauth, ISAKMP_NPTYPE_VID);
+                       
+               if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
+                       plog(LLV_ERROR, LOCATION, NULL,
+                            "Unity vendor ID generation failed\n");
+               else
+                       plist = isakmp_plist_append(plist,
+                           vid_unity, ISAKMP_NPTYPE_VID);
+               break;
+       default:
+               break;
+       }
+#endif
+#ifdef ENABLE_FRAG
+       if (iph1->rmconf->ike_frag) {
+               if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Frag vendorID construction failed\n");
+               } else {
+                       vid_frag = isakmp_frag_addcap(vid_frag,
+                           VENDORID_FRAG_IDENT);
+                       plist = isakmp_plist_append(plist, 
+                           vid_frag, ISAKMP_NPTYPE_VID);
+               }
+       }
+#endif
 #ifdef ENABLE_DPD
        if(iph1->rmconf->dpd){
                vid_dpd = set_vendorid(VENDORID_DPD);
                if (vid_dpd != NULL)
                        plist = isakmp_plist_append(plist, vid_dpd,
-                                                                               ISAKMP_NPTYPE_VID);
+                           ISAKMP_NPTYPE_VID);
        }
 #endif
 
@@ -156,18 +219,42 @@ ident_i1send(iph1, msg)
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        iph1->status = PHASE1ST_MSG1SENT;
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Initiator, Main-Mode message 1"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Initiator, Main-Mode Message 1"),
+                                                               CONSTSTR("Failed to transmit Main-Mode Message 1"));
+       }
+#ifdef ENABLE_FRAG
+       if (vid_frag) 
+               vfree(vid_frag);
+#endif  
 #ifdef ENABLE_NATT
        for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
                vfree(vid_natt[i]);
 #endif
+#ifdef ENABLE_HYBRID
+       if (vid_xauth != NULL)
+               vfree(vid_xauth);
+       if (vid_unity != NULL)
+               vfree(vid_unity);
+#endif
 #ifdef ENABLE_DPD
        if (vid_dpd != NULL)
                vfree(vid_dpd);
@@ -212,8 +299,11 @@ ident_i2recv(iph1, msg)
         * NOTE: even if there's multiple VID/N, we'll ignore them.
         */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
        pa = (struct isakmp_parse_t *)pbuf->v;
 
        /* SA payload is fixed postion */
@@ -224,8 +314,11 @@ ident_i2recv(iph1, msg)
                        pa->type, ISAKMP_NPTYPE_SA);
                goto end;
        }
-       if (isakmp_p2ph(&satmp, pa->ptr) < 0)
+       if (isakmp_p2ph(&satmp, pa->ptr) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to process SA payload");
                goto end;
+       }
        pa++;
 
        for (/*nothing*/;
@@ -239,6 +332,22 @@ ident_i2recv(iph1, msg)
                        if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
                          natt_handle_vendorid(iph1, vid_numeric);
 #endif
+#ifdef ENABLE_HYBRID
+                       switch (vid_numeric) {
+                       case VENDORID_XAUTH:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_XAUTH;
+                               break;
+       
+                       case VENDORID_UNITY:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_UNITY;
+                               break;
+       
+                       default:
+                               break;
+                       }
+#endif  
 #ifdef ENABLE_DPD
                        if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
                                iph1->dpd_support=1;
@@ -278,7 +387,18 @@ ident_i2recv(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Initiator, Main-Mode message 2"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Initiator, Main-Mode Message 2"),
+                                                               CONSTSTR("Failed to process Main-Mode Message 2"));
+       }
        if (pbuf)
                vfree(pbuf);
        if (satmp)
@@ -315,24 +435,36 @@ ident_i2send(iph1, msg)
 
        /* generate DH public value */
        if (oakley_dh_generate(iph1->approval->dhgrp,
-                               &iph1->dhpub, &iph1->dhpriv) < 0)
+                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate DH");
                goto end;
+       }
 
        /* generate NONCE value */
        iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
-       if (iph1->nonce == NULL)
+       if (iph1->nonce == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate NONCE");
                goto end;
+       }
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
-           gssapi_get_itoken(iph1, NULL) < 0)
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
+           gssapi_get_itoken(iph1, NULL) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to get GSS token");
                goto end;
+       }
 #endif
 
        /* create buffer to send isakmp payload */
        iph1->sendbuf = ident_ir2mx(iph1);
-       if (iph1->sendbuf == NULL)
+       if (iph1->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to create send buffer");
                goto end;
+       }
 
 #ifdef HAVE_PRINT_ISAKMP_C
        isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
@@ -340,11 +472,15 @@ ident_i2send(iph1, msg)
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -354,7 +490,18 @@ ident_i2send(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Initiator, Main-Mode message 3"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Initiator, Main-Mode Message 3"),
+                                                               CONSTSTR("Failed to transmit Main-Mode Message 3"));
+       }
        return error;
 }
 
@@ -374,6 +521,7 @@ ident_i3recv(iph1, msg)
        vchar_t *pbuf = NULL;
        struct isakmp_parse_t *pa;
        int error = -1;
+       int vid_numeric;
 #ifdef HAVE_GSSAPI
        vchar_t *gsstoken = NULL;
 #endif
@@ -391,8 +539,11 @@ ident_i3recv(iph1, msg)
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
 
        for (pa = (struct isakmp_parse_t *)pbuf->v;
             pa->type != ISAKMP_NPTYPE_NONE;
@@ -400,24 +551,57 @@ ident_i3recv(iph1, msg)
 
                switch (pa->type) {
                case ISAKMP_NPTYPE_KE:
-                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process KE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_NONCE:
-                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process NONCE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_VID:
-                       (void)check_vendorid(pa->ptr);
+                       vid_numeric = check_vendorid(pa->ptr);
+#ifdef ENABLE_HYBRID
+                       switch (vid_numeric) {
+                       case VENDORID_XAUTH:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_XAUTH;
+                               break;
+       
+                       case VENDORID_UNITY:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_UNITY;
+                               break;
+       
+                       default:
+                               break;
+                       }
+#endif  
+#ifdef ENABLE_DPD
+                       if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
+                               iph1->dpd_support=1;
+#endif
+                               
                        break;
                case ISAKMP_NPTYPE_CR:
-                       if (oakley_savecr(iph1, pa->ptr) < 0)
+                       if (oakley_savecr(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CR payload");
                                goto end;
+                       }
                        break;
 #ifdef HAVE_GSSAPI
                case ISAKMP_NPTYPE_GSS:
-                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
+                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process GSS payload");
                                goto end;
+                       }
                        gssapi_save_received_token(iph1, gsstoken);
                        break;
 #endif
@@ -431,8 +615,11 @@ ident_i3recv(iph1, msg)
                        if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
                            pa->type == iph1->natt_options->payload_nat_d) {
                                natd_received = NULL;
-                               if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
+                               if (isakmp_p2ph (&natd_received, pa->ptr) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                                "failed to process NATD payload");
                                        goto end;
+                               }
                         
                                /* set both bits first so that we can clear them
                                   upon verifying hashes */
@@ -494,7 +681,22 @@ ident_i3recv(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Initiator, Main-Mode message 4"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Initiator, Main-Mode Message 4"),
+                                                               CONSTSTR("Failed to process Main-Mode Message 4"));
+       }
+#ifdef HAVE_GSSAPI
+       if (gsstoken)
+               vfree(gsstoken);
+#endif
        if (pbuf)
                vfree(pbuf);
        if (error) {
@@ -536,29 +738,50 @@ ident_i3send(iph1, msg0)
 
        /* compute sharing secret of DH */
        if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
-                               iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
+                                                 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute DH");
                goto end;
+       }
 
        /* generate SKEYIDs & IV & final cipher key */
-       if (oakley_skeyid(iph1) < 0)
+       if (oakley_skeyid(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID");
                goto end;
-       if (oakley_skeyid_dae(iph1) < 0)
+       }
+       if (oakley_skeyid_dae(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID-DAE");
                goto end;
-       if (oakley_compute_enckey(iph1) < 0)
+       }
+       if (oakley_compute_enckey(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate ENCKEY");
                goto end;
-       if (oakley_newiv(iph1) < 0)
+       }
+       if (oakley_newiv(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate IV");
                goto end;
+       }
 
        /* make ID payload into isakmp status */
-       if (ipsecdoi_setid1(iph1) < 0)
+       if (ipsecdoi_setid1(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set ID");
                goto end;
+       }
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
            gssapi_more_tokens(iph1)) {
                plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n");
-               if (gssapi_get_itoken(iph1, &len) < 0)
+               if (gssapi_get_itoken(iph1, &len) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to get GSSAPI token");
                        goto end;
+               }
                if (len != 0)
                        dohash = 0;
        }
@@ -567,8 +790,11 @@ ident_i3send(iph1, msg0)
        /* generate HASH to send */
        if (dohash) {
                iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
-               if (iph1->hash == NULL)
+               if (iph1->hash == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate HASH");
                        goto end;
+               }
        } else
                iph1->hash = NULL;
 
@@ -577,16 +803,23 @@ ident_i3send(iph1, msg0)
 
        /* create HDR;ID;HASH payload */
        iph1->sendbuf = ident_ir3mx(iph1);
-       if (iph1->sendbuf == NULL)
+       if (iph1->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to allocate send buffer");
                goto end;
+       }
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -599,7 +832,18 @@ ident_i3send(iph1, msg0)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Initiator, Main-Mode message 5"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Initiator, Main-Mode Message 5"),
+                                                               CONSTSTR("Failed to transmit Main-Mode Message 5"));
+       }
        return error;
 }
 
@@ -621,6 +865,7 @@ ident_i4recv(iph1, msg0)
        vchar_t *msg = NULL;
        int error = -1;
        int type;
+       int vid_numeric;
 #ifdef HAVE_GSSAPI
        vchar_t *gsstoken = NULL;
 #endif
@@ -640,13 +885,19 @@ ident_i4recv(iph1, msg0)
                goto end;
        }
        msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
-       if (msg == NULL)
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to decrypt");
                goto end;
+       }
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
 
        iph1->pl_hash = NULL;
 
@@ -656,30 +907,46 @@ ident_i4recv(iph1, msg0)
 
                switch (pa->type) {
                case ISAKMP_NPTYPE_ID:
-                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process ID payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_HASH:
                        iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
                        break;
                case ISAKMP_NPTYPE_CERT:
-                       if (oakley_savecert(iph1, pa->ptr) < 0)
+                       if (oakley_savecert(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CERT payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_SIG:
-                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process SIG payload");
                                goto end;
+                       }
                        break;
 #ifdef HAVE_GSSAPI
                case ISAKMP_NPTYPE_GSS:
-                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
+                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process GSS payload");
                                goto end;
+                       }
                        gssapi_save_received_token(iph1, gsstoken);
                        break;
 #endif
                case ISAKMP_NPTYPE_VID:
-                       (void)check_vendorid(pa->ptr);
-                       break;
+                               vid_numeric = check_vendorid(pa->ptr);
+#ifdef ENABLE_DPD
+                               if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
+                                       iph1->dpd_support=1;
+#endif
+                               break;
                case ISAKMP_NPTYPE_N:
                        isakmp_check_notify(pa->ptr, iph1);
                        break;
@@ -708,6 +975,10 @@ ident_i4recv(iph1, msg0)
 #endif
                type = oakley_validate_auth(iph1);
                if (type != 0) {
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL,
+                                                                       CONSTSTR("Initiator, Main-Mode Message 6"),
+                                                                       CONSTSTR("Failed to authenticate Main-Mode Message 6"));
                        if (type == -1) {
                                /* msg printed inner oakley_validate_auth() */
                                goto end;
@@ -717,6 +988,10 @@ ident_i4recv(iph1, msg0)
                        isakmp_info_send_n1(iph1, type, NULL);
                        goto end;
                }
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC,
+                                                               CONSTSTR("Initiator, Main-Mode Message 6"),
+                                                               CONSTSTR(NULL));
 #ifdef HAVE_GSSAPI
        }
 #endif
@@ -744,7 +1019,18 @@ ident_i4recv(iph1, msg0)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Initiator, Main-Mode message 6"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Initiator, Main-Mode Message 6"),
+                                                               CONSTSTR("Failed to transmit Main-Mode Message 6"));
+       }
        if (pbuf)
                vfree(pbuf);
        if (msg)
@@ -788,6 +1074,11 @@ ident_i4send(iph1, msg)
 
        iph1->status = PHASE1ST_ESTABLISHED;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC,
+                                                       CONSTSTR("Initiator, Main-Mode"),
+                                                       CONSTSTR(NULL));
+       
        error = 0;
 
 end:
@@ -823,8 +1114,11 @@ ident_r1recv(iph1, msg)
         * NOTE: XXX even if multiple VID, we'll silently ignore those.
         */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
        pa = (struct isakmp_parse_t *)pbuf->v;
 
        /* check the position of SA payload */
@@ -835,8 +1129,11 @@ ident_r1recv(iph1, msg)
                        pa->type, ISAKMP_NPTYPE_SA);
                goto end;
        }
-       if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
+       if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to process SA payload");
                goto end;
+       }
        pa++;
 
        for (/*nothing*/;
@@ -850,6 +1147,27 @@ ident_r1recv(iph1, msg)
                        if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
                                natt_handle_vendorid(iph1, vid_numeric);
 #endif
+#ifdef ENABLE_FRAG
+                       if ((vid_numeric == VENDORID_FRAG) &&
+                           (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT))
+                               iph1->frag = 1;
+#endif   
+#ifdef ENABLE_HYBRID
+                       switch (vid_numeric) {
+                       case VENDORID_XAUTH:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_XAUTH;
+                               break;
+               
+                       case VENDORID_UNITY:
+                               iph1->mode_cfg->flags |=
+                                   ISAKMP_CFG_VENDORID_UNITY;
+                               break;
+       
+                       default:  
+                               break;
+                       }
+#endif
 #ifdef ENABLE_DPD
                        if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
                                iph1->dpd_support=1;
@@ -890,7 +1208,18 @@ ident_r1recv(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Responder, Main-Mode message 1"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Responder, Main-Mode Message 1"),
+                                                               CONSTSTR("Failed to process Main-Mode Message 1"));
+       }
        if (pbuf)
                vfree(pbuf);
        if (error) {
@@ -915,13 +1244,22 @@ ident_r1send(iph1, msg)
        struct payload_list *plist = NULL;
        int error = -1;
        vchar_t *gss_sa = NULL;
-       vchar_t *vid = NULL;
+#ifdef HAVE_GSSAPI
+       int free_gss_sa = 0;
+#endif
 #ifdef ENABLE_NATT
        vchar_t *vid_natt = NULL;
 #endif
+#ifdef ENABLE_HYBRID
+        vchar_t *vid_xauth = NULL;
+        vchar_t *vid_unity = NULL;
+#endif  
 #ifdef ENABLE_DPD
        vchar_t *vid_dpd = NULL;
 #endif
+#ifdef ENABLE_FRAG          
+       vchar_t *vid_frag = NULL;
+#endif 
 
        /* validity check */
        if (iph1->status != PHASE1ST_MSG1RECEIVED) {
@@ -934,19 +1272,39 @@ ident_r1send(iph1, msg)
        isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->gssid != NULL)
+       if (iph1->approval->gssid != NULL) {
                gss_sa = ipsecdoi_setph1proposal(iph1->approval);
-       else
+               if (gss_sa != iph1->sa_ret)
+                       free_gss_sa = 1;
+       } else 
 #endif
                gss_sa = iph1->sa_ret;
 
        /* set SA payload to reply */
        plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA);
 
-       /* Set Vendor ID, if necessary. */
-       if (vid)
-               plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
+#ifdef ENABLE_HYBRID
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
+               plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
+               if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Cannot create Xauth vendor ID\n");
+                       goto end;
+               }
+               plist = isakmp_plist_append(plist,
+                   vid_xauth, ISAKMP_NPTYPE_VID);
+       }
 
+       if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) {
+               if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Cannot create Unity vendor ID\n");
+                       goto end;
+               }
+               plist = isakmp_plist_append(plist,
+                   vid_unity, ISAKMP_NPTYPE_VID);
+       }
+#endif
 #ifdef ENABLE_NATT
        /* Has the peer announced NAT-T? */
        if (NATT_AVAILABLE(iph1))
@@ -963,6 +1321,20 @@ ident_r1send(iph1, msg)
                        plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
        }
 #endif
+#ifdef ENABLE_FRAG
+       if (iph1->frag) {
+               vid_frag = set_vendorid(VENDORID_FRAG);
+               if (vid_frag != NULL)
+                       vid_frag = isakmp_frag_addcap(vid_frag,
+                           VENDORID_FRAG_IDENT);
+               if (vid_frag == NULL)
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "Frag vendorID construction failed\n");
+               else
+                       plist = isakmp_plist_append(plist, 
+                            vid_frag, ISAKMP_NPTYPE_VID);
+       }
+#endif
 
        iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 
@@ -972,11 +1344,15 @@ ident_r1send(iph1, msg)
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -990,22 +1366,40 @@ ident_r1send(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Responder, Main-Mode message 2"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Responder, Main-Mode Message 2"),
+                                                               CONSTSTR("Failed to transmit Main-Mode Message 2"));
+       }
 #ifdef HAVE_GSSAPI
-       if (gss_sa != iph1->sa_ret)
+       if (free_gss_sa)
                vfree(gss_sa);
 #endif
-       if (vid)
-               vfree(vid);
-
 #ifdef ENABLE_NATT
        if (vid_natt)
                vfree(vid_natt);
 #endif
+#ifdef ENABLE_HYBRID
+       if (vid_xauth != NULL)
+               vfree(vid_xauth);
+       if (vid_unity != NULL)
+               vfree(vid_unity);
+#endif
 #ifdef ENABLE_DPD
        if (vid_dpd != NULL)
                vfree(vid_dpd);
 #endif
+#ifdef ENABLE_FRAG
+       if (vid_frag != NULL)
+               vfree(vid_frag);
+#endif
 
        return error;
 }
@@ -1043,20 +1437,29 @@ ident_r2recv(iph1, msg)
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
 
        for (pa = (struct isakmp_parse_t *)pbuf->v;
             pa->type != ISAKMP_NPTYPE_NONE;
             pa++) {
                switch (pa->type) {
                case ISAKMP_NPTYPE_KE:
-                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process KE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_NONCE:
-                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process NONCE payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_VID:
                        (void)check_vendorid(pa->ptr);
@@ -1068,8 +1471,11 @@ ident_r2recv(iph1, msg)
                        break;
 #ifdef HAVE_GSSAPI
                case ISAKMP_NPTYPE_GSS:
-                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
+                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process GSS payload");
                                goto end;
+                       }
                        gssapi_save_received_token(iph1, gsstoken);
                        break;
 #endif
@@ -1086,8 +1492,11 @@ ident_r2recv(iph1, msg)
                                vchar_t *natd_received = NULL;
                                int natd_verified;
                                
-                               if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
+                               if (isakmp_p2ph (&natd_received, pa->ptr) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                                "failed to process NATD payload");
                                        goto end;
+                               }
                                
                                if (natd_seq == 0)
                                        iph1->natt_flags |= NAT_DETECTED;
@@ -1137,7 +1546,18 @@ ident_r2recv(iph1, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Responder, Main-Mode message 3"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Responder, Main-Mode Message 3"),
+                                                               CONSTSTR("Failed to process Main-Mode Message 3"));
+       }
        if (pbuf)
                vfree(pbuf);
 #ifdef HAVE_GSSAPI
@@ -1178,23 +1598,32 @@ ident_r2send(iph1, msg)
 
        /* generate DH public value */
        if (oakley_dh_generate(iph1->approval->dhgrp,
-                               &iph1->dhpub, &iph1->dhpriv) < 0)
+                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate DH");
                goto end;
+       }
 
        /* generate NONCE value */
        iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
-       if (iph1->nonce == NULL)
+       if (iph1->nonce == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate NONCE");
                goto end;
+       }
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
                gssapi_get_rtoken(iph1, NULL);
 #endif
 
        /* create HDR;KE;NONCE payload */
        iph1->sendbuf = ident_ir2mx(iph1);
-       if (iph1->sendbuf == NULL)
+       if (iph1->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to allocate send buffer");
                goto end;
+       }
 
 #ifdef HAVE_PRINT_ISAKMP_C
        isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
@@ -1202,11 +1631,15 @@ ident_r2send(iph1, msg)
 
        /* send the packet, add to the schedule to resend */
        iph1->retry_counter = iph1->rmconf->retry_counter;
-       if (isakmp_ph1resend(iph1) == -1)
+       if (isakmp_ph1resend(iph1) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -1214,24 +1647,50 @@ ident_r2send(iph1, msg)
 
        /* compute sharing secret of DH */
        if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
-                               iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
+                                                 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute DH");
                goto end;
+       }
 
        /* generate SKEYIDs & IV & final cipher key */
-       if (oakley_skeyid(iph1) < 0)
+       if (oakley_skeyid(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID");
                goto end;
-       if (oakley_skeyid_dae(iph1) < 0)
+       }
+       if (oakley_skeyid_dae(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate SKEYID-DAE");
                goto end;
-       if (oakley_compute_enckey(iph1) < 0)
+       }
+       if (oakley_compute_enckey(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate ENCKEY");
                goto end;
-       if (oakley_newiv(iph1) < 0)
+       }
+       if (oakley_newiv(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate IV");
                goto end;
+       }
 
        iph1->status = PHASE1ST_MSG2SENT;
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Responder, Main-Mode message 4"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Responder, Main-Mode Message 4"),
+                                                               CONSTSTR("Failed to transmit Main-Mode Message 4"));
+       }
        return error;
 }
 
@@ -1272,13 +1731,19 @@ ident_r3recv(iph1, msg0)
                goto end;
        }
        msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
-       if (msg == NULL)
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to decrypt");
                goto end;
+       }
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
 
        iph1->pl_hash = NULL;
 
@@ -1288,28 +1753,43 @@ ident_r3recv(iph1, msg0)
 
                switch (pa->type) {
                case ISAKMP_NPTYPE_ID:
-                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process ID payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_HASH:
                        iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
                        break;
                case ISAKMP_NPTYPE_CR:
-                       if (oakley_savecr(iph1, pa->ptr) < 0)
+                       if (oakley_savecr(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CR payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_CERT:
-                       if (oakley_savecert(iph1, pa->ptr) < 0)
+                       if (oakley_savecert(iph1, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process CERT payload");
                                goto end;
+                       }
                        break;
                case ISAKMP_NPTYPE_SIG:
-                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process SIG payload");
                                goto end;
+                       }
                        break;
 #ifdef HAVE_GSSAPI
                case ISAKMP_NPTYPE_GSS:
-                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
+                       if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process GSS payload");
                                goto end;
+                       }
                        gssapi_save_received_token(iph1, gsstoken);
                        break;
 #endif
@@ -1334,18 +1814,31 @@ ident_r3recv(iph1, msg0)
     {
        int ng = 0;
 
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+#endif
                if (iph1->id_p == NULL || iph1->pl_hash == NULL)
                        ng++;
                break;
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+#endif
                if (iph1->id_p == NULL || iph1->sig_p == NULL)
                        ng++;
                break;
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+#endif
                if (iph1->pl_hash == NULL)
                        ng++;
                break;
@@ -1381,6 +1874,10 @@ ident_r3recv(iph1, msg0)
 #endif
                type = oakley_validate_auth(iph1);
                if (type != 0) {
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL,
+                                                                       CONSTSTR("Responder, Main-Mode Message 5"),
+                                                                       CONSTSTR("Failed to authenticate Main-Mode Message 5"));
                        if (type == -1) {
                                /* msg printed inner oakley_validate_auth() */
                                goto end;
@@ -1390,6 +1887,10 @@ ident_r3recv(iph1, msg0)
                        isakmp_info_send_n1(iph1, type, NULL);
                        goto end;
                }
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC,
+                                                               CONSTSTR("Responder, Main-Mode Message 5"),
+                                                               CONSTSTR(NULL));
 #ifdef HAVE_GSSAPI
        }
 #endif
@@ -1419,7 +1920,18 @@ ident_r3recv(iph1, msg0)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Responder, Main-Mode message 5"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Responder, Main-Mode Message 5"),
+                                                               CONSTSTR("Failed to process Main-Mode Message 5"));
+       }
        if (pbuf)
                vfree(pbuf);
        if (msg)
@@ -1470,11 +1982,14 @@ ident_r3send(iph1, msg)
        }
 
        /* make ID payload into isakmp status */
-       if (ipsecdoi_setid1(iph1) < 0)
+       if (ipsecdoi_setid1(iph1) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set ID");
                goto end;
+       }
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
            gssapi_more_tokens(iph1)) {
                gssapi_get_rtoken(iph1, &len);
                if (len != 0)
@@ -1486,8 +2001,11 @@ ident_r3send(iph1, msg)
                /* generate HASH to send */
                plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
                iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
-               if (iph1->hash == NULL)
+               if (iph1->hash == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate HASH");
                        goto end;
+               }
        } else
                iph1->hash = NULL;
 
@@ -1496,15 +2014,22 @@ ident_r3send(iph1, msg)
 
        /* create HDR;ID;HASH payload */
        iph1->sendbuf = ident_ir3mx(iph1);
-       if (iph1->sendbuf == NULL)
+       if (iph1->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to create send buffer");
                goto end;
+       }
 
        /* send HDR;ID;HASH to responder */
-       if (isakmp_send(iph1, iph1->sendbuf) < 0)
+       if (isakmp_send(iph1, iph1->sendbuf) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
+       if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
+                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -1515,9 +2040,25 @@ ident_r3send(iph1, msg)
 
        iph1->status = PHASE1ST_ESTABLISHED;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC,
+                                                       CONSTSTR("Responder, Main-Mode"),
+                                                       CONSTSTR(NULL));
+       
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Responder, Main-Mode message 6"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Responder, Main-Mode Message 6"),
+                                                               CONSTSTR("Failed to process Main-Mode Message 6"));
+       }
 
        return error;
 }
@@ -1568,7 +2109,7 @@ ident_ir2mx(iph1)
        }
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
                gssapi_get_token_to_send(iph1, &gsstoken);
 #endif
 
@@ -1579,7 +2120,7 @@ ident_ir2mx(iph1)
        plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
                plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
 #endif
 
@@ -1681,8 +2222,14 @@ ident_ir3mx(iph1)
        vchar_t *gsshash = NULL;
 #endif
 
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+#endif
                /* create isakmp ID payload */
                plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
 
@@ -1691,11 +2238,25 @@ ident_ir3mx(iph1)
                break;
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
-               if (oakley_getmycert(iph1) < 0)
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+#endif 
+               if (oakley_getmycert(iph1) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to get mycert");
                        goto end;
+               }
 
-               if (oakley_getsign(iph1) < 0)
+               if (oakley_getsign(iph1) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to get sign");
                        goto end;
+               }
 
                /* create CR if need */
                if (iph1->side == INITIATOR
@@ -1706,7 +2267,7 @@ ident_ir3mx(iph1)
                        cr = oakley_getcr(iph1);
                        if (cr == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL,
-                                       "failed to get cr buffer.\n");
+                                       "failed to get CR");
                                goto end;
                        }
                }
@@ -1731,8 +2292,11 @@ ident_ir3mx(iph1)
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
                if (iph1->hash != NULL) {
                        gsshash = gssapi_wraphash(iph1);
-                       if (gsshash == NULL)
+                       if (gsshash == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to generate GSSAPI HASH");
                                goto end;
+                       }
                } else {
                        gssapi_get_token_to_send(iph1, &gsstoken);
                }
@@ -1752,6 +2316,12 @@ ident_ir3mx(iph1)
 #endif
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+#endif
                plog(LLV_ERROR, LOCATION, NULL,
                        "not supported authentication type %d\n",
                        iph1->approval->authmethod);
@@ -1771,8 +2341,11 @@ ident_ir3mx(iph1)
 
        /* encoding */
        new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv);
-       if (new == NULL)
+       if (new == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to encrypt");
                goto end;
+       }
 
        vfree(buf);
 
@@ -1781,6 +2354,10 @@ ident_ir3mx(iph1)
        error = 0;
 
 end:
+#ifdef HAVE_GSSAPI
+       if (gsstoken)
+               vfree(gsstoken);
+#endif
        if (cr)
                vfree(cr);
        if (error && buf != NULL) {
index a6810611697dce27ceaa16a48faab7029ed89af3..af7d93b116efb4edfdb8732a0a6e22980248b5f4 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_inf.c,v 1.14.4.9 2005/08/02 15:09:26 vanhu Exp $ */
+/*     $NetBSD: isakmp_inf.c,v 1.14.4.8 2007/08/01 11:52:20 vanhu Exp $        */
+
+/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -62,6 +64,9 @@
 #  include <time.h>
 # endif
 #endif
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
 
 #include "libpfkey.h"
 
 #include "localconf.h"
 #include "remoteconf.h"
 #include "sockmisc.h"
+#include "handler.h"
+#include "policy.h"
+#include "proposal.h"
 #include "isakmp_var.h"
 #include "evt.h"
 #include "isakmp.h"
 #ifdef ENABLE_HYBRID
 #include "isakmp_xauth.h"
+#include "isakmp_unity.h"
 #include "isakmp_cfg.h" 
 #endif
 #include "isakmp_inf.h"
 #include "oakley.h"
-#include "handler.h"
 #include "ipsec_doi.h"
 #include "crypto_openssl.h"
 #include "pfkey.h"
 #endif
 #include "vpn_control_var.h"
 #include "vpn_control.h"
+#include "ike_session.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
 
 /* information exchange */
-static int isakmp_info_recv_n __P((struct ph1handle *, vchar_t *, int));
-static int isakmp_info_recv_d __P((struct ph1handle *, vchar_t *));
+static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int);
+static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int);
 
 #ifdef ENABLE_DPD
 static int isakmp_info_recv_r_u __P((struct ph1handle *,
        struct isakmp_pl_ru *, u_int32_t));
 static int isakmp_info_recv_r_u_ack __P((struct ph1handle *,
        struct isakmp_pl_ru *, u_int32_t));
-static void isakmp_info_send_r_u __P((void *));
 #endif
 
 #ifdef ENABLE_VPNCONTROL_PORT
@@ -117,9 +127,64 @@ static int isakmp_info_recv_lb __P((struct ph1handle *, struct isakmp_pl_lb *lb,
 #endif
 
 static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
-static void purge_ipsec_spi __P((struct sockaddr *, int, u_int32_t *, size_t));
 static void info_recv_initialcontact __P((struct ph1handle *));
 
+static int
+isakmp_ph1_responder_lifetime (struct ph1handle               *iph1,
+                               struct isakmp_pl_resp_lifetime *notify)
+{
+    char *spi;
+
+    if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
+        plog(LLV_ERROR, LOCATION, iph1->remote,
+             "invalid spi_size in notification payload.\n");
+        return -1;
+    }
+    spi = val2str((char *)(notify + 1), notify->spi_size);
+
+    plog(LLV_DEBUG, LOCATION, iph1->remote,
+         "notification message ISAKMP-SA RESPONDER-LIFETIME, "
+         "doi=%d proto_id=%d spi=%s(size=%d).\n",
+         ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
+    
+    /* TODO */
+    #if 0
+        struct isakmp_pl_attr *attrpl;
+        int                    len = ntohs(notify->h.len) - (sizeof(*notify) + notify->spi_size);
+
+        attrpl = (struct isakmp_pl_attr *)((char *)(notify + 1) + notify->spi_size);
+        while (len > 0) {
+        }
+    #endif
+
+    racoon_free(spi);
+    return 0;
+}
+
+static int
+isakmp_ph2_responder_lifetime (struct ph2handle               *iph2,
+                               struct isakmp_pl_resp_lifetime *notify)
+{
+    char *spi;
+
+    if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
+        plog(LLV_ERROR, LOCATION, iph2->dst,
+             "invalid spi_size in notification payload.\n");
+        return -1;
+    }
+    spi = val2str((char *)(notify + 1), notify->spi_size);
+    
+    plog(LLV_DEBUG, LOCATION, iph2->dst,
+         "notification message IPSEC-SA RESPONDER-LIFETIME, "
+         "doi=%d proto_id=%d spi=%s(size=%d).\n",
+         ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
+    
+    /* TODO */
+    
+    racoon_free(spi);
+    return 0;
+}
+
 /* \f%%%
  * Information Exchange
  */
@@ -132,33 +197,60 @@ isakmp_info_recv(iph1, msg0)
        vchar_t *msg0;
 {
        vchar_t *msg = NULL;
+       vchar_t *pbuf = NULL;
+       u_int32_t msgid = 0;
        int error = -1;
        struct isakmp *isakmp;
        struct isakmp_gen *gen;
+       struct isakmp_parse_t *pa, *pap;
        void *p;
        vchar_t *hash, *payload;
        struct isakmp_gen *nd;
        u_int8_t np;
        int encrypted;
+       int flag;
 
        plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n");
 
        encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
+       msgid = ((struct isakmp *)msg0->v)->msgid;
 
        /* Use new IV to decrypt Informational message. */
        if (encrypted) {
-
                struct isakmp_ivm *ivm;
 
+               if (iph1->ivm == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n");
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                       CONSTSTR("Information message"),
+                                                                       CONSTSTR("Failed to process Information Message (no IV)"));
+                       return -1;
+               }
+
                /* compute IV */
                ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
-               if (ivm == NULL)
+               if (ivm == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to compute IV");
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                       CONSTSTR("Information message"),
+                                                                       CONSTSTR("Failed to process Information Message (can't compute IV)"));
                        return -1;
+               }
 
                msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
                oakley_delivm(ivm);
-               if (msg == NULL)
+               if (msg == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to decrypt packet");
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                                       CONSTSTR("Information message"),
+                                                                       CONSTSTR("Failed to decrypt Information message"));
                        return -1;
+               }
 
        } else
                msg = vdup(msg0);
@@ -183,7 +275,8 @@ isakmp_info_recv(iph1, msg0)
                        goto end;
                }
 
-               if (iph1->status != PHASE1ST_ESTABLISHED) {
+               if (iph1->status != PHASE1ST_ESTABLISHED &&
+            (!iph1->approval || !iph1->skeyid_a)) {
                        plog(LLV_ERROR, LOCATION, NULL,
                            "ignore information because ISAKMP-SA "
                            "has not been established yet.\n");
@@ -257,7 +350,7 @@ isakmp_info_recv(iph1, msg0)
                vfree(hash);
                vfree(payload);
        } else {
-               /* make sure the packet were encrypted after the beginning of phase 1. */
+               /* make sure the packet was encrypted after the beginning of phase 1. */
                switch (iph1->etype) {
                case ISAKMP_ETYPE_AGG:
                case ISAKMP_ETYPE_BASE:
@@ -271,40 +364,350 @@ isakmp_info_recv(iph1, msg0)
                        plog(LLV_ERROR, LOCATION, iph1->remote,
                                "%s message must be encrypted\n",
                                s_isakmp_nptype(np));
+                       error = 0;
                        goto end;
                }
        }
 
-       switch (np) {
-       case ISAKMP_NPTYPE_N:
-               isakmp_info_recv_n(iph1, msg, encrypted);
+       if (!(pbuf = isakmp_parse(msg))) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
+               error = -1;
+               goto end;
+       }
+
+       error = 0;
+       for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) {
+               switch (pa->type) {
+               case ISAKMP_NPTYPE_HASH:
+                       /* Handled above */
+                       break;
+               case ISAKMP_NPTYPE_N:
+                       error = isakmp_info_recv_n(iph1,
+                               (struct isakmp_pl_n *)pa->ptr,
+                               msgid, encrypted);
+                       break;
+               case ISAKMP_NPTYPE_D:
+                       error = isakmp_info_recv_d(iph1,
+                               (struct isakmp_pl_d *)pa->ptr,
+                               msgid, encrypted);
+                       break;
+               case ISAKMP_NPTYPE_NONCE:
+                       /* XXX to be 6.4.2 ike-01.txt */
+                       /* XXX IV is to be synchronized. */
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                               "ignore Acknowledged Informational\n");
+                       break;
+               default:
+                       /* don't send information, see isakmp_ident_r1() */
+                       error = 0;
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                               "reject the packet, "
+                               "received unexpected payload type %s.\n",
+                               s_isakmp_nptype(gen->np));
+               }
+               if(error < 0) {
+                       break;
+               } else {
+                       flag |= error;
+               }
+       }
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Information message"),
+                                                       CONSTSTR(NULL));
+       
+end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to process Information Message"));
+       }
+       if (msg != NULL)
+               vfree(msg);
+       if (pbuf != NULL)
+               vfree(pbuf);
+       return error;
+}
+
+/*
+ * handling of Notification payload
+ */
+static int
+isakmp_info_recv_n(iph1, notify, msgid, encrypted)
+       struct ph1handle *iph1;
+       struct isakmp_pl_n *notify;
+       u_int32_t msgid;
+       int encrypted;
+{
+       u_int type;
+       vchar_t *pbuf;
+       vchar_t *ndata;
+       char *nraw;
+       size_t l;
+       char *spi;
+
+       type = ntohs(notify->type);
+
+       switch (type) {
+       case ISAKMP_NTYPE_CONNECTED:
+       case ISAKMP_NTYPE_REPLAY_STATUS:
+#ifdef ENABLE_HYBRID
+       case ISAKMP_NTYPE_UNITY_HEARTBEAT:
+#endif
+               /* do something */
                break;
-       case ISAKMP_NPTYPE_D:
+    case ISAKMP_NTYPE_RESPONDER_LIFETIME:
+        if (encrypted) {
+            return(isakmp_ph1_responder_lifetime(iph1,
+                                                 (struct isakmp_pl_resp_lifetime *)notify));
+        }
+        break;
+       case ISAKMP_NTYPE_INITIAL_CONTACT:
                if (encrypted)
-                       isakmp_info_recv_d(iph1, msg);
-               else
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "unencrypted information message with delete payload received\n");
+                       info_recv_initialcontact(iph1);
+                       return 0;
                break;
-       case ISAKMP_NPTYPE_NONCE:
-               /* XXX to be 6.4.2 ike-01.txt */
-               /* XXX IV is to be synchronized. */
-               plog(LLV_ERROR, LOCATION, iph1->remote,
-                       "ignore Acknowledged Informational\n");
+#ifdef ENABLE_DPD
+       case ISAKMP_NTYPE_R_U_THERE:
+               if (encrypted)
+                       return isakmp_info_recv_r_u(iph1,
+                               (struct isakmp_pl_ru *)notify, msgid);
+               break;
+       case ISAKMP_NTYPE_R_U_THERE_ACK:
+               if (encrypted)
+                       return isakmp_info_recv_r_u_ack(iph1,
+                               (struct isakmp_pl_ru *)notify, msgid);
                break;
+#endif
+#ifdef ENABLE_VPNCONTROL_PORT
+       case ISAKMP_NTYPE_LOAD_BALANCE:
+               isakmp_info_recv_lb(iph1, (struct isakmp_pl_lb *)notify, encrypted);
+               break;
+#endif
+
        default:
-               /* don't send information, see isakmp_ident_r1() */
-               error = 0;
+           {
+               /* XXX there is a potential of dos attack. */
+               if(type >= ISAKMP_NTYPE_MINERROR &&
+                  type <= ISAKMP_NTYPE_MAXERROR) {
+                       if (msgid == 0) {
+                               /* don't think this realy deletes ph1 ? */
+                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                       "delete phase1 handle.\n");
+                               return -1;
+                       } else {
+                               if (getph2bymsgid(iph1, msgid) == NULL) {
+                                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                                               "fatal %s notify messsage, "
+                                               "phase1 should be deleted.\n",
+                                               s_isakmp_notify_msg(type));
+                               } else {
+                                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                                               "fatal %s notify messsage, "
+                                               "phase2 should be deleted.\n",
+                                               s_isakmp_notify_msg(type));
+                               }
+                       }
+               } else {
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                               "unhandled notify message %s, "
+                               "no phase2 handle found.\n",
+                               s_isakmp_notify_msg(type));
+               }
+           }
+           break;
+       }
+
+       /* get spi if specified and allocate */
+       if(notify->spi_size > 0) {
+               if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                               "invalid spi_size in notification payload.\n");
+                       return -1;
+               }
+               spi = val2str((char *)(notify + 1), notify->spi_size);
+
+               plog(LLV_DEBUG, LOCATION, iph1->remote,
+                       "notification message %d:%s, "
+                       "doi=%d proto_id=%d spi=%s(size=%d).\n",
+                       type, s_isakmp_notify_msg(type),
+                       ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
+
+               racoon_free(spi);
+       }
+
+       /* Send the message data to the logs */
+       if(type >= ISAKMP_NTYPE_MINERROR &&
+          type <= ISAKMP_NTYPE_MAXERROR) {
+               l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
+               if (l > 0) {
+                       nraw = (char*)notify;   
+                       nraw += sizeof(*notify) + notify->spi_size;
+                       if ((ndata = vmalloc(l)) != NULL) {
+                               memcpy(ndata->v, nraw, ndata->l);
+                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                   "Message: '%s'.\n", 
+                                   binsanitize(ndata->v, ndata->l));
+                               vfree(ndata);
+                       } else {
+                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                   "Cannot allocate memory\n");
+                       }
+               }
+       }
+       return 0;
+}
+
+/*
+ * handling of Deletion payload
+ */
+static int
+isakmp_info_recv_d(iph1, delete, msgid, encrypted)
+       struct ph1handle *iph1;
+       struct isakmp_pl_d *delete;
+       u_int32_t msgid;
+       int encrypted;
+{
+       int tlen, num_spi;
+       vchar_t *pbuf;
+       int protected = 0;
+       struct ph1handle *del_ph1;
+       struct ph2handle *iph2;
+       union {
+               u_int32_t spi32;
+               u_int16_t spi16[2];
+       } spi;
+
+       if (ntohl(delete->doi) != IPSEC_DOI) {
                plog(LLV_ERROR, LOCATION, iph1->remote,
-                       "reject the packet, "
-                       "received unexpecting payload type %d.\n",
-                       gen->np);
+                       "delete payload with invalid doi:%d.\n",
+                       ntohl(delete->doi));
+#ifdef ENABLE_HYBRID
+               /*
+                * At deconnexion time, Cisco VPN client does this
+                * with a zero DOI. Don't give up in that situation.
+                */
+               if (((iph1->mode_cfg->flags &
+                   ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0))
+                       return 0;
+#else
+               return 0;
+#endif
+       }
+
+       num_spi = ntohs(delete->num_spi);
+       tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d);
+
+       if (tlen != num_spi * delete->spi_size) {
+               plog(LLV_ERROR, LOCATION, iph1->remote,
+                       "deletion payload with invalid length.\n");
+               return 0;
+       }
+
+       plog(LLV_DEBUG, LOCATION, iph1->remote,
+               "delete payload for protocol %s\n",
+               s_ipsecdoi_proto(delete->proto_id));
+
+       if(!iph1->rmconf->weak_phase1_check && !encrypted) {
+               plog(LLV_WARNING, LOCATION, iph1->remote,
+                       "Ignoring unencrypted delete payload "
+                       "(check the weak_phase1_check option)\n");
+               return 0;
+       }
+
+       switch (delete->proto_id) {
+       case IPSECDOI_PROTO_ISAKMP:
+               if (delete->spi_size != sizeof(isakmp_index)) {
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                               "delete payload with strange spi "
+                               "size %d(proto_id:%d)\n",
+                               delete->spi_size, delete->proto_id);
+                       return 0;
+               }
+
+               del_ph1=getph1byindex((isakmp_index *)(delete + 1));
+               if(del_ph1 != NULL){
+
+            // hack: start a rekey now, if one was pending (only for client).
+            if (del_ph1->sce_rekey &&
+                del_ph1->parent_session &&
+                del_ph1->parent_session->is_client &&
+                del_ph1->parent_session->established) {
+                isakmp_ph1rekeyexpire(del_ph1);
+            }
+            
+                       EVT_PUSH(del_ph1->local, del_ph1->remote,
+                       EVTT_PEERPH1_NOPROP, NULL);
+                       if (del_ph1->scr)
+                               SCHED_KILL(del_ph1->scr);
+
+                       /*
+                        * Do not delete IPsec SAs when receiving an IKE delete notification.
+                        * Just delete the IKE SA.
+                        */
+#ifdef ENABLE_VPNCONTROL_PORT
+
+                       if (del_ph1->started_by_api)
+                               if (islast_ph1(del_ph1)) {
+                                       u_int32_t address;
+                                       
+                                       /* notify the API that we have received the delete */
+                                       if (iph1->remote->sa_family == AF_INET)
+                                               address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr;
+                                       else
+                                               address = 0;
+                                       vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE, FROM_REMOTE, address, 0, NULL);
+                               }
+#endif
+                       isakmp_ph1expire(del_ph1);
+               }
+               break;
+
+       case IPSECDOI_PROTO_IPSEC_AH:
+       case IPSECDOI_PROTO_IPSEC_ESP:
+               if (delete->spi_size != sizeof(u_int32_t)) {
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                               "delete payload with strange spi "
+                               "size %d(proto_id:%d)\n",
+                               delete->spi_size, delete->proto_id);
+                       return 0;
+               }
+               EVT_PUSH(iph1->local, iph1->remote, 
+                   EVTT_PEER_DELETE, NULL);
+               purge_ipsec_spi(iph1->remote, delete->proto_id,
+                   (u_int32_t *)(delete + 1), num_spi);
                break;
+
+       case IPSECDOI_PROTO_IPCOMP:
+               /* need to handle both 16bit/32bit SPI */
+               memset(&spi, 0, sizeof(spi));
+               if (delete->spi_size == sizeof(spi.spi16[1])) {
+                       memcpy(&spi.spi16[1], delete + 1,
+                           sizeof(spi.spi16[1]));
+               } else if (delete->spi_size == sizeof(spi.spi32))
+                       memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32));
+               else {
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                               "delete payload with strange spi "
+                               "size %d(proto_id:%d)\n",
+                               delete->spi_size, delete->proto_id);
+                       return 0;
+               }
+               purge_ipsec_spi(iph1->remote, delete->proto_id,
+                   &spi.spi32, num_spi);
+               break;
+
+       default:
+               plog(LLV_ERROR, LOCATION, iph1->remote,
+                       "deletion message received, "
+                       "invalid proto_id: %d\n",
+                       delete->proto_id);
+               return 0;
        }
 
-    end:
-       if (msg != NULL)
-               vfree(msg);
+       plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n");
 
        return 0;
 }
@@ -348,6 +751,17 @@ isakmp_info_send_d1(iph1)
        error = isakmp_info_send_common(iph1, payload,
                                        ISAKMP_NPTYPE_D, 0);
        vfree(payload);
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("Delete ISAKMP-SA"),
+                                                               CONSTSTR("Failed to transmit Delete-ISAKMP-SA message"));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+                                                               CONSTSTR("Delete ISAKMP-SA"),
+                                                               CONSTSTR(NULL));
+       }
 
        return error;
 }
@@ -375,9 +789,23 @@ isakmp_info_send_d2(iph2)
         * don't send delete information if there is no phase 1 handler.
         * It's nonsensical to negotiate phase 1 to send the information.
         */
-       iph1 = getph1byaddr(iph2->src, iph2->dst); 
-       if (iph1 == NULL)
+    iph1 = ike_session_get_established_ph1(iph2->parent_session);
+    if (!iph1) {
+        iph1 = getph1byaddr(iph2->src, iph2->dst);
+    }
+       if (iph1 == NULL){
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to transmit Information message"));
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("Delete IPSEC-SA"),
+                                                               CONSTSTR("Failed to transmit Delete-IPSEC-SA message"));
+               plog(LLV_DEBUG2, LOCATION, NULL,
+                        "No ph1 handler found, could not send DELETE_SA\n");
                return 0;
+       }
 
        /* create delete payload */
        for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
@@ -392,6 +820,14 @@ isakmp_info_send_d2(iph2)
                tlen = sizeof(*d) + pr->spisize;
                payload = vmalloc(tlen);
                if (payload == NULL) {
+                       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                                       CONSTSTR("Information message"),
+                                                                       CONSTSTR("Failed to transmit Information message"));
+                       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                                       CONSTSTR("Delete IPSEC-SA"),
+                                                                       CONSTSTR("Failed to transmit Delete-IPSEC-SA message"));
                        plog(LLV_ERROR, LOCATION, NULL, 
                                "failed to get buffer for payload.\n");
                        return errno;
@@ -416,6 +852,17 @@ isakmp_info_send_d2(iph2)
                error = isakmp_info_send_common(iph1, payload,
                                                ISAKMP_NPTYPE_D, 0);
                vfree(payload);
+               if (error) {
+                       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                                       CONSTSTR("Delete IPSEC-SA"),
+                                                                       CONSTSTR("Failed to transmit Delete-IPSEC-SA"));
+               } else {
+                       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+                                                                       CONSTSTR("Delete IPSEC-SA"),
+                                                                       CONSTSTR(NULL));
+               }
        }
 
        return error;
@@ -438,10 +885,15 @@ isakmp_info_send_nx(isakmp, remote, local, type, data)
        int error = -1;
        struct isakmp_pl_n *n;
        int spisiz = 0;         /* see below */
+       ike_session_t *sess = ike_session_get_session(local, remote, FALSE);
 
        /* search appropreate configuration */
        rmconf = getrmconf(remote);
        if (rmconf == NULL) {
+               IPSECSESSIONTRACEREVENT(sess,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to transmit Information message (no remote configuration)"));
                plog(LLV_ERROR, LOCATION, remote,
                        "no configuration found for peer address.\n");
                goto end;
@@ -449,20 +901,43 @@ isakmp_info_send_nx(isakmp, remote, local, type, data)
 
        /* add new entry to isakmp status table. */
        iph1 = newph1();
-       if (iph1 == NULL)
+       if (iph1 == NULL) {
+               IPSECSESSIONTRACEREVENT(sess,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to transmit Information message (no new phase1)"));
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to allocate ph1");
                return -1;
+       }
 
        memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
        isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
        iph1->status = PHASE1ST_START;
        iph1->rmconf = rmconf;
+#ifdef __APPLE__
+       if (link_rmconf_to_ph1(rmconf) < 0) {
+               IPSECSESSIONTRACEREVENT(sess,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to transmit Information message (can't link remote configuration to phase1)"));
+               plog(LLV_ERROR, LOCATION, remote,
+                        "couldn't link "
+                        "configuration.\n");
+               iph1->rmconf = NULL;
+               error = -1;
+               goto end;
+       }
+#endif
        iph1->side = INITIATOR;
        iph1->version = isakmp->v;
        iph1->flags = 0;
        iph1->msgid = 0;        /* XXX */
 #ifdef ENABLE_HYBRID
-       if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL)
-               return -1;
+       if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
+               error = -1;
+               goto end;
+       }
 #endif
 #ifdef ENABLE_FRAG
        iph1->frag = 0;
@@ -470,16 +945,29 @@ isakmp_info_send_nx(isakmp, remote, local, type, data)
 #endif
 
        /* copy remote address */
-       if (copy_ph1addresses(iph1, rmconf, remote, local) < 0)
-               return -1;
+       if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
+               IPSECSESSIONTRACEREVENT(sess,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to transmit Information Message (can't copy phase1 addresses)"));
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to copy ph1 addresses");
+               error = -1;
+               goto end;
+       }
 
        tlen = sizeof(*n) + spisiz;
        if (data)
                tlen += data->l;
        payload = vmalloc(tlen);
        if (payload == NULL) { 
+               IPSECSESSIONTRACEREVENT(sess,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to transmit Information Message (can't allocate payload)"));
                plog(LLV_ERROR, LOCATION, NULL,
                        "failed to get buffer to send.\n");
+               error = -1;
                goto end;
        }
 
@@ -491,7 +979,7 @@ isakmp_info_send_nx(isakmp, remote, local, type, data)
        n->spi_size = spisiz;
        n->type = htons(type);
        if (spisiz)
-               memset(n + 1, 0, spisiz);       /*XXX*/
+               memset(n + 1, 0, spisiz);       /* XXX spisiz is always 0 */
        if (data)
                memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
 
@@ -512,7 +1000,18 @@ isakmp_info_send_nx(isakmp, remote, local, type, data)
 
        error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
        vfree(payload);
-
+       if (error) {
+               IPSECSESSIONTRACEREVENT(sess,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("Without ISAKMP-SA"),
+                                                               CONSTSTR("Failed to transmit Without-ISAKMP-SA message"));
+       } else {
+               IPSECSESSIONTRACEREVENT(sess,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+                                                               CONSTSTR("Without ISAKMP-SA"),
+                                                               CONSTSTR(NULL));
+       }
+       
     end:
        if (iph1 != NULL)
                delph1(iph1);
@@ -556,6 +1055,10 @@ isakmp_info_send_n1(iph1, type, data)
                tlen += data->l;
        payload = vmalloc(tlen);
        if (payload == NULL) { 
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("ISAKMP-SA"),
+                                                               CONSTSTR("Failed to transmit ISAKMP-SA message (can't allocate payload)"));
                plog(LLV_ERROR, LOCATION, NULL,
                        "failed to get buffer to send.\n");
                return errno;
@@ -591,6 +1094,17 @@ isakmp_info_send_n1(iph1, type, data)
 
        error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
        vfree(payload);
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("ISAKMP-SA"),
+                                                               CONSTSTR("Can't transmit ISAKMP-SA message"));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+                                                               CONSTSTR("ISAKMP-SA"),
+                                                               CONSTSTR(NULL));
+       }
 
        return error;
 }
@@ -622,6 +1136,10 @@ isakmp_info_send_n2(iph2, type, data)
                tlen += data->l;
        payload = vmalloc(tlen);
        if (payload == NULL) { 
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("IPSEC-SA"),
+                                                               CONSTSTR("Failed to transmit IPSEC-SA message (can't allocate payload)"));
                plog(LLV_ERROR, LOCATION, NULL,
                        "failed to get buffer to send.\n");
                return errno;
@@ -641,7 +1159,18 @@ isakmp_info_send_n2(iph2, type, data)
        iph2->flags |= ISAKMP_FLAG_E;   /* XXX Should we do FLAG_A ? */
        error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
        vfree(payload);
-
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("IPSEC-SA"),
+                                                               CONSTSTR("Failed to transmit IPSEC-SA message"));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+                                                               CONSTSTR("IPSEC-SA"),
+                                                               CONSTSTR(NULL));
+       }
+       
        return error;
 }
 
@@ -666,22 +1195,39 @@ isakmp_info_send_common(iph1, payload, np, flags)
 
        /* add new entry to isakmp status table */
        iph2 = newph2();
-       if (iph2 == NULL)
+       if (iph2 == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to allocate ph2");
                goto end;
+       }
 
        iph2->dst = dupsaddr(iph1->remote);
+       if (iph2->dst == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to duplicate remote address");
+               delph2(iph2);
+               goto end;
+       }
        iph2->src = dupsaddr(iph1->local);
+       if (iph2->src == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to duplicate local address");
+               delph2(iph2);
+               goto end;
+       }
        switch (iph1->remote->sa_family) {
        case AF_INET:
-#ifndef ENABLE_NATT
+#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
                ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
                ((struct sockaddr_in *)iph2->src)->sin_port = 0;
 #endif
                break;
 #ifdef INET6
        case AF_INET6:
+#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
                ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
                ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
+#endif
                break;
 #endif
        default:
@@ -699,6 +1245,8 @@ isakmp_info_send_common(iph1, payload, np, flags)
        if (iph1->skeyid_a != NULL) {
                iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
                if (iph2->ivm == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate IV");
                        delph2(iph2);
                        goto end;
                }
@@ -706,6 +1254,8 @@ isakmp_info_send_common(iph1, payload, np, flags)
                /* generate HASH(1) */
                hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
                if (hash == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate HASH");
                        delph2(iph2);
                        goto end;
                }
@@ -775,13 +1325,18 @@ isakmp_info_send_common(iph1, payload, np, flags)
                tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
                                iph2->ivm->iv);
                VPTRINIT(iph2->sendbuf);
-               if (tmp == NULL)
+               if (tmp == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to encrypt packet");
                        goto err;
+               }
                iph2->sendbuf = tmp;
        }
 
        /* HDR*, HASH(1), N */
        if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                VPTRINIT(iph2->sendbuf);
                goto err;
        }
@@ -797,9 +1352,20 @@ isakmp_info_send_common(iph1, payload, np, flags)
        /* XXX If Acknowledged Informational required, don't delete ph2handle */
        error = 0;
        VPTRINIT(iph2->sendbuf);
+       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Information message"),
+                                                       CONSTSTR(NULL));
+       
        goto err;       /* XXX */
 
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Information message"),
+                                                               CONSTSTR("Failed to transmit Information message"));
+       }
        if (hash)
                vfree(hash);
        return error;
@@ -865,157 +1431,7 @@ isakmp_add_pl_n(buf0, np_p, type, pr, data)
        return buf;
 }
 
-/*
- * handling to receive Notification payload
- */
-static int
-isakmp_info_recv_n(iph1, msg, encrypted)
-       struct ph1handle *iph1;
-       vchar_t *msg;
-       int encrypted;
-{
-       struct isakmp_pl_n *n = NULL;
-       u_int type;
-       vchar_t *pbuf;
-       struct isakmp_parse_t *pa, *pap;
-       char *spi;
-
-       if (!(pbuf = isakmp_parse(msg)))
-               return -1;
-       pa = (struct isakmp_parse_t *)pbuf->v;
-       for (pap = pa; pap->type; pap++) {
-               switch (pap->type) {
-               case ISAKMP_NPTYPE_HASH:
-                       /* do something here */
-                       break;
-               case ISAKMP_NPTYPE_NONCE:
-                       /* send to ack */
-                       break;
-               case ISAKMP_NPTYPE_N:
-                       n = (struct isakmp_pl_n *)pap->ptr;
-                       break;
-               default:
-                       vfree(pbuf);
-                       return -1;
-               }
-       }
-       vfree(pbuf);
-       if (!n)
-               return -1;
-
-       type = ntohs(n->type);
-
-       switch (type) {
-       case ISAKMP_NTYPE_CONNECTED:
-       case ISAKMP_NTYPE_RESPONDER_LIFETIME:
-       case ISAKMP_NTYPE_REPLAY_STATUS:
-               /* do something */
-               break;
-       case ISAKMP_NTYPE_INITIAL_CONTACT:
-               if (encrypted)
-                       info_recv_initialcontact(iph1);
-               else
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                            "unencrypted INITIAL_CONTACT message received");
-               break;
-#ifdef ENABLE_DPD
-       case ISAKMP_NTYPE_R_U_THERE:
-               if (encrypted)
-                       isakmp_info_recv_r_u(iph1, (struct isakmp_pl_ru *)n,
-                                    ((struct isakmp *)msg->v)->msgid);
-               else
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                            "unencrypted R_U_THERE message received");
-               break;
-       case ISAKMP_NTYPE_R_U_THERE_ACK:
-               if (encrypted)
-                       isakmp_info_recv_r_u_ack(iph1, (struct isakmp_pl_ru *)n,
-                                        ((struct isakmp *)msg->v)->msgid);
-               else
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                            "unencrypted R_U_THERE_ACK received");
-               break;
-#endif
-
-#ifdef ENABLE_VPNCONTROL_PORT
-       case ISAKMP_NTYPE_LOAD_BALANCE:
-               isakmp_info_recv_lb(iph1, (struct isakmp_pl_lb *)n, encrypted);
-               break;
-#endif
-
-       default:
-               if (encrypted) {
-                       u_int32_t msgid = ((struct isakmp *)msg->v)->msgid;
-                       struct ph2handle *iph2;
-
-                       /* XXX there is a potential of dos attack. */
-                       if (msgid == 0) {
-                               /* delete ph1 */
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                       "delete phase1 handle.\n");
-                               return -1;
-                       } else {
-                               iph2 = getph2bymsgid(iph1, msgid);
-                               if (iph2 == NULL) {
-                                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                                               "unknown notify message, "
-                                               "no phase2 handle found.\n");
-                               } else {
-                                       /* sanity check */
-                                       if (n->h.len < (sizeof(struct isakmp_pl_n) + n->spi_size))
-                                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                                       "notification payload length invalid.\n");
-                                       else {          
-                                               
-#ifdef ENABLE_VPNCONTROL_PORT
-
-                                               u_int32_t address;
-                                               u_int16_t data_len = n->h.len - (sizeof(struct isakmp_pl_n) + n->spi_size);
-                                               u_int8_t *data_ptr = ((u_int8_t *)n) + (n->h.len - data_len);
-                                               
-                                               if (type == ISAKMP_INTERNAL_ERROR ||
-                                                       type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) {
-                                                       if (iph1->remote->sa_family == AF_INET)
-                                                               address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
-                                                       else
-                                                               address = 0;
-                                                       
-                                                       vpncontrol_notify_ike_failed(type, FROM_REMOTE, address, data_len, data_ptr);
-                                               }
-#endif
-                                               /* delete ph2 */
-                                               unbindph12(iph2);
-                                               remph2(iph2);
-                                               delph2(iph2);
-                                       }
-                               }
-                       }
-               } else
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                            "unencrypted notification message received");
-               break;
-       }
-
-       /* get spi and allocate */
-       if (ntohs(n->h.len) < sizeof(*n) + n->spi_size) {
-               plog(LLV_ERROR, LOCATION, iph1->remote,
-                       "invalid spi_size in notification payload.\n");
-               return -1;
-       }
-       spi = val2str((char *)(n + 1), n->spi_size);
-
-       plog(LLV_DEBUG, LOCATION, iph1->remote,
-               "notification message %d:%s, "
-               "doi=%d proto_id=%d spi=%s(size=%d).\n",
-               type, s_isakmp_notify_msg(type),
-               ntohl(n->doi), n->proto_id, spi, n->spi_size);
-
-       racoon_free(spi);
-
-       return(0);
-}
-
-void
+static void
 purge_isakmp_spi(proto, spi, n)
        int proto;
        isakmp_index *spi;      /*network byteorder*/
@@ -1034,14 +1450,17 @@ purge_isakmp_spi(proto, spi, n)
                        s_ipsecdoi_proto(proto),
                        isakmp_pindex(&spi[i], 0));
 
-               if (iph1->sce)
-                       SCHED_KILL(iph1->sce);
+               SCHED_KILL(iph1->sce);
+               SCHED_KILL(iph1->sce_rekey);
                iph1->status = PHASE1ST_EXPIRED;
+               ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1
                iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
        }
 }
 
-static void
+
+
+void
 purge_ipsec_spi(dst0, proto, spi, n)
        struct sockaddr *dst0;
        int proto;
@@ -1051,11 +1470,18 @@ purge_ipsec_spi(dst0, proto, spi, n)
        vchar_t *buf = NULL;
        struct sadb_msg *msg, *next, *end;
        struct sadb_sa *sa;
+       struct sadb_lifetime *lt;
        struct sockaddr *src, *dst;
        struct ph2handle *iph2;
+       u_int64_t created;
        size_t i;
        caddr_t mhp[SADB_EXT_MAX + 1];
 
+       plog(LLV_DEBUG2, LOCATION, NULL,
+                "purge_ipsec_spi:\n");
+       plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0));
+       plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0]));
+
        buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto));
        if (buf == NULL) {
                plog(LLV_DEBUG, LOCATION, NULL,
@@ -1091,18 +1517,27 @@ purge_ipsec_spi(dst0, proto, spi, n)
                }
                src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
                dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+               lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
+               if(lt != NULL)
+                       created = lt->sadb_lifetime_addtime;
+               else
+                       created = 0;
 
                if (sa->sadb_sa_state != SADB_SASTATE_MATURE
                 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
                        msg = next;
                        continue;
                }
+               plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
+               plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst));
+
+
 
                /* XXX n^2 algorithm, inefficient */
 
                /* don't delete inbound SAs at the moment */
                /* XXX should we remove SAs with opposite direction as well? */
-               if (CMPSADDR(dst0, dst)) {
+               if (CMPSADDR2(dst0, dst)) {
                        msg = next;
                        continue;
                }
@@ -1125,7 +1560,7 @@ purge_ipsec_spi(dst0, proto, spi, n)
                         * exists.
                         */
                        iph2 = getph2bysaidx(src, dst, proto, spi[i]);
-                       if (iph2) {
+                       if(iph2 != NULL){
                                delete_spd(iph2);
                                unbindph12(iph2);
                                remph2(iph2);
@@ -1170,9 +1605,12 @@ info_recv_initialcontact(iph1)
        if (f_local)
                return;
 
+       // TODO: make sure that is_rekey is cleared for this. and session indicates the same
 #if 0
-       loc = strdup(saddrwop2str(iph1->local));
-       rem = strdup(saddrwop2str(iph1->remote));
+       loc = racoon_strdup(saddrwop2str(iph1->local));
+       rem = racoon_strdup(saddrwop2str(iph1->remote));
+       STRDUP_FATAL(loc);
+       STRDUP_FATAL(rem);
 
        /*
         * Purge all IPSEC-SAs for the peer.  We can do this
@@ -1347,162 +1785,6 @@ info_recv_initialcontact(iph1)
        vfree(buf);
 }
 
-/*
- * handling to receive Deletion payload
- */
-static int
-isakmp_info_recv_d(iph1, msg)
-       struct ph1handle *iph1;
-       vchar_t *msg;
-{
-       struct isakmp_pl_d *d;
-       int tlen, num_spi;
-       vchar_t *pbuf;
-       struct isakmp_parse_t *pa, *pap;
-       int protected = 0;
-       union {
-               u_int32_t spi32;
-               u_int16_t spi16[2];
-       } spi;
-
-       /* validate the type of next payload */
-       if (!(pbuf = isakmp_parse(msg)))
-               return -1;
-       pa = (struct isakmp_parse_t *)pbuf->v;
-       for (pap = pa; pap->type; pap++) {
-               switch (pap->type) {
-               case ISAKMP_NPTYPE_D:
-                       break;
-               case ISAKMP_NPTYPE_HASH:
-                       if (pap == pa) {
-                               protected++;
-                               break;
-                       }
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "received next payload type %d "
-                               "in wrong place (must be the first payload).\n",
-                               pap->type);
-                       vfree(pbuf);
-                       return -1;
-               default:
-                       /* don't send information, see isakmp_ident_r1() */
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "reject the packet, "
-                               "received unexpecting payload type %d.\n",
-                               pap->type);
-                       vfree(pbuf);
-                       return 0;
-               }
-       }
-
-       if (!protected) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "delete payload is not proteted, "
-                       "ignored.\n");
-               vfree(pbuf);
-               return -1;
-       }
-
-       /* process a delete payload */
-       for (pap = pa; pap->type; pap++) {
-               if (pap->type != ISAKMP_NPTYPE_D)
-                       continue;
-
-               d = (struct isakmp_pl_d *)pap->ptr;
-
-               if (ntohl(d->doi) != IPSEC_DOI) {
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "delete payload with invalid doi:%d.\n",
-                               ntohl(d->doi));
-#ifdef ENABLE_HYBRID
-                       /*
-                        * At deconnexion time, Cisco VPN client does this
-                        * with a zero DOI. Don't give up in that situation.
-                        */
-                       if (((iph1->mode_cfg->flags &
-                           ISAKMP_CFG_VENDORID_UNITY) == 0) || (d->doi != 0))
-                               continue;
-#else
-                       continue;
-#endif
-               }
-
-               num_spi = ntohs(d->num_spi);
-               tlen = ntohs(d->h.len) - sizeof(struct isakmp_pl_d);
-
-               if (tlen != num_spi * d->spi_size) {
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "deletion payload with invalid length.\n");
-                       vfree(pbuf);
-                       return -1;
-               }
-
-               switch (d->proto_id) {
-               case IPSECDOI_PROTO_ISAKMP:
-                       if (d->spi_size != sizeof(isakmp_index)) {
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                       "delete payload with strange spi "
-                                       "size %d(proto_id:%d)\n",
-                                       d->spi_size, d->proto_id);
-                               continue;
-                       }
-
-                       if (iph1->scr)
-                               SCHED_KILL(iph1->scr);
-
-                       purge_remote(iph1);
-                       break;
-
-               case IPSECDOI_PROTO_IPSEC_AH:
-               case IPSECDOI_PROTO_IPSEC_ESP:
-                       if (d->spi_size != sizeof(u_int32_t)) {
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                       "delete payload with strange spi "
-                                       "size %d(proto_id:%d)\n",
-                                       d->spi_size, d->proto_id);
-                               continue;
-                       }
-                       EVT_PUSH(iph1->local, iph1->remote, 
-                           EVTT_PEER_DELETE, NULL);
-                       purge_ipsec_spi(iph1->remote, d->proto_id,
-                           (u_int32_t *)(d + 1), num_spi);
-                       break;
-
-               case IPSECDOI_PROTO_IPCOMP:
-                       /* need to handle both 16bit/32bit SPI */
-                       memset(&spi, 0, sizeof(spi));
-                       if (d->spi_size == sizeof(spi.spi16[1])) {
-                               memcpy(&spi.spi16[1], d + 1,
-                                   sizeof(spi.spi16[1]));
-                       } else if (d->spi_size == sizeof(spi.spi32))
-                               memcpy(&spi.spi32, d + 1, sizeof(spi.spi32));
-                       else {
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                       "delete payload with strange spi "
-                                       "size %d(proto_id:%d)\n",
-                                       d->spi_size, d->proto_id);
-                               continue;
-                       }
-                       purge_ipsec_spi(iph1->remote, d->proto_id,
-                           &spi.spi32, num_spi);
-                       break;
-
-               default:
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "deletion message received, "
-                               "invalid proto_id: %d\n",
-                               d->proto_id);
-                       continue;
-               }
-
-               plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n");
-       }
-
-       vfree(pbuf);
-
-       return 0;
-}
-
 void
 isakmp_check_notify(gen, iph1)
        struct isakmp_gen *gen;         /* points to Notify payload */
@@ -1515,16 +1797,15 @@ isakmp_check_notify(gen, iph1)
 
        switch (ntohs(notify->type)) {
        case ISAKMP_NTYPE_CONNECTED:
-               plog(LLV_WARNING, LOCATION, iph1->remote,
-                       "ignore CONNECTED notification.\n");
-               break;
        case ISAKMP_NTYPE_RESPONDER_LIFETIME:
-               plog(LLV_WARNING, LOCATION, iph1->remote,
-                       "ignore RESPONDER-LIFETIME notification.\n");
-               break;
        case ISAKMP_NTYPE_REPLAY_STATUS:
+       case ISAKMP_NTYPE_HEARTBEAT:
+#ifdef ENABLE_HYBRID
+       case ISAKMP_NTYPE_UNITY_HEARTBEAT:
+#endif
                plog(LLV_WARNING, LOCATION, iph1->remote,
-                       "ignore REPLAY-STATUS notification.\n");
+                       "ignore %s notification.\n",
+                       s_isakmp_notify_msg(ntohs(notify->type)));
                break;
        case ISAKMP_NTYPE_INITIAL_CONTACT:
                plog(LLV_WARNING, LOCATION, iph1->remote,
@@ -1536,20 +1817,61 @@ isakmp_check_notify(gen, iph1)
                        "ignore LOAD-BALANCE notification, "
                        "because it is only accepted after phase1.\n");
                break;
-       case ISAKMP_NTYPE_HEARTBEAT:
-               plog(LLV_WARNING, LOCATION, iph1->remote,
-                       "ignore HEARTBEAT notification\n");
-               break;
        default:
                isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
                plog(LLV_ERROR, LOCATION, iph1->remote,
-                       "received unknown notification type %u.\n",
-                   ntohs(notify->type));
+                       "received unknown notification type %s.\n",
+                       s_isakmp_notify_msg(ntohs(notify->type)));
        }
 
        return;
 }
 
+void
+isakmp_check_ph2_notify(gen, iph2)
+struct isakmp_gen *gen;                /* points to Notify payload */
+struct ph2handle *iph2;
+{
+       struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
+    
+       plog(LLV_DEBUG, LOCATION, iph2->dst,
+         "Phase2 Notify Message received\n");
+    
+       switch (ntohs(notify->type)) {
+        case ISAKMP_NTYPE_RESPONDER_LIFETIME:
+            return((void)isakmp_ph2_responder_lifetime(iph2,
+                                                       (struct isakmp_pl_resp_lifetime *)notify));
+            break;
+        case ISAKMP_NTYPE_CONNECTED:
+        case ISAKMP_NTYPE_REPLAY_STATUS:
+        case ISAKMP_NTYPE_HEARTBEAT:
+#ifdef ENABLE_HYBRID
+        case ISAKMP_NTYPE_UNITY_HEARTBEAT:
+#endif
+            plog(LLV_WARNING, LOCATION, iph2->dst,
+                 "ignore %s notification.\n",
+                 s_isakmp_notify_msg(ntohs(notify->type)));
+            break;
+        case ISAKMP_NTYPE_INITIAL_CONTACT:
+            plog(LLV_WARNING, LOCATION, iph2->dst,
+                 "ignore INITIAL-CONTACT notification, "
+                 "because it is only accepted after phase1.\n");
+            break;
+        case ISAKMP_NTYPE_LOAD_BALANCE:
+            plog(LLV_WARNING, LOCATION, iph2->dst,
+                 "ignore LOAD-BALANCE notification, "
+                 "because it is only accepted after phase1.\n");
+            break;
+        default:
+            isakmp_info_send_n1(iph2->ph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
+            plog(LLV_ERROR, LOCATION, iph2->dst,
+                 "received unknown notification type %s.\n",
+                 s_isakmp_notify_msg(ntohs(notify->type)));
+       }
+    
+       return;
+}
+
 #ifdef ENABLE_VPNCONTROL_PORT
 static int
 isakmp_info_recv_lb(iph1, n, encrypted)
@@ -1586,6 +1908,17 @@ isakmp_info_recv_lb(iph1, n, encrypted)
                        "received LOAD_BALANCE notification - redirect address=%x.\n",
                                ntohl(n->address));
 
+    if (((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr != ntohl(n->address)) {
+        plog(LLV_DEBUG, LOCATION, iph1->remote,
+             "deleting old phase1 because of LOAD_BALANCE notification - redirect address=%x.\n",
+             ntohl(n->address));
+
+        if (iph1->status == PHASE1ST_ESTABLISHED) {
+            isakmp_info_send_d1(iph1);
+        }
+        isakmp_ph1expire(iph1);
+    }
+
        return 0;
 }
 #endif
@@ -1610,6 +1943,10 @@ isakmp_info_recv_r_u (iph1, ru, msgid)
        tlen = sizeof(*ru_ack);
        payload = vmalloc(tlen);
        if (payload == NULL) { 
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("R-U-THERE? ACK"),
+                                                               CONSTSTR("Failed to transmit DPD response"));
                plog(LLV_ERROR, LOCATION, NULL,
                        "failed to get buffer to send.\n");
                return errno;
@@ -1630,6 +1967,17 @@ isakmp_info_recv_r_u (iph1, ru, msgid)
        error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
                                        ISAKMP_FLAG_E);
        vfree(payload);
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("R-U-THERE? ACK"),
+                                                               CONSTSTR("Failed to transmit DPD ack"));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+                                                               CONSTSTR("R-U-THERE? ACK"),
+                                                               CONSTSTR(NULL));
+       }
 
        plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n");
 
@@ -1650,10 +1998,10 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid)
        /* XXX Maintain window of acceptable sequence numbers ?
         * => ru->data <= iph2->dpd_seq &&
         *    ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */
-       if (ntohl(ru->data) != iph1->dpd_seq-1) {
+       if (ntohl(ru->data) != iph1->dpd_seq) {
                plog(LLV_ERROR, LOCATION, iph1->remote,
                         "Wrong DPD sequence number (%d, %d expected).\n", 
-                        ntohl(ru->data), iph1->dpd_seq-1);
+                        ntohl(ru->data), iph1->dpd_seq);
                return 0;
        }
 
@@ -1666,14 +2014,26 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid)
 
        iph1->dpd_fails = 0;
 
+       iph1->dpd_seq++;
+
        /* Useless ??? */
        iph1->dpd_lastack = time(NULL);
 
-       if (iph1->dpd_r_u != NULL)
-               SCHED_KILL(iph1->dpd_r_u);
+       SCHED_KILL(iph1->dpd_r_u);
 
        isakmp_sched_r_u(iph1, 0);
 
+       if (iph1->side == INITIATOR) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RESP,
+                                                               CONSTSTR("Initiator DPD Response"),
+                                                               CONSTSTR(NULL));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RESP,
+                                                               CONSTSTR("Responder DPD Response"),
+                                                               CONSTSTR(NULL));
+       }
        plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
 
        return 0;
@@ -1683,7 +2043,7 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid)
 /*
  * send Delete payload (for ISAKMP SA) in Informational exchange.
  */
-static void
+void
 isakmp_info_send_r_u(arg)
        void *arg;
 {
@@ -1695,10 +2055,27 @@ isakmp_info_send_r_u(arg)
        int tlen;
        int error = 0;
 
-       plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n");
+    if (iph1->status != PHASE1ST_ESTABLISHED) {
+        plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD r-u send aborted, invalid phase1 status %d....\n",
+             iph1->status);
+        return;
+    }
 
        if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
+               u_int32_t address;
+
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT,
+                                                               CONSTSTR("DPD maximum retransmits"),
+                                                               CONSTSTR("maxed-out of DPD requests without receiving an ack"));
+
                EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL);
+               if (iph1->remote->sa_family == AF_INET)
+                       address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
+               else
+                       address = 0;
+               (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PEER_DEAD, FROM_LOCAL, address, 0, NULL);
+
                purge_remote(iph1);
                plog(LLV_DEBUG, LOCATION, iph1->remote,
                         "DPD: remote seems to be dead\n");
@@ -1709,26 +2086,13 @@ isakmp_info_send_r_u(arg)
                return;
        }
 
-       /* TODO: check recent activity to avoid useless sends... */
-
-       /* XXX: why do we have a NULL LIST_FIRST even when a Phase2 exists ??? */
-#if 0
-       if (LIST_FIRST(&iph1->ph2tree) == NULL){
-               /* XXX: No Ph2 => no need to test ph1 ?
-                */
-               /* Reschedule the r_u_there....
-                  XXX: reschedule when a new ph2 ?
-                */
-               isakmp_sched_r_u(iph1, 0);
-               plog(LLV_DEBUG, LOCATION, iph1->remote,
-                        "no phase2 handler, rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_interval);
-               return 0;
-       }
-#endif
-
        tlen = sizeof(*ru);
        payload = vmalloc(tlen);
        if (payload == NULL) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("R-U-THERE?"),
+                                                               CONSTSTR("Failed to transmit DPD request"));
                plog(LLV_ERROR, LOCATION, NULL, 
                         "failed to get buffer for payload.\n");
                return;
@@ -1754,16 +2118,35 @@ isakmp_info_send_r_u(arg)
 
        error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
        vfree(payload);
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
+                                                               CONSTSTR("R-U-THERE?"),
+                                                               CONSTSTR("Failed to transmit DPD request"));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
+                                                               CONSTSTR("R-U-THERE?"),
+                                                               CONSTSTR(NULL));
+       }
 
+       if (iph1->side == INITIATOR) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ,
+                                                               CONSTSTR("Initiator DPD Request"),
+                                                               CONSTSTR(NULL));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ,
+                                                               CONSTSTR("Responder DPD Request"),
+                                                               CONSTSTR(NULL));
+       }
        plog(LLV_DEBUG, LOCATION, iph1->remote,
                 "DPD R-U-There sent (%d)\n", error);
 
        /* will be decreased if ACK received... */
        iph1->dpd_fails++;
 
-       /* XXX should be increased only when ACKed ? */
-       iph1->dpd_seq++;
-
        /* Reschedule the r_u_there with a short delay,
         * will be deleted/rescheduled if ACK received before */
        isakmp_sched_r_u(iph1, 1);
@@ -1772,6 +2155,97 @@ isakmp_info_send_r_u(arg)
                 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry);
 }
 
+/*
+ * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange.
+ */
+static void
+isakmp_info_monitor_r_u_algo_inbound_detect (struct ph1handle *iph1)
+{
+    if (iph1->status != PHASE1ST_ESTABLISHED) {
+        plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) aborted, invalid phase1 status %d....\n",
+             iph1->status);
+        return;
+    }
+
+       plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) ....\n");
+    
+    // check phase1 for ike packets received from peer
+    if (iph1->peer_sent_ike) {
+        // yes, reshedule check
+        iph1->peer_sent_ike = 0;
+        
+        /* ike packets received from peer... reschedule dpd */
+        isakmp_sched_r_u(iph1, 0);
+        
+        plog(LLV_DEBUG, LOCATION, iph1->remote,
+             "ike packets received from peer... reschedule monitor.\n");
+
+        return;
+    }
+
+    // after ike packets, next we check if any data was received
+    if (!iph1->parent_session->peer_sent_data_sc_dpd) {
+        isakmp_info_send_r_u(iph1);
+    } else {
+        isakmp_sched_r_u(iph1, 0);
+        
+        plog(LLV_DEBUG, LOCATION, iph1->remote,
+             "rescheduling DPD monitoring (for ALGORITHM_INBOUND_DETECT).\n");
+    }
+    iph1->parent_session->peer_sent_data_sc_dpd = 0;
+}
+
+/*
+ * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange.
+ */
+static void
+isakmp_info_monitor_r_u_algo_blackhole_detect (struct ph1handle *iph1)
+{
+    if (iph1->status != PHASE1ST_ESTABLISHED) {
+        plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) aborted, invalid phase1 status %d....\n",
+             iph1->status);
+        return;
+    }
+
+       plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) ....\n");
+
+    // check if data was sent but none was received
+    if (iph1->parent_session->i_sent_data_sc_dpd &&
+        !iph1->parent_session->peer_sent_data_sc_dpd) {
+        isakmp_info_send_r_u(iph1);
+    } else {
+        isakmp_sched_r_u(iph1, 0);
+        
+        plog(LLV_DEBUG, LOCATION, iph1->remote,
+             "rescheduling DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) i = %d, peer %d.\n",
+             iph1->parent_session->i_sent_data_sc_dpd,
+             iph1->parent_session->peer_sent_data_sc_dpd);
+    }
+    iph1->parent_session->i_sent_data_sc_dpd = 0;
+    iph1->parent_session->peer_sent_data_sc_dpd = 0;
+}
+
+/*
+ * monitor DPD Informational exchange.
+ */
+static void
+isakmp_info_monitor_r_u(arg)
+void *arg;
+{
+       struct ph1handle *iph1 = arg;
+
+    if (iph1 && iph1->rmconf) {
+        if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT) {
+            isakmp_info_monitor_r_u_algo_inbound_detect(iph1);
+        } else if (iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) {
+            isakmp_info_monitor_r_u_algo_blackhole_detect(iph1);
+        } else {
+            plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring aborted, invalid algorithm %d....\n",
+                 iph1->rmconf->dpd_algo);
+        }
+    }
+}
+
 /* Schedule a new R-U-THERE */
 int
 isakmp_sched_r_u(iph1, retry)
@@ -1787,13 +2261,49 @@ isakmp_sched_r_u(iph1, retry)
           iph1->rmconf->dpd_interval == 0)
                return 0;
 
-       if(retry)
+       if(retry) {
                iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry,
-                                         isakmp_info_send_r_u, iph1);
-       else
-               sched_new(iph1->rmconf->dpd_interval,
-                         isakmp_info_send_r_u, iph1);
+                                                                 isakmp_info_send_r_u, iph1);
+       } else {
+        if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT ||
+            iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) {
+            iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
+                                      isakmp_info_monitor_r_u, iph1);
+        } else {
+            iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
+                                      isakmp_info_send_r_u, iph1);
+        }
+    }
 
        return 0;
 }
+
+/*
+ * punts dpd for later because of some activity that:
+ * 1) implicitly does dpd (e.g. phase2 exchanges), or
+ * 2) indicates liveness (e.g. received ike packets).
+ */
+void
+isakmp_reschedule_info_monitor_if_pending (struct ph1handle *iph1,
+                                          char             *reason)
+{
+    if (!iph1 ||
+        iph1->status != PHASE1ST_ESTABLISHED ||
+        !iph1->dpd_support ||
+        !iph1->rmconf->dpd_interval ||
+        iph1->rmconf->dpd_algo == DPD_ALGO_DEFAULT) {
+        return;
+    }
+
+    if (!iph1->peer_sent_ike) {
+        SCHED_KILL(iph1->dpd_r_u);
+
+        isakmp_sched_r_u(iph1, 0);
+
+        plog(LLV_DEBUG, LOCATION, iph1->remote,
+             "%s... rescheduling send_r_u.\n",
+             reason);
+    }
+    iph1->peer_sent_ike++;
+}
 #endif
index 4f22ece175b58b392d536227fc80f458e443e900..50cd2f977dc43aee7f432300e9326699eb8d145f 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_inf.h,v 1.4 2004/11/16 15:44:46 ludvigm Exp $ */
+/*     $NetBSD: isakmp_inf.h,v 1.4 2006/09/09 16:22:09 manu Exp $      */
+
+/* Id: isakmp_inf.h,v 1.6 2005/05/07 14:15:59 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -32,6 +34,8 @@
 #ifndef _ISAKMP_INF_H
 #define _ISAKMP_INF_H
 
+#include "proposal.h"
+
 struct saproto;
 extern int isakmp_info_recv __P((struct ph1handle *, vchar_t *));
 extern int isakmp_info_send_d1 __P((struct ph1handle *));
@@ -48,8 +52,15 @@ extern vchar_t * isakmp_add_pl_n __P((vchar_t *, u_int8_t **, int,
 
 extern void isakmp_check_notify __P((struct isakmp_gen *, struct ph1handle *));
 
+extern void isakmp_check_ph2_notify __P((struct isakmp_gen *, struct ph2handle *));
+
 #ifdef ENABLE_DPD
 extern int isakmp_sched_r_u __P((struct ph1handle *, int));
+extern void isakmp_reschedule_info_monitor_if_pending __P((struct ph1handle *, char *));
+extern void isakmp_info_send_r_u __P((void *));
 #endif
 
+extern void purge_ipsec_spi __P((struct sockaddr *, int,       u_int32_t *, size_t));
+extern int tunnel_mode_prop __P((struct saprop *));
+
 #endif /* _ISAKMP_INF_H */
index 0db0107188c30a57b55902459fbf22130c0f631e..211e632e13b4ba3f5f110ad20e128f347963f9fc 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: isakmp_newg.c,v 1.4 2006/09/09 16:22:09 manu Exp $     */
+
 /*     $KAME: isakmp_newg.c,v 1.10 2002/09/27 05:55:52 itojun Exp $    */
 
 /*
index a872904dead2ee84b14f653b44895ccb2343ec8e..005ca95d2eea47bd6a526fdf81192d4ba098954d 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_quick.c,v 1.13.2.7 2005/07/20 08:02:05 vanhu Exp $ */
+/*     $NetBSD: isakmp_quick.c,v 1.11.4.1 2007/08/01 11:52:21 vanhu Exp $      */
+
+/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -51,6 +53,9 @@
 #  include <time.h>
 # endif
 #endif
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
 
 #ifndef HAVE_NETINET6_IPSEC
 #include <netinet/ipsec.h>
 
 #include "localconf.h"
 #include "remoteconf.h"
+#include "handler.h"
+#include "policy.h"
+#include "proposal.h"
 #include "isakmp_var.h"
 #include "isakmp.h"
 #include "isakmp_inf.h"
 #include "isakmp_quick.h"
 #include "oakley.h"
-#include "handler.h"
 #include "ipsec_doi.h"
 #include "crypto_openssl.h"
 #include "pfkey.h"
@@ -84,6 +91,8 @@
 #include "admin.h"
 #include "strnames.h"
 #include "nattraversal.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
 
 /* quick mode */
 static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *));
@@ -111,6 +120,8 @@ quick_i1prep(iph2, msg)
        }
 
        iph2->msgid = isakmp_newmsgid2(iph2->ph1);
+       if (iph2->ivm != NULL)
+               oakley_delivm(iph2->ivm);
        iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid);
        if (iph2->ivm == NULL)
                return 0;
@@ -124,8 +135,11 @@ quick_i1prep(iph2, msg)
        }
 
        /* send getspi message */
-       if (pk_sendgetspi(iph2) < 0)
+       if (pk_sendgetspi(iph2) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send getspi message");
                goto end;
+       }
 
        plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
 
@@ -140,7 +154,7 @@ end:
 
 /*
  * send to responder
- *     HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
+ *     HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
  */
 int
 quick_i1send(iph2, msg)
@@ -149,8 +163,10 @@ quick_i1send(iph2, msg)
 {
        vchar_t *body = NULL;
        vchar_t *hash = NULL;
+#ifdef ENABLE_NATT     
        vchar_t *natoa_i = NULL;
        vchar_t *natoa_r = NULL;
+#endif /* ENABLE_NATT */
        int             natoa_type = 0;
        struct isakmp_gen *gen;
        char *p;
@@ -173,13 +189,19 @@ quick_i1send(iph2, msg)
        }
 
        /* create SA payload for my proposal */
-       if (ipsecdoi_setph2proposal(iph2) < 0)
+       if (ipsecdoi_setph2proposal(iph2) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set proposal");
                goto end;
+       }
 
        /* generate NONCE value */
        iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
-       if (iph2->nonce == NULL)
+       if (iph2->nonce == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate NONCE");
                goto end;
+       }
 
        /*
         * DH value calculation is kicked out into cfparse.y.
@@ -197,6 +219,8 @@ quick_i1send(iph2, msg)
                }
                if (oakley_dh_generate(iph2->pfsgrp,
                                &iph2->dhpub, &iph2->dhpriv) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate DH");
                        goto end;
                }
        }
@@ -207,9 +231,9 @@ quick_i1send(iph2, msg)
                        "failed to get ID.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "IDci:");
+       plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n");
        plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
-       plog(LLV_DEBUG, LOCATION, NULL, "IDcr:");
+       plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n");
        plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
 
        /*
@@ -239,22 +263,28 @@ quick_i1send(iph2, msg)
        if (idcr)
                tlen += sizeof(*gen) + iph2->id_p->l;
 
-#ifdef NOT_NOW
 #ifdef ENABLE_NATT     
-       /* 
-        * create natoa payloads if needed but only
-        * if transport mode proposals are present
+       /*
+        * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
+        * we should send NAT-OA
         */
-       if (ipsecdoi_tunnelmode(iph2) != 1) {
+       if (ipsecdoi_any_transportmode(iph2->proposal)
+               && (iph2->ph1->natt_flags & NAT_DETECTED)) {
                natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r);
-               if (natoa_type == -1)
+               if (natoa_type == -1) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate NAT-OA payload.\n");
                        goto end;
-               else if (natoa_type != 0) {
+               else if (natoa_type != 0) {
                        tlen += sizeof(*gen) + natoa_i->l;
                        tlen += sizeof(*gen) + natoa_r->l;
+                       
+                       plog(LLV_DEBUG, LOCATION, NULL, "initiator send NAT-OAi:\n");
+                       plogdump(LLV_DEBUG, natoa_i->v, natoa_i->l);
+                       plog(LLV_DEBUG, LOCATION, NULL, "initiator send NAT-OAr:\n");
+                       plogdump(LLV_DEBUG, natoa_r->v, natoa_r->l);
                }
        }
-#endif
 #endif
 
        body = vmalloc(tlen);
@@ -275,34 +305,21 @@ quick_i1send(iph2, msg)
        else if (idci || idcr)
                np = ISAKMP_NPTYPE_ID;
        else
-#ifdef NOT_NOW
                np = (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
-#else
-               np = ISAKMP_NPTYPE_NONE;
-#endif
        p = set_isakmp_payload(p, iph2->nonce, np);
 
        /* add KE payload if need. */
-#ifdef NOT_NOW
        np = (idci || idcr) ? ISAKMP_NPTYPE_ID : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
-#else
-       np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
-#endif
        if (pfsgroup)
                p = set_isakmp_payload(p, iph2->dhpub, np);
 
        /* IDci */
-#ifdef NOT_NOW
        np = (idcr) ? ISAKMP_NPTYPE_ID : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
-#else
-       np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
-#endif
        if (idci)
                p = set_isakmp_payload(p, iph2->id, np);
 
        /* IDcr */
        if (idcr)
-#ifdef NOT_NOW
                p = set_isakmp_payload(p, iph2->id_p, natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
                
        /* natoa */
@@ -310,48 +327,65 @@ quick_i1send(iph2, msg)
                p = set_isakmp_payload(p, natoa_i, natoa_type);
                p = set_isakmp_payload(p, natoa_r, ISAKMP_NPTYPE_NONE);
        }
-#else
-               p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE);
-#endif
 
        /* generate HASH(1) */
        hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
-       if (hash == NULL)
+       if (hash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
+       }
 
        /* send isakmp payload */
        iph2->sendbuf = quick_ir1mx(iph2, body, hash);
-       if (iph2->sendbuf == NULL)
+       if (iph2->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to get send buffer");
                goto end;
+       }
 
        /* send the packet, add to the schedule to resend */
        iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
-       if (isakmp_ph2resend(iph2) == -1)
+       if (isakmp_ph2resend(iph2) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* change status of isakmp status entry */
        iph2->status = PHASE2ST_MSG1SENT;
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Initiator, Quick-Mode message 1"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Initiator, Quick-Mode Message 1"),
+                                                               CONSTSTR("Failed to transmit Quick-Mode Message 1"));
+       }
        if (body != NULL)
                vfree(body);
        if (hash != NULL)
                vfree(hash);
-#ifdef NOT_NOW
+#ifdef ENABLE_NATT     
        if (natoa_i)
                vfree(natoa_i);
        if (natoa_r)
                vfree(natoa_r);
-#endif
+#endif /* ENABLE_NATT */
 
        return error;
 }
 
 /*
  * receive from responder
- *     HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
+ *     HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
  */
 int
 quick_i2recv(iph2, msg0)
@@ -368,6 +402,8 @@ quick_i2recv(iph2, msg0)
        char *p;
        int tlen;
        int error = ISAKMP_INTERNAL_ERROR;
+       struct sockaddr *natoa_i = NULL;
+       struct sockaddr *natoa_r = NULL;
 
        /* validity check */
        if (iph2->status != PHASE2ST_MSG1SENT) {
@@ -383,8 +419,11 @@ quick_i2recv(iph2, msg0)
                goto end;
        }
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
-       if (msg == NULL)
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to decrypt");
                goto end;
+       }
 
        /* create buffer for validating HASH(2) */
        /*
@@ -394,8 +433,11 @@ quick_i2recv(iph2, msg0)
         *      3. two IDs must be considered as IDci, then IDcr
         */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
        pa = (struct isakmp_parse_t *)pbuf->v;
 
        /* HASH payload is fixed postion */
@@ -454,18 +496,27 @@ quick_i2recv(iph2, msg0)
                                        "isn't supported.\n");
                                break;
                        }
-                       if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process SA payload");
                                goto end;
+                       }
                        break;
 
                case ISAKMP_NPTYPE_NONCE:
-                       if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process NONCE payload");
                                goto end;
+                       }
                        break;
 
                case ISAKMP_NPTYPE_KE:
-                       if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process KE payload");
                                goto end;
+                       }
                        break;
 
                case ISAKMP_NPTYPE_ID:
@@ -523,14 +574,38 @@ quick_i2recv(iph2, msg0)
                        break;
 
                case ISAKMP_NPTYPE_N:
-                       isakmp_check_notify(pa->ptr, iph2->ph1);
+                       isakmp_check_ph2_notify(pa->ptr, iph2);
                        break;
 
 #ifdef ENABLE_NATT
                case ISAKMP_NPTYPE_NATOA_DRAFT:
                case ISAKMP_NPTYPE_NATOA_BADDRAFT:
                case ISAKMP_NPTYPE_NATOA_RFC:
-                       /* Ignore original source/destination messages */
+                   {
+                               vchar_t         *vp = NULL;
+                               struct sockaddr *daddr;
+
+                               isakmp_p2ph(&vp, pa->ptr);
+
+                               if (vp) {
+                                       daddr = process_natoa_payload(vp);
+                                       if (daddr) {
+                                               if (natoa_i == NULL) {
+                                                       natoa_i = daddr;
+                                                       plog(LLV_DEBUG, LOCATION, NULL, "initiaor rcvd NAT-OA i: %s\n",
+                                                                saddr2str(natoa_i));
+                                               } else if (natoa_r == NULL) {
+                                                       natoa_r = daddr;
+                                                       plog(LLV_DEBUG, LOCATION, NULL, "initiator rcvd NAT-OA r: %s\n",
+                                                                saddr2str(natoa_r));
+                                               } else {
+                                                       racoon_free(daddr);
+                                               }
+                                       }
+                                       vfree(vp);
+                               }
+
+                       }
                        break;
 #endif
 
@@ -576,8 +651,11 @@ quick_i2recv(iph2, msg0)
        plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
 
        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
-       if (my_hash == NULL)
+       if (my_hash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
+       }
 
        result = memcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
@@ -592,6 +670,8 @@ quick_i2recv(iph2, msg0)
 
        /* validity check SA payload sent from responder */
        if (ipsecdoi_checkph2proposal(iph2) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to validate SA proposal");
                error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
                goto end;
        }
@@ -601,7 +681,18 @@ quick_i2recv(iph2, msg0)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Initiator, Quick-Mode message 2"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Initiator, Quick-Mode Message 2"),
+                                                               CONSTSTR("Failed to process Quick-Mode Message 2 "));
+       }
        if (hbuf)
                vfree(hbuf);
        if (pbuf)
@@ -609,6 +700,15 @@ end:
        if (msg)
                vfree(msg);
 
+#ifdef ENABLE_NATT
+       if (natoa_i) {
+               racoon_free(natoa_i);
+       }
+       if (natoa_r) {
+               racoon_free(natoa_r);
+       }
+#endif
+
        if (error) {
                VPTRINIT(iph2->sa_ret);
                VPTRINIT(iph2->nonce_p);
@@ -635,6 +735,7 @@ quick_i2send(iph2, msg0)
        char *p = NULL;
        int tlen;
        int error = ISAKMP_INTERNAL_ERROR;
+       int packet_error = -1;
 
        /* validity check */
        if (iph2->status != PHASE2ST_STATUS6) {
@@ -661,8 +762,11 @@ quick_i2send(iph2, msg0)
        hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
        vfree(tmp);
 
-       if (hash == NULL)
+       if (hash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
+       }
     }
 
        /* create buffer for isakmp payload */
@@ -677,8 +781,11 @@ quick_i2send(iph2, msg0)
 
        /* create isakmp header */
        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
-       if (p == NULL)
+       if (p == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to create ISAKMP header");
                goto end;
+       }
 
        /* add HASH(3) payload */
        p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE);
@@ -689,32 +796,51 @@ quick_i2send(iph2, msg0)
 
        /* encoding */
        iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
-       if (iph2->sendbuf == NULL)
+       if (iph2->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to encrypt packet");
                goto end;
+       }
 
        /* if there is commit bit, need resending */
        if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
                /* send the packet, add to the schedule to resend */
                iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
-               if (isakmp_ph2resend(iph2) == -1)
+               if (isakmp_ph2resend(iph2) == -1) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to send packet, commit-bit");
                        goto end;
+               }
        } else {
                /* send the packet */
-               if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
+               if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to send packet");
                        goto end;
+               }
        }
 
        /* the sending message is added to the received-list. */
        if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
-                       iph2->sendbuf, msg0) == -1) {
+                     iph2->sendbuf, msg0,
+                     PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
        }
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Initiator, Quick-Mode message 3"),
+                                                       CONSTSTR(NULL));
+       packet_error = 0;
+
        /* compute both of KEYMATs */
-       if (oakley_compute_keymat(iph2, INITIATOR) < 0)
+       if (oakley_compute_keymat(iph2, INITIATOR) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute KEYMAT");
                goto end;
+       }
 
        iph2->status = PHASE2ST_ADDSA;
 
@@ -749,6 +875,12 @@ quick_i2send(iph2, msg0)
        error = 0;
 
 end:
+       if (packet_error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Initiator, Quick-Mode Message 3"),
+                                                               CONSTSTR("Failed to transmit Quick-Mode Message 3"));
+       }
        if (buf != NULL)
                vfree(buf);
        if (msg != NULL)
@@ -774,6 +906,7 @@ quick_i3recv(iph2, msg0)
        struct isakmp_pl_hash *hash = NULL;
        vchar_t *notify = NULL;
        int error = ISAKMP_INTERNAL_ERROR;
+       int packet_error = -1;
 
        /* validity check */
        if (iph2->status != PHASE2ST_COMMIT) {
@@ -789,13 +922,19 @@ quick_i3recv(iph2, msg0)
                goto end;
        }
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
-       if (msg == NULL)
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to decrypt packet");
                goto end;
+       }
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
 
        for (pa = (struct isakmp_parse_t *)pbuf->v;
             pa->type != ISAKMP_NPTYPE_NONE;
@@ -806,7 +945,12 @@ quick_i3recv(iph2, msg0)
                        hash = (struct isakmp_pl_hash *)pa->ptr;
                        break;
                case ISAKMP_NPTYPE_N:
-                       isakmp_check_notify(pa->ptr, iph2->ph1);
+                       if (notify != NULL) {
+                               plog(LLV_WARNING, LOCATION, NULL,
+                                   "Ignoring multiple notifications\n");
+                               break;
+                       }
+                       isakmp_check_ph2_notify(pa->ptr, iph2);
                        notify = vmalloc(pa->len);
                        if (notify == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL,
@@ -846,8 +990,11 @@ quick_i3recv(iph2, msg0)
 
        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
        vfree(tmp);
-       if (my_hash == NULL)
+       if (my_hash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
+       }
 
        result = memcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
@@ -860,6 +1007,12 @@ quick_i3recv(iph2, msg0)
        }
     }
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Initiator, Quick-Mode message 4"),
+                                                       CONSTSTR(NULL));
+       packet_error = 0;
+
        iph2->status = PHASE2ST_ADDSA;
        iph2->flags ^= ISAKMP_FLAG_C;   /* reset bit */
 
@@ -887,6 +1040,12 @@ quick_i3recv(iph2, msg0)
        error = 0;
 
 end:
+       if (packet_error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Initiator, Quick-Mode Message 4"),
+                                                               CONSTSTR("Failed to process Quick-Mode Message 4"));
+       }
        if (msg != NULL)
                vfree(msg);
        if (pbuf != NULL)
@@ -899,7 +1058,7 @@ end:
 
 /*
  * receive from initiator
- *     HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
+ *     HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
  */
 int
 quick_r1recv(iph2, msg0)
@@ -916,6 +1075,8 @@ quick_r1recv(iph2, msg0)
        int tlen;
        int f_id_order; /* for ID payload detection */
        int error = ISAKMP_INTERNAL_ERROR;
+       struct sockaddr *natoa_i = NULL;
+       struct sockaddr *natoa_r = NULL;
 
        /* validity check */
        if (iph2->status != PHASE2ST_START) {
@@ -933,8 +1094,11 @@ quick_r1recv(iph2, msg0)
        }
        /* decrypt packet */
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
-       if (msg == NULL)
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to decrypt packet");
                goto end;
+       }
 
        /* create buffer for using to validate HASH(1) */
        /*
@@ -944,8 +1108,11 @@ quick_r1recv(iph2, msg0)
         *      3. two IDs must be considered as IDci, then IDcr
         */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
        pa = (struct isakmp_parse_t *)pbuf->v;
 
        /* HASH payload is fixed postion */
@@ -1018,18 +1185,27 @@ quick_r1recv(iph2, msg0)
                                        "Multi SAs isn't supported.\n");
                                goto end;
                        }
-                       if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process SA payload");
                                goto end;
+                       }
                        break;
 
                case ISAKMP_NPTYPE_NONCE:
-                       if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process NONCE payload");
                                goto end;
+                       }
                        break;
 
                case ISAKMP_NPTYPE_KE:
-                       if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
+                       if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "failed to process KE payload");
                                goto end;
+                       }
                        break;
 
                case ISAKMP_NPTYPE_ID:
@@ -1037,8 +1213,11 @@ quick_r1recv(iph2, msg0)
                                /* for IDci */
                                f_id_order++;
 
-                               if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0)
+                               if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                                "failed to process IDci2 payload");
                                        goto end;
+                               }
 
                        } else if (iph2->id == NULL) {
                                /* for IDcr */
@@ -1050,8 +1229,11 @@ quick_r1recv(iph2, msg0)
                                        /* XXX we allowed in this case. */
                                }
 
-                               if (isakmp_p2ph(&iph2->id, pa->ptr) < 0)
+                               if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                                "failed to process IDcr2 payload");
                                        goto end;
+                               }
                        } else {
                                plog(LLV_ERROR, LOCATION, NULL,
                                        "received too many ID payloads.\n");
@@ -1062,14 +1244,38 @@ quick_r1recv(iph2, msg0)
                        break;
 
                case ISAKMP_NPTYPE_N:
-                       isakmp_check_notify(pa->ptr, iph2->ph1);
+                       isakmp_check_ph2_notify(pa->ptr, iph2);
                        break;
 
 #ifdef ENABLE_NATT
                case ISAKMP_NPTYPE_NATOA_DRAFT:
                case ISAKMP_NPTYPE_NATOA_BADDRAFT:
                case ISAKMP_NPTYPE_NATOA_RFC:
-                       /* Ignore original source/destination messages */
+                   {
+                               vchar_t         *vp = NULL;
+                               struct sockaddr *daddr;
+                               
+                               isakmp_p2ph(&vp, pa->ptr);
+                               
+                               if (vp) {
+                                       daddr = process_natoa_payload(vp);
+                                       if (daddr) {
+                                               if (natoa_i == NULL) {
+                                                       natoa_i = daddr;
+                                                       plog(LLV_DEBUG, LOCATION, NULL, "responder rcvd NAT-OA i: %s\n",
+                                                                saddr2str(natoa_i));
+                                               } else if (natoa_r == NULL) {
+                                                       natoa_r = daddr;
+                                                       plog(LLV_DEBUG, LOCATION, NULL, "responder rcvd NAT-OA r: %s\n",
+                                                                saddr2str(natoa_r));
+                                               } else {
+                                                       racoon_free(daddr);
+                                               }
+                                       }
+                                       vfree(vp);
+                               }
+                               
+                       }
                        break;
 #endif
 
@@ -1120,8 +1326,11 @@ quick_r1recv(iph2, msg0)
        plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
 
        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
-       if (my_hash == NULL)
+       if (my_hash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
+       }
 
        result = memcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
@@ -1142,10 +1351,10 @@ quick_r1recv(iph2, msg0)
                goto end;
        }
 
-       /* check the existence of ID payload and create responder's proposal */
-       error = get_proposal_r(iph2, 0);
-       if (error != -2 && error != 0 && (iph2->ph1->natt_flags & NAT_DETECTED_ME) && lcconf->ext_nat_id != NULL)
-               error = get_proposal_r(iph2, 1);
+    /* check the existence of ID payload and create responder's proposal */
+    error = get_proposal_r(iph2, 0);
+    if (error != -2 && error != 0 && (iph2->ph1->natt_flags & NAT_DETECTED_ME) && (lcconf->ext_nat_id != NULL || ike_session_is_client_ph2_rekey(iph2)))
+        error = get_proposal_r(iph2, 1);
                
        switch (error) {
        case -2:
@@ -1160,6 +1369,8 @@ quick_r1recv(iph2, msg0)
        case 0:
                /* select single proposal or reject it. */
                if (ipsecdoi_selectph2proposal(iph2) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to select proposal.\n");
                        error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
                        goto end;
                }
@@ -1184,6 +1395,8 @@ quick_r1recv(iph2, msg0)
                goto end;
        }
 
+       ike_session_update_mode(iph2); /* update the mode, now that we have a proposal */
+
        /*
         * save the packet from the initiator in order to resend the
         * responder's first packet against this packet.
@@ -1195,7 +1408,18 @@ quick_r1recv(iph2, msg0)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Responder, Quick-Mode message 1"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Responder, Quick-Mode Message 1"),
+                                                               CONSTSTR("Failed to process Quick-Mode Message 1"));
+       }
        if (hbuf)
                vfree(hbuf);
        if (msg)
@@ -1203,6 +1427,15 @@ end:
        if (pbuf)
                vfree(pbuf);
 
+#ifdef ENABLE_NATT
+       if (natoa_i) {
+               racoon_free(natoa_i);
+       }
+       if (natoa_r) {
+               racoon_free(natoa_r);
+       }
+#endif
+
        if (error) {
                VPTRINIT(iph2->sa);
                VPTRINIT(iph2->nonce_p);
@@ -1234,8 +1467,11 @@ quick_r1prep(iph2, msg)
        iph2->status = PHASE2ST_GETSPISENT;
 
        /* send getspi message */
-       if (pk_sendgetspi(iph2) < 0)
+       if (pk_sendgetspi(iph2) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send getspi");
                goto end;
+       }
 
        plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
 
@@ -1250,7 +1486,7 @@ end:
 
 /*
  * send to initiator
- *     HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
+ *     HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
  */
 int
 quick_r2send(iph2, msg)
@@ -1262,7 +1498,6 @@ quick_r2send(iph2, msg)
        vchar_t *natoa_i = NULL;
        vchar_t *natoa_r = NULL;
        int             natoa_type = 0;
-       int             encmode;
        struct isakmp_gen *gen;
        char *p;
        int tlen;
@@ -1290,8 +1525,11 @@ quick_r2send(iph2, msg)
 
        /* generate NONCE value */
        iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
-       if (iph2->nonce == NULL)
+       if (iph2->nonce == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to generate NONCE");
                goto end;
+       }
 
        /* generate KE value if need */
        pfsgroup = iph2->approval->pfs_group;
@@ -1305,6 +1543,8 @@ quick_r2send(iph2, msg)
                /* generate DH public value */
                if (oakley_dh_generate(iph2->pfsgrp,
                                &iph2->dhpub, &iph2->dhpriv) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to generate DH public");
                        goto end;
                }
        }
@@ -1318,24 +1558,30 @@ quick_r2send(iph2, msg)
                tlen += (sizeof(*gen) + iph2->id_p->l
                        + sizeof(*gen) + iph2->id->l);
 
-#ifdef NOT_NOW
 #ifdef ENABLE_NATT
-       /* create natoa payloads if needed */
-       encmode = iph2->approval->head->encmode;
-       if (encmode == IPSECDOI_ATTR_ENC_MODE_TRNS ||
-               encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC ||
-               encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT) {
-
+       /*
+        * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
+        * we should send NAT-OA
+        */
+       if (ipsecdoi_any_transportmode(iph2->approval)
+               && (iph2->ph1->natt_flags & NAT_DETECTED)) {
                natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r);
-               if (natoa_type == -1)
+               if (natoa_type == -1) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to create NATOA payloads");
                        goto end;
+               }
                else if (natoa_type != 0) {
                        tlen += sizeof(*gen) + natoa_i->l;
                        tlen += sizeof(*gen) + natoa_r->l;
+                       
+                       plog(LLV_DEBUG, LOCATION, NULL, "responder send NAT-OAi:\n");
+                       plogdump(LLV_DEBUG, natoa_i->v, natoa_i->l);
+                       plog(LLV_DEBUG, LOCATION, NULL, "responder send NAT-OAr:\n");
+                       plogdump(LLV_DEBUG, natoa_r->v, natoa_r->l);
                }
        }
 #endif
-#endif
 
 
        body = vmalloc(tlen);
@@ -1356,23 +1602,13 @@ quick_r2send(iph2, msg)
                                ? ISAKMP_NPTYPE_KE
                                : (iph2->id_p != NULL
                                        ? ISAKMP_NPTYPE_ID
-#ifdef NOT_NOW
                                        : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE)));
-#else
-                                       : ISAKMP_NPTYPE_ID));
-#endif
 
        /* add KE payload if need. */
        if (iph2->dhpub_p != NULL && pfsgroup != 0) {
                np_p = &((struct isakmp_gen *)p)->np;   /* XXX */
                p = set_isakmp_payload(p, iph2->dhpub,
-                       (iph2->id_p == NULL)
-#ifdef NOT_NOW
-                               ? (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE)
-#else
-                               ? ISAKMP_NPTYPE_NONE
-#endif
-                               : ISAKMP_NPTYPE_ID);
+                       (iph2->id_p == NULL) ? (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE) : ISAKMP_NPTYPE_ID);
        }
 
        /* add ID payloads received. */
@@ -1381,11 +1617,7 @@ quick_r2send(iph2, msg)
                p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
                /* IDcr */
                np_p = &((struct isakmp_gen *)p)->np;   /* XXX */
-#ifdef NOT_NOW
                p = set_isakmp_payload(p, iph2->id, (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE));
-#else
-               p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE);
-#endif
        }
 
        /* add a RESPONDER-LIFETIME notify payload if needed */
@@ -1398,23 +1630,35 @@ quick_r2send(iph2, msg)
                u_int32_t v = htonl((u_int32_t)pp->lifetime);
                data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
                                        IPSECDOI_ATTR_SA_LD_TYPE_SEC);
-               if (!data)
+               if (!data) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to add RESPONDER-LIFETIME notify (type) payload");
                        goto end;
+               }
                data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
                                        (caddr_t)&v, sizeof(v));
-               if (!data)
+               if (!data) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to add RESPONDER-LIFETIME notify (value) payload");
                        goto end;
+               }
        }
        if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) {
                u_int32_t v = htonl((u_int32_t)pp->lifebyte);
                data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
                                        IPSECDOI_ATTR_SA_LD_TYPE_KB);
-               if (!data)
+               if (!data) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to add RESPONDER-LIFETIME notify (type) payload");
                        goto end;
+               }
                data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
                                        (caddr_t)&v, sizeof(v));
-               if (!data)
+               if (!data) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to add RESPONDER-LIFETIME notify (value) payload");
                        goto end;
+               }
        }
 
        /*
@@ -1426,6 +1670,8 @@ quick_r2send(iph2, msg)
                        body = isakmp_add_pl_n(body, &np_p,
                                        ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data);
                        if (!body) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "invalid RESPONDER-LIFETIME payload");
                                vfree(data);
                                return error;   /* XXX */
                        }
@@ -1434,13 +1680,11 @@ quick_r2send(iph2, msg)
        }
     }
 
-#ifdef NOT_NOW
        /* natoa */
        if (natoa_type) {
                p = set_isakmp_payload(p, natoa_i, natoa_type);
                p = set_isakmp_payload(p, natoa_r, ISAKMP_NPTYPE_NONE);
        }
-#endif
 
        /* generate HASH(2) */
     {
@@ -1458,22 +1702,32 @@ quick_r2send(iph2, msg)
        hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp);
        vfree(tmp);
 
-       if (hash == NULL)
+       if (hash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
     }
+       }
 
        /* send isakmp payload */
        iph2->sendbuf = quick_ir1mx(iph2, body, hash);
-       if (iph2->sendbuf == NULL)
+       if (iph2->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to get send buffer");
                goto end;
+       }
 
        /* send the packet, add to the schedule to resend */
        iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
-       if (isakmp_ph2resend(iph2) == -1)
+       if (isakmp_ph2resend(iph2) == -1) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1) == -1) {
+       if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1,
+                     PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -1484,17 +1738,26 @@ quick_r2send(iph2, msg)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Responder, Quick-Mode message 2"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Responder, Quick-Mode Message 2"),
+                                                               CONSTSTR("Failed to transmit Quick-Mode Message 2"));
+       }
        if (body != NULL)
                vfree(body);
        if (hash != NULL)
                vfree(hash);
-#ifdef NOT_NOW
        if (natoa_i)
                vfree(natoa_i);
        if (natoa_r)
                vfree(natoa_r);
-#endif
 
        return error;
 }
@@ -1528,13 +1791,19 @@ quick_r3recv(iph2, msg0)
                goto end;
        }
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
-       if (msg == NULL)
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to decrypt packet");
                goto end;
+       }
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
-       if (pbuf == NULL)
+       if (pbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to parse msg");
                goto end;
+       }
 
        for (pa = (struct isakmp_parse_t *)pbuf->v;
             pa->type != ISAKMP_NPTYPE_NONE;
@@ -1545,7 +1814,7 @@ quick_r3recv(iph2, msg0)
                        hash = (struct isakmp_pl_hash *)pa->ptr;
                        break;
                case ISAKMP_NPTYPE_N:
-                       isakmp_check_notify(pa->ptr, iph2->ph1);
+                       isakmp_check_ph2_notify(pa->ptr, iph2);
                        break;
                default:
                        /* don't send information, see ident_r1recv() */
@@ -1588,8 +1857,11 @@ quick_r3recv(iph2, msg0)
 
        my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
        vfree(tmp);
-       if (my_hash == NULL)
+       if (my_hash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
+       }
 
        result = memcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
@@ -1610,7 +1882,18 @@ quick_r3recv(iph2, msg0)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
+                                                       CONSTSTR("Responder, Quick-Mode message 3"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                                               CONSTSTR("Responder, Quick-Mode Message 3"),
+                                                               CONSTSTR("Failed to process Quick-Mode Message 3"));
+       }
        if (pbuf != NULL)
                vfree(pbuf);
        if (msg != NULL)
@@ -1665,8 +1948,11 @@ quick_r3send(iph2, msg0)
        memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize);
 
        myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
-       if (myhash == NULL)
+       if (myhash == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute HASH");
                goto end;
+       }
 
        /* create buffer for isakmp payload */
        tlen = sizeof(struct isakmp)
@@ -1681,8 +1967,11 @@ quick_r3send(iph2, msg0)
 
        /* create isakmp header */
        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
-       if (p == NULL)
+       if (p == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set ISAKMP header");
                goto end;
+       }
 
        /* add HASH(4) payload */
        p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N);
@@ -1696,15 +1985,22 @@ quick_r3send(iph2, msg0)
 
        /* encoding */
        iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
-       if (iph2->sendbuf == NULL)
+       if (iph2->sendbuf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to encrypt packet");
                goto end;
+       }
 
        /* send the packet */
-       if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
+       if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to send packet");
                goto end;
+       }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0) == -1) {
+       if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0,
+                     PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -1714,7 +2010,18 @@ quick_r3send(iph2, msg0)
 
        error = 0;
 
+       IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
+                                                       CONSTSTR("Responder, Quick-Mode message 4"),
+                                                       CONSTSTR(NULL));
+       
 end:
+       if (error) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
+                                                               CONSTSTR("Responder, Quick-Mode Message 4"),
+                                                               CONSTSTR("Failed to transmit Quick-Mode Message 4"));
+       }
        if (buf != NULL)
                vfree(buf);
        if (myhash != NULL)
@@ -1725,6 +2032,7 @@ end:
        return error;
 }
 
+
 /*
  * set SA to kernel.
  */
@@ -1744,8 +2052,11 @@ quick_r3prep(iph2, msg0)
        }
 
        /* compute both of KEYMATs */
-       if (oakley_compute_keymat(iph2, RESPONDER) < 0)
+       if (oakley_compute_keymat(iph2, RESPONDER) < 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to compute KEYMAT");
                goto end;
+       }
 
        iph2->status = PHASE2ST_ADDSA;
        iph2->flags ^= ISAKMP_FLAG_C;   /* reset bit */
@@ -1875,8 +2186,11 @@ quick_ir1mx(iph2, body, hash)
 
        /* set isakmp header */
        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
-       if (p == NULL)
+       if (p == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to set ISAKMP header");
                goto end;
+       }
 
        /* add HASH payload */
        /* XXX is next type always SA ? */
@@ -1891,8 +2205,11 @@ quick_ir1mx(iph2, body, hash)
 
        /* encoding */
        new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
-       if (new == NULL)
+       if (new == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to encrypt packet");
                goto end;
+       }
 
        vfree(buf);
 
@@ -1920,8 +2237,10 @@ get_sainfo_r(iph2)
        vchar_t *idsrc = NULL, *iddst = NULL;
        int prefixlen;
        int error = ISAKMP_INTERNAL_ERROR;
+       int remoteid = 0;
 
-       if (iph2->id_p == NULL) {
+       if (iph2->id == NULL ||
+        ((iph2->ph1->natt_flags & NAT_DETECTED_ME) && ike_session_is_client_ph2_rekey(iph2))) {
                switch (iph2->src->sa_family) {
                case AF_INET:
                        prefixlen = sizeof(struct in_addr) << 3;
@@ -1945,7 +2264,8 @@ get_sainfo_r(iph2)
                goto end;
        }
 
-       if (iph2->id == NULL) {
+       if (iph2->id_p == NULL ||
+        ((iph2->ph1->natt_flags & NAT_DETECTED_PEER) && ike_session_is_client_ph2_rekey(iph2))) {
                switch (iph2->dst->sa_family) {
                case AF_INET:
                        prefixlen = sizeof(struct in_addr) << 3;
@@ -1978,9 +2298,27 @@ get_sainfo_r(iph2)
                        "failed to get sainfo.\n");
                goto end;
        }
+#ifdef __APPLE__
+       if (link_sainfo_to_ph2(iph2->sainfo) != 0) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to link sainfo\n");
+               iph2->sainfo = NULL;
+               goto end;
+       }
+#endif
+       
+#ifdef ENABLE_HYBRID
+       /* xauth group inclusion check */
+       if (iph2->sainfo->group != NULL)
+               if(group_check(iph2->ph1,&iph2->sainfo->group->v,1)) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to group check");
+                       goto end;
+               }
+#endif
 
        plog(LLV_DEBUG, LOCATION, NULL,
-               "get sa info: %s\n", sainfo2str(iph2->sainfo));
+               "selected sainfo: %s\n", sainfo2str(iph2->sainfo));
 
        error = 0;
 end:
@@ -2011,6 +2349,7 @@ get_proposal_r(iph2, use_remote_addr)
        struct secpolicy *sp_in, *sp_out;
        int idi2type = 0;       /* switch whether copy IDs into id[src,dst]. */
        int error = ISAKMP_INTERNAL_ERROR;
+       int generated_policy_exit_early = 1;
 
        /* check the existence of ID payload */
        if ((iph2->id_p != NULL && iph2->id == NULL)
@@ -2137,7 +2476,17 @@ get_proposal_r(iph2, use_remote_addr)
                if (_XIDT(iph2->id_p) == idi2type
                 && spidx.dst.ss_family == spidx.src.ss_family) {
                        iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst);
+                       if (iph2->src_id  == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                   "buffer allocation failed.\n");
+                               return ISAKMP_INTERNAL_ERROR;
+                       }
                        iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src);
+                       if (iph2->dst_id  == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                   "buffer allocation failed.\n");
+                               return ISAKMP_INTERNAL_ERROR;
+                       }
                }
 
        } else {
@@ -2192,38 +2541,45 @@ get_proposal_r(iph2, use_remote_addr)
        sp_in = getsp_r(&spidx);
        if (sp_in == NULL || sp_in->policy == IPSEC_POLICY_GENERATE) {
                if (iph2->ph1->rmconf->gen_policy) {
-                       plog(LLV_INFO, LOCATION, NULL,
-                               "no policy found, "
-                               "try to generate the policy : %s\n",
-                               spidx2str(&spidx));
+                       if (sp_in)
+                                plog(LLV_INFO, LOCATION, NULL,
+                                       "Update the generated policy : %s\n",
+                                       spidx2str(&spidx));
+                       else
+                               plog(LLV_INFO, LOCATION, NULL,
+                                       "no policy found, "
+                                       "try to generate the policy : %s\n",
+                                       spidx2str(&spidx));
                        iph2->spidx_gen = racoon_malloc(sizeof(spidx));
                        if (!iph2->spidx_gen) {
-                               plog(LLV_ERROR, LOCATION, NULL,
-                                       "buffer allocation failed.\n");
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "buffer allocation failed.\n");
                                return ISAKMP_INTERNAL_ERROR;
                        }
                        memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
-                       return -2;      /* special value */
-               }
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "no policy found: %s\n", spidx2str(&spidx));
-               return ISAKMP_INTERNAL_ERROR;
-       }
-       /* Refresh existing generated policies
-        */
-       if (iph2->ph1->rmconf->gen_policy) {
-               plog(LLV_INFO, LOCATION, NULL,
-                        "Update the generated policy : %s\n",
-                        spidx2str(&spidx));
-               iph2->spidx_gen = racoon_malloc(sizeof(spidx));
-               if (!iph2->spidx_gen) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                                "buffer allocation failed.\n");
+                       generated_policy_exit_early = 1;        /* special value */
+               } else {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "no policy found: %s\n", spidx2str(&spidx));
                        return ISAKMP_INTERNAL_ERROR;
                }
-               memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
+       } else {
+               /* Refresh existing generated policies
+                */
+               if (iph2->ph1->rmconf->gen_policy) {
+                       plog(LLV_INFO, LOCATION, NULL,
+                               "Update the generated policy : %s\n",
+                               spidx2str(&spidx));
+                       iph2->spidx_gen = racoon_malloc(sizeof(spidx));
+                       if (!iph2->spidx_gen) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "buffer allocation failed.\n");
+                               return ISAKMP_INTERNAL_ERROR;
+                       }
+                       memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
+               }
        }
-
+    
        /* get outbound policy */
     {
        struct sockaddr_storage addr;
@@ -2242,12 +2598,21 @@ get_proposal_r(iph2, use_remote_addr)
                plog(LLV_WARNING, LOCATION, NULL,
                        "no outbound policy found: %s\n",
                        spidx2str(&spidx));
+       } else {
+
+               if (!iph2->spid) {
+                       iph2->spid = sp_out->id;
+               }
        }
     }
 
        plog(LLV_DEBUG, LOCATION, NULL,
                "suitable SP found:%s\n", spidx2str(&spidx));
 
+       if (generated_policy_exit_early) {
+               return -2;
+       }
+
        /*
         * In the responder side, the inbound policy should be using IPsec.
         * outbound policy is not checked currently.
index 21a1962ee5622e3ca5368de2275a41bd0c87f15b..c7951ba4768710a5b70a0b100c99f027bf69465f 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_unity.c,v 1.5.4.1 2005/05/10 09:45:46 manubsd Exp $ */
+/*     $NetBSD: isakmp_unity.c,v 1.7 2006/10/09 06:17:20 manu Exp $    */
+
+/* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
@@ -59,6 +61,7 @@
 #include <unistd.h>
 #endif
 #include <ctype.h>
+#include <resolv.h>
 
 #include "var.h"
 #include "misc.h"
@@ -76,6 +79,9 @@
 #include "isakmp_cfg.h"
 #include "strnames.h"
 
+static vchar_t *isakmp_cfg_split(struct ph1handle *, 
+    struct isakmp_data *, struct unity_netentry*,int);
+
 vchar_t *
 isakmp_unity_req(iph1, attr)
        struct ph1handle *iph1;
@@ -98,13 +104,14 @@ isakmp_unity_req(iph1, attr)
                type &= ~ISAKMP_GEN_MASK;
 
                plog(LLV_DEBUG, LOCATION, NULL,
-                    "Short attribute %d = %d\n", 
-                    type, ntohs(attr->lorv));
+                    "Short attribute %s = %d\n", 
+                    s_isakmp_cfg_type(type), ntohs(attr->lorv));
 
                switch (type) {
                default:
                        plog(LLV_DEBUG, LOCATION, NULL,
-                            "Ignored short attribute %d\n", type);
+                            "Ignored short attribute %s\n",
+                            s_isakmp_cfg_type(type));
                        break;
                }
 
@@ -117,7 +124,7 @@ isakmp_unity_req(iph1, attr)
                char buf[MAXMOTD + 1];
                int fd;
                char *filename = &isakmp_cfg_config.motd[0];
-               size_t len;
+               int len;
 
                if ((fd = open(filename, O_RDONLY, 0)) == -1) {
                        plog(LLV_ERROR, LOCATION, NULL, 
@@ -154,14 +161,37 @@ isakmp_unity_req(iph1, attr)
                break;
 
        case UNITY_DEF_DOMAIN:
-       case UNITY_FW_TYPE:
-       case UNITY_SPLITDNS_NAME:
+               reply_attr = isakmp_cfg_string(iph1, 
+                   attr, isakmp_cfg_config.default_domain);
+               break;
+
        case UNITY_SPLIT_INCLUDE:
+               if(isakmp_cfg_config.splitnet_type == UNITY_SPLIT_INCLUDE)
+                       reply_attr = isakmp_cfg_split(iph1, attr,
+                       isakmp_cfg_config.splitnet_list,
+                       isakmp_cfg_config.splitnet_count);
+               else
+                       return NULL;
+               break;
+       case UNITY_LOCAL_LAN:
+               if(isakmp_cfg_config.splitnet_type == UNITY_LOCAL_LAN)
+                       reply_attr = isakmp_cfg_split(iph1, attr,
+                       isakmp_cfg_config.splitnet_list,
+                       isakmp_cfg_config.splitnet_count);
+               else
+                       return NULL;
+               break;
+       case UNITY_SPLITDNS_NAME:
+               reply_attr = isakmp_cfg_varlen(iph1, attr,
+                               isakmp_cfg_config.splitdns_list,
+                               isakmp_cfg_config.splitdns_len);
+               break;
+       case UNITY_FW_TYPE:
        case UNITY_NATT_PORT:
        case UNITY_BACKUP_SERVERS:
        default:
                plog(LLV_DEBUG, LOCATION, NULL,
-                    "Ignored attribute %d\n", type);
+                    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
                return NULL;
                break;
        }
@@ -169,4 +199,218 @@ isakmp_unity_req(iph1, attr)
        return reply_attr;
 }
 
+void
+isakmp_unity_reply(iph1, attr)
+       struct ph1handle *iph1;
+       struct isakmp_data *attr;
+{
+       int type = ntohs(attr->type);
+       int alen = ntohs(attr->lorv);
+
+       type &= ~ISAKMP_GEN_MASK;
+       
+       struct unity_network *network = (struct unity_network *)(attr + 1);
+       int index = 0;
+       int count = 0;
+
+       switch(type) {
+       case UNITY_SPLIT_INCLUDE:
+       {
+               if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) == 0) {
+                       if (alen)
+                               count = alen / sizeof(struct unity_network);
+
+                       for(;index < count; index++)
+                               splitnet_list_add(
+                                       &iph1->mode_cfg->split_include,
+                                       &network[index],
+                                       &iph1->mode_cfg->include_count);
+
+                       iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_INCLUDE;
+               }
+               break;
+       }
+       case UNITY_LOCAL_LAN:
+       {
+               if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) == 0) {
+                       if (alen)
+                               count = alen / sizeof(struct unity_network);
+
+                       for(;index < count; index++)
+                               splitnet_list_add(
+                                       &iph1->mode_cfg->split_local,
+                                       &network[index],
+                                       &iph1->mode_cfg->local_count);
+
+                       iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_LOCAL;
+               }
+               break;
+       }
+       case UNITY_PFS:
+       {
+               break;
+       }
+       case UNITY_SPLITDNS_NAME:
+       case UNITY_BANNER:
+       case UNITY_SAVE_PASSWD:
+       case UNITY_NATT_PORT:
+       case UNITY_FW_TYPE:
+       case UNITY_BACKUP_SERVERS:
+       case UNITY_DDNS_HOSTNAME:
+       default:
+               plog(LLV_WARNING, LOCATION, NULL,
+                    "Ignored attribute %s\n",
+                    s_isakmp_cfg_type(type));
+               break;
+       }
+       return;
+}
+
+static vchar_t *
+isakmp_cfg_split(iph1, attr, netentry, count)
+       struct ph1handle *iph1;
+       struct isakmp_data *attr;
+       struct unity_netentry *netentry;
+       int count;
+{
+       vchar_t *buffer;
+       struct isakmp_data *new;
+       struct unity_network * network;
+       size_t len;
+       int index = 0;
+
+       char tmp1[40];
+       char tmp2[40];
+
+       len = sizeof(struct unity_network) * count;
+       if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
+               return NULL;
+       }
+
+       new = (struct isakmp_data *)buffer->v;
+       new->type = attr->type;
+       new->lorv = htons(len);
+
+       network = (struct unity_network *)(new + 1);
+       for (; index < count; index++) {
+
+               memcpy(&network[index],
+                       &netentry->network,
+                       sizeof(struct unity_network));
+
+               inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
+               inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
+               plog(LLV_DEBUG, LOCATION, NULL, "splitnet: %s/%s\n", tmp1, tmp2);
+
+               netentry = netentry->next;
+       }
+
+       return buffer;
+}
+
+int  splitnet_list_add(list, network, count)
+       struct unity_netentry ** list;
+       struct unity_network * network;
+       int *count;
+{
+       struct unity_netentry * newentry;
+
+       /*
+        * allocate new netentry and copy
+         * new splitnet network data
+        */
+       newentry = (struct unity_netentry *)
+               racoon_malloc(sizeof(struct unity_netentry));
+       if (newentry == NULL)
+               return -1;
+
+       memcpy(&newentry->network,network,
+               sizeof(struct unity_network));
+       newentry->next = NULL;
+
+       /*
+        * locate the last netentry in our
+        * splitnet list and add our entry
+        */
+       if (*list == NULL)
+               *list = newentry;
+       else {
+               struct unity_netentry * tmpentry = *list;
+               while (tmpentry->next != NULL)
+                       tmpentry = tmpentry->next;
+               tmpentry->next = newentry;
+       }
+
+       (*count)++;
+
+       return 0;
+}
 
+void splitnet_list_free(list, count)
+       struct unity_netentry * list;
+       int *count;
+{
+       struct unity_netentry * netentry = list;
+       struct unity_netentry * delentry;
+
+       *count = 0;
+
+       while (netentry != NULL) {
+               delentry = netentry;
+               netentry = netentry->next;
+               racoon_free(delentry);
+       }
+}
+
+char * splitnet_list_2str(list)
+       struct unity_netentry * list;
+{
+       struct unity_netentry * netentry;
+       char tmp1[40];
+       char tmp2[40];
+       char * str;
+       int len;
+       int print_len;
+       int rc;
+
+       /* determine string length */
+       len = 0;
+       netentry = list;
+       while (netentry != NULL) {
+
+               inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
+               inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
+               len += strlen(tmp1);
+               len += strlen(tmp2);
+               len += 2;
+
+               netentry = netentry->next;
+       }
+
+       /* allocate network list string */
+       str = racoon_malloc(len);
+       if (str == NULL)
+               return NULL;
+
+       /* create network list string */
+       str[0] = 0;
+       print_len = 0;
+       netentry = list;
+       while (netentry != NULL && print_len < len) {
+
+               inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
+               inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
+
+               rc = snprintf(str+print_len, len-print_len, "%s/%s ", tmp1, tmp2);
+               if (rc < 0) {
+                       // failure -> exit loop
+                       break;
+               }
+               print_len += rc;
+
+               netentry = netentry->next;
+       }
+
+       return str;
+}
index 4f09af1f2b253a0d8cef18962694610febb653e8..b52f02c554c13175293cd227aff63c4088a5561c 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: isakmp_unity.h,v 1.4 2006/09/09 16:22:09 manu Exp $    */
+
 /*     $KAME$ */
 
 /*
  * SUCH DAMAGE.
  */
 
+/* ISAKMP notifies specific to the Unity vendor Id */
+/* Sent during xauth if the user types his password too slowly */
+#define ISAKMP_NTYPE_UNITY_HEARTBEAT   40500
+
 /* ISAKMP mode config attributes specific to the Unity vendor Id */
 #define UNITY_BANNER           28672
 #define UNITY_SAVE_PASSWD      28673
 #define UNITY_BACKUP_SERVERS   28681
 #define UNITY_DDNS_HOSTNAME    28682
 
+/*
+ * Unity adress/mask lists
+ * XXX : the padding is probably there for something !
+ */
+        
+struct unity_network {
+       struct in_addr addr4;
+       struct in_addr mask4;
+       char padding[6];
+} __attribute__((__packed__));
+        
+struct unity_netentry {
+       struct unity_network    network;       
+       struct unity_netentry   *next;
+};
+
+int    splitnet_list_add(struct unity_netentry **, struct unity_network *, int *);
+void   splitnet_list_free(struct unity_netentry *, int *);
+char * splitnet_list_2str(struct unity_netentry *);
+
 vchar_t *isakmp_unity_req(struct ph1handle *, struct isakmp_data *);
+void isakmp_unity_reply(struct ph1handle *, struct isakmp_data *);
index ef32d5bbc201346a3b3523342eb3fb7eff02f904..d6dc017f5deaf3ba078790569a9628160d17787b 100644 (file)
@@ -61,12 +61,16 @@ struct isakmp_pl_nonce;     /* XXX */
 
 extern int isakmp_handler __P((int));
 extern int isakmp_ph1begin_i __P((struct remoteconf *, struct sockaddr *,
-       struct sockaddr *));
+       struct sockaddr *, int));
 
 extern vchar_t *isakmp_parsewoh __P((int, struct isakmp_gen *, int));
 extern vchar_t *isakmp_parse __P((vchar_t *));
 
+#ifndef __APPLE__
 extern int isakmp_init __P((void));
+#else
+extern int isakmp_init __P((int));
+#endif /* __APPLE__ */
 extern void isakmp_cleanup __P((void));
 
 extern const char *isakmp_pindex __P((const isakmp_index *, const u_int32_t));
@@ -84,6 +88,9 @@ extern void isakmp_ph2resend_stub __P((void *));
 extern int isakmp_ph2resend __P((struct ph2handle *));
 extern void isakmp_ph1expire_stub __P((void *));
 extern void isakmp_ph1expire __P((struct ph1handle *));
+extern void isakmp_ph1rekeyexpire_stub __P((void *));
+extern void isakmp_ph1rekeyexpire __P((struct ph1handle *));
+extern int  isakmp_ph1rekeyretry __P((struct ph1handle *));
 extern void isakmp_ph1delete_stub __P((void *));
 extern void isakmp_ph1delete __P((struct ph1handle *));
 extern void isakmp_ph2expire_stub __P((void *));
@@ -126,11 +133,11 @@ extern void log_ph1established __P((const struct ph1handle *));
 
 extern void script_hook __P((struct ph1handle *, int)); 
 extern int script_env_append __P((char ***, int *, char *, char *));
-extern int script_exec __P((int, int, char * const *));
+extern int script_exec __P((char *, int, char * const *));
 
 void purge_remote __P((struct ph1handle *));
 void delete_spd __P((struct ph2handle *));
 #ifdef INET6
 u_int32_t setscopeid __P((struct sockaddr *, struct sockaddr *));
-#endif 
+#endif
 #endif /* _ISAKMP_VAR_H */
index 1bf87c1b1aa89aa9091b99c0bde3b2b587898e14..aeb5aa869debe582b5d56c216430d534edc5a90b 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: isakmp_xauth.c,v 1.17.2.5 2005/05/20 07:31:09 manubsd Exp $ */
+/*     $NetBSD: isakmp_xauth.c,v 1.11.6.1 2007/08/07 04:49:24 manu Exp $       */
+
+/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
 
 /*
  * Copyright (C) 2004-2005 Emmanuel Dreyfus
@@ -43,9 +45,7 @@
 #include <string.h>
 #include <errno.h>
 #include <pwd.h>
-#ifdef HAVE_SHADOW_H
-#include <shadow.h>
-#endif
+#include <grp.h>
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
 # include <time.h>
 #include <unistd.h>
 #endif
 #include <ctype.h>
+#include <resolv.h>
+
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
 
 #include "var.h"
 #include "misc.h"
 #include "ipsec_doi.h"
 #include "remoteconf.h"
 #include "localconf.h"
+#include "vpn_control.h"
+#include "vpn_control_var.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
 
 #ifdef HAVE_LIBRADIUS
 #include <radlib.h>
@@ -96,11 +105,7 @@ struct rad_handle *radius_acct_state = NULL;
 #endif
 
 #ifdef HAVE_LIBPAM
-#ifdef __APPLE__
-#include <pam/pam_appl.h>
-#else
 #include <security/pam_appl.h>
-#endif
 
 static char *PAM_usr = NULL;
 static char *PAM_pwd = NULL;
@@ -109,6 +114,11 @@ static int PAM_conv(int, const struct pam_message **,
 static struct pam_conv PAM_chat = { &PAM_conv, NULL };
 #endif
 
+#ifdef HAVE_LIBLDAP
+#include "ldap.h"
+#include <arpa/inet.h>
+struct xauth_ldap_config xauth_ldap_config;
+#endif
 
 void 
 xauth_sendreq(iph1)
@@ -167,7 +177,7 @@ xauth_sendreq(iph1)
        pwdattr->lorv = htons(0);
 
        isakmp_cfg_send(iph1, buffer, 
-           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
+           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
        
        vfree(buffer);
 
@@ -176,7 +186,7 @@ xauth_sendreq(iph1)
        return;
 }
 
-void 
+int
 xauth_attr_reply(iph1, attr, id)
        struct ph1handle *iph1;
        struct isakmp_data *attr;
@@ -191,13 +201,13 @@ xauth_attr_reply(iph1, attr, id)
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Xauth reply but peer did not declare "
                    "itself as Xauth capable\n");
-               return;
+               return -1;
        }
 
        if (xst->status != XAUTHST_REQSENT) {
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Xauth reply while Xauth state is %d\n", xst->status);
-               return;
+               return -1;
        }
 
        type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
@@ -211,7 +221,7 @@ xauth_attr_reply(iph1, attr, id)
                        plog(LLV_WARNING, LOCATION, NULL, 
                            "Unexpected authentication type %d\n", 
                            ntohs(type));
-                       return;
+                       return -1;
                }
                break;
 
@@ -232,10 +242,10 @@ xauth_attr_reply(iph1, attr, id)
        if (outlet != NULL) {
                alen = ntohs(attr->lorv);
 
-               if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
+               if ((*outlet = racoon_realloc(*outlet, alen + 1)) == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL, 
                            "Cannot allocate memory for Xauth Data\n");
-                       return;
+                       return -1;
                }
 
                memcpy(*outlet, attr + 1, alen);
@@ -256,8 +266,7 @@ xauth_attr_reply(iph1, attr, id)
                plog(LLV_DEBUG, LOCATION, NULL, 
                    "Got username \"%s\", password \"%s\"\n", usr, pwd);
 #endif
-               strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
-               iph1->mode_cfg->login[LOGINLEN] = '\0';
+               strlcpy(iph1->mode_cfg->login, usr, sizeof(iph1->mode_cfg->login));
 
                res = -1;
                if ((port = isakmp_cfg_getport(iph1)) == -1) {
@@ -280,6 +289,11 @@ xauth_attr_reply(iph1, attr, id)
                        res = privsep_xauth_login_pam(iph1->mode_cfg->port, 
                            iph1->remote, usr, pwd);
                        break;
+#endif
+#ifdef HAVE_LIBLDAP
+               case ISAKMP_CFG_AUTH_LDAP:
+                       res = xauth_login_ldap(iph1, usr, pwd);
+                       break;
 #endif
                default:
                        plog(LLV_ERROR, LOCATION, NULL, 
@@ -288,6 +302,14 @@ xauth_attr_reply(iph1, attr, id)
                        break;
                }
 
+               /*
+                * Optional group authentication
+                */
+               if (!res && (isakmp_cfg_config.groupcount))
+                       res = group_check(iph1,
+                               isakmp_cfg_config.grouplist,
+                               isakmp_cfg_config.groupcount);
+
                /*
                 * On failure, throttle the connexion for the remote host
                 * in order to make password attacks more difficult.
@@ -313,8 +335,7 @@ skip_auth:
                        if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL, 
                                    "malloc failed, bypass throttling\n");
-                               xauth_reply(iph1, port, id, res);
-                               return;
+                               return xauth_reply(iph1, port, id, res);
                        }
 
                        /*
@@ -328,11 +349,11 @@ skip_auth:
                        xra->res = res;
                        sched_new(throttle_delay, xauth_reply_stub, xra);
                } else {
-                       xauth_reply(iph1, port, id, res);
+                       return xauth_reply(iph1, port, id, res);
                }
        }
 
-       return;
+       return 0;
 }
 
 void 
@@ -343,7 +364,7 @@ xauth_reply_stub(args)
        struct ph1handle *iph1;
 
        if ((iph1 = getph1byindex(&xra->index)) != NULL)
-               xauth_reply(iph1, xra->port, xra->id, xra->res);
+               (void)xauth_reply(iph1, xra->port, xra->id, xra->res);
        else
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Delayed Xauth reply: phase 1 no longer exists.\n"); 
@@ -352,7 +373,7 @@ xauth_reply_stub(args)
        return;
 }
 
-void 
+int
 xauth_reply(iph1, port, id, res)
        struct ph1handle *iph1;
        int port;
@@ -377,7 +398,7 @@ xauth_reply(iph1, port, id, res)
                remph1(iph1);
                delph1(iph1);
 
-               return;
+               return -1;
        }
 
        xst->status = XAUTHST_OK;
@@ -386,7 +407,7 @@ xauth_reply(iph1, port, id, res)
 
        xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
 
-       return;
+       return 0;
 }
 
 void
@@ -420,7 +441,7 @@ xauth_sendstatus(iph1, status, id)
        stattr->lorv = htons(status);
 
        isakmp_cfg_send(iph1, buffer, 
-           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
+           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
        
        vfree(buffer);
 
@@ -452,7 +473,7 @@ xauth_radius_init(void)
 
        if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
            (radius_acct_state == NULL)) {
-               if ((radius_acct_state = rad_auth_open()) == NULL) {
+               if ((radius_acct_state = rad_acct_open()) == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL, 
                            "Cannot init libradius\n");
                        return -1;
@@ -513,13 +534,13 @@ xauth_login_radius(iph1, usr, pwd)
                        case RAD_FRAMED_IP_ADDRESS:
                                iph1->mode_cfg->addr4 = rad_cvt_addr(data);
                                iph1->mode_cfg->flags 
-                                   |= ISAKMP_CFG_ADDR4_RADIUS;
+                                   |= ISAKMP_CFG_ADDR4_EXTERN;
                                break;
 
                        case RAD_FRAMED_IP_NETMASK:
                                iph1->mode_cfg->mask4 = rad_cvt_addr(data);
                                iph1->mode_cfg->flags 
-                                   |= ISAKMP_CFG_MASK4_RADIUS;
+                                   |= ISAKMP_CFG_MASK4_EXTERN;
                                break;
 
                        default:
@@ -574,13 +595,21 @@ PAM_conv(msg_count, msg, rsp, dontcare)
                case PAM_PROMPT_ECHO_ON:
                        /* Send the username, libpam frees resp */
                        reply[i].resp_retcode = PAM_SUCCESS;
-                       reply[i].resp = strdup(PAM_usr);
+                       if ((reply[i].resp = strdup(PAM_usr)) == NULL) {
+                               plog(LLV_ERROR, LOCATION, 
+                                   NULL, "strdup failed\n");
+                               exit(1);
+                       }
                        break;
 
                case PAM_PROMPT_ECHO_OFF:
                        /* Send the password, libpam frees resp */
                        reply[i].resp_retcode = PAM_SUCCESS;
-                       reply[i].resp = strdup(PAM_pwd);
+                       if ((reply[i].resp = strdup(PAM_pwd)) == NULL) {
+                               plog(LLV_ERROR, LOCATION, 
+                                   NULL, "strdup failed\n");
+                               exit(1);
+                       }
                        break;
 
                case PAM_TEXT_INFO:
@@ -615,7 +644,7 @@ xauth_login_pam(port, raddr, usr, pwd)
        const void *data;
        size_t len;
        int type;
-       char *remote;
+       char *remote = NULL;
        pam_handle_t *pam = NULL;
 
        if (isakmp_cfg_config.port_pool == NULL) {
@@ -678,15 +707,528 @@ xauth_login_pam(port, raddr, usr, pwd)
                goto out;
        }
 
+       if (remote != NULL)
+               free(remote);
+
        return 0;
 
 out:
        pam_end(pam, error);
        isakmp_cfg_config.port_pool[port].pam = NULL;
+       if (remote != NULL)
+               free(remote);
        return -1;
 }
 #endif
 
+#ifdef HAVE_LIBLDAP
+int 
+xauth_ldap_init(void)
+{
+       int tmplen;
+       int error = -1;
+
+       xauth_ldap_config.pver = 3;
+       xauth_ldap_config.host = NULL;
+       xauth_ldap_config.port = LDAP_PORT;
+       xauth_ldap_config.base = NULL;
+       xauth_ldap_config.subtree = 0;
+       xauth_ldap_config.bind_dn = NULL;
+       xauth_ldap_config.bind_pw = NULL;
+       xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE;
+       xauth_ldap_config.attr_user = NULL;
+       xauth_ldap_config.attr_addr = NULL;
+       xauth_ldap_config.attr_mask = NULL;
+       xauth_ldap_config.attr_group = NULL;
+       xauth_ldap_config.attr_member = NULL;
+
+       /* set default host */
+       tmplen = strlen(LDAP_DFLT_HOST);
+       xauth_ldap_config.host = vmalloc(tmplen);
+       if (xauth_ldap_config.host == NULL)
+               goto out;
+       memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen);
+
+       /* set default user naming attribute */
+       tmplen = strlen(LDAP_DFLT_USER);
+       xauth_ldap_config.attr_user = vmalloc(tmplen);
+       if (xauth_ldap_config.attr_user == NULL)
+               goto out;       
+       memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen);
+
+       /* set default address attribute */
+       tmplen = strlen(LDAP_DFLT_ADDR);
+       xauth_ldap_config.attr_addr = vmalloc(tmplen);
+       if (xauth_ldap_config.attr_addr == NULL)
+               goto out;
+       memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen);
+
+       /* set default netmask attribute */
+       tmplen = strlen(LDAP_DFLT_MASK);
+       xauth_ldap_config.attr_mask = vmalloc(tmplen);
+       if (xauth_ldap_config.attr_mask == NULL)
+               goto out;
+       memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen);
+
+       /* set default group naming attribute */
+       tmplen = strlen(LDAP_DFLT_GROUP);
+       xauth_ldap_config.attr_group = vmalloc(tmplen);
+       if (xauth_ldap_config.attr_group == NULL)
+               goto out;
+       memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen);
+
+       /* set default member attribute */
+       tmplen = strlen(LDAP_DFLT_MEMBER);
+       xauth_ldap_config.attr_member = vmalloc(tmplen);
+       if (xauth_ldap_config.attr_member == NULL)
+               goto out;
+       memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen);
+
+       error = 0;
+out:
+       if (error != 0)
+               plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n");
+
+       return error;
+}
+
+void
+xauth_ldap_flush(void)
+{
+       if (xauth_ldap_config.host) {
+               vfree(xauth_ldap_config.host);
+               xauth_ldap_config.host = NULL;
+       }
+       if (xauth_ldap_config.base) {
+               vfree(xauth_ldap_config.base);
+               xauth_ldap_config.base = NULL;
+       }
+       if (xauth_ldap_config.bind_dn) {
+               vfree(xauth_ldap_config.bind_dn);
+               xauth_ldap_config.bind_dn = NULL;
+       }
+       if (xauth_ldap_config.bind_pw) {
+               vfree(xauth_ldap_config.bind_pw);
+               xauth_ldap_config.bind_pw = NULL;
+       }
+       if (xauth_ldap_config.attr_user) {
+               vfree(xauth_ldap_config.attr_user);
+               xauth_ldap_config.attr_user = NULL;
+       }
+       if (xauth_ldap_config.attr_addr) {
+               vfree(xauth_ldap_config.attr_addr);
+               xauth_ldap_config.attr_addr = NULL;
+       }
+       if (xauth_ldap_config.attr_mask) {
+               vfree(xauth_ldap_config.attr_mask);
+               xauth_ldap_config.attr_mask = NULL;
+       }
+       if (xauth_ldap_config.attr_group) {
+               vfree(xauth_ldap_config.attr_group);
+               xauth_ldap_config.attr_group = NULL;
+       }
+       if (xauth_ldap_config.attr_member) {
+               vfree(xauth_ldap_config.attr_member);
+               xauth_ldap_config.attr_member = NULL;
+       }
+}
+
+int
+xauth_login_ldap(iph1, usr, pwd)
+       struct ph1handle *iph1;
+       char *usr;
+       char *pwd;
+{
+       int rtn = -1;
+       int res = -1;
+       LDAP *ld = NULL;
+       LDAPMessage *lr = NULL;
+       LDAPMessage *le = NULL;
+       struct berval cred;
+       struct berval **bv = NULL;
+       struct timeval timeout;
+       char *init = NULL;
+       char *filter = NULL;
+       char *atlist[3];
+       int   atlist_len[sizeof(atlist)/sizeof(__typeof__(*atlist))];
+       char *basedn = NULL;
+       char *userdn = NULL;
+       int udn_len = 0;
+       int tmplen = 0;
+       int ecount = 0;
+       int scope = LDAP_SCOPE_ONE;
+
+       atlist[0] = NULL;
+       atlist_len[0] = 0;
+       atlist[1] = NULL;
+       atlist_len[1] = 0;
+       atlist[2] = NULL;
+       atlist_len[2] = 0;
+
+       /* build our initialization url */
+       tmplen = strlen("ldap://:") + 17;
+       tmplen += strlen(xauth_ldap_config.host->v);
+       init = racoon_malloc(tmplen);
+       if (init == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unable to alloc ldap init url\n");
+               goto ldap_end;
+       }
+       snprintf(init, tmplen, "ldap://%s:%d",
+               xauth_ldap_config.host->v,
+               xauth_ldap_config.port );
+
+       /* initialize the ldap handle */
+       res = ldap_initialize(&ld, init);
+       if (res != LDAP_SUCCESS) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_initialize failed: %s\n",
+                       ldap_err2string(res));
+               goto ldap_end;
+       }
+
+       /* initialize the protocol version */
+       ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
+               &xauth_ldap_config.pver);
+
+       /*
+        * attempt to bind to the ldap server.
+         * default to anonymous bind unless a
+        * user dn and password has been
+        * specified in our configuration
+         */
+       if ((xauth_ldap_config.bind_dn != NULL)&&
+           (xauth_ldap_config.bind_pw != NULL))
+       {
+               cred.bv_val = xauth_ldap_config.bind_pw->v;
+               cred.bv_len = strlen( cred.bv_val );
+               res = ldap_sasl_bind_s(ld,
+                       xauth_ldap_config.bind_dn->v, NULL, &cred,
+                       NULL, NULL, NULL);
+       }
+       else
+       {
+               res = ldap_sasl_bind_s(ld,
+                       NULL, NULL, NULL,
+                       NULL, NULL, NULL);
+       }
+       
+       if (res!=LDAP_SUCCESS) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_sasl_bind_s (search) failed: %s\n",
+                       ldap_err2string(res));
+               goto ldap_end;
+       }
+
+       /* build an ldap user search filter */
+       tmplen = strlen(xauth_ldap_config.attr_user->v);
+       tmplen += 1;
+       tmplen += strlen(usr);
+       tmplen += 1;
+       filter = racoon_malloc(tmplen);
+       if (filter == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unable to alloc ldap search filter buffer\n");
+               goto ldap_end;
+       }
+       snprintf(filter, tmplen, "%s=%s",
+               xauth_ldap_config.attr_user->v, usr);
+
+       /* build our return attribute list */
+       atlist_len[0] = strlen(xauth_ldap_config.attr_addr->v) + 1;
+       atlist[0] = racoon_malloc(atlist_len[0]);
+       atlist_len[1] = strlen(xauth_ldap_config.attr_mask->v) + 1;
+       atlist[1] = racoon_malloc(atlist_len[1]);
+       if ((atlist[0] == NULL)||(atlist[1] == NULL)) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unable to alloc ldap attrib list buffer\n");
+               goto ldap_end;
+       }
+       strlcpy(atlist[0],xauth_ldap_config.attr_addr->v,atlist_len[0]);
+       strlcpy(atlist[1],xauth_ldap_config.attr_mask->v,atlist_len[1]);
+
+       /* attempt to locate the user dn */
+       if (xauth_ldap_config.base != NULL)
+               basedn = xauth_ldap_config.base->v;
+       if (xauth_ldap_config.subtree)
+               scope = LDAP_SCOPE_SUBTREE;
+       timeout.tv_sec = 15;
+       timeout.tv_usec = 0;
+       res = ldap_search_ext_s(ld, basedn, scope,
+               filter, atlist, 0, NULL, NULL,
+               &timeout, 2, &lr);
+       if (res != LDAP_SUCCESS) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_search_ext_s failed: %s\n",
+                       ldap_err2string(res));
+               goto ldap_end;
+       }
+
+       /* check the number of ldap entries returned */
+       ecount = ldap_count_entries(ld, lr);
+       if (ecount < 1) {
+               plog(LLV_WARNING, LOCATION, NULL, 
+                       "no ldap results for filter \'%s\'\n", 
+                        filter);
+               goto ldap_end;
+       }
+       if (ecount > 1) {
+               plog(LLV_WARNING, LOCATION, NULL, 
+                       "multiple (%i) ldap results for filter \'%s\'\n", 
+                       ecount, filter);
+       }
+
+       /* obtain the dn from the first result */
+       le = ldap_first_entry(ld, lr);
+       if (le == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_first_entry failed: invalid entry returned\n");
+               goto ldap_end;
+       }
+       userdn = ldap_get_dn(ld, le);
+       if (userdn == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_get_dn failed: invalid string returned\n");
+               goto ldap_end;
+       }
+
+       /* cache the user dn in the xauth state */
+       udn_len = strlen(userdn)+1;
+       iph1->mode_cfg->xauth.udn = racoon_malloc(udn_len);
+       strlcpy(iph1->mode_cfg->xauth.udn,userdn,udn_len);
+
+       /* retrieve modecfg address */
+       bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v);
+       if (bv != NULL) {
+               char tmpaddr[16];
+               /* sanity check for address value */
+               if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                               "ldap returned invalid modecfg address\n");
+                       ldap_value_free_len(bv);
+                       goto ldap_end;
+               }
+               memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len);
+               tmpaddr[bv[0]->bv_len]=0;
+               iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr);
+               iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN;
+               plog(LLV_INFO, LOCATION, NULL,
+                       "ldap returned modecfg address %s\n", tmpaddr);
+               ldap_value_free_len(bv);
+       }
+
+       /* retrieve modecfg netmask */
+       bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v);
+       if (bv != NULL) {
+               char tmpmask[16];
+               /* sanity check for netmask value */
+               if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
+                       plog(LLV_DEBUG, LOCATION, NULL,
+                               "ldap returned invalid modecfg netmask\n");
+                       ldap_value_free_len(bv);
+                       goto ldap_end;
+               }
+               memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len);
+               tmpmask[bv[0]->bv_len]=0;
+               iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask);
+               iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN;
+               plog(LLV_INFO, LOCATION, NULL,
+                       "ldap returned modecfg netmask %s\n", tmpmask);
+               ldap_value_free_len(bv);
+       }
+
+       /*
+        * finally, use the dn and the xauth
+        * password to check the users given
+        * credentials by attempting to bind
+        * to the ldap server
+        */
+       plog(LLV_INFO, LOCATION, NULL,
+               "attempting ldap bind for dn \'%s\'\n", userdn);
+       cred.bv_val = pwd;
+       cred.bv_len = strlen( cred.bv_val );
+       res = ldap_sasl_bind_s(ld,
+               userdn, NULL, &cred,
+               NULL, NULL, NULL);
+        if(res==LDAP_SUCCESS)
+               rtn = 0;
+
+ldap_end:
+
+       /* free ldap resources */
+       if (userdn != NULL)
+               ldap_memfree(userdn);
+       if (atlist[0] != NULL)
+               racoon_free(atlist[0]);
+       if (atlist[1] != NULL)
+               racoon_free(atlist[1]);
+       if (filter != NULL)
+               racoon_free(filter);
+       if (lr != NULL)
+               ldap_msgfree(lr);
+       if (init != NULL)
+               racoon_free(init);
+
+       ldap_unbind_ext_s(ld, NULL, NULL);
+
+       return rtn;
+}
+
+int
+xauth_group_ldap(udn, grp)
+       char * udn;
+       char * grp;
+{
+       int rtn = -1;
+       int res = -1;
+       LDAP *ld = NULL;
+       LDAPMessage *lr = NULL;
+       LDAPMessage *le = NULL;
+       struct berval cred;
+       struct timeval timeout;
+       char *init = NULL;
+       char *filter = NULL;
+       char *basedn = NULL;
+       char *groupdn = NULL;
+       int tmplen = 0;
+       int ecount = 0;
+       int scope = LDAP_SCOPE_ONE;
+
+       /* build our initialization url */
+       tmplen = strlen("ldap://:") + 17;
+       tmplen += strlen(xauth_ldap_config.host->v);
+       init = racoon_malloc(tmplen);
+       if (init == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unable to alloc ldap init url\n");
+               goto ldap_group_end;
+       }
+       snprintf(init, tmplen, "ldap://%s:%d",
+               xauth_ldap_config.host->v,
+               xauth_ldap_config.port );
+
+       /* initialize the ldap handle */
+       res = ldap_initialize(&ld, init);
+       if (res != LDAP_SUCCESS) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_initialize failed: %s\n",
+                       ldap_err2string(res));
+               goto ldap_group_end;
+       }
+
+       /* initialize the protocol version */
+       ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
+               &xauth_ldap_config.pver);
+
+       /*
+        * attempt to bind to the ldap server.
+         * default to anonymous bind unless a
+        * user dn and password has been
+        * specified in our configuration
+         */
+       if ((xauth_ldap_config.bind_dn != NULL)&&
+           (xauth_ldap_config.bind_pw != NULL))
+       {
+               cred.bv_val = xauth_ldap_config.bind_pw->v;
+               cred.bv_len = strlen( cred.bv_val );
+               res = ldap_sasl_bind_s(ld,
+                       xauth_ldap_config.bind_dn->v, NULL, &cred,
+                       NULL, NULL, NULL);
+       }
+       else
+       {
+               res = ldap_sasl_bind_s(ld,
+                       NULL, NULL, NULL,
+                       NULL, NULL, NULL);
+       }
+
+       if (res!=LDAP_SUCCESS) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_sasl_bind_s (search) failed: %s\n",
+                       ldap_err2string(res));
+               goto ldap_group_end;
+       }
+
+       /* build an ldap group search filter */
+       tmplen = strlen("(&(=)(=))") + 1;
+       tmplen += strlen(xauth_ldap_config.attr_group->v);
+       tmplen += strlen(grp);
+       tmplen += strlen(xauth_ldap_config.attr_member->v);
+       tmplen += strlen(udn);
+       filter = racoon_malloc(tmplen);
+       if (filter == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unable to alloc ldap search filter buffer\n");
+               goto ldap_group_end;
+       }
+       snprintf(filter, tmplen, "(&(%s=%s)(%s=%s))",
+               xauth_ldap_config.attr_group->v, grp,
+               xauth_ldap_config.attr_member->v, udn);
+
+       /* attempt to locate the group dn */
+       if (xauth_ldap_config.base != NULL)
+               basedn = xauth_ldap_config.base->v;
+       if (xauth_ldap_config.subtree)
+               scope = LDAP_SCOPE_SUBTREE;
+       timeout.tv_sec = 15;
+       timeout.tv_usec = 0;
+       res = ldap_search_ext_s(ld, basedn, scope,
+               filter, NULL, 0, NULL, NULL,
+               &timeout, 2, &lr);
+       if (res != LDAP_SUCCESS) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_search_ext_s failed: %s\n",
+                       ldap_err2string(res));
+               goto ldap_group_end;
+       }
+
+       /* check the number of ldap entries returned */
+       ecount = ldap_count_entries(ld, lr);
+       if (ecount < 1) {
+               plog(LLV_WARNING, LOCATION, NULL, 
+                       "no ldap results for filter \'%s\'\n", 
+                        filter);
+               goto ldap_group_end;
+       }
+
+       /* success */
+       rtn = 0;
+
+       /* obtain the dn from the first result */
+       le = ldap_first_entry(ld, lr);
+       if (le == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_first_entry failed: invalid entry returned\n");
+               goto ldap_group_end;
+       }
+       groupdn = ldap_get_dn(ld, le);
+       if (groupdn == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "ldap_get_dn failed: invalid string returned\n");
+               goto ldap_group_end;
+       }
+
+       plog(LLV_INFO, LOCATION, NULL,
+               "ldap membership group returned \'%s\'\n", groupdn);
+ldap_group_end:
+
+       /* free ldap resources */
+       if (groupdn != NULL)
+               ldap_memfree(groupdn);
+       if (filter != NULL)
+               racoon_free(filter);
+       if (lr != NULL)
+               ldap_msgfree(lr);
+       if (init != NULL)
+               racoon_free(init);
+
+       ldap_unbind_ext_s(ld, NULL, NULL);
+
+       return rtn;
+}
+
+#endif
+
 int
 xauth_login_system(usr, pwd)
        char *usr;
@@ -724,22 +1266,54 @@ xauth_login_system(usr, pwd)
        return -1;
 }
 
+int
+xauth_group_system(usr, grp)
+       char * usr;
+       char * grp;
+{
+       struct group * gr;
+       char * member;
+       int index = 0;
+
+       gr = getgrnam(grp);
+       if (gr == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "the system group name \'%s\' is unknown\n",
+                       grp);
+               return -1;
+       }
+
+       while ((member = gr->gr_mem[index++])!=NULL) {
+               if (!strcmp(member,usr)) {
+                       plog(LLV_INFO, LOCATION, NULL,
+                               "membership validated\n");
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
 int 
 xauth_check(iph1)
        struct ph1handle *iph1;
 {
        struct xauth_state *xst = &iph1->mode_cfg->xauth;
 
-       /* If we don't use Xauth, then we pass */
-       switch (iph1->approval->authmethod) {
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       /* 
+        * Only the server side (edge device) really check for Xauth 
+        * status. It does it if the chose authmethod is using Xauth.
+        * On the client side (roadwarrior), we don't check anything.
+        */
+       switch (AUTHMETHOD(iph1)) {
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
        /* The following are not yet implemented */
-       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
-       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
-       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
-       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
-       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
                if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
                        plog(LLV_ERROR, LOCATION, NULL,
                            "Hybrid auth negotiated but peer did not "
@@ -764,6 +1338,80 @@ xauth_check(iph1)
        return 0;
 }
 
+int
+group_check(iph1, grp_list, grp_count)
+       struct ph1handle *iph1;
+       char **grp_list;
+       int grp_count;
+{
+       int res = -1;
+       int grp_index = 0;
+       char * usr = NULL;
+
+       /* check for presence of modecfg data */
+
+       if(iph1->mode_cfg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "xauth group specified but modecfg not found\n");
+               return res;
+       }
+
+       /* loop through our group list */
+
+       for(; grp_index < grp_count; grp_index++) {
+
+               /* check for presence of xauth data */
+
+               usr = iph1->mode_cfg->xauth.authdata.generic.usr;
+
+               if(usr == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "xauth group specified but xauth not found\n");
+                       return res;
+               }
+
+               /* call appropriate group validation funtion */
+
+               switch (isakmp_cfg_config.groupsource) {
+
+                       case ISAKMP_CFG_GROUP_SYSTEM:
+                               res = xauth_group_system(
+                                       usr,
+                                       grp_list[grp_index]);
+                               break;
+
+#ifdef HAVE_LIBLDAP
+                       case ISAKMP_CFG_GROUP_LDAP:
+                               res = xauth_group_ldap(
+                                       iph1->mode_cfg->xauth.udn,
+                                       grp_list[grp_index]);
+                               break;
+#endif
+
+                       default:
+                               /* we should never get here */
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                   "Unknown group auth source\n");
+                               break;
+               }
+
+               if( !res ) {
+                       plog(LLV_INFO, LOCATION, NULL,
+                               "user \"%s\" is a member of group \"%s\"\n",
+                               usr,
+                               grp_list[grp_index]);
+                       break;
+               } else {
+                       plog(LLV_INFO, LOCATION, NULL,
+                               "user \"%s\" is not a member of group \"%s\"\n",
+                               usr,
+                               grp_list[grp_index]);
+               }
+       }
+
+       return res;
+}
+
 vchar_t *
 isakmp_xauth_req(iph1, attr)
        struct ph1handle *iph1;
@@ -774,6 +1422,8 @@ isakmp_xauth_req(iph1, attr)
        int ashort = 0;
        int value = 0;
        vchar_t *buffer = NULL;
+       char* mraw = NULL;
+       vchar_t *mdata = NULL;
        char *data;
        vchar_t *usr = NULL;
        vchar_t *pwd = NULL;
@@ -809,48 +1459,41 @@ isakmp_xauth_req(iph1, attr)
                break;
 
        case XAUTH_USER_NAME:
-               if (iph1->rmconf->idvtype != IDTYPE_LOGIN) {
-                       plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
-                           "while identifier is not a login\n");
-                       return NULL;
-               }
-
-               if (iph1->rmconf->idv == NULL) {
+               if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
                        plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
                            "with no login supplied\n");
                        return NULL;
                }
 
-               dlen = iph1->rmconf->idv->l;
+               dlen = iph1->rmconf->xauth->login->l - 1;
+               iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
                break;
 
        case XAUTH_USER_PASSWORD:
-               if (iph1->rmconf->idvtype != IDTYPE_LOGIN) 
-                       return NULL;
-
-               if (iph1->rmconf->idv == NULL)
+       case XAUTH_PASSCODE:
+               if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
                        return NULL;
 
                skip = sizeof(struct ipsecdoi_id_b);
-               if ((usr = vmalloc(iph1->rmconf->idv->l + skip)) == NULL) {
+               usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
+               if (usr == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL, 
                            "Cannot allocate memory\n");
                        return NULL;
                }
-
                memset(usr->v, 0, skip);
                memcpy(usr->v + skip, 
-                   iph1->rmconf->idv->v, 
-                   iph1->rmconf->idv->l);
+                   iph1->rmconf->xauth->login->v, 
+                   iph1->rmconf->xauth->login->l - 1);
 
-               if (iph1->rmconf->key) {
+               if (iph1->rmconf->xauth->pass) {
                        /* A key given through racoonctl */
-                       pwd = iph1->rmconf->key;
+                       pwd = iph1->rmconf->xauth->pass;
                } else {
                        if ((pwd = getpskbyname(usr)) == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL, 
                                    "No password was found for login %s\n", 
-                                   iph1->rmconf->idv->v);
+                                   iph1->rmconf->xauth->login->v);
                                vfree(usr);
                                return NULL;
                        }
@@ -859,13 +1502,32 @@ isakmp_xauth_req(iph1, attr)
                }
                vfree(usr);
 
-               dlen = pwd->l;
+               iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
+               dlen = pwd->l - 1;
 
                break;
-
+               
+       case XAUTH_MESSAGE:
+               if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
+                       dlen = ntohs(attr->lorv);
+                       if (dlen > 0) {
+                               mraw = (char*)(attr + 1);
+                               if ((mdata = vmalloc(dlen)) == NULL) {
+                                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                                           "Cannot allocate memory\n");
+                                       return NULL;
+                               }
+                               memcpy(mdata->v, mraw, mdata->l);
+                               plog(LLV_NOTIFY,LOCATION, iph1->remote,
+                                       "XAUTH Message: '%s'.\n",
+                                       binsanitize(mdata->v, mdata->l));
+                               vfree(mdata);
+                       }
+               }
+               return NULL;
        default:
                plog(LLV_WARNING, LOCATION, NULL,
-                   "Ignored attribute %d\n", type);
+                   "Ignored attribute %s\n", s_isakmp_cfg_type(type));
                return NULL;
                break;
        }
@@ -889,9 +1551,14 @@ isakmp_xauth_req(iph1, attr)
 
        switch(type) {
        case XAUTH_USER_NAME:
-               memcpy(data, iph1->rmconf->idv->v, dlen);
+               /* 
+                * iph1->rmconf->xauth->login->v is valid, 
+                * we just checked it in the previous switch case 
+                */
+               memcpy(data, iph1->rmconf->xauth->login->v, dlen);
                break;
        case XAUTH_USER_PASSWORD:
+       case XAUTH_PASSCODE:
                memcpy(data, pwd->v, dlen);
                break;
        default:
@@ -913,8 +1580,16 @@ isakmp_xauth_set(iph1, attr)
        int type;
        vchar_t *buffer = NULL;
        char *data;
+       struct xauth_state *xst;
+       size_t dlen = 0;
+       char* mraw = NULL;
+       vchar_t *mdata = NULL;
 
        if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+                                                               CONSTSTR("XAUTH is not supported by peer"),
+                                                               CONSTSTR("XAUTH dropped (not supported by peer)"));
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Xauth mode config set but peer "
                    "did not declare itself as Xauth capable\n");
@@ -925,31 +1600,107 @@ isakmp_xauth_set(iph1, attr)
 
        switch(type) {
        case XAUTH_STATUS:
+               /* 
+                * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
+                * when running as a client (initiator).
+                */
+               xst = &iph1->mode_cfg->xauth;
+               switch(AUTHMETHOD(iph1)) {
+        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+            if (!iph1->is_rekey) {
+                IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                        IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+                                        CONSTSTR("Unexpected XAUTH Status"),
+                                        CONSTSTR("Xauth dropped (unexpected Xauth status)... not a phase1 rekey"));
+                plog(LLV_ERROR, LOCATION, NULL, 
+                     "Unexpected XAUTH_STATUS_OK... not a phase1 rekey\n");
+                return NULL;
+            }
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+               case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+               /* Not implemented ... */
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+               case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+                       break;
+               default:
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+                                                                       CONSTSTR("Unexpected XAUTH Status"),
+                                                                       CONSTSTR("Xauth dropped (unexpected Xauth status)"));
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                           "Unexpected XAUTH_STATUS_OK\n");
+                       return NULL;
+                       break;
+               }
+
                /* If we got a failure, delete iph1 */
                if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL,
+                                                                       CONSTSTR("XAUTH Status is not OK"),
+                                                                       CONSTSTR("Xauth Failed (status not ok)"));
                        plog(LLV_ERROR, LOCATION, NULL, 
                            "Xauth authentication failed\n");
 
                        EVT_PUSH(iph1->local, iph1->remote, 
                            EVTT_XAUTH_FAILED, NULL);
+                               
+                       vpncontrol_notify_ike_failed(VPNCTL_NTYPE_AUTHENTICATION_FAILED, FROM_LOCAL,
+                               ((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr, 0, NULL);
 
                        iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
                } else {
-                       EVT_PUSH(iph1->local, 
-                           iph1->remote, EVTT_XAUTH_SUCCESS, NULL);
+                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                                       IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC,
+                                                                       CONSTSTR("XAUTH Status is OK"),
+                                                                       CONSTSTR(NULL));
+                       EVT_PUSH(iph1->local, iph1->remote, 
+                           EVTT_XAUTH_SUCCESS, NULL);
+            if (iph1->is_rekey) {
+                xst->status = XAUTHST_OK;
+            }
                }
 
 
                /* We acknowledge it */
                break;
+       case XAUTH_MESSAGE:
+               if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
+                       dlen = ntohs(attr->lorv);
+                       if (dlen > 0) {
+                               mraw = (char*)(attr + 1);
+                               if ((mdata = vmalloc(dlen)) == NULL) {
+                                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                                           "Cannot allocate memory\n");
+                                       return NULL;
+                               }
+                               memcpy(mdata->v, mraw, mdata->l);
+                               plog(LLV_NOTIFY,LOCATION, iph1->remote,
+                                       "XAUTH Message: '%s'.\n",
+                                       binsanitize(mdata->v, mdata->l));
+                               vfree(mdata);
+                       }
+               }
+
        default:
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+                                                               CONSTSTR("ignored attribute"),
+                                                               CONSTSTR("Xauth dropped (ignored attribute)"));
                plog(LLV_WARNING, LOCATION, NULL,
-                   "Ignored attribute %d\n", type);
+                   "Ignored attribute %s\n", s_isakmp_cfg_type(type));
                return NULL;
                break;
        }
 
        if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
+               IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+                                                               CONSTSTR("Failed to allocate attribute"),
+                                                               CONSTSTR("Xauth dropped (failed to allocate attribute)"));
                plog(LLV_ERROR, LOCATION, NULL,
                    "Cannot allocate memory\n");
                return NULL;
@@ -990,6 +1741,56 @@ xauth_rmstate(xst)
                break;
        }
 
+#ifdef HAVE_LIBLDAP
+       if (xst->udn != NULL)
+               racoon_free(xst->udn);
+#endif
        return;
 }
 
+int
+xauth_rmconf_used(xauth_rmconf)
+       struct xauth_rmconf **xauth_rmconf;
+{
+       if (*xauth_rmconf == NULL) {
+               *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
+               if (*xauth_rmconf == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                           "xauth_rmconf_used: malloc failed\n");
+                       return -1;
+               }
+
+               (*xauth_rmconf)->login = NULL;
+               (*xauth_rmconf)->pass = NULL;
+               (*xauth_rmconf)->state = 0;
+       } else {
+               if ((*xauth_rmconf)->login) {
+                       vfree((*xauth_rmconf)->login);
+                       (*xauth_rmconf)->login = NULL;
+               }
+               if ((*xauth_rmconf)->pass != NULL) {
+                       vfree((*xauth_rmconf)->pass);
+                       (*xauth_rmconf)->pass = NULL;
+               }
+               (*xauth_rmconf)->state = 0;
+       }
+
+       return 0;
+}
+
+void 
+xauth_rmconf_delete(xauth_rmconf)
+       struct xauth_rmconf **xauth_rmconf;
+{
+       if (*xauth_rmconf != NULL) { 
+               if ((*xauth_rmconf)->login != NULL)
+                       vfree((*xauth_rmconf)->login);
+               if ((*xauth_rmconf)->pass != NULL)
+                       vfree((*xauth_rmconf)->pass);
+
+               racoon_free(*xauth_rmconf);
+               *xauth_rmconf = NULL;
+       }
+
+       return;
+}
index 5d4bdbbc731955ebb5c57651f74e2f98296e5464..58980622432ba9898dc23ec3f924ee0654f2b5b9 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: isakmp_xauth.h,v 1.4 2006/09/09 16:22:09 manu Exp $    */
+
 /*     $KAME$ */
 
 /*
@@ -29,6 +31,9 @@
  * SUCH DAMAGE.
  */
 
+#ifndef _ISAKMP_XAUTH_H
+#define _ISAKMP_XAUTH_H
+
 /* ISAKMP mode config attribute types specific to the Xauth vendor ID */
 #define        XAUTH_TYPE                16520
 #define        XAUTH_USER_NAME           16521
@@ -51,8 +56,9 @@
 #define        XAUTH_STATUS_FAIL       0
 #define        XAUTH_STATUS_OK         1
 
+/* For phase 1 Xauth status */
 struct xauth_state {
-       int status;
+       int status; /* authentication status, used only on server side */
        int vendorid;
        int authtype;
        union {
@@ -61,6 +67,21 @@ struct xauth_state {
                        char *pwd;
                } generic;
        } authdata;
+#ifdef HAVE_LIBLDAP
+       char *udn; /* ldap user dn */
+#endif
+};
+
+/* What's been sent */
+#define XAUTH_SENT_USERNAME 1
+#define XAUTH_SENT_PASSWORD 2
+#define XAUTH_SENT_EVERYTHING (XAUTH_SENT_USERNAME | XAUTH_SENT_PASSWORD)
+
+/* For rmconf Xauth data */
+struct xauth_rmconf {
+       vchar_t *login; /* xauth login */
+       vchar_t *pass;  /* xauth password */
+       int state;      /* what's been sent */
 };
 
 /* status */
@@ -76,21 +97,60 @@ struct xauth_reply_arg {
 };
 
 struct ph1handle;
+struct isakmp_data;
 void xauth_sendreq(struct ph1handle *);
-void xauth_attr_reply(struct ph1handle *, struct isakmp_data *, int);
+int xauth_attr_reply(struct ph1handle *, struct isakmp_data *, int);
 int xauth_login_system(char *, char *);
 void xauth_sendstatus(struct ph1handle *, int, int);
 int xauth_check(struct ph1handle *);
+int group_check(struct ph1handle *, char **, int);
 vchar_t *isakmp_xauth_req(struct ph1handle *, struct isakmp_data *);
 vchar_t *isakmp_xauth_set(struct ph1handle *, struct isakmp_data *);
 void xauth_rmstate(struct xauth_state *);
 void xauth_reply_stub(void *);
-void xauth_reply(struct ph1handle *, int, int, int);
+int xauth_reply(struct ph1handle *, int, int, int);
+int xauth_rmconf_used(struct xauth_rmconf **);
+void xauth_rmconf_delete(struct xauth_rmconf **);
 
 #ifdef HAVE_LIBRADIUS
 int xauth_login_radius(struct ph1handle *, char *, char *);
 int xauth_radius_init(void);
 #endif
+
 #ifdef HAVE_LIBPAM
 int xauth_login_pam(int, struct sockaddr *, char *, char *);
 #endif
+
+#ifdef HAVE_LIBLDAP
+
+#define LDAP_DFLT_HOST         "localhost"
+#define LDAP_DFLT_USER         "cn"
+#define LDAP_DFLT_ADDR         "racoon-address"
+#define LDAP_DFLT_MASK         "racoon-netmask"
+#define LDAP_DFLT_GROUP                "cn"
+#define LDAP_DFLT_MEMBER       "member"
+
+struct xauth_ldap_config {
+       int             pver;
+       vchar_t         *host;
+       int             port;
+       vchar_t         *base;
+       int             subtree;
+       vchar_t         *bind_dn;
+       vchar_t         *bind_pw;
+       int             auth_type;
+       vchar_t         *attr_user;
+       vchar_t         *attr_addr;
+       vchar_t         *attr_mask;
+       vchar_t         *attr_group;
+       vchar_t         *attr_member;
+};
+
+extern struct xauth_ldap_config xauth_ldap_config;
+
+int xauth_ldap_init(void);
+void xauth_ldap_flush(void);
+int xauth_login_ldap(struct ph1handle *, char *, char *);
+#endif
+
+#endif /* _ISAKMP_XAUTH_H */
index b9eec1ad2128cf33dc6287d93255ba51b17d1a9e..f4629accf869b133ead29270c973de4dce429a6c 100644 (file)
@@ -65,6 +65,7 @@
 #endif
 #include <err.h>
 #include <sys/ioctl.h> 
+#include <resolv.h>
 
 #include "libpfkey.h"
 
@@ -106,7 +107,7 @@ com_init()
        memset(&name, 0, sizeof(name));
        name.sun_family = AF_UNIX;
        snprintf(name.sun_path, sizeof(name.sun_path),
-               "%s", ADMINSOCK_PATH);
+               "%s", adminsock_path);
 
        so = socket(AF_UNIX, SOCK_STREAM, 0);
        if (so < 0)
index 6725987951b0bb714bbf2f3c44137d1d26995fa2..7b2c5baffd6c1a5e622e86e6d979a7a4293db5a3 100644 (file)
 
 #ifdef __APPLE__
 #include <CoreFoundation/CoreFoundation.h>
+#if HAVE_SECURITY_FRAMEWORK
 #include <Security/Security.h>
+#else
+typedef void * SecKeychainRef;
+#endif
 #endif
 
 struct localconf *lcconf;
@@ -135,6 +139,7 @@ setdefault()
        lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL;
        lcconf->auto_exit_delay = 0;
        lcconf->auto_exit_state &= ~LC_AUTOEXITSTATE_SET;
+       lcconf->auto_exit_state |= LC_AUTOEXITSTATE_CLIENT;                             /* always auto exit as default */
 }
 
 /*
@@ -165,7 +170,7 @@ end:
        return key;
 }
 
-#ifdef __APPLE__
+#if defined(__APPLE__) && HAVE_KEYCHAIN
 /*
  * get PSK from keyChain.
  */
@@ -210,7 +215,7 @@ getpskfromkeychain(const char *name, u_int8_t etype, int secrettype, vchar_t *id
                        case IPSECDOI_ID_IPV6_ADDR_RANGE:
                        case IPSECDOI_ID_DER_ASN1_DN:
                        case IPSECDOI_ID_DER_ASN1_GN:
-                               goto end;
+                               goto no_id;
                                break;
                                
                        case IPSECDOI_ID_FQDN:
@@ -239,11 +244,23 @@ getpskfromkeychain(const char *name, u_int8_t etype, int secrettype, vchar_t *id
                                                                &cur_password,
                                                                NULL);
 
+               /* try find it using using only the peer id. */
+               if (status == errSecItemNotFound) 
+                       status = SecKeychainFindGenericPassword(keychain,
+                                                               idlen,
+                                                               peer_id,
+                                                               0,
+                                                               0,
+                                                               &cur_password_len,
+                                                               &cur_password,
+                                                               NULL);
+       
                if (status == noErr)
                        goto end;
                /* otherwise fall through to use the default value */
        }
        
+no_id:
        /*      use the value in remote config sharedsecret field
                this is either the value specified for lookup or the 
                default when lookup by id fails.
@@ -482,3 +499,5 @@ doitype2doi(doitype)
        return -1;
 }
 
+
+
index 95fda0966b256928fbddbac784dbe910275d015a..f2671be73db4f1c1c17f637375c8db4bd3bfa8e2 100644 (file)
 #ifndef _LOCALCONF_H
 #define _LOCALCONF_H
 
+#if !TARGET_OS_EMBEDDED
+#include <vproc.h>
+#endif
+
 /* local configuration */
 
 #define LC_DEFAULT_CF  SYSCONFDIR "/racoon.conf"
@@ -79,6 +83,9 @@ struct vpnctl_socket_elem {
 struct bound_addr {
        LIST_ENTRY(bound_addr) chain;
        u_int32_t       address;
+       vchar_t         *user_id;
+       vchar_t         *user_pw;
+       vchar_t         *version;       /* our version string - if present */
 };
 
 struct redirect {
@@ -93,6 +100,7 @@ struct saved_msg_elem {
        void* msg;
 };
 
+
 struct localconf {
        char *racoon_conf;              /* configuration filename */
 
@@ -108,6 +116,7 @@ struct localconf {
        int sock_vpncontrol;
        int sock_pfkey;
        int rtsock;                     /* routing socket */
+
        LIST_HEAD(_vpnctl_socket_elem_, vpnctl_socket_elem) vpnctl_comm_socks;
        LIST_HEAD(_redirect_, redirect) redirect_addresses;
        int auto_exit_state;            /* auto exit state */
@@ -118,7 +127,7 @@ struct localconf {
        int autograbaddr;
        struct myaddrs *myaddrs;
 
-       char *logfile_param;    /* from command line */
+       char *logfile_param;            /* from command line */
        char *pathinfo[LC_PATHTYPE_MAX];
        vchar_t *ident[LC_IDENTTYPE_MAX]; /* base of Identifier payload. */
 
@@ -154,6 +163,9 @@ struct localconf {
                 */
 
        int gss_id_enc;                 /* GSS ID encoding to use */
+#if !TARGET_OS_EMBEDDED
+       vproc_transaction_t vt; /* returned by vproc_transaction_begin */
+#endif
 };
 
 extern struct localconf *lcconf;
@@ -162,7 +174,7 @@ extern void initlcconf __P((void));
 extern void flushlcconf __P((void));
 extern vchar_t *getpskbyname __P((vchar_t *));
 extern vchar_t *getpskbyaddr __P((struct sockaddr *));
-#ifdef __APPLE__
+#if defined(__APPLE__) && HAVE_KEYCHAIN
 extern vchar_t *getpskfromkeychain __P((const char *, u_int8_t, int, vchar_t *));
 #endif
 extern void getpathname __P((char *, int, int, const char *));
@@ -170,4 +182,5 @@ extern int sittype2doi __P((int));
 extern int doitype2doi __P((int));
 extern vchar_t *getpsk __P((const char *, const int)); 
 
+
 #endif /* _LOCALCONF_H */
index 03a3ac693e27e74a3dab1266a6e595602fd2baf7..b9ac5584f1a998c111a91da40cb5ce1a653fc305 100644 (file)
@@ -87,7 +87,7 @@ log_open(siz, fname)
 
        p->siz = siz;
        if (fname)
-               p->fname = strdup(fname);
+               p->fname = racoon_strdup(fname);
 
        return p;
 }
@@ -105,7 +105,7 @@ log_add(p, str)
        /* syslog if p->fname == NULL? */
        if (p->buf[p->head])
                racoon_free(p->buf[p->head]);
-       p->buf[p->head] = strdup(str);
+       p->buf[p->head] = racoon_strdup(str);
        p->tbuf[p->head] = time(NULL);
        p->head++;
        p->head %= p->siz;
index f325c90b8abd1fb1be84c71e3bbac56204e1f1a8..82057e7d9c8a925e1f65503f59da5259e3ac4295 100644 (file)
@@ -49,6 +49,7 @@
 #endif
 #include <paths.h>
 #include <err.h>
+#include <launch.h>
 
 /*
  * If we're using a debugging malloc library, this may define our
 
 #include "cfparse_proto.h"
 #include "isakmp_var.h"
-#ifdef HAVE_LIBRADIUS
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
 #include "isakmp.h"
 #include "isakmp_xauth.h"
+#include "isakmp_cfg.h"
 #endif
 #include "remoteconf.h"
 #include "localconf.h"
 #include "session.h"
 #include "oakley.h"
 #include "pfkey.h"
+#include "policy.h"
 #include "crypto_openssl.h"
 #include "backupsa.h"
 #include "vendorid.h"
 
+#ifdef __APPLE__
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#endif
+
 //#include "package_version.h"
 
 int f_local = 0;       /* local test mode.  behave like a wall. */
@@ -99,6 +108,7 @@ static void restore_params __P((void));
 static void save_params __P((void));
 static void saverestore_params __P((int));
 static void cleanup_pidfile __P((void));
+static int launchedbylaunchd(void);
 
 pid_t racoon_pid = 0;
 int print_pid = 1;     /* for racoon only */
@@ -106,7 +116,7 @@ int print_pid = 1;  /* for racoon only */
 void
 usage()
 {
-       printf("usage: racoon [-BdFve%s] %s[-f (file)] [-l (file)] [-p (port)]\n",
+       printf("usage: racoon [-BdFvs%s] %s[-f (file)] [-l (file)] [-p (port)]\n",
 #ifdef INET6
                "46",
 #else
@@ -125,7 +135,7 @@ usage()
        printf("   -L: include location in debug messages\n");
        printf("   -F: run in foreground, do not become daemon.\n");
        printf("   -v: be more verbose\n");
-       printf("   -e: enable auto exit\n");
+       printf("   -s: override enable auto exit\n");
 #ifdef INET6
        printf("   -4: IPv4 mode.\n");
        printf("   -6: IPv6 mode.\n");
@@ -146,6 +156,7 @@ main(ac, av)
        char **av;
 {
        int error;
+       char                            logFileStr[MAXPATHLEN+1];
 
        if (geteuid() != 0) {
                errx(1, "must be root to invoke this program.");
@@ -168,6 +179,8 @@ main(ac, av)
        DRM_init();
 #endif
 
+       logFileStr[0] = 0;
+
        eay_init();
        initlcconf();
        initrmconf();
@@ -175,8 +188,63 @@ main(ac, av)
        compute_vendorids();
 
        parse(ac, av);
-       if (lcconf->logfile_param)
-               plogset(lcconf->logfile_param);
+       
+       #ifdef __APPLE__
+       /*
+        * Check IPSec plist
+        */
+       {
+               SCPreferencesRef        prefs = NULL;
+               CFPropertyListRef       globals;
+               CFStringRef                     logFileRef;
+               CFNumberRef                     debugLevelRef;
+               
+               int                                     level = 0;
+               
+               logFileStr[0] = 0;
+                  
+           if ((prefs = SCPreferencesCreate(0, CFSTR("racoon"), CFSTR("com.apple.ipsec.plist"))) == NULL)
+                       goto skip;
+               globals = SCPreferencesGetValue(prefs, CFSTR("Global"));
+               if (!globals || (CFGetTypeID(globals) != CFDictionaryGetTypeID()))
+                       goto skip;
+               debugLevelRef = CFDictionaryGetValue(globals, CFSTR("DebugLevel"));
+               if (!debugLevelRef || (CFGetTypeID(debugLevelRef) != CFNumberGetTypeID()))
+                       goto skip;
+               CFNumberGetValue(debugLevelRef, kCFNumberSInt32Type, &level);
+               switch (level)
+               {
+                       case 0:
+                               loglevel = 5;
+                               goto skip;
+                               break;
+                       case 1:
+                               loglevel = 6;
+                               break;
+                       case 2:
+                               loglevel = 7;
+                               break;
+                       default:
+                               break; /* invalid - ignore */
+               }
+               
+               logFileRef = CFDictionaryGetValue(globals, CFSTR("DebugLogfile"));
+               if (!logFileRef || (CFGetTypeID(logFileRef) != CFStringGetTypeID())) {  
+                       goto skip;
+               }
+               CFStringGetCString(logFileRef, logFileStr, MAXPATHLEN, kCFStringEncodingMacRoman);
+skip:
+               if (prefs)
+                       CFRelease(prefs);
+       }
+       
+       if (logFileStr[0])
+                       plogset(logFileStr);
+       else    
+#endif /* __APPLE__ */
+               if (lcconf->logfile_param)
+                       plogset(lcconf->logfile_param);                 
+
        ploginit();
 
        plog(LLV_INFO, LOCATION, NULL, "***** racoon started: pid=%d  started by: %d\n", getpid(), getppid());
@@ -184,6 +252,8 @@ main(ac, av)
        plog(LLV_INFO, LOCATION, NULL, "@(#)"
            "This product linked %s (http://www.openssl.org/)"
            "\n", eay_version());
+       plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n", 
+           lcconf->racoon_conf);
 
        if (pfkey_init() < 0) {
                errx(1, "something error happened "
@@ -191,6 +261,16 @@ main(ac, av)
                /* NOTREACHED*/
        }
 
+#ifdef ENABLE_HYBRID
+       if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD))
+               errx(1, "could not initialize ISAKMP mode config structures");
+#endif
+
+#ifdef HAVE_LIBLDAP
+       if (xauth_ldap_init() != 0)
+               errx(1, "could not initialize libldap");
+#endif
+
        /*
         * in order to prefer the parameters by command line,
         * saving some parameters before parsing configuration file.
@@ -200,7 +280,8 @@ main(ac, av)
        if (error != 0)
                errx(1, "failed to parse configuration file.");
        restore_params();
-       if (lcconf->logfile_param == NULL)
+       
+       if (lcconf->logfile_param == NULL && logFileStr[0] == 0)
                plogreset(lcconf->pathinfo[LC_PATHTYPE_LOGFILE]);
                
 #ifdef ENABLE_NATT
@@ -235,54 +316,67 @@ main(ac, av)
 
        if (f_foreground)
                close(0);
-       else if (exec_done) {
-               if (atexit(cleanup_pidfile) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "cannot register pidfile cleanup");
-               }
-       } else {
-               #define MAX_EXEC_ARGS 32
-               
-               char *args[MAX_EXEC_ARGS + 1];
-               char *env[1] = {0};     
-               int     i;
-               
-               if (ac > MAX_EXEC_ARGS) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "too many arguments.\n");
-                       exit(1);
-               }
-               
-               if (daemon(0, 0) < 0) {
-                       errx(1, "failed to be daemon. (%s)",
-                               strerror(errno));
-               }
+       else {
+               if ( !exec_done && launchedbylaunchd() ){
+                       plog(LLV_INFO, LOCATION, NULL,
+                                "racoon launched by launchd.\n");
+                       exec_done = 1;
+                       if (atexit(cleanup_pidfile) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "cannot register pidfile cleanup");
+                       }
+               }else {
                
-               /* Radar 5129006 - Prevent non-root user from killing racoon
-                * when launched by setuid process
-                */
-               if (setuid(0)) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "cannot set uid.\n");
-                       exit(1);
-               }
-               if (setgid(0)) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "cannot set gid.\n");
-                       exit(1);
+                       if (exec_done) {
+                               if (atexit(cleanup_pidfile) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                               "cannot register pidfile cleanup");
+                               }
+                       } else {
+                               #define MAX_EXEC_ARGS 32
+                               
+                               char *args[MAX_EXEC_ARGS + 2]; /* 2 extra, for '-x' and NULL */
+                               char *env[1] = {0};     
+                               int     i;
+                               
+                               if (ac > MAX_EXEC_ARGS) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                               "too many arguments.\n");
+                                       exit(1);
+                               }
+                               
+                               if (daemon(0, 0) < 0) {
+                                       errx(1, "failed to be daemon. (%s)",
+                                               strerror(errno));
+                               }
+                               
+                               /* Radar 5129006 - Prevent non-root user from killing racoon
+                                * when launched by setuid process
+                                */
+                               if (setuid(0)) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                               "cannot set uid.\n");
+                                       exit(1);
+                               }
+                               if (setgid(0)) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                               "cannot set gid.\n");
+                                       exit(1);
+                               }
+                               
+                               /* setup args to re-exec - for CoreFoundation issues */
+                               args[0] = PATHRACOON;   
+                               for (i = 1; i < ac; i++)
+                                       args[i] = *(av + i);
+                               args[ac] = "-x";                /* tells racoon its been exec'd */
+                               args[ac+1] = 0;
+                               
+                               execve(PATHRACOON, args, env);
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                               "failed to exec racoon. (%s)", strerror(errno));
+                               exit(1);
+                       }
                }
-               
-               /* setup args to re-exec - for CoreFoundation issues */
-               args[0] = PATHRACOON;   
-               for (i = 1; i < ac; i++)
-                       args[i] = *(av + i);
-               args[ac] = "-x";                /* tells racoon its been exec'd */
-               args[ac+1] = 0;
-               
-               execve(PATHRACOON, args, env);
-               plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to exec racoon. (%s)", strerror(errno));
-               exit(1);
        }
 
        session();
@@ -291,6 +385,41 @@ main(ac, av)
 }
 
 
+static int
+launchedbylaunchd(){
+       int             launchdlaunched = 1;
+       launch_data_t checkin_response = NULL;
+       launch_data_t checkin_request = NULL;
+       
+       /* check in with launchd */
+       if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "launch_data_new_string fails.\n");
+               launchdlaunched = 0;
+               goto done;
+       }
+       if ((checkin_response = launch_msg(checkin_request)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "launch_msg fails.\n");
+               launchdlaunched = 0;
+               goto done;
+       }
+       if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "launch_data_get_type fails errno %d.\n", launch_data_get_errno(checkin_response));
+               launchdlaunched = 0;
+               goto done;
+       }
+       
+done:
+       /* clean up before we leave */
+       if ( checkin_request )
+               launch_data_free(checkin_request);
+       if ( checkin_response )
+               launch_data_free(checkin_response);
+       return launchdlaunched;
+}
+
 static void
 cleanup_pidfile()
 {
@@ -300,12 +429,12 @@ cleanup_pidfile()
        /* if it's not child process, clean everything */
        if (racoon_pid == p) {
                if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) 
-                       strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN);
+                       strlcpy(pid_file, _PATH_VARRUN "racoon.pid", sizeof(pid_file));
                else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') 
-                       strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
+                       strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file));
                else {
-                       strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN);
-                       strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
+                       strlcat(pid_file, _PATH_VARRUN, sizeof(pid_file));
+                       strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file));
                }
                (void) unlink(pid_file);
        }
@@ -335,7 +464,7 @@ parse(ac, av)
        plogset("/tmp/racoon.log");
 #endif
 
-       while ((c = getopt(ac, av, "dLFp:P:a:f:l:veZBCx"
+       while ((c = getopt(ac, av, "dLFp:P:a:f:l:vsZBCx"
 #ifdef YYDEBUG
                        "y"
 #endif
@@ -378,8 +507,8 @@ parse(ac, av)
                case 'v':
                        vflag++;
                        break;
-               case 'e':
-                       lcconf->auto_exit_state |= LC_AUTOEXITSTATE_CLIENT;
+               case 's':
+                       lcconf->auto_exit_state &= ~LC_AUTOEXITSTATE_CLIENT;    /* override default auto exit state */
                        break;
                case 'x':
                        exec_done = 1;
index 8f90cc9c6d60201f7c31353f38dda3c5d0ae468d..cb335331a3c3c00c97ed985295e9fda5d77085e0 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: misc.h,v 1.6.10.1 2005/11/06 17:18:26 monas Exp $ */
+/*     $NetBSD: misc.h,v 1.4 2006/09/09 16:22:09 manu Exp $    */
+
+/* Id: misc.h,v 1.9 2006/04/06 14:00:06 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -47,15 +49,26 @@ extern const char *debug_location __P((const char *, int, const char *));
 extern int getfsize __P((char *));
 struct timeval;
 extern double timedelta __P((struct timeval *, struct timeval *));
+char *strdup __P((const char *));
 
-#ifndef HAVE_STRLCPY
-#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0')
+#if defined(__APPLE__)
+#define RACOON_TAILQ_FOREACH_REVERSE(var, head, headname ,field)       \
+  TAILQ_FOREACH_REVERSE(var, head, field, headname)
+#else
+#define RACOON_TAILQ_FOREACH_REVERSE(var, head, headname ,field)       \
+    TAILQ_FOREACH_REVERSE(var, head, headname, field)
 #endif
 
-#ifndef HAVE_STRLCAT
-#define strlcat(d,s,l) strncat(d,s,(l)-strlen(d)-1)
-#endif
+#define STRDUP_FATAL(x) if (x == NULL) {                       \
+       plog(LLV_ERROR, LOCATION, NULL, "strdup failed\n");     \
+       exit(1);                                                \
+}
 
 #include "libpfkey.h"
 
+#define remainingsize(string_buffer_sizeof, filled_str) (string_buffer_sizeof - strlen(filled_str) - 1)
+#define remainingsize_opt(string_buffer_sizeof, filled_strlen) (string_buffer_sizeof - filled_strlen - 1)
+#define remainingsizeof(string_buffer) (sizeof(string_buffer) - strlen(string_buffer) - 1)
+#define remainingsizeof_opt(string_buffer, filled_strlen) (sizeof(string_buffer) - filled_strlen - 1)
+
 #endif /* _MISC_H */
index a9c02b12b206cfc855f98fcddf47490348c8b73f..4bd1f1ff6db13975d08246c52c43ce96d34d0a5c 100644 (file)
@@ -65,6 +65,7 @@
 #include "schedule.h"
 #include "nattraversal.h"
 #include "grabmyaddr.h"
+#include "ike_session.h"
 
 struct natt_ka_addrs {
   struct sockaddr      *src;
@@ -220,6 +221,9 @@ natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received,
     verified = 1;
   }
 
+    if (iph1->parent_session)
+        iph1->parent_session->natt_flags = iph1->natt_flags;
+
   vfree (natd_computed);
 
   return verified;
@@ -300,98 +304,110 @@ natt_fill_options (struct ph1natt_options *opts, int version)
   return 0;
 }
 
-#ifdef NOT_NOW
-static int
+int
 create_natoa_payloads(struct ph2handle *iph2, vchar_t **natoa_i, vchar_t **natoa_r)
 {
        int natoa_type = 0;
-       int natt_type;
        vchar_t         *i;
        vchar_t         *r;
        u_int8_t        *p;
-       size_t          src_size;
-       size_t          dst_size;
+       struct sockaddr *i_addr;
+       struct sockaddr *r_addr;
+       size_t          i_size;
+       size_t          r_size;
        
        *natoa_i = *natoa_r = NULL;
        
 
        /* create natoa payloads if natt being used */
        /* don't send if type == apple                          */
-       if ((natt_type = natd_hasnat(iph2->ph1)) != 0)
-               if (natt_type == natt_type_rfc)
-                       natoa_type = ISAKMP_NPTYPE_NATOA_RFC;
-               else if (natt_type == natt_type_02 || natt_type == natt_type_02N)
-                       natoa_type = ISAKMP_NPTYPE_NATOA_DRAFT;
-       
+       if (!iph2->ph1->natt_options)
+               return 0;
+
+       natoa_type = iph2->ph1->natt_options->payload_nat_oa;
        if (natoa_type == 0)
                return 0;
-               
-       switch (iph2->src->sa_family) {
+
+       if (iph2->side == INITIATOR) {
+               i_addr = iph2->src;
+               r_addr = iph2->dst;
+       } else {
+               i_addr = iph2->dst;
+               r_addr = iph2->src;
+       }
+
+       switch (i_addr->sa_family) {
                case AF_INET:
-                       src_size = sizeof(in_addr_t);
+                       i_size = sizeof(in_addr_t);
                        break;
 #ifdef INET6
                case AF_INET6:
-                       src_size = sizeof(struct in6_addr);
+                       i_size = sizeof(struct in6_addr);
                        break;
 #endif
                default:
                        plog(LLV_ERROR, LOCATION, NULL,
-                       "invalid address family: %d\n", iph2->src->sa_family);
+                                "invalid address family: %d\n", i_addr->sa_family);
                        return -1;              
        }
-               
-       switch (iph2->dst->sa_family) {
+
+       switch (r_addr->sa_family) {
                case AF_INET:
-                       dst_size = sizeof(in_addr_t);
+                       r_size = sizeof(in_addr_t);
                        break;
 #ifdef INET6
                case AF_INET6:
-                       dst_size = sizeof(struct in6_addr);
+                       r_size = sizeof(struct in6_addr);
                        break;
 #endif
                default:
                        plog(LLV_ERROR, LOCATION, NULL,
-                       "invalid address family: %d\n", iph2->dst->sa_family);
+                                "invalid address family: %d\n", r_addr->sa_family);
                        return -1;              
        }
 
-       i = vmalloc(sizeof(struct isakmp_pl_natoa) + src_size - sizeof(struct isakmp_gen));     
-       r = vmalloc(sizeof(struct isakmp_pl_natoa) + dst_size - sizeof(struct isakmp_gen));
-       if (i == NULL || r == NULL) {
+       i = vmalloc(sizeof(struct isakmp_pl_natoa) + i_size - sizeof(struct isakmp_gen));
+       if (i == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to get buffer for natoa payload.\n");
+               return -1;
+       }
+       r = vmalloc(sizeof(struct isakmp_pl_natoa) + r_size - sizeof(struct isakmp_gen));
+       if (r == NULL) {
+               vfree(i);
                plog(LLV_ERROR, LOCATION, NULL,
                        "failed to get buffer for natoa payload.\n");
                return -1;
        }
        
        /* copy src address */
-       p = i->v;
+       p = (__typeof__(p))i->v;
        
-       switch (iph2->src->sa_family) {
+       switch (i_addr->sa_family) {
                case AF_INET:
                        *p = IPSECDOI_ID_IPV4_ADDR;
-                       bcopy(&(((struct sockaddr_in *)iph2->src)->sin_addr.s_addr), p + sizeof(u_int32_t), src_size);
+                       bcopy(&(((struct sockaddr_in *)i_addr)->sin_addr.s_addr), p + sizeof(u_int32_t), i_size);
                        break;
 #ifdef INET6
                case AF_INET6:
                        *p = IPSECDOI_ID_IPV6_ADDR;
-                       bcopy(&(((struct sockaddr_in6 *)iph2->src)->sin6_addr), p + sizeof(u_int32_t), src_size);
+                       bcopy(&(((struct sockaddr_in6 *)i_addr)->sin6_addr), p + sizeof(u_int32_t), i_size);
                        break;
 #endif
        }
 
        /* copy dst address */
-       p = r->v;
+       p = (__typeof__(p))r->v;
        
-       switch (iph2->dst->sa_family) {
+       switch (r_addr->sa_family) {
                case AF_INET:
                        *p = IPSECDOI_ID_IPV4_ADDR;
-                       bcopy(&(((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr), p + sizeof(u_int32_t), dst_size);
+                       bcopy(&(((struct sockaddr_in *)r_addr)->sin_addr.s_addr), p + sizeof(u_int32_t), r_size);
                        break;
 #ifdef INET6
                case AF_INET6:
                        *p = IPSECDOI_ID_IPV6_ADDR;
-                       bcopy(&(((struct sockaddr_in6 *)iph2->dst)->sin6_addr), p + sizeof(u_int32_t), dst_size);
+                       bcopy(&(((struct sockaddr_in6 *)r_addr)->sin6_addr), p + sizeof(u_int32_t), r_size);
                        break;
 #endif
        }
@@ -400,8 +416,49 @@ create_natoa_payloads(struct ph2handle *iph2, vchar_t **natoa_i, vchar_t **natoa
        *natoa_r = r;
        return natoa_type;
 }      
-#endif 
-       
+
+struct sockaddr *
+process_natoa_payload(vchar_t *buf)
+{
+       struct sockaddr      *saddr = NULL;
+       struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)buf->v;
+
+       switch (id_b->type) {
+               case IPSECDOI_ID_IPV4_ADDR:
+                       saddr = racoon_malloc(sizeof(struct sockaddr_in));
+                       if (!saddr) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "error allocating addr for NAT-OA payload\n");
+                               return NULL;
+                       }
+                       saddr->sa_len = sizeof(struct sockaddr_in);
+                       saddr->sa_family = AF_INET;
+                       ((struct sockaddr_in *)saddr)->sin_port = IPSEC_PORT_ANY;
+                       memcpy(&((struct sockaddr_in *)saddr)->sin_addr,
+                                  buf->v + sizeof(*id_b), sizeof(struct in_addr));
+                       break;
+#ifdef INET6
+               case IPSECDOI_ID_IPV6_ADDR:
+                       saddr = racoon_malloc(sizeof(struct sockaddr_in6));
+                       if (!saddr) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                        "error allocating addr for NAT-OA payload\n");
+                               return NULL;
+                       }
+                       saddr->sa_len = sizeof(struct sockaddr_in6);
+                       saddr->sa_family = AF_INET6;
+                       ((struct sockaddr_in6 *)saddr)->sin6_port = IPSEC_PORT_ANY;
+                       memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr,
+                                  buf->v + sizeof(*id_b), sizeof(struct in6_addr));
+                       break;
+#endif
+               default:
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "invalid NAT-OA payload %d\n", id_b->type);
+                       return NULL;
+       }
+       return saddr;
+}
 
 void
 natt_float_ports (struct ph1handle *iph1)
@@ -429,7 +486,8 @@ natt_float_ports (struct ph1handle *iph1)
                set_port (iph1->remote, iph1->natt_options->float_port);
        iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
 
-       
+       ike_session_ikev1_float_ports(iph1);
+
 #ifndef __APPLE__
        natt_keepalive_add_ph1 (iph1);
 #endif
@@ -516,8 +574,16 @@ natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst)
     return -1;
   }
 
-  new_addr->src = dupsaddr(src);
-  new_addr->dst = dupsaddr(dst);
+  if ((new_addr->src = dupsaddr(src)) == NULL) {
+       racoon_free(new_addr);
+       plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n");
+       return -1;
+  }
+  if ((new_addr->dst = dupsaddr(dst)) == NULL) {
+       racoon_free(new_addr);
+       plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n");
+       return -1;
+  }
   new_addr->in_use = 1;
   TAILQ_INSERT_TAIL(&ka_tree, new_addr, chain);
 
index f03c76c9637400c046435e31827e57e250f91b81..693fc40226391934202e73ee1ad3b6849dde3bc5 100644 (file)
 #define        NON_ESP_MARKER_LEN      sizeof(u_int32_t)
 #define        NON_ESP_MARKER_USE(iph1)        ((iph1)->natt_flags & NAT_ADD_NON_ESP_MARKER)
 
+#ifdef ENABLE_NATT
+#ifdef ENABLE_FRAG
+#define PH1_NON_ESP_EXTRA_LEN(iph1) ((iph1->frag && iph1->sendbuf->l > ISAKMP_FRAG_MAXLEN) ? 0: (NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0))
+#define PH2_NON_ESP_EXTRA_LEN(iph2) ((iph2->ph1->frag && iph2->sendbuf->l > ISAKMP_FRAG_MAXLEN) ? 0: (NON_ESP_MARKER_USE(iph2->ph1) ? NON_ESP_MARKER_LEN : 0))
+#else
+#define PH1_NON_ESP_EXTRA_LEN(iph1) (NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0)
+#define PH2_NON_ESP_EXTRA_LEN(iph2) (NON_ESP_MARKER_USE(iph2->ph1) ? NON_ESP_MARKER_LEN : 0)
+#endif
+#else
+#define PH1_NON_ESP_EXTRA_LEN(iph1) 0
+#define PH2_NON_ESP_EXTRA_LEN(iph2) 0
+#endif
+
 /* These are the values from parsing "remote {}" 
    block of the config file. */
 #define NATT_OFF       FALSE   /* = 0 */
@@ -83,9 +96,8 @@ int natt_udp_encap (int encmode);
 int natt_fill_options (struct ph1natt_options *opts, int version);
 void natt_float_ports (struct ph1handle *iph1);
 void natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric);
-#ifdef NOT_NOW
 int create_natoa_payloads(struct ph2handle *iph2, vchar_t **, vchar_t **);
-#endif
+struct sockaddr * process_natoa_payload(vchar_t *buf);
 
 struct payload_list *
 isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]);
index 1d5288579d197622537eb25a856cda0a08db55ef..9ab26f91405f1fe519701f6efbe14c69dd9d5115 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: oakley.c,v 1.17.2.5 2005/10/04 09:54:27 manubsd Exp $ */
+/*     $NetBSD: oakley.c,v 1.9.6.2 2007/04/04 13:08:28 vanhu Exp $     */
+
+/* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 #include <sys/socket.h>        /* XXX for subjectaltname */
 #include <netinet/in.h>        /* XXX for subjectaltname */
 
-#include <openssl/x509.h>
 #include <openssl/pkcs7.h>
+#include <openssl/x509.h>
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <arpa/inet.h>
+#include <TargetConditionals.h>
 
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
@@ -54,6 +58,9 @@
 #  include <time.h>
 # endif
 #endif
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
 
 #include "var.h"
 #include "misc.h"
@@ -72,7 +79,6 @@
 #include "admin.h"
 #include "privsep.h"
 #include "localconf.h"
-#include "remoteconf.h"
 #include "policy.h"
 #include "handler.h"
 #include "ipsec_doi.h"
 #include "crypto_openssl.h"
 #ifdef __APPLE__
 #include "crypto_cssm.h"
+#if HAVE_OPENDIR
 #include "open_dir.h"
 #endif
+#endif
 #include "dnssec.h"
 #include "sockmisc.h"
 #include "strnames.h"
 #include "gcmalloc.h"
 #include "rsalist.h"
 #ifdef __APPLE__
-#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CoreFoundation.h>
 #endif
-
+#include "remoteconf.h"
 
 #ifdef HAVE_GSSAPI
 #include "gssapi.h"
@@ -610,6 +618,7 @@ oakley_compute_keymat_x(iph2, side, sa_dir)
 
                        while (dupkeymat--) {
                                vchar_t *this = NULL;   /* Kn */
+                               int update_prev;
 
                                memcpy(seed->v, prev->v, prev->l);
                                memcpy(seed->v + prev->l, buf->v, buf->l);
@@ -625,8 +634,14 @@ oakley_compute_keymat_x(iph2, side, sa_dir)
                                        goto end;
                                }
 
+                               update_prev = (prev && prev == res) ? 1 : 0;
+
                                l = res->l;
                                res = vrealloc(res, l + this->l);
+
+                               if (update_prev)
+                                       prev = res;
+
                                if (res == NULL) {
                                        plog(LLV_ERROR, LOCATION, NULL,
                                                "failed to get keymat buffer.\n");
@@ -868,7 +883,7 @@ oakley_ph1hash_common(iph1, sw)
                + (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
                if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
                        bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
                        len += bp->l;
@@ -929,7 +944,7 @@ oakley_ph1hash_common(iph1, sw)
        p += bp->l;
 
 #ifdef HAVE_GSSAPI
-       if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
+       if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
                if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
                        bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
                        memcpy(p, bp->v, bp->l);
@@ -950,7 +965,8 @@ oakley_ph1hash_common(iph1, sw)
 
        error = 0;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
+       plog(LLV_DEBUG, LOCATION, NULL, "HASH (%s) computed:\n",
+               iph1->side == INITIATOR ? "init" : "resp");
        plogdump(LLV_DEBUG, res->v, res->l);
 
 end:
@@ -989,10 +1005,18 @@ oakley_ph1hash_base_i(iph1, sw)
                return NULL;
        }
 
-       switch (iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+#endif
                if (iph1->skeyid == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
                        return NULL;
@@ -1002,12 +1026,18 @@ oakley_ph1hash_base_i(iph1, sw)
 
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+#ifdef HAVE_GSSAPI
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
+#endif
 #ifdef ENABLE_HYBRID
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
 #endif
                /* make hash for seed */
                len = iph1->nonce->l + iph1->nonce_p->l;
@@ -1115,16 +1145,28 @@ oakley_ph1hash_base_r(iph1, sw)
                        "invalid etype for this hash function\n");
                return NULL;
        }
-       if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG
+
+       switch(AUTHMETHOD(iph1)) {
+       case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
+       case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 #ifdef ENABLE_HYBRID
-        && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
-        && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 #endif
-        && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG) {
+               break;
+       default:
                plog(LLV_ERROR, LOCATION, NULL,
                        "not supported authentication method %d\n",
                        iph1->approval->authmethod);
                return NULL;
+               break;
        }
 
        /* make hash for seed */
@@ -1186,7 +1228,7 @@ oakley_ph1hash_base_r(iph1, sw)
        memcpy(p, bp->v, bp->l);
        p += bp->l;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
+       plog(LLV_DEBUG, LOCATION, NULL, "HASH_R with:\n");
        plogdump(LLV_DEBUG, buf->v, buf->l);
 
        /* compute HASH */
@@ -1196,7 +1238,7 @@ oakley_ph1hash_base_r(iph1, sw)
 
        error = 0;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
+       plog(LLV_DEBUG, LOCATION, NULL, "HASH_R computed:\n");
        plogdump(LLV_DEBUG, res->v, res->l);
 
 end:
@@ -1231,8 +1273,13 @@ oakley_validate_auth(iph1)
 #ifdef ENABLE_STATS
        gettimeofday(&start, NULL);
 #endif
-       switch (iph1->approval->authmethod) {
+
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+#endif
                /* validate HASH */
            {
                char *r_hash;
@@ -1242,10 +1289,20 @@ oakley_validate_auth(iph1)
                                "few isakmp message received.\n");
                        return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
                }
-
+#ifdef ENABLE_HYBRID
+               if (AUTHMETHOD(iph1) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I &&
+                   ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0))
+               {
+                       plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
+                           "hybrid auth is enabled, "
+                           "but peer is no Xauth compliant\n");
+                       return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
+                       break;
+               }
+#endif
                r_hash = (caddr_t)(iph1->pl_hash + 1);
 
-               plog(LLV_DEBUG, LOCATION, NULL, "HASH received:");
+               plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n");
                plogdump(LLV_DEBUG, r_hash,
                        ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash));
 
@@ -1282,8 +1339,12 @@ oakley_validate_auth(iph1)
        case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
        case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 #ifdef ENABLE_HYBRID
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
 #endif
            {
                int error = 0;
@@ -1380,10 +1441,13 @@ oakley_validate_auth(iph1)
                /* check configured peers identifier against cert IDs                           */
                /* allows checking of specified ID against multiple ids in the cert */
                /* such as multiple domain names                                                                        */
+#if !TARGET_OS_EMBEDDED
                if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER &&
                        (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_RMCONFIG)) != 0)
                        return error;
+#endif
 
+#if HAVE_OPENDIR
                /* check cert common name against Open Directory authentication group */
                if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_OPEN_DIR) {
                        
@@ -1405,16 +1469,17 @@ oakley_validate_auth(iph1)
                                        return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
                        }
                }
-#endif
+#endif /* HAVE_OPENDIR */
+#endif /* __APPLE__ */
 
                /* verify certificate */
                if (iph1->rmconf->verify_cert
                 && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) {
                        certtype = iph1->rmconf->certtype;
 #ifdef ENABLE_HYBRID
-                       switch (iph1->approval->authmethod) {
-                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+                       switch (AUTHMETHOD(iph1)) {
+                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
                                certtype = iph1->cert_p->type;
                                break;
                        default:
@@ -1423,11 +1488,49 @@ oakley_validate_auth(iph1)
 #endif
                        switch (certtype) {
                        case ISAKMP_CERT_X509SIGN:
+
+#if TARGET_OS_EMBEDDED
+                       {
+                               /* use ID from remote configuration */  
+                               /* check each ID in list                        */
+                               struct idspec *id_spec;
+                               CFStringRef     hostname = NULL;
+                               char *peers_id;
+                               struct genlist_entry *gpb = NULL;
+                               
+                               if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER) {
+                                       id_spec = genlist_next(iph1->rmconf->idvl_p, &gpb);     /* expect only one id */                                                
+                                       if (id_spec->idtype == IDTYPE_ADDRESS) {
+                                               switch (((struct sockaddr *)(id_spec->id->v))->sa_family) {                                                     
+                                                       case AF_INET:
+                                                               peers_id = inet_ntoa(((struct sockaddr_in *)(id_spec->id->v))->sin_addr);
+                                                               hostname = CFStringCreateWithCString(NULL, peers_id, kCFStringEncodingUTF8);
+                                                               break;
+#ifdef INET6
+                                                       case AF_INET6:
+                                                               return ISAKMP_NTYPE_INVALID_ID_INFORMATION;             /* not currently supported for embedded */
+                                                               break;
+#endif
+                                                       default:
+                                                               plog(LLV_ERROR, LOCATION, NULL,
+                                                                       "unknown address type for peers identifier.\n");
+                                                               return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
+                                                               break;
+                                               }                                               
+                                       } else
+                                               hostname = CFStringCreateWithBytes(NULL, (u_int8_t *)id_spec->id->v, id_spec->id->l, kCFStringEncodingUTF8, FALSE);
+                               }
+                               error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, hostname);
+                               if (hostname)
+                                       CFRelease(hostname);
+                       }
+                       
+#else /* TARGET_OS_EMBEDDED */
 #ifdef __APPLE__
                                if (iph1->rmconf->cert_verification == VERIFICATION_MODULE_SEC_FRAMEWORK)
-                                       error = crypto_cssm_check_x509cert(&iph1->cert_p->cert);
+                                       error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, NULL);
                                else 
-#endif
+#endif /* __APPLE__ */
                                {
                                        char path[MAXPATHLEN];
                                        char *ca;
@@ -1445,6 +1548,7 @@ oakley_validate_auth(iph1)
                                                lcconf->pathinfo[LC_PATHTYPE_CERT], 
                                                ca, 0);
                                }
+#endif /* TARGET_OS_EMBEDDED */
                                break;
                        
                        default:
@@ -1459,7 +1563,6 @@ oakley_validate_auth(iph1)
                        }
                }
 
-
                plog(LLV_DEBUG, LOCATION, NULL, "CERT validated\n");
 
                /* compute hash */
@@ -1485,9 +1588,9 @@ oakley_validate_auth(iph1)
 
                certtype = iph1->rmconf->certtype;
 #ifdef ENABLE_HYBRID
-               switch (iph1->approval->authmethod) {
-               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+               switch (AUTHMETHOD(iph1)) {
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+               case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
                        certtype = iph1->cert_p->type;
                        break;
                default:
@@ -1526,8 +1629,8 @@ oakley_validate_auth(iph1)
            }
                break;
 #ifdef ENABLE_HYBRID
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
-       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
            {
                if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
                        plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
@@ -1545,6 +1648,11 @@ oakley_validate_auth(iph1)
 #endif
 #ifdef HAVE_GSSAPI
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
+               /* check if we're not into XAUTH_PSKEY_I instead */
+#ifdef ENABLE_HYBRID
+               if (iph1->rmconf->xauth)
+                       break;
+#endif
                switch (iph1->etype) {
                case ISAKMP_ETYPE_IDENT:
                case ISAKMP_ETYPE_AGG:
@@ -1582,6 +1690,12 @@ oakley_validate_auth(iph1)
 #endif
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+#endif
                if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
                        plog(LLV_ERROR, LOCATION, iph1->remote,
                                "few isakmp message received.\n");
@@ -1670,11 +1784,11 @@ get_cert_fromlocal(iph1, my)
 
        switch (iph1->rmconf->certtype) {
        case ISAKMP_CERT_X509SIGN:
-#ifdef __APPLE__
+#if defined(__APPLE__)
                if (iph1->rmconf->identity_in_keychain) {
                        CFDataRef dataRef;
                        
-                       if (base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
+                       if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
                                goto end;
                        cert = crypto_cssm_get_x509cert(dataRef);
                        CFRelease(dataRef);
@@ -1750,28 +1864,39 @@ get_plainrsa_fromlocal(iph1, my)
        int error = -1;
 
        iph1->rsa_candidates = rsa_lookup_keys(iph1, my);
-       if (!iph1->rsa_candidates || rsa_list_count(iph1->rsa_candidates) == 0) {
+       if (!iph1->rsa_candidates || 
+           rsa_list_count(iph1->rsa_candidates) == 0) {
                plog(LLV_ERROR, LOCATION, NULL,
                        "%s RSA key not found for %s\n",
                        my ? "Private" : "Public",
-                       saddr2str_fromto("%s <-> %s", iph1->local, iph1->remote));
+                       saddr2str_fromto("%s <-> %s", 
+                       iph1->local, iph1->remote));
                goto end;
        }
 
        if (my && rsa_list_count(iph1->rsa_candidates) > 1) {
                plog(LLV_WARNING, LOCATION, NULL,
-                       "More than one (=%lu) private PlainRSA key found for %s\n",
+                       "More than one (=%lu) private "
+                       "PlainRSA key found for %s\n",
                        rsa_list_count(iph1->rsa_candidates),
-                       saddr2str_fromto("%s <-> %s", iph1->local, iph1->remote));
+                       saddr2str_fromto("%s <-> %s", 
+                       iph1->local, iph1->remote));
                plog(LLV_WARNING, LOCATION, NULL,
-                       "This may have unpredictable results, i.e. wrong key could be used!\n");
+                       "This may have unpredictable results, "
+                       "i.e. wrong key could be used!\n");
                plog(LLV_WARNING, LOCATION, NULL,
-                       "Consider using only one single private key for all peers...\n");
+                       "Consider using only one single private "
+                       "key for all peers...\n");
        }
        if (my) {
-               iph1->rsa = ((struct rsa_key *)genlist_next(iph1->rsa_candidates, NULL))->rsa;
+               iph1->rsa = ((struct rsa_key *)
+                   genlist_next(iph1->rsa_candidates, NULL))->rsa;
+
                genlist_free(iph1->rsa_candidates, NULL);
                iph1->rsa_candidates = NULL;
+
+               if (iph1->rsa == NULL)
+                       goto end;
        }
 
        error = 0;
@@ -1791,12 +1916,12 @@ oakley_getsign(iph1)
 
        switch (iph1->rmconf->certtype) {
        case ISAKMP_CERT_X509SIGN:
-#ifdef __APPLE__
+#if defined(__APPLE__)
                // cert in keychain - use cssm to sign
                if (iph1->rmconf->identity_in_keychain) {
                        CFDataRef dataRef;
                        
-                       if (base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
+                       if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
                                goto end;
                        iph1->sig = crypto_cssm_getsign(dataRef, iph1->hash);
                        CFRelease(dataRef);
@@ -2121,7 +2246,9 @@ oakley_check_certid(iph1)
                vfree(name);
                if (error != 0) {
                        plog(LLV_ERROR, LOCATION, NULL,
-                               "ID mismatched with subjectAltName.\n");
+                               "ID mismatched with ASN1 SubjectName.\n");
+                       plogdump(LLV_DEBUG, id_b + 1, idlen);
+                       plogdump(LLV_DEBUG, name->v, idlen);
                        return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
                }
                return 0;
@@ -2192,6 +2319,8 @@ oakley_check_certid(iph1)
                if (error != 0) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "ID mismatched with subjectAltName.\n");
+                       plogdump(LLV_DEBUG, id_b + 1, idlen);
+                       plogdump(LLV_DEBUG, a, idlen);
                        return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
                }
                return 0;
@@ -2240,6 +2369,8 @@ oakley_check_certid(iph1)
                error = memcmp(id_b + 1, altname, idlen);
                if (error) {
                        plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
+                       plogdump(LLV_DEBUG, id_b + 1, idlen);
+                       plogdump(LLV_DEBUG, altname, idlen);
                        racoon_free(altname);
                        return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
                }
@@ -2538,6 +2669,12 @@ save_certbuf(gen)
 {
        cert_t *new;
 
+       if(ntohs(gen->len) <= sizeof(*gen)){
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "Len is too small !!.\n");
+               return NULL;
+       }
+
        new = oakley_newcert();
        if (!new) {
                plog(LLV_ERROR, LOCATION, NULL,
@@ -2613,10 +2750,15 @@ oakley_getcr(iph1)
                        "failed to get cr buffer\n");
                return NULL;
        }
-       buf->v[0] = iph1->rmconf->certtype;
-
-       plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
+       if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) {
+               buf->v[0] = iph1->rmconf->cacerttype;
+               plog(LLV_DEBUG, LOCATION, NULL, "create my CR: NONE, using %s instead\n",
+               s_isakmp_certtype(iph1->rmconf->cacerttype));
+       } else {
+               buf->v[0] = iph1->rmconf->certtype;
+               plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
                s_isakmp_certtype(iph1->rmconf->certtype));
+       }
        if (buf->l > 1)
                plogdump(LLV_DEBUG, buf->v, buf->l);
 
@@ -2660,6 +2802,10 @@ oakley_needcr(type)
 #ifdef ENABLE_HYBRID
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
 #endif
                return 1;
        default:
@@ -2685,8 +2831,12 @@ oakley_skeyid(iph1)
        int error = -1;
 
        /* SKEYID */
-       switch(iph1->approval->authmethod) {
+       switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+#ifdef ENABLE_HYBRID
+       case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+#endif
 #ifdef __APPLE__
        if (iph1->rmconf->shared_secret) {
 
@@ -2695,6 +2845,7 @@ oakley_skeyid(iph1)
                                        /* in psk file - use KEY from remote configuration to locate it */
                                        iph1->authstr = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1);
                                        break;
+#if HAVE_KEYCHAIN
                                case SECRETTYPE_KEYCHAIN:
                                        /* in the system keychain */
                                        iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, NULL);
@@ -2703,6 +2854,7 @@ oakley_skeyid(iph1)
                                        /* in the system keychain - use peer id */
                                        iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, iph1->id_p);
                                        break;
+#endif HAVE_KEYCHAIN
                                case SECRETTYPE_USE:
                                        /* in the remote configuration */
                                default:
@@ -2778,6 +2930,10 @@ oakley_skeyid(iph1)
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
        case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
 #endif
 #ifdef HAVE_GSSAPI
        case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
@@ -2809,6 +2965,12 @@ oakley_skeyid(iph1)
                break;
        case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
        case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+#ifdef ENABLE_HYBRID
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+#endif
                plog(LLV_WARNING, LOCATION, NULL,
                        "not supported authentication method %s\n",
                        s_oakley_attr_method(iph1->approval->authmethod));
@@ -2878,7 +3040,7 @@ oakley_skeyid_dae(iph1)
        buf = NULL;
 
        plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n");
-       plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid->l);
+       plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l);
 
        /* SKEYID A */
        /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
@@ -3191,6 +3353,9 @@ oakley_newiv(iph1)
        plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n");
        plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
 
+       if (iph1->ivm != NULL)
+               oakley_delivm(iph1->ivm);
+
        iph1->ivm = newivm;
 
        return 0;
@@ -3290,6 +3455,7 @@ oakley_delivm(ivm)
        if (ivm->ive != NULL)
                vfree(ivm->ive);
        racoon_free(ivm);
+       plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n");
 
        return;
 }
index 66edfefa88db283ac151f56054312d658ff346cc..5916b16fc711455739215f9ccd0063c2f91d0a35 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: oakley.h,v 1.9 2004/10/24 17:37:00 manubsd Exp $ */
+/*     $NetBSD: oakley.h,v 1.5 2006/10/06 12:02:27 manu Exp $  */
+
+/* Id: oakley.h,v 1.13 2005/05/30 20:12:43 fredsen Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -73,7 +75,7 @@
 
                                        /*      65001 - 65535 Private Use */
 
-        /* Plain Xauth, Not implemented */
+        /* Plain Xauth */
 #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I  65001
 #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R  65002
 #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I 65003
 #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R 65010
 #endif
 
+                                       /*      65500 -> still private
+                                        * to avoid clash with GSSAPI_KRB below 
+                                        */
+#define FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I      65500
+
+
        /*
         * The following are valid when the Vendor ID is one of
         * the following:
@@ -215,4 +223,20 @@ extern vchar_t *oakley_do_decrypt __P((struct ph1handle *,
 extern vchar_t *oakley_do_encrypt __P((struct ph1handle *,
        vchar_t *, vchar_t *, vchar_t *));
 
+#ifdef ENABLE_HYBRID
+#define AUTHMETHOD(iph1)                                                    \
+    (((iph1)->rmconf->xauth &&                                              \
+    (iph1)->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ? \
+       FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I : (iph1)->approval->authmethod)
+#define RMAUTHMETHOD(iph1)                                                  \
+    (((iph1)->rmconf->xauth &&                                              \
+    (iph1)->rmconf->proposal->authmethod ==                                  \
+       OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ?                             \
+       FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I :                                  \
+       (iph1)->rmconf->proposal->authmethod)
+#else
+#define AUTHMETHOD(iph1) (iph1)->approval->authmethod
+#define RMAUTHMETHOD(iph1) (iph1)->rmconf->proposal->authmethod
+#endif /* ENABLE_HYBRID */
+
 #endif /* _OAKLEY_H */
index 63d749853c5dcad077d018ef76c9e60165060fc9..f434b807defb26cfca5bdc0cff07778373ba2741 100644 (file)
@@ -32,6 +32,8 @@
 #ifndef _PFKEY_H
 #define _PFKEY_H
 
+#include "ike_session.h"
+
 struct pfkey_satype {
        u_int8_t        ps_satype;
        const char      *ps_name;
@@ -58,6 +60,8 @@ extern int pk_sendeacquire __P((struct ph2handle *));
 extern int pk_sendspdupdate2 __P((struct ph2handle *));
 extern int pk_sendspdadd2 __P((struct ph2handle *));
 extern int pk_sendspddelete __P((struct ph2handle *));
+extern int pk_sendget_inbound_sastats __P((ike_session_t *));
+extern int pk_sendget_outbound_sastats __P((ike_session_t *));
 
 extern void pfkey_timeover_stub __P((void *));
 extern void pfkey_timeover __P((struct ph2handle *));
index 03e70b4394f9f634a8b4d79b469525c337b63b14..390cb197a25bcaa3dd7eb8e8839a48ee1cca1a62 100644 (file)
 #include "grabmyaddr.h"
 #include "vpn_control.h"
 #include "vpn_control_var.h"
+#include "ike_session.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
 
 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
 #define SADB_X_EALG_AESCBC  SADB_X_EALG_RIJNDAELCBC
@@ -133,6 +136,7 @@ static int pk_recvspdexpire __P((caddr_t *));
 static int pk_recvspdget __P((caddr_t *));
 static int pk_recvspddump __P((caddr_t *));
 static int pk_recvspdflush __P((caddr_t *));
+static int pk_recvgetsastat __P((caddr_t *));
 static struct sadb_msg *pk_recv __P((int, int *));
 
 static int (*pkrecvf[]) __P((caddr_t *)) = {
@@ -159,9 +163,10 @@ pk_recvspdflush,
 NULL,  /* SADB_X_SPDSETIDX */
 pk_recvspdexpire,
 NULL,  /* SADB_X_SPDDELETE2 */
+pk_recvgetsastat, /* SADB_GETSASTAT */
 NULL,  /* SADB_X_NAT_T_NEW_MAPPING */
 NULL, /* SADB_X_MIGRATE */
-#if (SADB_MAX > 24)
+#if (SADB_MAX > 25)
 #error "SADB extra message?"
 #endif
 };
@@ -191,7 +196,6 @@ static int addnewsp __P((caddr_t *));
 #endif
 #endif
 
-       
 int
 pfkey_process(msg)
        struct sadb_msg *msg;
@@ -1001,6 +1005,19 @@ pk_recvgetspi(mhp)
                return -1;
        }
 
+    // check the underlying iph2->ph1
+    if (!iph2->ph1) {
+        if (!ike_session_update_ph2_ph1bind(iph2)) {
+            plog(LLV_ERROR, LOCATION, NULL,
+                 "can't proceed with getspi for  %s. no suitable ISAKMP-SA found \n",
+                 saddrwop2str(iph2->dst));
+            unbindph12(iph2);
+            remph2(iph2);
+            delph2(iph2);
+            return -1;
+        }
+    }
+
        /* set SPI, and check to get all spi whether or not */
        allspiok = 1;
        notfound = 1;
@@ -1026,6 +1043,9 @@ pk_recvgetspi(mhp)
                plog(LLV_ERROR, LOCATION, NULL,
                        "get spi for unknown address %s\n",
                        saddrwop2str(iph2->dst));
+        unbindph12(iph2);
+        remph2(iph2);
+        delph2(iph2);
                return -1;
        }
 
@@ -1129,8 +1149,10 @@ pk_sendupdate(iph2)
                        memset (&natt, 0, sizeof (natt));
                        natt.sport = extract_port (iph2->ph1->remote);
                        flags |= SADB_X_EXT_NATT;
-                       if (iph2->ph1->natt_flags & NAT_DETECTED_ME)
-                               flags |= SADB_X_EXT_NATT_KEEPALIVE;
+                       if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
+                               if (iph2->ph1->rmconf->natt_keepalive == TRUE)
+                                       flags |= SADB_X_EXT_NATT_KEEPALIVE;
+                       }
                        else if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
                                mode == IPSEC_MODE_TRANSPORT &&
                                src->sa_family == AF_INET)
@@ -1370,6 +1392,20 @@ pk_recvupdate(mhp)
        /* update status */
        iph2->status = PHASE2ST_ESTABLISHED;
 
+       if (iph2->side == INITIATOR) {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC,
+                                                               CONSTSTR("Initiator, Quick-Mode"),
+                                                               CONSTSTR(NULL));
+       } else {
+               IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                                               IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC,
+                                                               CONSTSTR("Responder, Quick-Mode"),
+                                                               CONSTSTR(NULL));
+       }
+
+       ike_session_ph2_established(iph2);
+
 #ifdef ENABLE_STATS
        gettimeofday(&iph2->end, NULL);
        syslog(LOG_NOTICE, "%s(%s): %8.6f",
@@ -1480,8 +1516,10 @@ pk_sendadd(iph2)
                        memset (&natt, 0, sizeof (natt));
                        natt.dport = extract_port (iph2->ph1->remote);
                        flags |= SADB_X_EXT_NATT;
-                       if (iph2->ph1->natt_flags & NAT_DETECTED_ME)
-                               flags |= SADB_X_EXT_NATT_KEEPALIVE;
+                       if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
+                               if (iph2->ph1->rmconf->natt_keepalive == TRUE)
+                                       flags |= SADB_X_EXT_NATT_KEEPALIVE;
+                       }
                        else if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
                                mode == IPSEC_MODE_TRANSPORT &&
                                dst->sa_family == AF_INET)
@@ -1696,6 +1734,8 @@ pk_recvadd(mhp)
                sadbsecas2str(iph2->src, iph2->dst,
                        msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
                        
+       ike_session_cleanup_other_established_ph2s(iph2->parent_session, iph2);
+       
 #ifdef ENABLE_VPNCONTROL_PORT
                {
                        u_int32_t address;
@@ -1788,9 +1828,10 @@ pk_recvexpire(mhp)
 
        iph2->status = PHASE2ST_EXPIRED;
 
-       /* INITIATOR, begin phase 2 exchange. */
+       /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
        /* allocate buffer for status management of pfkey message */
-       if (iph2->side == INITIATOR) {
+       if (iph2->side == INITIATOR &&
+               !ike_session_has_other_established_ph2(iph2->parent_session, iph2)) {
 
                initph2(iph2);
 
@@ -1801,7 +1842,7 @@ pk_recvexpire(mhp)
                if (isakmp_post_acquire(iph2) < 0) {
                        plog(LLV_ERROR, LOCATION, iph2->dst,
                                "failed to begin ipsec sa "
-                               "re-negotication.\n");
+                               "re-negotiation.\n");
                        unbindph12(iph2);
                        remph2(iph2);
                        delph2(iph2);
@@ -1912,8 +1953,8 @@ pk_recvacquire(mhp)
         *       should ignore such a acquire message because the phase 2
         *       is just negotiating.
         *    2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
-        *       has to prcesss such a acquire message because racoon may
-        *       lost the expire message.
+        *       has to process such a acquire message because racoon may
+        *       have lost the expire message.
         */
        iph2[0] = getph2byid(src, dst, xpl->sadb_x_policy_id);
        if (iph2[0] != NULL) {
@@ -2025,6 +2066,15 @@ pk_recvacquire(mhp)
                return -1;
                /* XXX should use the algorithm list from register message */
        }
+#ifdef __APPLE__
+               if (link_sainfo_to_ph2(iph2[n]->sainfo) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "failed to link sainfo\n");
+                       iph2[n]->sainfo = NULL;
+                       delph2(iph2[n]);
+                       return -1;
+               }
+#endif
     }
 
        if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) {
@@ -2039,10 +2089,19 @@ pk_recvacquire(mhp)
        /* XXX should be looped if there are multiple phase 2 handler. */
        if (isakmp_post_acquire(iph2[n]) < 0) {
                plog(LLV_ERROR, LOCATION, NULL,
-                       "failed to begin ipsec sa negotication.\n");
+                       "failed to begin ipsec sa negotiation.\n");
                goto err;
        }
+       
+#if !TARGET_OS_EMBEDDED
+       if ( lcconf->vt == NULL){
+               if (!(lcconf->vt = vproc_transaction_begin(NULL)))
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "vproc_transaction_begin returns NULL.\n");
+       }
+#endif                         
 
+       
        return 0;
 
 err:
@@ -2072,7 +2131,6 @@ pk_recvdelete(mhp)
 
        /* sanity check */
        if (mhp[0] == NULL
-        || mhp[SADB_EXT_SA] == NULL
         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
         || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
                plog(LLV_ERROR, LOCATION, NULL,
@@ -2100,6 +2158,16 @@ pk_recvdelete(mhp)
                return -1;
        }
 
+    plog(LLV_DEBUG2, LOCATION, NULL, "SADB delete message: proto-id %d\n", proto_id);
+    plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
+    plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst));
+    
+    if (!sa) {
+        deleteallph2(src, dst, proto_id);
+        deleteallph1(src, dst);
+        return 0;
+    }
+
        iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
        if (iph2 == NULL) {
                /* ignore */
@@ -2119,6 +2187,7 @@ pk_recvdelete(mhp)
        if (iph2->status == PHASE2ST_ESTABLISHED)
                isakmp_info_send_d2(iph2);
 
+       ike_session_cleanup_ph1s_by_ph2(iph2);
        unbindph12(iph2);
        remph2(iph2);
        delph2(iph2);
@@ -2141,7 +2210,8 @@ pk_recvflush(mhp)
                return -1;
        }
 
-       flushph2();
+       flushph2(false);
+       flushph1(false);
 
        return 0;
 }
@@ -2543,6 +2613,8 @@ pk_recvspddelete(mhp)
                return -1;
        }
 
+    purgephXbyspid(xpl->sadb_x_policy_id, true);
+
        remsp(sp);
        delsp(sp);
 
@@ -2598,6 +2670,8 @@ pk_recvspdexpire(mhp)
                return -1;
        }
 
+    purgephXbyspid(xpl->sadb_x_policy_id, false);
+
        remsp(sp);
        delsp(sp);
 
@@ -2692,6 +2766,8 @@ pk_recvspdflush(mhp)
                return -1;
        }
 
+    flushph2(false);
+    flushph1(false);
        flushsp();
 
        return 0;
@@ -2733,6 +2809,145 @@ pk_sendeacquire(iph2)
        return 0;
 }
 
+int
+pk_sendget_inbound_sastats(ike_session_t *session)
+{
+    u_int32_t max_stats;
+    u_int32_t seq;
+
+    if (!session) {
+        plog(LLV_DEBUG, LOCATION, NULL, "invalid args in %s \n", __FUNCTION__);
+        return -1;
+    }
+
+    session->traffic_monitor.num_in_curr_req = 0;
+    bzero(session->traffic_monitor.in_curr_req, sizeof(session->traffic_monitor.in_curr_req));
+    max_stats = (sizeof(session->traffic_monitor.in_curr_req) / sizeof(session->traffic_monitor.in_curr_req[0]));
+
+    // get list of SAs
+    if ((session->traffic_monitor.num_in_curr_req = ike_session_get_sas_for_stats(session,
+                                                                                  IPSEC_DIR_INBOUND,
+                                                                                  &seq,
+                                                                                  session->traffic_monitor.in_curr_req,
+                                                                                  max_stats))) {
+        u_int64_t session_ids[] = {(u_int64_t)session, 0};
+
+        plog(LLV_DEBUG, LOCATION, NULL, "about to call %s\n", __FUNCTION__);
+
+        if (pfkey_send_getsastats(lcconf->sock_pfkey,
+                                  seq,
+                                  session_ids,
+                                  1,
+                                  IPSEC_DIR_INBOUND,
+                                  session->traffic_monitor.in_curr_req,
+                                  session->traffic_monitor.num_in_curr_req) < 0) {
+            return -1;
+        }
+        plog(LLV_DEBUG, LOCATION, NULL, "%s successful\n", __FUNCTION__);
+
+        return session->traffic_monitor.num_in_curr_req;
+    }
+    return 0;
+}
+
+int
+pk_sendget_outbound_sastats(ike_session_t *session)
+{
+    u_int32_t max_stats;
+    u_int32_t seq;
+    
+    if (!session) {
+        plog(LLV_DEBUG, LOCATION, NULL, "invalid args in %s \n", __FUNCTION__);
+        return -1;
+    }
+    
+    session->traffic_monitor.num_out_curr_req = 0;
+    bzero(session->traffic_monitor.out_curr_req, sizeof(session->traffic_monitor.out_curr_req));
+    max_stats = (sizeof(session->traffic_monitor.out_curr_req) / sizeof(session->traffic_monitor.out_curr_req[0]));
+
+    // get list of SAs
+    if ((session->traffic_monitor.num_out_curr_req = ike_session_get_sas_for_stats(session,
+                                                                                   IPSEC_DIR_OUTBOUND,
+                                                                                   &seq,
+                                                                                   session->traffic_monitor.out_curr_req,
+                                                                                   max_stats))) {
+        u_int64_t session_ids[] = {(u_int64_t)session, 0};
+        
+        plog(LLV_DEBUG, LOCATION, NULL, "about to call %s\n", __FUNCTION__);
+        
+        if (pfkey_send_getsastats(lcconf->sock_pfkey,
+                                  seq,
+                                  session_ids,
+                                  1,
+                                  IPSEC_DIR_OUTBOUND,
+                                  session->traffic_monitor.out_curr_req,
+                                  session->traffic_monitor.num_out_curr_req) < 0) {
+            return -1;
+        }
+        plog(LLV_DEBUG, LOCATION, NULL, "%s successful\n", __FUNCTION__);
+        
+        return session->traffic_monitor.num_out_curr_req;
+    }
+    return 0;
+}
+
+/*
+ * receive GETSPDSTAT from kernel.
+ */
+static int
+pk_recvgetsastat(mhp) 
+caddr_t *mhp;
+{
+       struct sadb_msg        *msg;
+    struct sadb_session_id *session_id;
+    struct sadb_sastat     *stat_resp;
+       ike_session_t          *session;
+
+       /* validity check */
+       if (mhp[0] == NULL ||
+        mhp[SADB_EXT_SESSION_ID] == NULL ||
+        mhp[SADB_EXT_SASTAT] == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+             "inappropriate sadb getsastat response.\n");
+               return -1;
+       }
+       msg = (struct sadb_msg *)mhp[0];
+    session_id = (ike_session_t *)mhp[SADB_EXT_SESSION_ID];
+       stat_resp = (struct sadb_sastat *)mhp[SADB_EXT_SASTAT];
+
+       /* the message has to be processed or not ? */
+       if (msg->sadb_msg_pid != getpid()) {
+               plog(LLV_DEBUG, LOCATION, NULL,
+             "%s message is not interesting "
+             "because pid %d is not mine.\n",
+             s_pfkey_type(msg->sadb_msg_type),
+             msg->sadb_msg_pid);
+               return -1;
+       }
+    if (!session_id->sadb_session_id_v[0]) {
+               plog(LLV_DEBUG, LOCATION, NULL,
+             "%s message is bad "
+             "because session-id[0] is invalid.\n",
+             s_pfkey_type(msg->sadb_msg_type));
+        return -1;
+    }
+    session = (__typeof__(session))session_id->sadb_session_id_v[0];
+
+    if (!stat_resp->sadb_sastat_list_len) {
+               plog(LLV_DEBUG, LOCATION, NULL,
+             "%s message is bad "
+             "because it has no sastats.\n",
+             s_pfkey_type(msg->sadb_msg_type));
+        return -1;
+    }
+
+    ike_session_update_traffic_idle_status(session,
+                                           stat_resp->sadb_sastat_dir,
+                                           (struct sastat *)(stat_resp + 1),
+                                           stat_resp->sadb_sastat_list_len);
+       return 0;
+}
+
 /*
  * check if the algorithm is supported or not.
  * OUT  0: ok
@@ -2793,8 +3008,8 @@ pk_checkalg(class, calg, keylen)
  */
 static struct sadb_msg *
 pk_recv(so, lenp)
-int so;
-int *lenp;
+       int so;
+       int *lenp;
 {
        struct sadb_msg *newmsg;
        int reallen = 0; 
@@ -2805,10 +3020,10 @@ int *lenp;
        
        if (reallen == 0)
                return NULL;
-       
+
        if ((newmsg = racoon_calloc(1, reallen)) == NULL)
                return NULL;
-       
+
        *lenp = recv(so, (caddr_t)newmsg, reallen, 0);
        if (*lenp < 0) {
                racoon_free(newmsg);
@@ -2817,12 +3032,10 @@ int *lenp;
                racoon_free(newmsg);
                return NULL;
        }
-       
+
        return newmsg;
 }
 
-
-
 /* see handler.h */
 u_int32_t
 pk_getseq()
index 974f3cbc347a199298c439b462fcb27b422c7a4b..92bfdfb68a136322b05d07723b2c5cf451a81a6a 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: plainrsa-gen.c,v 1.4.8.2 2005/04/21 09:07:20 monas Exp $ */
+/*     $NetBSD: plainrsa-gen.c,v 1.4 2006/09/09 16:22:10 manu Exp $    */
+
+/* Id: plainrsa-gen.c,v 1.6 2005/04/21 09:08:40 monas Exp */
 /*
  * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
  * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs
@@ -64,8 +66,7 @@ int print_pid = 0;
 void
 usage (char *argv0)
 {
-       //%%% fprintf(stderr, "Plain RSA key generator, part of %s\n", TOP_PACKAGE_STRING);
-       fprintf(stderr, "Plain RSA key generator\n");
+//     fprintf(stderr, "Plain RSA key generator, part of %s\n", TOP_PACKAGE_STRING);
        fprintf(stderr, "By Michal Ludvig (http://www.logix.cz/michal)\n");
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: %s [options]\n", argv0);
index 6b00980db2d2f4f79626e44ee61476cc5329ea90..0bfae4cd33c352ab06c5c0634a4afc6b9d25a801 100644 (file)
@@ -64,7 +64,7 @@
 #include "gcmalloc.h"
 
 #ifndef VA_COPY
-# define VA_COPY(dst,src) memcpy(&(dst), &(src), sizeof(va_list))
+# define VA_COPY(dst,src) memcpy(&(dst), (src), sizeof(va_list))
 #endif
 
 extern int print_pid;
@@ -147,13 +147,13 @@ plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...)
        va_list ap;
 
        va_start(ap, fmt);
-       plogv(pri, func, sa, fmt, ap);
+       plogv(pri, func, sa, fmt, &ap);
        va_end(ap);
 }
 
 void
 plogv(int pri, const char *func, struct sockaddr *sa,
-       const char *fmt, va_list ap)
+       const char *fmt, va_list *ap)
 {
        char *newfmt;
        va_list ap_bak;
@@ -166,7 +166,7 @@ plogv(int pri, const char *func, struct sockaddr *sa,
        VA_COPY(ap_bak, ap);
        
        if (f_foreground)
-               vprintf(newfmt, ap);
+               vprintf(newfmt, *ap);
 
        if (logfile)
                log_vaprint(logp, newfmt, ap_bak);
@@ -239,7 +239,8 @@ plogset(file)
 {
        if (logfile != NULL)
                racoon_free(logfile);
-       logfile = strdup(file);
+       logfile = racoon_strdup(file);
+       STRDUP_FATAL(logfile);
 }
 
 void
@@ -266,5 +267,29 @@ plogreset(file)
        if (file)
                plogset(file);
        ploginit();
-}                      
-                       
+}              
+
+/*
+   Returns a printable string from (possibly) binary data ;
+   concatenates all unprintable chars to one space.
+   XXX Maybe the printable chars range is too large...
+ */
+char*
+binsanitize(binstr, n)
+       char *binstr;
+       size_t n;
+{
+       int p,q;
+       char* d;
+       for (p = 0, q = 0; p < n; p++) {
+                 if (isgraph((int)binstr[p])) {
+                       binstr[q++] = binstr[p];
+               } else {
+                       if (q && binstr[q - 1] != ' ')
+                                binstr[q++] = ' ';
+               }
+       }
+       binstr[q++] = '\0';
+       return binstr;
+}
+       
index d1448dfa23c7afc7d85bddb9478e6f2d19b3d7e7..8b5a35415097be0672685a7d93e173bf2e95cb1c 100644 (file)
@@ -69,10 +69,11 @@ struct sockaddr;
 extern void plog __P((int, const char *, struct sockaddr *, const char *, ...))
        __attribute__ ((__format__ (__printf__, 4, 5)));
 extern void plogv __P((int, const char *, struct sockaddr *,
-       const char *, va_list));
+       const char *, va_list *));
 extern void plogdump __P((int, void *, size_t));
 extern void ploginit __P((void));
 extern void plogset __P((char *));
-extern void plogreset __P((char *));
+
+extern char* binsanitize __P((char*, size_t));
 
 #endif /* _PLOG_H */
index d553d267475e6198af33e772ba0a089e130f0ca2..82d698155b5770ba5f2f90ccdbfbcc5c133ca274 100644 (file)
@@ -383,7 +383,7 @@ inssp(new)
        }
        if (p == NULL)
 #endif
-               TAILQ_INSERT_TAIL(&sptree, new, chain);
+               TAILQ_INSERT_HEAD(&sptree, new, chain);
 
        check_auto_exit();
        return;
index 8dc4fd1036ba52916a9e4c2efb7f563dd9ac8434..d343bbfa2463ae13bfb2132065a6433dabc755b5 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: privsep.c,v 1.6.2.7 2005/08/08 11:25:01 vanhu Exp $ */
+/*     $NetBSD: privsep.c,v 1.6 2006/09/09 16:22:10 manu Exp $ */
+
+/* Id: privsep.c,v 1.15 2005/08/08 11:23:44 vanhu Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
 #include "isakmp_var.h"
 #include "isakmp.h"
 #ifdef ENABLE_HYBRID
+#include "resolv.h"
 #include "isakmp_xauth.h"
 #include "isakmp_cfg.h"
 #endif
 #include "localconf.h"
 #include "remoteconf.h"
 #include "admin.h"
+#include "sockmisc.h"
 #include "privsep.h"
 
 static int privsep_sock[2] = { -1, -1 };
@@ -67,14 +71,10 @@ static int privsep_sock[2] = { -1, -1 };
 static int privsep_recv(int, struct privsep_com_msg **, size_t *);
 static int privsep_send(int, struct privsep_com_msg *, size_t);
 static int safety_check(struct privsep_com_msg *, int i);
-#ifdef HAVE_LIBPAM
 static int port_check(int);
-#endif
 static int unsafe_env(char *const *);
 static int unknown_name(int);
-static int unknown_script(int);
 static int unsafe_path(char *, int);
-static char *script_name2path(int);
 
 static int
 privsep_send(sock, buf, len)
@@ -179,7 +179,7 @@ privsep_init(void)
        if ((lcconf->pathinfo[LC_PATHTYPE_CERT] == NULL) ||
            (lcconf->pathinfo[LC_PATHTYPE_SCRIPT] == NULL)) {
                plog(LLV_ERROR, LOCATION, NULL, "privilege separation "
-                   "require path cert and path script in the config file\n");
+                  "require path cert and path script in the config file\n");
                return -1;
        }
 
@@ -333,7 +333,7 @@ privsep_init(void)
                 * stuff eay_get_pkcs1privkey and eay_get_x509sign
                 * together and sign the hash in the privilegied 
                 * instance? 
-                * pro: the key remains inaccessibleato
+                * pro: the key remains inaccessible to unpriv
                 * con: a compromised unpriv racoon can still sign anything
                 */
                case PRIVSEP_EAY_GET_PKCS1PRIVKEY: {
@@ -345,11 +345,14 @@ privsep_init(void)
                        bufs[0][combuf->bufs.buflen[0] - 1] = '\0';
 
                        if (unsafe_path(bufs[0], LC_PATHTYPE_CERT) != 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(LLV_ERROR, LOCATION, NULL, 
                                    "privsep_eay_get_pkcs1privkey: "
-                                   "unsafe key \"%s\"\n", bufs[0]);
+                                   "unsafe cert \"%s\"\n", bufs[0]);
                        }
 
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "eay_get_pkcs1privkey(\"%s\")\n", bufs[0]);
+
                        if ((privkey = eay_get_pkcs1privkey(bufs[0])) == NULL){
                                reply->hdr.ac_errno = errno;
                                break;
@@ -371,7 +374,7 @@ privsep_init(void)
                }
                
                case PRIVSEP_SCRIPT_EXEC: {
-                       int script;
+                       char *script;
                        int name;
                        char **envp = NULL;
                        int envc = 0;
@@ -384,6 +387,9 @@ privsep_init(void)
                         *
                         * We expect: script, name, envp[], void
                         */ 
+                       if (safety_check(combuf, 0) != 0)
+                               break;
+                       bufs[0][combuf->bufs.buflen[0] - 1] = '\0';
                        count++;        /* script */
                        count++;        /* name */
 
@@ -421,13 +427,7 @@ privsep_init(void)
                         * Populate script, name and envp 
                         */
                        count = 0;
-
-                       if (combuf->bufs.buflen[count] != sizeof(script)) {
-                               plog(LLV_ERROR, LOCATION, NULL, 
-                                   "privsep_script_exec: corrupted message\n");
-                               goto out;
-                       }
-                       memcpy((char *)&script, bufs[count++], sizeof(script));
+                       script = bufs[count++];
 
                        if (combuf->bufs.buflen[count] != sizeof(name)) {
                                plog(LLV_ERROR, LOCATION, NULL, 
@@ -441,6 +441,10 @@ privsep_init(void)
 
                        count++;                /* void */
 
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "script_exec(\"%s\", %d, %p)\n", 
+                           script, name, envp);
+
                        /* 
                         * Check env for dangerous variables
                         * Check script path and name
@@ -448,15 +452,12 @@ privsep_init(void)
                         */
                        if ((unsafe_env(envp) == 0) &&
                            (unknown_name(name) == 0) &&
-                           (unknown_script(script) == 0) &&
-                           (unsafe_path(script_name2path(script), 
-                           LC_PATHTYPE_SCRIPT) == 0))
+                           (unsafe_path(script, LC_PATHTYPE_SCRIPT) == 0))
                                (void)script_exec(script, name, envp);
                        else
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(LLV_ERROR, LOCATION, NULL, 
                                    "privsep_script_exec: "
-                                   "unsafe script \"%s\"\n", 
-                                   script_name2path(script));
+                                   "unsafe script \"%s\"\n", script);
 
                        racoon_free(envp);
                        break;
@@ -477,6 +478,10 @@ privsep_init(void)
                                goto out;
                        }
                        memcpy(&keylen, bufs[1], sizeof(keylen));
+
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "getpsk(\"%s\", %d)\n", bufs[0], keylen);
+
                        if ((psk = getpsk(bufs[0], keylen)) == NULL) {
                                reply->hdr.ac_errno = errno;
                                break;
@@ -498,6 +503,44 @@ privsep_init(void)
                }
 
 #ifdef ENABLE_HYBRID
+               case PRIVSEP_ACCOUNTING_SYSTEM: {
+                       int pool_size;
+                       int port;
+                       int inout;
+                       struct sockaddr *raddr;
+
+                       if (safety_check(combuf, 0) != 0)
+                               break;
+                       if (safety_check(combuf, 1) != 0)
+                               break;
+                       if (safety_check(combuf, 2) != 0)
+                               break;
+                       if (safety_check(combuf, 3) != 0)
+                               break;
+
+                       memcpy(&port, bufs[0], sizeof(port));
+                       raddr = (struct sockaddr *)bufs[1];
+
+                       bufs[2][combuf->bufs.buflen[2] - 1] = '\0';
+                       memcpy(&inout, bufs[3], sizeof(port));
+
+                       if (port_check(port) != 0)
+                               break;
+
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "accounting_system(%d, %s, %s)\n", 
+                           port, saddr2str(raddr), bufs[2]); 
+
+                       errno = 0;
+                       if (isakmp_cfg_accounting_system(port, 
+                           raddr, bufs[2], inout) != 0) {
+                               if (errno == 0)
+                                       reply->hdr.ac_errno = EINVAL;
+                               else
+                                       reply->hdr.ac_errno = errno;
+                       }
+                       break;
+               }
                case PRIVSEP_XAUTH_LOGIN_SYSTEM: {
                        if (safety_check(combuf, 0) != 0)
                                break;
@@ -507,6 +550,10 @@ privsep_init(void)
                                break;
                        bufs[1][combuf->bufs.buflen[1] - 1] = '\0';
 
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "xauth_login_system(\"%s\", <password>)\n", 
+                           bufs[0]);
+
                        errno = 0;
                        if (xauth_login_system(bufs[0], bufs[1]) != 0) {
                                if (errno == 0)
@@ -520,18 +567,30 @@ privsep_init(void)
                case PRIVSEP_ACCOUNTING_PAM: {
                        int port;
                        int inout;
+                       int pool_size;
 
                        if (safety_check(combuf, 0) != 0)
                                break;
                        if (safety_check(combuf, 1) != 0)
                                break;
+                       if (safety_check(combuf, 2) != 0)
+                               break;
 
                        memcpy(&port, bufs[0], sizeof(port));
                        memcpy(&inout, bufs[1], sizeof(inout));
+                       memcpy(&pool_size, bufs[2], sizeof(pool_size));
+
+                       if (pool_size != isakmp_cfg_config.pool_size)
+                               if (isakmp_cfg_resize_pool(pool_size) != 0)
+                                       break;
 
                        if (port_check(port) != 0)
                                break;
 
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "isakmp_cfg_accounting_pam(%d, %d)\n", 
+                           port, inout); 
+
                        errno = 0;
                        if (isakmp_cfg_accounting_pam(port, inout) != 0) {
                                if (errno == 0)
@@ -544,6 +603,7 @@ privsep_init(void)
 
                case PRIVSEP_XAUTH_LOGIN_PAM: {
                        int port;
+                       int pool_size;
                        struct sockaddr *raddr;
 
                        if (safety_check(combuf, 0) != 0)
@@ -554,19 +614,30 @@ privsep_init(void)
                                break;
                        if (safety_check(combuf, 3) != 0)
                                break;
+                       if (safety_check(combuf, 4) != 0)
+                               break;
 
                        memcpy(&port, bufs[0], sizeof(port));
-                       raddr = (struct sockaddr *)bufs[1];
+                       memcpy(&pool_size, bufs[1], sizeof(pool_size));
+                       raddr = (struct sockaddr *)bufs[2];
                        
-                       bufs[2][combuf->bufs.buflen[2] - 1] = '\0';
                        bufs[3][combuf->bufs.buflen[3] - 1] = '\0';
+                       bufs[4][combuf->bufs.buflen[4] - 1] = '\0';
+
+                       if (pool_size != isakmp_cfg_config.pool_size)
+                               if (isakmp_cfg_resize_pool(pool_size) != 0)
+                                       break;
 
                        if (port_check(port) != 0)
                                break;
 
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "xauth_login_pam(%d, %s, \"%s\", <password>)\n", 
+                           port, saddr2str(raddr), bufs[3]); 
+
                        errno = 0;
                        if (xauth_login_pam(port, 
-                           raddr, bufs[2], bufs[3]) != 0) {
+                           raddr, bufs[3], bufs[4]) != 0) {
                                if (errno == 0)
                                        reply->hdr.ac_errno = EINVAL;
                                else
@@ -577,15 +648,26 @@ privsep_init(void)
 
                case PRIVSEP_CLEANUP_PAM: {
                        int port;
+                       int pool_size;
 
                        if (safety_check(combuf, 0) != 0)
                                break;
+                       if (safety_check(combuf, 1) != 0)
+                               break;
 
                        memcpy(&port, bufs[0], sizeof(port));
+                       memcpy(&pool_size, bufs[1], sizeof(pool_size));
+
+                       if (pool_size != isakmp_cfg_config.pool_size)
+                               if (isakmp_cfg_resize_pool(pool_size) != 0)
+                                       break;
 
                        if (port_check(port) != 0)
                                break;
 
+                       plog(LLV_DEBUG, LOCATION, NULL, 
+                           "cleanup_pam(%d)\n", port);
+
                        cleanup_pam(port);
                        reply->hdr.ac_errno = 0;
 
@@ -695,7 +777,7 @@ privsep_pfkey_close(ps)
 
 int
 privsep_script_exec(script, name, envp)
-       int script;
+       char *script;
        int name;
        char *const envp[];
 {
@@ -745,7 +827,7 @@ privsep_script_exec(script, name, envp)
         * Compute the length
         */
        count = 0;
-       msg->bufs.buflen[count] = sizeof(script);       /* script */
+       msg->bufs.buflen[count] = strlen(script) + 1;   /* script */
        msg->hdr.ac_len += msg->bufs.buflen[count++];
 
        msg->bufs.buflen[count] = sizeof(name);         /* name */
@@ -771,7 +853,7 @@ privsep_script_exec(script, name, envp)
        data = (char *)(msg + 1);
        count = 0;
 
-       memcpy(data, (char *)&script, msg->bufs.buflen[count]); /* script */
+       memcpy(data, (char *)script, msg->bufs.buflen[count]);  /* script */
        data += msg->bufs.buflen[count++];
 
        memcpy(data, (char *)&name, msg->bufs.buflen[count]);   /* name */
@@ -903,9 +985,73 @@ privsep_xauth_login_system(usr, pwd)
        racoon_free(msg);
        return 0;
 }
-#endif /* ENABLE_HYBRID */
 
-#ifdef HAVE_LIBPAM
+int 
+privsep_accounting_system(port, raddr, usr, inout)
+       int port;
+       struct sockaddr *raddr;
+       char *usr;
+       int inout;
+{
+       struct privsep_com_msg *msg;
+       size_t len;
+       char *data;
+       int result;
+
+       if (geteuid() == 0)
+               return isakmp_cfg_accounting_system(port, raddr,
+                                                   usr, inout);
+
+       len = sizeof(*msg) 
+           + sizeof(port)
+           + sysdep_sa_len(raddr) 
+           + strlen(usr) + 1
+           + sizeof(inout);
+
+       if ((msg = racoon_malloc(len)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL, 
+                   "Cannot allocate memory: %s\n", strerror(errno));
+               return -1;
+       }
+       bzero(msg, len);
+       msg->hdr.ac_cmd = PRIVSEP_ACCOUNTING_SYSTEM;
+       msg->hdr.ac_len = len;
+       msg->bufs.buflen[0] = sizeof(port);
+       msg->bufs.buflen[1] = sysdep_sa_len(raddr);
+       msg->bufs.buflen[2] = strlen(usr) + 1;
+       msg->bufs.buflen[3] = sizeof(inout);
+
+       data = (char *)(msg + 1);
+       memcpy(data, &port, msg->bufs.buflen[0]);
+
+       data += msg->bufs.buflen[0];
+       memcpy(data, raddr, msg->bufs.buflen[1]);
+
+       data += msg->bufs.buflen[1];
+       memcpy(data, usr, msg->bufs.buflen[2]);
+
+       data += msg->bufs.buflen[2];
+       memcpy(data, &inout, msg->bufs.buflen[3]);
+
+       if (privsep_send(privsep_sock[1], msg, len) != 0)
+               return -1;
+
+       if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
+               return -1;
+
+       if (msg->hdr.ac_errno != 0) {
+               errno = msg->hdr.ac_errno;
+               goto out;
+       }
+
+       racoon_free(msg);
+       return 0;
+
+out:
+       racoon_free(msg);
+       return -1;
+}
+
 static int
 port_check(port)
        int port;
@@ -967,10 +1113,10 @@ found:
        return -1;
 }
 
-/*                       
- * Check path safety     
- */                     
-static int                  
+/*
+ * Check path safety
+ */
+static int 
 unsafe_path(script, pathtype)
        char *script;
        int pathtype;
@@ -979,8 +1125,8 @@ unsafe_path(script, pathtype)
        char rpath[MAXPATHLEN + 1];
        size_t len;
 
-       if (script == NULL)
-               return -1; 
+       if (script == NULL) 
+               return -1;
 
        path = lcconf->pathinfo[pathtype];
 
@@ -1001,45 +1147,6 @@ unsafe_path(script, pathtype)
        return 0;
 }
 
-static char *
-script_name2path(name)
-       int name;
-{
-       vchar_t **sp;
-
-       if (script_paths == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "script_name2path: script_paths was not initialized\n");
-               return NULL;
-       }
-
-       sp = (vchar_t **)(script_paths->v);
-
-       return sp[name]->v;
-}
-
-/*
- * Check the script path index is correct
- */
-static int 
-unknown_script(script)
-       int script;
-{
-       if (script_paths == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL, 
-                   "privsep_script_exec: script_paths was not initialized\n");
-               return -1;
-       }
-
-       if ((script < 0) || (script > (script_paths->l / sizeof(vchar_t *)))) {
-               plog(LLV_ERROR, LOCATION, NULL, 
-                   "privsep_script_exec: unsafe script index\n");
-               return -1;
-       }
-
-        return 0;
-}
-
 static int 
 unknown_name(name)
        int name;
@@ -1063,12 +1170,17 @@ privsep_accounting_pam(port, inout)
        size_t len;
        int *port_data;
        int *inout_data;
+       int *pool_size_data;
        int result;
 
        if (geteuid() == 0)
                return isakmp_cfg_accounting_pam(port, inout);
 
-       len = sizeof(*msg) + sizeof(port) + sizeof(inout);
+       len = sizeof(*msg) 
+           + sizeof(port) 
+           + sizeof(inout)
+           + sizeof(isakmp_cfg_config.pool_size);
+
        if ((msg = racoon_malloc(len)) == NULL) {
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Cannot allocate memory: %s\n", strerror(errno));
@@ -1079,12 +1191,15 @@ privsep_accounting_pam(port, inout)
        msg->hdr.ac_len = len;
        msg->bufs.buflen[0] = sizeof(port);
        msg->bufs.buflen[1] = sizeof(inout);
+       msg->bufs.buflen[2] = sizeof(isakmp_cfg_config.pool_size);
 
        port_data = (int *)(msg + 1);
        inout_data = (int *)(port_data + 1);
+       pool_size_data = (int *)(inout_data + 1);
 
        *port_data = port;
        *inout_data = inout;
+       *pool_size_data = isakmp_cfg_config.pool_size;
 
        if (privsep_send(privsep_sock[1], msg, len) != 0)
                return -1;
@@ -1122,9 +1237,11 @@ privsep_xauth_login_pam(port, raddr, usr, pwd)
 
        len = sizeof(*msg) 
            + sizeof(port)
+           + sizeof(isakmp_cfg_config.pool_size)
            + sysdep_sa_len(raddr) 
            + strlen(usr) + 1
            + strlen(pwd) + 1;
+
        if ((msg = racoon_malloc(len)) == NULL) {
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Cannot allocate memory: %s\n", strerror(errno));
@@ -1134,21 +1251,25 @@ privsep_xauth_login_pam(port, raddr, usr, pwd)
        msg->hdr.ac_cmd = PRIVSEP_XAUTH_LOGIN_PAM;
        msg->hdr.ac_len = len;
        msg->bufs.buflen[0] = sizeof(port);
-       msg->bufs.buflen[1] = sysdep_sa_len(raddr);
-       msg->bufs.buflen[2] = strlen(usr) + 1;
-       msg->bufs.buflen[3] = strlen(pwd) + 1;
+       msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size);
+       msg->bufs.buflen[2] = sysdep_sa_len(raddr);
+       msg->bufs.buflen[3] = strlen(usr) + 1;
+       msg->bufs.buflen[4] = strlen(pwd) + 1;
 
        data = (char *)(msg + 1);
        memcpy(data, &port, msg->bufs.buflen[0]);
 
-       data += sizeof(msg->bufs.buflen[0]);
-       memcpy(data, raddr, msg->bufs.buflen[1]);
+       data += msg->bufs.buflen[0];
+       memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]);
 
        data += msg->bufs.buflen[1];
-       memcpy(data, usr, msg->bufs.buflen[2]);
+       memcpy(data, raddr, msg->bufs.buflen[2]);
 
        data += msg->bufs.buflen[2];
-       memcpy(data, pwd, msg->bufs.buflen[3]);
+       memcpy(data, usr, msg->bufs.buflen[3]);
+
+       data += msg->bufs.buflen[3];
+       memcpy(data, pwd, msg->bufs.buflen[4]);
 
        if (privsep_send(privsep_sock[1], msg, len) != 0)
                return -1;
@@ -1181,7 +1302,10 @@ privsep_cleanup_pam(port)
        if (geteuid() == 0)
                return cleanup_pam(port);
 
-       len = sizeof(*msg) + sizeof(port);
+       len = sizeof(*msg) 
+           + sizeof(port)
+           + sizeof(isakmp_cfg_config.pool_size);
+
        if ((msg = racoon_malloc(len)) == NULL) {
                plog(LLV_ERROR, LOCATION, NULL, 
                    "Cannot allocate memory: %s\n", strerror(errno));
@@ -1191,10 +1315,14 @@ privsep_cleanup_pam(port)
        msg->hdr.ac_cmd = PRIVSEP_CLEANUP_PAM;
        msg->hdr.ac_len = len;
        msg->bufs.buflen[0] = sizeof(port);
+       msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size);
 
        data = (char *)(msg + 1);
        memcpy(data, &port, msg->bufs.buflen[0]);
 
+       data += msg->bufs.buflen[0];
+       memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]);
+
        if (privsep_send(privsep_sock[1], msg, len) != 0)
                return;
 
index 10e3aa226d03a71a0b56372693c9ddb911513509..0fa43631feaab2dee7a281b7ffd70bdfa4b7bfab 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: privsep.h,v 1.3 2005/02/10 02:02:56 manubsd Exp $ */
+/*     $NetBSD: privsep.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */
+
+/* Id: privsep.h,v 1.5 2005/06/07 12:22:11 fredsen Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
@@ -39,8 +41,9 @@
 #define PRIVSEP_ACCOUNTING_PAM         0x0806  /* admin_com_bufs follows */
 #define PRIVSEP_XAUTH_LOGIN_PAM                0x0807  /* admin_com_bufs follows */
 #define PRIVSEP_CLEANUP_PAM            0x0808  /* admin_com_bufs follows */
+#define PRIVSEP_ACCOUNTING_SYSTEM      0x0809  /* admin_com_bufs follows */
 
-#define PRIVSEP_NBUF_MAX 16
+#define PRIVSEP_NBUF_MAX 24
 #define PRIVSEP_BUFLEN_MAX 4096
 struct admin_com_bufs {
        size_t buflen[PRIVSEP_NBUF_MAX];
@@ -57,7 +60,7 @@ int privsep_init __P((void));
 vchar_t *privsep_eay_get_pkcs1privkey __P((char *));
 int privsep_pfkey_open __P((void));
 void privsep_pfkey_close __P((int));
-int privsep_script_exec __P((int, int, char * const *));
+int privsep_script_exec __P((char *, int, char * const *));
 vchar_t *privsep_getpsk __P((const char *, const int));
 int privsep_xauth_login_system __P((char *, char *));
 #ifdef HAVE_LIBPAM
@@ -65,5 +68,5 @@ int privsep_accounting_pam __P((int, int));
 int privsep_xauth_login_pam __P((int, struct sockaddr *, char *, char *));
 void privsep_cleanup_pam __P((int));
 #endif
-
+int privsep_accounting_system __P((int, struct sockaddr *, char *, int));
 #endif /* _PRIVSEP_H */
index a2f053a3b525ca9efbbdff515180c53025441436..7ade8874dadb8c6a1d3f08dd0f3f1e9298425406 100644 (file)
@@ -452,6 +452,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side)
                if (newtr == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "failed to allocate satrns.\n");
+                       racoon_free(newpr);
                        goto err;
                }
                newtr->trns_no = tr1->trns_no;
@@ -706,6 +707,7 @@ aproppair2saprop(p0)
                if (sizeof(newpr->spi) < p->prop->spi_size) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "invalid spi size %d.\n", p->prop->spi_size);
+                       racoon_free(newpr);
                        goto err;
                }
 
@@ -740,11 +742,15 @@ aproppair2saprop(p0)
                        if (newtr == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL,
                                        "failed to allocate satrns.\n");
+                               racoon_free(newpr);
                                goto err;
                        }
 
-                       if (ipsecdoi_t2satrns(t->trns, newpp, newpr, newtr) < 0) {
+                       if (ipsecdoi_t2satrns(t->trns, 
+                           newpp, newpr, newtr) < 0) {
                                flushsaprop(newpp);
+                               racoon_free(newtr);
+                               racoon_free(newpr);
                                return NULL;
                        }
 
@@ -1047,6 +1053,7 @@ set_proposal_from_policy(iph2, sp_main, sp_sub)
                if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "failed to get algorithms.\n");
+                       racoon_free(newpr);
                        goto err;
                }
 
@@ -1077,10 +1084,14 @@ set_proposal_from_policy(iph2, sp_main, sp_sub)
 
        iph2->proposal = newpp;
 
+    ike_session_update_mode(iph2);
+
        printsaprop0(LLV_DEBUG, newpp);
 
        return 0;
 err:
+       if (newpp)
+               flushsaprop(newpp);
        return -1;
 }
 
@@ -1111,6 +1122,10 @@ set_proposal_from_proposal(iph2)
         for (i = 0; i < MAXPROPPAIRLEN; i++) {
                 if (pair[i] == NULL)
                         continue;
+
+               if (pp_peer != NULL)
+                       flushsaprop(pp_peer);
+
                pp_peer = aproppair2saprop(pair[i]);
                if (pp_peer == NULL)
                        goto end;
@@ -1138,6 +1153,7 @@ set_proposal_from_proposal(iph2)
                        if (newpr == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL,
                                    "failed to allocate saproto.\n");
+                               racoon_free(pp0);
                                goto end;
                        }
                        newpr->proto_id = pr->proto_id;
@@ -1147,15 +1163,17 @@ set_proposal_from_proposal(iph2)
                        newpr->spi_p = pr->spi; /* copy peer's SPI */
                        newpr->reqid_in = 0;
                        newpr->reqid_out = 0;
-               }
 
-               if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to get algorithms.\n");
-                       goto end;
+                       if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "failed to get algorithms.\n");
+                               racoon_free(newpr);
+                               racoon_free(pp0);
+                               goto end;
+                       }
+                       inssaproto(pp0, newpr);
                }
 
-               inssaproto(pp0, newpr);
                inssaprop(&newpp, pp0);
        }
 
@@ -1164,6 +1182,8 @@ set_proposal_from_proposal(iph2)
 
        iph2->proposal = newpp;
 
+       ike_session_update_mode(iph2);
+
        error = 0;
 
 end:
@@ -1172,7 +1192,8 @@ end:
 
        if (pp_peer)
                flushsaprop(pp_peer);
-       free_proppair(pair);
+       if (pair)
+               free_proppair(pair);
        return error;
 }
 
index e95752bc52cbcce7e7ddd2f3778436ebbbd0f4d4..72df73ae851048b6a28ff01d7cd712936871c4d9 100644 (file)
@@ -206,6 +206,6 @@ extern void print_proppair __P((int, struct prop_pair *));
 extern int set_proposal_from_policy __P((struct ph2handle *,
        struct secpolicy *, struct secpolicy *));
 extern int set_proposal_from_proposal __P((struct ph2handle *));
-extern int tunnel_mode_prop __P((struct saprop *p));
+extern int tunnel_mode_prop __P((struct saprop *));
 
 #endif /* _PROPOSAL_H */
index b44eafc5442273b256b193a6bf3e7f02538cb51e..b8d3c2058ed49e23ffac4c25520704d5f6aacdf8 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp $ */
+/*     $NetBSD: prsa_par.y,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
+/* Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp */
 
 %{
 /*
@@ -98,7 +100,7 @@ prsaerror(const char *s, ...)
 #endif
        snprintf(fmt, sizeof(fmt), "%s:%d: %s",
                prsa_cur_fname, prsa_cur_lineno, s);
-       plogv(LLV_ERROR, LOCATION, NULL, fmt, ap);
+       plogv(LLV_ERROR, LOCATION, NULL, fmt, &ap);
        va_end(ap);
 }
 
@@ -115,7 +117,7 @@ prsawarning(const char *s, ...)
 #endif
        snprintf(fmt, sizeof(fmt), "%s:%d: %s",
                prsa_cur_fname, prsa_cur_lineno, s);
-       plogv(LLV_WARNING, LOCATION, NULL, fmt, ap);
+       plogv(LLV_WARNING, LOCATION, NULL, fmt, &ap);
        va_end(ap);
 }
 
index be0d26c046925d75fac23b6f2820ae05ffce2ac5..1c9288bf327891d99f25653277de1feb9efc227f 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: prsa_tok.l,v 1.2 2004/07/12 20:43:51 ludvigm Exp $ */
+/*     $NetBSD: prsa_tok.l,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
+/* Id: prsa_tok.l,v 1.2 2004/07/12 20:43:51 ludvigm Exp */
 
 %{
 /*
index 8e0232279bf111f1571ae02e2bbd8323fd78002f..b47f8f40482694db68c37cf8de3297bffae9c807 100644 (file)
@@ -131,8 +131,6 @@ The command exits with 0 on success, and non-zero on errors.
 .Bl -tag -width /private/etc/racoon/remote/anonymous -compact
 .It Pa /private/etc/racoon/racoon.conf 
 default configuration file.
-.It Pa /private/etc/racoon/remote/anonymous 
-default anonymous configuration file.
 .It Pa /private/etc/racoon/psk.txt 
 default pre-shared key file.
 .El
index 1183e615d9c0ad531a3ecef70d80748922865da9..3b3ff5b9d59ca7e38c956327736a4db5d591342d 100644 (file)
@@ -1,4 +1,6 @@
-.\"    $Id: racoon.conf.5,v 1.27.2.12 2005/11/25 16:06:32 manubsd Exp $
+.\"    $NetBSD: racoon.conf.5,v 1.34.4.2 2007/07/18 22:53:03 mgrooms Exp $
+.\"
+.\"    Id: racoon.conf.5,v 1.54 2006/08/22 18:17:17 manubsd Exp
 .\"
 .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 .\" All rights reserved.
@@ -27,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd November 23, 2004
+.Dd September 19, 2006
 .Dt RACOON.CONF 5
 .Os
 .\"
@@ -127,13 +129,21 @@ is one of following:
 .Ss Privilege separation
 .Bl -tag -width Ds -compact
 .It Ic privsep { Ar statements Ic }
-specifies privilege separation parameters.
+Specifies privilege separation parameters.
 When enabled, these enable
 .Xr racoon 8
 to operate with an unprivileged instance doing most of the work, while
 a privileged instance takes care of performing the following operations
 as root: reading PSK and private keys, launching hook scripts, and
 validating passwords against system databases or against PAM.
+Please note that using privilege separation makes changes to the
+.Ar listen
+and
+.Ar paths
+sections ignored upon configuration reloads.
+A
+.Xr racoon 8
+restart is required if you want such changes to be taken into account.
 .Pp
 .Bl -tag -width Ds -compact
 .It Ic user Ar user ;
@@ -142,7 +152,7 @@ The user to which the unprivileged instance of
 should switch.
 This can be a quoted user name or a numeric UID.
 .It Ic group Ar group ;
-The group to which the unprivileged instance of
+The group the unprivilegied instance of
 .Xr racoon 8 ,
 should switch.
 This can be a quoted group name or a numeric GID.
@@ -156,8 +166,8 @@ reachable:
 .Bl -tag -width Ds -compact
 .It Pa /dev/random
 .It Pa /dev/urandom
-.It the certificates
-.It the file containing the Xauth banner
+.It The certificates
+.It The file containing the Xauth banner
 .El
 .Pp
 The PSK file, the private keys, and the hook scripts are accessed through the
@@ -169,19 +179,21 @@ tree.
 .El
 .El
 .Ss Path Specification
-This section specify various paths used by racoon.
+This section specifies various paths used by racoon.
 When running in privilege separation mode,
 .Ic certificate
 and
 .Ic script
-paths are mandatory.
+paths are mandatory. A
+.Xr racoon 8
+restart is required if you want path changes to be taken into account.
 .Bl -tag -width Ds -compact
 .It Ic path include Ar path ;
-specifies a path to include a file.
+Specifies a path to include a file.
 See
 .Sx File Inclusion .
 .It Ic path pre_shared_key Ar file ;
-specifies a file containing pre-shared key(s) for various ID(s).
+Specifies a file containing pre-shared key(s) for various ID(s).
 See
 .Sx Pre-shared key File .
 .It Ic path certificate Ar path ;
@@ -191,7 +203,7 @@ If you run with privilege separation,
 .Xr racoon 8
 will refuse to use a certificate stored outside of this directory.
 .It Ic path backupsa Ar file ;
-specifies a file to which SA information which is negotiated by
+Specifies a file to which SA information negotiated by
 racoon should be stored.
 .Xr racoon 8
 will install SA(s) from the file when started with the
@@ -208,22 +220,19 @@ If you run with privilege separation,
 .Xr racoon 8
 will refuse to execute a script stored outside of this directory.
 .It Ic path pidfile Ar file ;
-specifies file where to store PID of process.
+Specifies file where to store PID of process.
 If path starts with
 .Pa /
-it is treated as
-an absolute path, otherwise relative to VARRUN directory specified at
-compilation time.
+it is treated as an absolute path. Otherwise, it is treated as a relative 
+path to the VARRUN directory specified at compilation time.
 Default is
 .Pa racoon.pid .
-.It Ic path logfile Ar file ;
-specifies log file path.
 .El
 .\"
 .Ss File Inclusion
 .Bl -tag -width Ds -compact
 .It Ic include Ar file
-other configuration files can be included.
+Specifies other configuration files to be included.
 .El
 .\"
 .Ss Identifier Specification
@@ -235,26 +244,26 @@ directive.
 .Ss Timer Specification
 .Bl -tag -width Ds -compact
 .It Ic timer { Ar statements Ic }
-specifies various timer values.
+This section specifies various timer values used by racoon.
 .Pp
 .Bl -tag -width Ds -compact
 .It Ic counter Ar number ;
-the maximum number of retries to send.
+The maximum number of retries to send.
 The default is 5.
 .It Ic interval Ar number Ar timeunit ;
-the interval to resend, in seconds.
+The interval to resend, in seconds.
 The default time is 10 seconds.
 .It Ic persend Ar number ;
-the number of packets per send.
+The number of packets per send.
 The default is 1.
 .It Ic phase1 Ar number Ar timeunit ;
-the maximum time it should take to complete phase 1.
+The maximum time it should take to complete phase 1.
 The default time is 15 seconds.
 .It Ic phase2 Ar number Ar timeunit ;
-the maximum time it should take to complete phase 2.
+The maximum time it should take to complete phase 2.
 The default time is 10 seconds.
 .It Ic natt_keepalive Ar number Ar timeunit ;
-interval between sending NAT-Traversal keep-alive packets.
+The interval between sending NAT-Traversal keep-alive packets.
 The default time is 20 seconds.
 Set to 0s to disable keep-alive packets.
 .El
@@ -277,7 +286,7 @@ The following is the list of valid statements:
 .It Ic isakmp Ar address Bq Bq Ar port ;
 If this is specified,
 .Xr racoon 8
-will only listen on
+will only listen on the defined
 .Ar address .
 The default port is 500, which is specified by IANA.
 You can provide more than one address definition.
@@ -290,25 +299,32 @@ If you plan to use NAT-T, you should provide at least one address
 with port 4500, which is specified by IANA.
 There is no default.
 .It Ic strict_address ;
-require that all addresses for ISAKMP must be bound.
-This statement will be ignored if you do not specify any address.
+Requires that all addresses for ISAKMP be bound.
+This statement will be ignored if you do not specify address definitions.
 .El
+When running in privilege separation mode, you need to restart
+.Xr racoon 8
+to have changes to the
+.Ar listen
+section taken into account.
+.Pp
 The
 .Ar listen
-section can also be used to specify the admin socket mode and ownership,
+section can also be used to specify the admin socket mode and ownership
 if racoon was built with support for admin port.
 .Bl -tag -width Ds -compact
 .It Ic adminsock Ar path Op Ar owner\ group\ mode ;
+The
 .Ar path ,
 .Ar owner ,
 and
 .Ar group
-are the socket path, owner, and group; they must be quoted.
-Defaults are
+values specify the socket path, owner, and group. They must be quoted.
+The defaults are
 .Pa /var/racoon/racoon.sock ,
 UID 0, and GID 0.
 .Ar mode
-is the access mode in octal, default is 0600.
+is the access mode in octal. The default is 0600.
 .It Ic adminsock disabled ;
 This directive tells racoon to not listen on the admin socket.
 .El
@@ -352,12 +368,12 @@ This is the encoding used by older versions of
 .Bq Ic inherit Ar parent
 .Ic { Ar statements Ic }
 .Xc
-specifies the parameters for IKE phase 1 for each remote node.
+Specifies the IKE phase 1 parameters for each remote node.
 The default port is 500.
 If
 .Ic anonymous
-is specified, the statements apply to all peers which do not match
-any other
+is specified, the statements will apply to any peer that does not match a
+more specific
 .Ic remote
 directive.
 .Pp
@@ -369,7 +385,7 @@ is either
 .Ar address
 or a keyword
 .Ic anonymous )
-have all values predefined to those of a given
+that have all values predefined to those of a given
 .Ar parent .
 In these sections it is enough to redefine only the changed parameters.
 .Pp
@@ -378,46 +394,61 @@ The following are valid statements.
 .Bl -tag -width Ds -compact
 .\"
 .It Ic exchange_mode ( main | aggressive | base ) ;
-defines the exchange mode for phase 1 when racoon is the initiator.
-It also means the acceptable exchange mode when racoon is responder.
+Defines the exchange mode for phase 1 when racoon is the initiator.
+It also means the acceptable exchange mode when racoon is the responder.
 More than one mode can be specified by separating them with a comma.
 All of the modes are acceptable.
 The first exchange mode is what racoon uses when it is the initiator.
 .\"
 .It Ic doi Ic ipsec_doi ;
-means to use IPsec DOI as specified in RFC 2407.
+Means to use IPsec DOI as specified in RFC 2407.
 You can omit this statement.
 .\"
 .It Ic situation Ic identity_only ;
-means to use SIT_IDENTITY_ONLY as specified in RFC 2407.
+Means to use SIT_IDENTITY_ONLY as specified in RFC 2407.
 You can omit this statement.
 .\"
 .It Ic identifier Ar idtype ;
-is obsolete.
-Instead, use
+This statment is obsolete. Instead, use
 .Ic my_identifier .
 .\"
-.It Ic my_identifier Ar idtype ... ;
-specifies the identifier sent to the remote host
+.It Xo
+.Ic my_identifier Bq Ar qualifier
+.Ar idtype ... ;
+.Xc
+Specifies the identifier sent to the remote host
 and the type to use in the phase 1 negotiation.
 .Ic address, fqdn , user_fqdn , keyid ,
 and
 .Ic asn1dn
 can be used as an
 .Ar idtype .
-Use them in the following way:
+The
+.Ar qualifier
+is currently only used for
+.Ic keyid ,
+and can be either
+.Ic file
+or
+.Ic tag .
+The possible values are :
 .Bl -tag -width Ds -compact
 .It Ic my_identifier Ic address Bq Ar address ;
-the type is the IP address.
+The type is the IP address.
 This is the default type if you do not specify an identifier to use.
 .It Ic my_identifier Ic user_fqdn Ar string ;
-the type is a USER_FQDN (user fully-qualified domain name).
+The type is a USER_FQDN (user fully-qualified domain name).
 .It Ic my_identifier Ic fqdn Ar string ;
-the type is a FQDN (fully-qualified domain name).
-.It Ic my_identifier Ic keyid Ar file ;
-the type is a KEY_ID.
+The type is a FQDN (fully-qualified domain name).
+.It Xo
+.Ic my_identifier Ic keyid Bq Ic file
+.Ar file ;
+.Xc
+The type is a KEY_ID, read from the file.
+.It Ic my_identifier Ic keyid Ic tag Ar string ;
+The type is a KEY_ID, specified in the quoted string.
 .It Ic my_identifier Ic asn1dn Bq Ar string ;
-the type is an ASN.1 distinguished name.
+The type is an ASN.1 distinguished name.
 If
 .Ar string
 is omitted,
@@ -426,7 +457,7 @@ will get the DN from the Subject field in the certificate.
 .El
 .\"
 .It Ic xauth_login Bq Ar string ;
-specifies the login to use in client-side Hybrid authentication.
+Specifies the login to use in client-side Hybrid authentication.
 It is available only if
 .Xr racoon 8
 has been built with this option.
@@ -436,7 +467,7 @@ using the login
 as the key id.
 .\"
 .It Ic peers_identifier Ar idtype ... ;
-specifies the peer's identifier to be received.
+Specifies the peer's identifier to be received.
 If it is not defined then
 .Xr racoon 8
 will not verify the peer's identifier in ID payload transmitted from the peer.
@@ -455,17 +486,17 @@ Alternative acceptable peer identifiers may be specified by repeating the
 .Ic peers_identifier
 statement.
 .\"
-.It Ic verify_identifier (on \(ba off) ;
+.It Ic verify_identifier (on | off) ;
 If you want to verify the peer's identifier,
 set this to on.
 In this case, if the value defined by
 .Ic peers_identifier
 is not the same as the peer's identifier in the ID payload,
-the negotiation will failed.
+the negotiation will fail.
 The default is off.
 .\"
 .It Ic certificate_type Ar certspec ;
-specifies a certificate specification.
+Specifies a certificate specification.
 .Ar certspec
 is one of followings:
 .Bl -tag -width Ds -compact
@@ -475,8 +506,14 @@ means a file name of a certificate.
 .Ar privkeyfile
 means a file name of a secret key.
 .El
+.Bl -tag -width Ds -compact
+.It Ic plain_rsa Ar privkeyfile ;
+.Ar privkeyfile
+means a file name of a private key generated by plainrsa-gen(8).  Required
+for RSA authentication.
+.El
 .It Ic ca_type Ar cacertspec ;
-specifies a root certificate authority specification.
+Specifies a root certificate authority specification.
 .Ar cacertspec
 is one of followings:
 .Bl -tag -width Ds -compact
@@ -487,11 +524,17 @@ Default is
 .Pa /etc/openssl/cert.pem
 .El
 .\"
-.It Ic mode_cfg (on \(ba off) ;
+.It Ic mode_cfg (on | off) ;
 Gather network information through ISAKMP mode configuration.
 Default is off.
 .\"
-.It Ic peers_certfile ( dnssec | Ar certfile ) ;
+.It Ic weak_phase1_check (on | off) ;
+Tells racoon to act on unencrypted deletion messages during phase 1.
+This is a small security risk, so the default is off, meaning that
+racoon will keep on trying to establish a connection even if the
+user credentials are wrong, for instance.
+.\"
+.It Ic peers_certfile ( dnssec | Ar certfile | Ic plain_rsa Ar pubkeyfile ) ;
 If
 .Ic dnssec
 is defined,
@@ -504,6 +547,14 @@ is defined,
 .Xr racoon 8
 will ignore the CERT payload from the peer,
 and will use this certificate as the peer's certificate.
+If
+.Ic plain_rsa
+is defined,
+.Xr racoon 8
+will expect
+.Ar pubkeyfile
+to be the peer's public key that was generated
+by plainrsa-gen(8).
 .\"
 .It Ic script Ar script Ic phase1_up
 .It Ic script Ar script Ic phase1_down
@@ -532,41 +583,76 @@ was enabled:
 An IPv4 internal address obtained by ISAKMP mode config.
 .It INTERNAL_NETMASK4
 An IPv4 internal netmask obtained by ISAKMP mode config.
+.It INTERNAL_CIDR4
+An IPv4 internal netmask obtained by ISAKMP mode config, in CIDR notation.
 .It INTERNAL_DNS4
-Internal DNS server IPv4 address obtained by ISAKMP mode config.
-.It INTERNAL_NBNS4
-Internal WINS server IPv4 address obtained by ISAKMP mode config.
+The first internal DNS server IPv4 address obtained by ISAKMP mode config.
+.It INTERNAL_DNS4_LIST
+A list of internal DNS servers IPv4 address obtained by ISAKMP mode config,
+separated by spaces.
+.It INTERNAL_WINS4
+The first internal WINS server IPv4 address obtained by ISAKMP mode config.
+.It INTERNAL_WINS4_LIST
+A list of internal WINS servers IPv4 address obtained by ISAKMP mode config,
+separated by spaces.
+.It SPLIT_INCLUDE
+The space separated list of IPv4 addresses and masks (address slash mask)
+that define the networks to be encrypted (as opposed to the default where
+all the traffic should be encrypted) ; obtained by ISAKMP mode config ;
+SPLIT_INCLUDE and SPLIT_LOCAL are mutually exclusive.
+.It SPLIT_LOCAL
+The space separated list of IPv4 addresses and masks (address slash mask)
+that define the networks to be considered local, and thus excluded from the
+tunnels ; obtained by ISAKMP mode config.
+.It DEFAULT_DOMAIN
+The DNS default domain name obtained by ISAKMP mode config.
 .El
 .\"
 .\"
-.It Ic send_cert (on \(ba off) ;
-If you do not want to send a certificate for some reason, set this to off.
+.It Ic send_cert (on | off) ;
+If you do not want to send a certificate, set this to off.
 The default is on.
 .\"
-.It Ic send_cr (on \(ba off) ;
-If you do not want to send a certificate request for some reason, set this to off.
+.It Ic send_cr (on | off) ;
+If you do not want to send a certificate request, set this to off.
 The default is on.
 .\"
-.It Ic verify_cert (on \(ba off) ;
-If you do not want to verify the peer's certificate for some reason,
+.It Ic verify_cert (on | off) ;
+By default, the identifier sent by the remote host (as specified in its
+.Ic my_identifier
+statement) is compared with the credentials in the certificate
+used to authenticate the remote host as follows:
+.Bl -tag -width Ds -compact
+.It Type Ic asn1dn:
+The entire certificate subject name is compared with the identifier,
+e.g. "C=XX, O=YY, ...".
+.It Type Ic address, fqdn, or user_fqdn:
+The certificate's subjectAltName is compared with the identifier.
+.El
+If the two do not match the negotiation will fail.
+If you do not want to verify the identifier using the peer's certificate,
 set this to off.
-The default is on.
 .\"
 .It Ic lifetime time Ar number Ar timeunit ;
 Define a lifetime of a certain time
 which will be proposed in the phase 1 negotiations.
-Any proposal will be accepted, and the attribute(s) will be not proposed to
+Any proposal will be accepted, and the attribute(s) will not be proposed to
 the peer if you do not specify it (them).
 They can be individually specified in each proposal.
 .\"
-.It Ic ike_frag (on \(ba off) ;
-Enable receiver-side IKE fragmentation, if
+.It Ic ike_frag (on | off | force) ;
+Enable receiver-side IKE fragmentation if
 .Xr racoon 8
 has been built with this feature.
-This extension is there to work around
-broken firewalls that do not work with fragmented UDP packets.
-IKE fragmentation is always enabled on the sender-side, and
-it is used if the peer advertises itself as IKE fragmentation capable.
+If set to on, racoon will advertise
+itself as being capable of receiving packets split by IKE fragmentation.
+This extension is there to work around broken firewalls that do not
+work with fragmented UDP packets.
+IKE fragmentation is always enabled on the sender-side, and it is
+used if the peer advertises itself as IKE fragmentation capable.
+By selecting force, IKE Fragmentation will
+be used when racoon is acting as the initiator even before the remote
+peer has advertised itself as IKE fragmentation capable.
 .\"
 .It Ic esp_frag Ar fraglen ;
 This option is only relevant if you use NAT traversal in tunnel mode.
@@ -580,32 +666,33 @@ is the maximum size of the fragments.
 552 should work anywhere,
 but the higher
 .Ar fraglen
-is, the better is the performance.
+is, the better the performance.
 .Pp
 Note that because PMTU discovery is broken on many sites, you will
 have to use MSS clamping if you want TCP to work correctly.
 .\"
-.It Ic initial_contact (on \(ba off) ;
-enable this to send an INITIAL-CONTACT message.
+.It Ic initial_contact (on | off) ;
+Enable this to send an INITIAL-CONTACT message.
 The default value is
 .Ic on .
-This message is useful only when
-the implementation of the responder chooses an old SA when there are multiple
-SAs with different established time, and the initiator reboots.
+This message is useful only when the responder implementation chooses an
+old SA when there are multiple SAs with different established time and the
+initiator reboots.
 If racoon did not send the message,
 the responder would use an old SA even when a new SA was established.
-The KAME stack has the switch in the system wide value
-net.key.preferred_oldsa.
-when the value is zero, the stack always uses a new SA.
+For systems that use a KAME derived IPSEC stack, the
+.Xr sysctl 8
+variable net.key.preferred_oldsa can be used to control this preference.
+When the value is zero, the stack always uses a new SA.
 .\"
-.It Ic passive (on \(ba off) ;
+.It Ic passive (on | off) ;
 If you do not want to initiate the negotiation, set this to on.
 The default value is
 .Ic off .
 It is useful for a server.
 .\"
 .It Ic proposal_check Ar level ;
-specifies the action of lifetime length and PFS of the phase 2
+Specifies the action of lifetime length, key length and PFS of the phase 2
 selection on the responder side, and the action of lifetime check in
 phase 1.
 The default level is
@@ -615,37 +702,38 @@ If the
 is:
 .Bl -tag -width Ds -compact
 .It Ic obey
-the responder will obey the initiator anytime.
+The responder will obey the initiator anytime.
 .It Ic strict
-If the responder's length is longer than the initiator's one, the
-responder uses the initiator's one.
-Otherwise it rejects the proposal.
+If the responder's lifetime length is longer than the initiator's or
+the responder's key length is shorter than the initiator's,
+the responder will use the initiator's value.
+Otherwise, the proposal will be rejected.
 If PFS is not required by the responder, the responder will obey the proposal.
-If PFS is required by both sides and if the responder's group is not equal to
-the initiator's one, then the responder will reject the proposal.
+If PFS is required by both sides and the responder's group is not equal to
+the initiator's, then the responder will reject the proposal.
 .It Ic claim
-If the responder's length is longer than the initiator's one, the
-responder will use the initiator's one.
-If the responder's length is
-shorter than the initiator's one, the responder uses its own length
-AND sends a RESPONDER-LIFETIME notify message to an initiator in the
-case of lifetime (phase 2 only).
+If the responder's lifetime length is longer than the initiator's or
+the responder's key length is shorter than the initiator's,
+the responder will use the initiator's value.
+If the responder's lifetime length is shorter than the initiator's,
+the responder uses its own length AND sends a RESPONDER-LIFETIME notify
+message to an initiator in the case of lifetime (phase 2 only).
 For PFS, this directive behaves the same as
 .Ic strict .
 .It Ic exact
-If the initiator's length is not equal to the responder's one, the
-responder will reject the proposal.
-If PFS is required by both sides and if the responder's group is not equal to
-the initiator's one, then the responder will reject the proposal.
+If the initiator's lifetime or key length is not equal to the responder's,
+the responder will reject the proposal.
+If PFS is required by both sides and the responder's group is not equal to
+the initiator's, then the responder will reject the proposal.
 .El
 .\"
-.It Ic support_proxy (on \(ba off) ;
+.It Ic support_proxy (on | off) ;
 If this value is set to on, then both values of ID payloads in the
 phase 2 exchange are always used as the addresses of end-point of
 IPsec-SAs.
 The default is off.
 .\"
-.It Ic generate_policy (on \(ba off) ;
+.It Ic generate_policy (on | off | require | unique) ;
 This directive is for the responder.
 Therefore you should set
 .Ic passive
@@ -663,20 +751,27 @@ Note that an inappropriate policy might be installed into the responder's SPD
 by the initiator,
 so other communications might fail if such policies are installed
 due to a policy mismatch between the initiator and the responder.
+.Ic on
+and
+.Ic require
+values mean the same thing (generate a require policy).
+.Ic unique
+tells racoon to set up unique policies, with a monotoning increasing
+reqid number (between 1 and IPSEC_MANUAL_REQID_MAX).
 This directive is ignored in the initiator case.
 The default value is
 .Ic off .
 .\"
 .\"
-.It Ic nat_traversal (on \(ba off \(ba force) ;
+.It Ic nat_traversal (on | off | force) ;
 This directive enables use of the NAT-Traversal IPsec extension
 (NAT-T).
 NAT-T allows one or both peers to reside behind a NAT gateway (i.e.,
 doing address- or port-translation).
-Presence of NAT gateways along the path
-is discovered during phase 1 handshake and if found, NAT-T is negotiated.
-When NAT-T is in charge, all ESP and AH packets of a given connection
-are encapsulated into UDP datagrams (port 4500, by default).
+If a NAT gateway is detected during the phase 1 handshake, racoon will
+attempt to negotiate the use of NAT-T with the remote peer.
+If the negotiation succeeds, all ESP and AH packets for the given connection
+will be encapsulated into UDP datagrams (port 4500, by default).
 Possible values are:
 .Bl -tag -width Ds -compact
 .It Ic on
@@ -685,7 +780,8 @@ NAT-T is used when a NAT gateway is detected between the peers.
 NAT-T is not proposed/accepted.
 This is the default.
 .It Ic force
-NAT-T is used regardless if a NAT is detected between the peers or not.
+NAT-T is used regardless of whether a NAT gateway is detected between the
+peers or not.
 .El
 Please note that NAT-T support is a compile-time option.
 Although it is enabled in the source distribution by default, it
@@ -695,7 +791,7 @@ warning when using any NAT-T related config options.
 .\"
 .It Ic dpd_delay Ar delay ;
 This option activates the DPD and sets the time (in seconds) allowed
-between 2 proof of liveness requests.
+between 2 proof of liveliness requests.
 The default value is
 .Ic 0 ,
 which disables DPD monitoring, but still negotiates DPD support.
@@ -704,14 +800,14 @@ which disables DPD monitoring, but still negotiates DPD support.
 If
 .Ic dpd_delay
 is set, this sets the delay (in seconds) to wait for a proof of
-liveness before considering it as failed and send another request.
+liveliness before considering it as failed and send another request.
 The default value is
 .Ic 5 .
 .\"
 .It Ic dpd_maxfail Ar number ;
 If
 .Ic dpd_delay
-is set, this sets the maximum number of proof of liveness to request
+is set, this sets the maximum number of liveliness proofs to request
 (without reply) before considering the peer is dead.
 The default value is
 .Ic 5 .
@@ -722,23 +818,28 @@ Racoon can send any value although
 RFC2409 specifies that the value MUST be between 8 and 256 bytes.
 The default size is 16 bytes.
 .\"
+.It Ic ph1id Ar number ;
+An optionnal number to identify the remote proposal and to link it
+only with sainfos who have the same number.
+Defaults to 0.
+.\"
 .It Xo
 .Ic proposal { Ar sub-substatements Ic }
 .Xc
 .Bl -tag -width Ds -compact
 .\"
 .It Ic encryption_algorithm Ar algorithm ;
-specify the encryption algorithm used for the phase 1 negotiation.
+Specifies the encryption algorithm used for the phase 1 negotiation.
 This directive must be defined.
 .Ar algorithm
 is one of following:
-.Ic des , 3des , blowfish , cast128 , aes
+.Ic des, 3des, blowfish, cast128, aes, camellia
 .\".Ic rc5 , idea
 for Oakley.
 For other transforms, this statement should not be used.
 .\"
 .It Ic hash_algorithm Ar algorithm ;
-define the hash algorithm used for the phase 1 negotiation.
+Defines the hash algorithm used for the phase 1 negotiation.
 This directive must be defined.
 .Ar algorithm
 is one of following:
@@ -746,16 +847,19 @@ is one of following:
 for Oakley.
 .\"
 .It Ic authentication_method Ar type ;
-defines the authentication method used for the phase 1 negotiation.
+Defines the authentication method used for the phase 1 negotiation.
 This directive must be defined.
 .Ar type
 is one of:
-.Ic pre_shared_key , rsasig , gssapi_krb , hybrid_rsa_server ,
+.Ic pre_shared_key , rsasig
+(for plain RSA authentication),
+.Ic gssapi_krb , hybrid_rsa_server ,
+.Ic hybrid_rsa_client , xauth_rsa_server , xauth_rsa_client , xauth_psk_server
 or
-.Ic hybrid_rsa_client .
+.Ic xauth_psk_client .
 .\"
 .It Ic dh_group Ar group ;
-define the group used for the Diffie-Hellman exponentiations.
+Defines the group used for the Diffie-Hellman exponentiations.
 This directive must be defined.
 .Ar group
 is one of following:
@@ -766,14 +870,14 @@ Or you can define 1, 2, 5, 14, 15, 16, 17, or 18 as the DH group number.
 When you want to use aggressive mode,
 you must define the same DH group in each proposal.
 .It Ic lifetime time Ar number Ar timeunit ;
-define lifetime of the phase 1 SA proposal.
+Defines the lifetime of the phase 1 SA proposal.
 Refer to the description of the
 .Ic lifetime
 directive defined in the
 .Ic remote
 directive.
 .It Ic gss_id Ar string ;
-define the GSS-API endpoint name, to be included as an attribute in the SA,
+Defines the GSS-API endpoint name, to be included as an attribute in the SA,
 if the
 .Ic gssapi_krb
 authentication method is used.
@@ -800,7 +904,7 @@ and policies in the kernel.
 .Ss Sainfo Specifications
 .Bl -tag -width Ds -compact
 .It Xo
-.Ic sainfo ( Ar source_id destination_id | Ic anonymous ) [ from Ar idtype [ Ar string ] ]
+.Ic sainfo ( Ar source_id destination_id | Ar source_id Ic anonymous | Ic anonymous Ar destination_id | Ic anonymous ) [ from Ar idtype [ Ar string ] ] [ Ic group Ar string ]
 .Ic { Ar statements Ic }
 .Xc
 defines the parameters of the IKE phase 2 (IPsec-SA establishment).
@@ -825,18 +929,28 @@ or
 .Pp
 .Ar idtype Ar string
 .Pp
-It means exactly the content of ID payload.
+An id string should be expressed to match the exact value of an ID payload
+(source is the local end, destination is the remote end).
 This is not like a filter rule.
 For example, if you define 3ffe:501:4819::/48 as
 .Ar source_id .
 3ffe:501:4819:1000:/64 will not match.
 .Pp
-In case of longest prefix (selecting single host)
+In the case of a longest prefix (selecting a single host),
 .Ar address
-instructs to send ID type of ADDRESS, while
+instructs to send ID type of ADDRESS while
 .Ar subnet
 instructs to send ID type of SUBNET.
-Otherwise these instructions are identical.
+Otherwise, these instructions are identical.
+.Pp
+The group keyword allows an XAuth group membership check to be performed
+for this sainfo section.
+When the mode_cfg auth source is set to
+.Ic system
+or
+.Ic ldap ,
+the XAuth user is verified to be a member of the specified group
+before allowing a matching SA to be negotiated.
 .Pp
 .Bl -tag -width Ds -compact
 .\"
@@ -859,6 +973,11 @@ See the
 .Ic proposal_check
 directive.
 .\"
+.It Ic remoteid Ar number ;
+Sainfos will only be used if their remoteid matches the ph1id of the
+remote section used for phase 1.
+Defaults to 0, which is also the default for ph1id.
+.\"
 .It Ic my_identifier Ar idtype ... ;
 is obsolete.
 It does not make sense to specify an identifier in the phase 2.
@@ -897,7 +1016,7 @@ Note that the kernel may not support the algorithm you have specified.
 .Ic des , 3des , des_iv64 , des_iv32 ,
 .Ic rc5 , rc4 , idea , 3idea ,
 .Ic cast128 , blowfish , null_enc ,
-.Ic twofish , rijndael , aes
+.Ic twofish , rijndael , aes , camellia
 .Pq used with ESP
 .\"
 .It Ic authentication_algorithm Ar algorithms ;
@@ -914,42 +1033,42 @@ Note that the kernel may not support the algorithm you have specified.
 .Ss Logging level
 .Bl -tag -width Ds -compact
 .It Ic log Ar level ;
-define logging level.
+Defines the logging level.
 .Ar level
 is one of following:
-.Ic notify , debug ,
+.Ic error , warning , notify , info , debug
 and
 .Ic debug2 .
 The default is
-.Ic notify .
+.Ic info .
 If you set the logging level too high on slower machines,
 IKE negotiation can fail due to timing constraint changes.
 .El
 .\"
-.Ss Specifying the way to pad
+.Ss Specifies the way to pad
 .Bl -tag -width Ds -compact
 .It Ic padding { Ar statements Ic }
-specified padding format.
+specifies the padding format.
 The following are valid statements:
 .Bl -tag -width Ds -compact
-.It Ic randomize (on \(ba off) ;
-enable using a randomized value for padding.
+.It Ic randomize (on | off) ;
+Enables the use of a randomized value for padding.
 The default is on.
-.It Ic randomize_length (on \(ba off) ;
-the pad length is random.
+.It Ic randomize_length (on | off) ;
+The pad length will be random.
 The default is off.
 .It Ic maximum_length Ar number ;
-define a maximum padding length.
+Defines a maximum padding length.
 If
 .Ic randomize_length
 is off, this is ignored.
 The default is 20 bytes.
-.It Ic exclusive_tail (on \(ba off) ;
-means to put the number of pad bytes minus one into the last part
+.It Ic exclusive_tail (on | off) ;
+Means to put the number of pad bytes minus one into the last part
 of the padding.
 The default is on.
-.It Ic strict_check (on \(ba off) ;
-means to constrain the peer to set the number of pad bytes.
+.It Ic strict_check (on | off) ;
+Means to constrain the peer to set the number of pad bytes.
 The default is off.
 .El
 .El
@@ -959,12 +1078,12 @@ The default is off.
 Defines the information to return for remote hosts' ISAKMP mode config
 requests.
 Also defines the authentication source for remote peers
-authenticating through hybrid auth.
+authenticating through Xauth.
 .Pp
 The following are valid statements:
 .Bl -tag -width Ds -compact
-.It Ic auth_source (system \(ba radius \(ba pam) ;
-Specify the source for authentication of users through hybrid auth.
+.It Ic auth_source (system | radius | pam | ldap) ;
+Specifies the source for authentication of users through Xauth.
 .Ar system
 means to use the Unix user database.
 This is the default.
@@ -972,48 +1091,87 @@ This is the default.
 means to use a RADIUS server.
 It works only if
 .Xr racoon 8
-was built with libradius support, and the configuration is done in
+was built with libradius support. Radius configuration is hanlded by
 .Xr radius.conf 5 .
 .Ar pam
 means to use PAM.
 It works only if
 .Xr racoon 8
 was built with libpam support.
-.It Ic conf_source (local \(ba radius) ;
-Specify the source for IP addresses and netmask allocated through ISAKMP
+.Ar ldap
+means to use LDAP.
+It works only if
+.Xr racoon 8
+was built with libldap support. LDAP configuration is handled by
+statements in the
+.Ic ldapcfg
+section.
+.It Ic auth_groups Ar "group1", ... ;
+Specifies the group memberships for Xauth in quoted group name strings.
+When defined, the authenticating user must be a member of at least one
+group for Xauth to succeed.
+.It Ic group_source (system | ldap) ;
+Specifies the source for group validataion of users through Xauth.
+.Ar system
+means to use the Unix user database.
+This is the default.
+.Ar ldap
+means to use LDAP.
+It works only if
+.Xr racoon 8
+was built with libldap support and requires LDAP authentication.
+LDAP configuration is handled by statements in the
+.Ic ldapcfg
+section.
+.It Ic conf_source (local | radius | ldap) ;
+Specifies the source for IP addresses and netmask allocated through ISAKMP
 mode config.
 .Ar local
 means to use the local IP pool defined by the
 .Ic network4
 and
 .Ic pool_size
-keywords.
+statements.
 This is the default.
 .Ar radius
 means to use a RADIUS server.
 It works only if
 .Xr racoon 8
-was built with libradius support, and the configuration is done in
+was built with libradius support and requires RADIUS authentiation.
+RADIUS configuration is handled by
 .Xr radius.conf 5 .
-RADIUS configuration requires RADIUS authentication.
-.It Ic accounting (none \(ba radius \(ba pam) ;
-Enable or disable accounting for Xauth logins and logouts.
-Default is
-.Ar none ,
+.Ar ldap
+means to use an LDAP server.
+It works only if
+.Xr racoon 8
+was built with libldap support and requires LDAP authentication.
+LDAP configuration is handled by
+statements in the
+.Ic ldapcfg
+section.
+.It Ic accounting (none | system | radius | pam) ;
+Enables or disables accounting for Xauth logins and logouts.
+The default is
+.Ar none
 which disable accounting.
+Specifying
+.Ar system
+enables system accounting through
+.Xr utmp 5 .
+Specifying
 .Ar radius
-enable RADIUS accounting.
+enables RADIUS accounting.
 It works only if
 .Xr racoon 8
-was built with libradius support, and the configuration is done in
+was built with libradius support and requires RADIUS authentication.
+RADIUS configuration is handled by
 .Xr radius.conf 5 .
-RADIUS accounting require RADIUS authentication.
+Specifying
 .Ar pam
-enable PAM accounting.
+enables PAM accounting.
 It works only if
 .Xr racoon 8
-was built with libpam support.
-PAM accounting requires PAM authentication.
+was build with libpam support and requires PAM authentication.
 .It Ic pool_size Ar size
 Specify the size of the IP address pool, either local or allocated
 through RADIUS.
@@ -1035,18 +1193,36 @@ or if the RADIUS server returned
 .Ar 255.255.255.254 .
 Default is
 .Ar 0.0.0.0/0.0.0.0 .
-.It Ic dns4 Ar address ;
-The IPv4 address for a DNS server.
-.It Ic nbns4 Ar address ;
-The IPv4 address for a WINS server.
+.It Ic dns4 Ar addresses ;
+A list of IPv4 addresses for DNS servers, separated by commas, or on multiple
+.Ic dns4
+lines.
+.It Ic nbns4 Ar addresses ;
+A list of IPv4 address for WINS servers.
+.It Ic split_network (include | local_lan) Ar network/mask, ...
+The network configuration to send, in cidr notation (e.g. 192.168.1.0/24).
+If
+.Ic include
+is specified, the tunnel should be only used to encrypt the indicated
+destinations ; otherwise, if
+.Ic local_lan
+is used, everything will pass through the tunnel but those destinations.
+.It Ic default_domain Ar domain ;
+The default DNS domain to send.
+.It Ic split_dns Ar "domain", ...
+The split dns configuration to send, in quoted domain name strings.
+This list can be used to describe a list of domain names for which
+a peer should query a modecfg assigned dns server.
+DNS queries for all other domains would be handled locally.
+(Cisco VPN client only).
 .It Ic banner Ar path ;
 The path of a file displayed on the client at connection time.
 Default is
 .Ar /etc/motd .
 .It Ic auth_throttle Ar delay ;
-On each failed Xauth authentication attempt, refuse new attempts for
+On each failed Xauth authentication attempt, refuse new attempts for a set
 .Ar delay
-more seconds.
+of seconds.
 This is to avoid dictionary attacks on Xauth passwords.
 Default is one second.
 Set to zero to disable authentication delay.
@@ -1058,9 +1234,73 @@ Allow the client to save the Xauth password (Cisco VPN client only).
 Default is off.
 .El
 .El
+.Ss Ldap configuration settings
+.Bl -tag -width Ds -compact
+.It Ic ldapcfg { Ar statements Ic }
+Defines the parameters that will be used to communicate with an ldap
+server for
+.Ic xauth
+authentication.
+.Pp
+The following are valid statements:
+.Bl -tag -width Ds -compact
+.It Ic version (2 | 3) ;
+The ldap protocol version used to communicate with the server.
+The default is
+.Ic 3 .
+.It Ic host Ar (hostname | address) ;
+The host name or ip address of the ldap server.
+The default is
+.Ic localhost .
+.It Ic port Ar number;
+The port that the ldap server is configured to listen on.
+The default is
+.Ic 389 .
+.It Ic base Ar distinguished name;
+The ldap search base.
+This option has no default value.
+.It Ic subtree (on | off) ;
+Use the subtree ldap search scope.
+Otherwise, use the one level search scope.
+The default is
+.Ic off .
+.It Ic bind_dn Ar distinguised name;
+The user dn used to optionaly bind as before performing ldap search operations.
+If this option is not specified, anonymous binds are used.
+.It Ic bind_pw Ar string;
+The password used when binding as
+.Ic bind_dn .
+.It Ic attr_user Ar attribute name;
+The attribute used to specify a users name in an ldap directory.
+For example,
+if a user dn is "cn=jdoe,dc=my,dc=net" then the attribute would be "cn".
+The default value is
+.Ic cn .
+.It Ic attr_addr Ar attribute name;
+.It Ic attr_mask Ar attribute name;
+The attributes used to specify a users network address and subnet mask in an
+ldap directory.
+These values are forwarded during mode_cfg negotiation when
+the conf_source is set to ldap.
+The default values are
+.Ic racoon-address
+and
+.Ic racoon-netmask .
+.It Ic attr_group Ar attribute name;
+The attribute used to specify a group name in an ldap directory.
+For example,
+if a group dn is "cn=users,dc=my,dc=net" then the attribute would be "cn".
+The default value is
+.Ic cn .
+.It Ic attr_member Ar attribute name;
+The attribute used to specify group membership in an ldap directory.
+The default value is
+.Ic member .
+.El
+.El
 .Ss Special directives
 .Bl -tag -width Ds -compact
-.It Ic complex_bundle (on \(ba off) ;
+.It Ic complex_bundle (on | off) ;
 defines the interpretation of proposal in the case of SA bundle.
 Normally
 .Dq IP AH ESP IP payload
@@ -1121,6 +1361,25 @@ sainfo anonymous
 }
 .Ed
 .Pp
+If you are configuring plain RSA authentication, the remote directive
+should look like the following:
+.Bd -literal -offset
+path certificate "/usr/local/v6/etc" ;
+remote anonymous
+{
+        exchange_mode main,base ;
+        lifetime time 12 hour ;
+        certificate_type plain_rsa "/usr/local/v6/etc/myrsakey.priv";
+        peers_certfile plain_rsa "/usr/local/v6/etc/yourrsakey.pub";
+        proposal {
+                        encryption_algorithm aes ;
+                        hash_algorithm sha1 ;
+                        authentication_method rsasig ;
+                        dh_group 2 ;
+        }
+}
+.Ed
+.Pp
 The following is a sample for the pre-shared key file.
 .Bd -literal -offset
 10.160.94.3     mekmitasdigoat
index cf292a5e9639c71365b2af1829fb47ed2ea1a996..b27b188a9938539fd1d488bb49035abb2c244938 100644 (file)
@@ -1,4 +1,6 @@
-.\" $Id: racoonctl.8,v 1.2.4.2 2005/04/18 11:10:55 manubsd Exp $
+.\"    $NetBSD: racoonctl.8,v 1.13 2006/09/09 16:22:10 manu Exp $
+.\"
+.\" Id: racoonctl.8,v 1.6 2006/05/07 21:32:59 manubsd Exp
 .\"
 .\" Copyright (C) 2004 Emmanuel Dreyfus
 .\" All rights reserved.
@@ -64,6 +66,9 @@ vpn-disconnect
 .Nm
 show-event
 .Op Fl l
+.Nm
+logout-user
+.Ar login
 .\"
 .Sh DESCRIPTION
 .Nm
@@ -86,7 +91,6 @@ The following commands are available:
 This should cause
 .Xr racoon 8
 to reload its configuration file.
-This seems completely broken at the time this man page is written.
 .It show-schedule
 Unknown command.
 .It show-sa Op isakmp|esp|ah|ipsec
@@ -141,6 +145,9 @@ flag causes
 .Nm
 to not stop once all the events have been read, but rather to loop
 awaiting and reporting new events.
+.It logout-user Ar login
+Delete all SA established on behalf of the Xauth user
+.Ar login .
 .El
 .Pp
 Command shortcuts are available:
@@ -163,6 +170,8 @@ vpn-connect
 vpn-disconnect
 .It se
 show-event
+.It lu
+logout-user
 .El
 .\"
 .Sh RETURN VALUES
index e59b1f90b09cbdac7439462528a3e27135b40485..9f5f77af479ede2ab378d15998ec13a8103bdbff 100644 (file)
@@ -1,4 +1,6 @@
-/*     $Id: racoonctl.c,v 1.2.2.1 2005/04/21 09:07:20 monas Exp $ */
+/*     $NetBSD: racoonctl.c,v 1.7 2006/10/02 07:12:26 manu Exp $       */
+
+/*     Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -65,6 +67,7 @@
 #endif
 #include <err.h>
 #include <sys/ioctl.h> 
+#include <resolv.h>
 
 #include "var.h"
 #include "vmbuf.h"
@@ -77,6 +80,7 @@
 #include "handler.h"
 #include "sockmisc.h"
 #include "vmbuf.h"
+#include "plog.h"
 #include "isakmp_var.h"
 #include "isakmp.h"
 #include "isakmp_xauth.h"
@@ -97,8 +101,13 @@ static vchar_t *f_flushsa __P((int, char **));
 static vchar_t *f_deletesa __P((int, char **));
 static vchar_t *f_exchangesa __P((int, char **));
 static vchar_t *f_vpnc __P((int, char **));
+static vchar_t *f_exchangesatest __P((int, char **));
+static vchar_t *f_vpntest __P((int, char **));
 static vchar_t *f_vpnd __P((int, char **));
 static vchar_t *f_getevt __P((int, char **));
+#ifdef ENABLE_HYBRID
+static vchar_t *f_logoutusr __P((int, char **));
+#endif
 
 struct cmd_tag {
        vchar_t *(*func) __P((int, char **));
@@ -119,10 +128,15 @@ struct cmd_tag {
        { f_exchangesa, ADMIN_ESTABLISH_SA,     "es" },
        { f_vpnc,       ADMIN_ESTABLISH_SA,     "vpn-connect" },
        { f_vpnc,       ADMIN_ESTABLISH_SA,     "vc" },
+       { f_vpntest, ADMIN_ESTABLISH_SA_VPNCONTROL, "vpntest" },
        { f_vpnd,       ADMIN_DELETE_ALL_SA_DST,"vpn-disconnect" },
        { f_vpnd,       ADMIN_DELETE_ALL_SA_DST,"vd" },
        { f_getevt,     ADMIN_SHOW_EVT,         "show-event" },
        { f_getevt,     ADMIN_SHOW_EVT,         "se" },
+#ifdef ENABLE_HYBRID
+       { f_logoutusr,  ADMIN_LOGOUT_USER,      "logout-user" },
+       { f_logoutusr,  ADMIN_LOGOUT_USER,      "lu" },
+#endif
        { NULL, 0, NULL },
 };
 
@@ -145,7 +159,10 @@ struct evtmsg {
        { EVTT_XAUTH_FAILED, "Xauth exchange failed", ERROR },
        { EVTT_PEERPH1AUTH_FAILED, "Peer failed phase 1 authentication "
            "(certificate problem?)", ERROR },
+       { EVTT_PEERPH1_NOPROP, "Peer failed phase 1 initiation "
+           "(proposal problem?)", ERROR },
        { 0, NULL, UNSPEC },
+       { EVTT_NO_ISAKMP_CFG, "No need for ISAKMP mode config ", INFO },
 };
 
 static int get_proto __P((char *));
@@ -207,6 +224,7 @@ void print_evt __P((caddr_t, int));
 void print_cfg __P((caddr_t, int));
 void print_err __P((caddr_t, int));
 void print_ph1down __P((caddr_t, int));
+void print_ph1up __P((caddr_t, int));
 int evt_poll __P((void));
 char * fixed_addr __P((char *, char *, int));
 
@@ -329,6 +347,7 @@ evt_poll(void) {
                errx(1, "Cannot make combuf");
 
        while (evt_filter & (EVTF_LOOP|EVTF_PURGE)) {
+               /* handle_recv closes the socket time, so open it each time */
                com_init();
                if (com_send(sendbuf) != 0)
                        errx(1, "Cannot send combuf");
@@ -343,7 +362,7 @@ evt_poll(void) {
                (void)select(0, NULL, NULL, NULL, &tv);
        }
 
-       /* NOTREACHED */
+       vfree(sendbuf);
        return 0;
 }
 
@@ -555,7 +574,7 @@ f_deletesa(ac, av)
 
        buf = vmalloc(sizeof(*head) + index->l);
        if (buf == NULL)
-               return NULL;
+               goto out;
 
        head = (struct admin_com *)buf->v;
        head->ac_len = buf->l + index->l;
@@ -565,6 +584,10 @@ f_deletesa(ac, av)
 
        memcpy(buf->v+sizeof(*head), index->v, index->l);
 
+out:
+       if (index != NULL)
+               vfree(index);
+
        return buf;
 }
 
@@ -606,7 +629,7 @@ f_deleteallsadst(ac, av)
 
        buf = vmalloc(sizeof(*head) + index->l);
        if (buf == NULL)
-               return NULL;
+               goto out;
 
        head = (struct admin_com *)buf->v;
        head->ac_len = buf->l + index->l;
@@ -616,6 +639,10 @@ f_deleteallsadst(ac, av)
 
        memcpy(buf->v+sizeof(*head), index->v, index->l);
 
+out:
+       if (index != NULL)
+               vfree(index);
+
        return buf;
 }
 
@@ -691,21 +718,123 @@ f_exchangesa(ac, av)
        memcpy(buf->v+sizeof(*head), index->v, index->l);
 
        if (id && key) {
+               // overload com_len to track the number of unused bytes in buf->v
                char *data;
                acp = (struct admin_com_psk *)
                    (buf->v + sizeof(*head) + index->l);
+               com_len -= sizeof(*head) + index->l;
 
-               acp->id_type = IDTYPE_LOGIN;
+               acp->id_type = IDTYPE_USERFQDN;
                acp->id_len = strlen(id) + 1;
                acp->key_len = strlen(key) + 1;
 
                data = (char *)(acp + 1);
-               strcpy(data, id);
+               com_len -= sizeof(*acp);
+               strlcpy(data, id, com_len);
 
                data = (char *)(data + acp->id_len);
-               strcpy(data, key);
+               com_len -= acp->id_len;
+               strlcpy(data, key, com_len);
        }
 
+       vfree(index);
+
+       return buf;
+}
+
+// %%%%% testing
+static vchar_t *
+f_exchangesatest(ac, av)
+       int ac;
+       char **av;
+{
+       vchar_t *buf, *index;
+       struct admin_com *head;
+       int proto;
+       int cmd = ADMIN_ESTABLISH_SA_VPNCONTROL;
+       size_t com_len = 0;
+       char *id = NULL;
+       char *key = NULL;
+       struct admin_com_psk *acp;
+
+       if (ac < 1)
+               errx(1, "insufficient arguments");
+
+       /* Optional -u identity */
+       if (strcmp(av[0], "-u") == 0) {
+               if (ac < 2)
+                       errx(1, "-u require an argument");
+
+               id = av[1];
+               if ((key = getpass("Password: ")) == NULL)
+                       errx(1, "getpass() failed: %s", strerror(errno));
+               
+               com_len += sizeof(*acp) + strlen(id) + 1 + strlen(key) + 1;
+               cmd = ADMIN_ESTABLISH_SA_VPNCONTROL;
+
+               av += 2;
+               ac -= 2;
+       }
+
+       /* need protocol */
+       if (ac < 1)
+               errx(1, "insufficient arguments");
+       if ((proto = get_proto(*av)) == -1)
+               errx(1, "unknown protocol %s", *av);
+
+       /* get index(es) */
+       av++;
+       ac--;
+       switch (proto) {
+       case ADMIN_PROTO_ISAKMP:
+               index = get_index(ac, av);
+               if (index == NULL)
+                       return NULL;
+               break;
+       case ADMIN_PROTO_AH:
+       case ADMIN_PROTO_ESP:
+               index = get_index(ac, av);
+               if (index == NULL)
+                       return NULL;
+               break;
+       default:
+               errno = EPROTONOSUPPORT;
+               return NULL;
+       }
+
+       com_len += sizeof(*head) + index->l;
+       if ((buf = vmalloc(com_len)) == NULL)
+               errx(1, "Cannot allocate buffer");
+
+       head = (struct admin_com *)buf->v;
+       head->ac_len = buf->l;
+       head->ac_cmd = cmd;
+       head->ac_errno = 0;
+       head->ac_proto = proto;
+
+       memcpy(buf->v+sizeof(*head), index->v, index->l);
+
+       if (id && key) {
+               // overload com_len to track the number of unused bytes in buf->v
+               char *data;
+               acp = (struct admin_com_psk *)
+                   (buf->v + sizeof(*head) + index->l);
+               com_len -= sizeof(*head) + index->l;
+
+               acp->id_type = IDTYPE_USERFQDN;
+               acp->id_len = strlen(id) + 1;
+               acp->key_len = strlen(key) + 1;
+
+               data = (char *)(acp + 1);
+               strlcpy(data, id, com_len);
+
+               data = (char *)(data + acp->id_len);
+               com_len -= acp->id_len;
+               strlcpy(data, key, com_len);
+       }
+
+       vfree(index);
+
        return buf;
 }
 
@@ -774,6 +903,72 @@ f_vpnc(ac, av)
        return f_exchangesa(nac, nav);
 }
 
+// %%% testing
+static vchar_t *
+f_vpntest(ac, av)
+       int ac;
+       char **av;
+{
+       char *nav[] = {NULL, NULL, NULL, NULL, NULL, NULL};
+       int nac = 0;
+       char *isakmp = "isakmp";
+       char *inet = "inet";
+       char *srcaddr;
+       struct addrinfo hints, *res;
+       struct sockaddr *src;
+       char *idx;
+
+       if (ac < 1)
+               errx(1, "insufficient arguments");
+
+       evt_filter = (EVTF_LOOP|EVTF_CFG|EVTF_CFG_STOP|EVTF_ERR|EVTF_ERR_STOP);
+       time(&evt_start);
+       
+       /* Optional -u identity */
+       if (strcmp(av[0], "-u") == 0) {
+               if (ac < 2)
+                       errx(1, "-u require an argument");
+
+               nav[nac++] = av[0];
+               nav[nac++] = av[1];
+
+               ac -= 2;
+               av += 2;
+       }
+
+       if (ac < 1)
+               errx(1, "VPN gateway required");        
+       if (ac > 1)
+               warnx("Extra arguments");
+
+       /*
+        * Find the source address
+        */
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = PF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+       if (getaddrinfo(av[0], "4500", &hints, &res) != 0)
+               errx(1, "Cannot resolve destination address");
+
+       if ((src = getlocaladdr(res->ai_addr)) == NULL)
+               errx(1, "cannot find source address");
+
+       if ((srcaddr = saddr2str(src)) == NULL)
+               errx(1, "cannot read source address");
+
+       /* We get "ip[port]" strip the port */
+       if ((idx = index(srcaddr, '[')) == NULL) 
+               errx(1, "unexpected source address format");
+       *idx = '\0';
+
+       nav[nac++] = isakmp;
+       nav[nac++] = inet;
+       nav[nac++] = srcaddr;
+       nav[nac++] = av[0];
+
+       return f_exchangesa(nac, nav);
+}
+
 static vchar_t *
 f_vpnd(ac, av)
        int ac;
@@ -785,7 +980,6 @@ f_vpnd(ac, av)
        char *inet = "inet";
        char *anyaddr = "0.0.0.0";
        char *idx;
-       vchar_t *buf, *index;
 
        if (ac < 1)
                errx(1, "VPN gateway required");        
@@ -803,6 +997,39 @@ f_vpnd(ac, av)
        return f_deleteallsadst(nac, nav);
 }
 
+#ifdef ENABLE_HYBRID
+static vchar_t *
+f_logoutusr(ac, av)
+       int ac;
+       char **av;
+{
+       vchar_t *buf;
+       struct admin_com *head;
+       char *user;
+
+       /* need username */
+       if (ac < 1)
+               errx(1, "insufficient arguments");
+       user = av[0];
+       if ((user == NULL) || ((strlen(user) + 1) > LOGINLEN))
+               errx(1, "bad login (too long?)");
+
+       buf = vmalloc(sizeof(*head) + LOGINLEN);
+       if (buf == NULL)
+               return NULL;
+
+       head = (struct admin_com *)buf->v;
+       head->ac_len = buf->l;
+       head->ac_cmd = ADMIN_LOGOUT_USER;
+       head->ac_errno = 0;
+       head->ac_proto = 0;
+
+       strlcpy((char *)(head + 1), user, LOGINLEN);
+
+       return buf;
+}
+#endif /* ENABLE_HYBRID */
+
 
 static int
 get_proto(str)
@@ -959,28 +1186,34 @@ get_comindex(str, name, port, pref)
 
        *name = *port = *pref = NULL;
 
-       *name = strdup(str);
+       *name = racoon_strdup(str);
+       STRDUP_FATAL(*name);
        p = strpbrk(*name, "/[");
        if (p != NULL) {
                if (*(p + 1) == '\0')
                        goto bad;
                if (*p == '/') {
                        *p = '\0';
-                       *pref = strdup(p + 1);
+                       *pref = racoon_strdup(p + 1);
+                       STRDUP_FATAL(*pref);
                        p = strchr(*pref, '[');
                        if (p != NULL) {
                                if (*(p + 1) == '\0')
                                        goto bad;
                                *p = '\0';
-                               *port = strdup(p + 1);
+                               *port = racoon_strdup(p + 1);
+                               STRDUP_FATAL(*port);
                                p = strchr(*pref, ']');
                                if (p == NULL)
                                        goto bad;
                                *p = '\0';
                        }
                } else if (*p == '[') {
+                       if (*pref == NULL)
+                               goto bad;
                        *p = '\0';
-                       *port = strdup(p + 1);
+                       *port = racoon_strdup(p + 1);
+                       STRDUP_FATAL(*port);
                        p = strchr(*pref, ']');
                        if (p == NULL)
                                goto bad;
@@ -1369,7 +1602,8 @@ print_cfg(buf, len)
        
        memset(&addr4, 0, sizeof(addr4));
 
-       if (evtdump->type != EVTT_ISAKMP_CFG_DONE)
+       if (evtdump->type != EVTT_ISAKMP_CFG_DONE && 
+           evtdump->type != EVTT_NO_ISAKMP_CFG)
                return;
 
        len -= sizeof(*evtdump);
@@ -1422,8 +1656,12 @@ print_cfg(buf, len)
                            (n + sizeof(*attr) + ntohs(attr->lorv));
                }
        }
-
-       printf("Bound to address %s\n", inet_ntoa(addr4));
+       
+       if (evtdump->type == EVTT_ISAKMP_CFG_DONE)
+               printf("Bound to address %s\n", inet_ntoa(addr4));
+       else
+               printf("VPN connexion established\n");
+       
        if (banner) {
                struct winsize win;
                int col = 0;
@@ -1438,6 +1676,7 @@ print_cfg(buf, len)
                for (i = 0; i < col; i++)
                        printf("%c", '=');
                printf("\n");
+               racoon_free(banner);
        }
        
        if (evt_filter & EVTF_CFG_STOP)
index 2b8b5a858cb963fd83a2ac05ceb3547d4a75d7af..d507213165f5ea9a8dc447c66628da19cc5324f7 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: racoonctl.h,v 1.2 2004/12/30 11:08:32 manubsd Exp $ */
+/*     $NetBSD: racoonctl.h,v 1.4 2006/09/09 16:22:10 manu Exp $       */
+
+/* Id: racoonctl.h,v 1.3 2005/06/19 22:37:47 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -33,7 +35,7 @@
 #define _RACOONCTL_H
 
 /* bumped on any change to the interface */
-#define RACOONCTL_INTERFACE    20041230
+#define RACOONCTL_INTERFACE    20050619
 extern u_int32_t racoonctl_interface;
 
 /* bumped when introducing changes that break backward compatibility */
index 0185db699b7be65f7f9f0a335c88004f20a9f270..c7790da4d62b923ee10d7ffa49bda07d3eb4b19b 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: remoteconf.c,v 1.26.2.5 2005/11/06 17:18:26 monas Exp $ */
+/*     $NetBSD: remoteconf.c,v 1.9.4.1 2007/08/01 11:52:22 vanhu Exp $ */
+
+/* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 #include "debug.h"
 
 #include "isakmp_var.h"
+#ifdef ENABLE_HYBRID
+#include "isakmp_xauth.h"
+#endif
 #include "isakmp.h"
 #include "ipsec_doi.h"
 #include "oakley.h"
 #include "remoteconf.h"
 #include "localconf.h"
 #include "grabmyaddr.h"
+#include "policy.h"
 #include "proposal.h"
 #include "vendorid.h"
 #include "gcmalloc.h"
 #include "strnames.h"
 #include "algorithm.h"
 #include "nattraversal.h"
+#include "isakmp_frag.h"
 #include "genlist.h"
 #include "rsalist.h"
 
@@ -81,7 +88,6 @@ static TAILQ_HEAD(_rmtree, remoteconf) rmtree;
  * Script hook names and script hook paths
  */
 char *script_names[SCRIPT_MAX + 1] = { "phase1_up", "phase1_down" };
-vchar_t *script_paths = NULL;
 
 /*%%%*/
 /*
@@ -147,6 +153,11 @@ getrmconf_strict(remote, allow_anon)
        }
 
        TAILQ_FOREACH(p, &rmtree, chain) {
+#ifdef __APPLE__
+               if (p->to_delete || p->to_remove) {
+                       continue;
+               }
+#endif
                if ((remote->sa_family == AF_UNSPEC
                     && remote->sa_family == p->remote->sa_family)
                 || (!withport && cmpsaddrwop(remote, p->remote) == 0)
@@ -173,6 +184,20 @@ getrmconf_strict(remote, allow_anon)
        return NULL;
 }
 
+int
+no_remote_configs()
+{
+       
+       struct remoteconf *p;
+
+       TAILQ_FOREACH(p, &rmtree, chain) {
+               if (p->remote->sa_family == AF_UNSPEC)  /* anonymous */
+                       continue;
+               return 0;
+       }
+       return 1;
+}
+
 struct remoteconf *
 getrmconf(remote)
        struct sockaddr *remote;
@@ -180,6 +205,43 @@ getrmconf(remote)
        return getrmconf_strict(remote, 1);
 }
 
+#ifdef __APPLE__
+int
+link_rmconf_to_ph1 (struct remoteconf *new)
+{
+       if (!new) {
+               return(-1);
+       }
+       if (new->to_delete ||
+               new->to_remove) {
+               return(-1);
+       }
+       new->linked_to_ph1++;
+       return(0);
+}
+
+int
+unlink_rmconf_from_ph1 (struct remoteconf *old)
+{
+       if (!old) {
+               return(-1);
+       }
+       if (old->linked_to_ph1 <= 0) {
+               return(-1);
+       }
+       old->linked_to_ph1--;
+       if (old->linked_to_ph1 == 0) {
+               if (old->to_remove) {
+                       remrmconf(old);
+               }
+               if (old->to_delete) {
+                       delrmconf(old);
+               }
+       }
+       return(0);
+}
+#endif
+
 struct remoteconf *
 newrmconf()
 {
@@ -209,18 +271,23 @@ newrmconf()
        new->getcert_method = ISAKMP_GETCERT_PAYLOAD;
        new->getcacert_method = ISAKMP_GETCERT_LOCALFILE;
        new->cacerttype = ISAKMP_CERT_X509SIGN;
+       new->certtype = ISAKMP_CERT_NONE;
        new->cacertfile = NULL;
        new->send_cert = TRUE;
        new->send_cr = TRUE;
        new->support_proxy = FALSE;
        for (i = 0; i <= SCRIPT_MAX; i++)
-               new->script[i] = -1;
+               new->script[i] = NULL;
        new->gen_policy = FALSE;
        new->retry_counter = lcconf->retry_counter;
        new->retry_interval = lcconf->retry_interval;
 #ifdef __APPLE__
        new->nat_traversal = NATT_ON;
        new->natt_multiple_user = FALSE;
+       new->natt_keepalive = TRUE;
+       new->to_remove = FALSE;
+       new->to_delete = FALSE;
+       new->linked_to_ph1 = 0;
 #else
        new->nat_traversal = NATT_OFF;
 #endif
@@ -233,7 +300,15 @@ newrmconf()
        new->dpd_interval = 0; /* Disable DPD checks by default */
        new->dpd_retry = 5;
        new->dpd_maxfails = 5;
+    new->dpd_algo = DPD_ALGO_INBOUND_DETECT;
+    new->idle_timeout = 0;
 
+       new->weak_phase1_check = 0;
+
+#ifdef ENABLE_HYBRID
+       new->xauth = NULL;
+#endif
+       new->initiate_ph1rekey = TRUE;
        return new;
 }
 
@@ -266,8 +341,10 @@ dupidvl(entry, arg)
        id = newidspec();
        if (!id) return (void *) -1;
 
-       if (set_identifier(&id->id, old->idtype, old->id) != 0) 
+       if (set_identifier(&id->id, old->idtype, old->id) != 0) {
+               racoon_free(id);
                return (void *) -1;
+       }
 
        id->idtype = old->idtype;
 
@@ -338,10 +415,22 @@ void
 delrmconf(rmconf)
        struct remoteconf *rmconf;
 {
+#ifdef __APPLE__
+       if (rmconf->linked_to_ph1) {
+               rmconf->to_delete = TRUE;
+               return;
+       }
+#endif
        if (rmconf->remote)
                racoon_free(rmconf->remote);
-       if (rmconf->etypes)
+#ifdef ENABLE_HYBRID
+       if (rmconf->xauth)
+               xauth_rmconf_delete(&rmconf->xauth);
+#endif
+       if (rmconf->etypes) {
                deletypes(rmconf->etypes);
+               rmconf->etypes=NULL;
+       }
        if (rmconf->idv)
                vfree(rmconf->idv);
        if (rmconf->idvl_p)
@@ -436,6 +525,12 @@ void
 remrmconf(rmconf)
        struct remoteconf *rmconf;
 {
+#ifdef __APPLE__
+       if (rmconf->linked_to_ph1) {
+               rmconf->to_remove = TRUE;
+               return;
+       }
+#endif
        TAILQ_REMOVE(&rmtree, rmconf, chain);
 }
 
@@ -622,7 +717,8 @@ dump_rmconf_single (struct remoteconf *p, void *data)
        plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n",
                s_switch (p->passive));
        plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n",
-               s_switch (p->ike_frag));
+               p->ike_frag == ISAKMP_FRAG_FORCE ?
+                       "force" : s_switch (p->ike_frag));
        plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag);
        plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n",
                s_switch (p->ini_contact));
@@ -678,13 +774,13 @@ newidspec()
        return new;
 }
 
-int
+vchar_t *
 script_path_add(path)
        vchar_t *path;
 {
        char *script_dir;
-       vchar_t *new_storage;
        vchar_t *new_path;
+       vchar_t *new_storage;
        vchar_t **sp;
        size_t len;
        size_t size;
@@ -698,44 +794,24 @@ script_path_add(path)
                if ((new_path = vmalloc(len)) == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
                            "Cannot allocate memory: %s\n", strerror(errno));
-                       return -1;
+                       return NULL;
                }
 
                new_path->v[0] = '\0';
-               (void)strlcat(new_path->v, script_dir, len);
-               (void)strlcat(new_path->v, "/", len);
-               (void)strlcat(new_path->v, path->v, len);
+               (void)strlcat(new_path->v, script_dir, new_path->l);
+               (void)strlcat(new_path->v, "/", new_path->l);
+               (void)strlcat(new_path->v, path->v, new_path->l);
 
                vfree(path);
                path = new_path;
        }
 
-       /* First time, initialize */
-       if (script_paths == NULL)
-               len = sizeof(vchar_t *);
-       else
-               len = script_paths->l;
-
-       /* Add a slot for a new path */
-       len += sizeof(vchar_t *);
-       if ((new_storage = vrealloc(script_paths, len)) == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "Cannot allocate memory: %s\n", strerror(errno));
-               return -1;
-       }
-       script_paths = new_storage;
-
-       size = len / sizeof(vchar_t *);
-       sp = (vchar_t **)script_paths->v;       
-       sp[size - 1] = NULL;
-       sp[size - 2] = path;
-
-       return (size - 2);
+       return path;
 }
 
+
 struct isakmpsa *
-dupisakmpsa(sa)
-       struct isakmpsa *sa;
+dupisakmpsa(struct isakmpsa *sa)
 {
        struct isakmpsa *res = NULL;
 
@@ -748,9 +824,7 @@ dupisakmpsa(sa)
 
        *res = *sa;
 #ifdef HAVE_GSSAPI
-       /* 
-        * XXX gssid
-        */
+       res->gssid=vdup(sa->gssid);
 #endif
        res->next=NULL;
 
index 0a9d485ee2dc8560fc011224a84aca7ea11e1579..ee171daaa117073da8921e4424dceff4b49810f6 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: remoteconf.h,v 1.19.2.1 2005/05/20 00:37:42 manubsd Exp $ */
+/*     $NetBSD: remoteconf.h,v 1.7 2006/10/03 08:01:56 vanhu Exp $     */
+
+/* Id: remoteconf.h,v 1.26 2006/05/06 15:52:44 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 
 #include <sys/queue.h>
 #include "genlist.h"
+#ifdef ENABLE_HYBRID
+#include "isakmp_var.h"
+#include "isakmp_xauth.h"
+#endif
 #ifdef __APPLE__
 #include <CoreFoundation/CFData.h>
 #endif
 #include "algorithm.h"
 
+
 struct proposalspec {
        time_t lifetime;                /* for isakmp/ipsec */
        int lifebyte;                   /* for isakmp/ipsec */
@@ -75,12 +82,18 @@ struct etypes {
        struct etypes *next;
 };
 
+enum {
+    DPD_ALGO_DEFAULT = 0,
+    DPD_ALGO_INBOUND_DETECT,
+    DPD_ALGO_BLACKHOLE_DETECT,
+    DPD_ALGO_MAX,
+};
+
 /* Script hooks */
 #define SCRIPT_PHASE1_UP       0
 #define SCRIPT_PHASE1_DOWN     1
 #define SCRIPT_MAX             1
 extern char *script_names[SCRIPT_MAX + 1];
-extern vchar_t *script_paths;
 
 struct remoteconf {
        struct sockaddr *remote;        /* remote IP address */
@@ -127,14 +140,18 @@ struct remoteconf {
        int esp_frag;                   /* ESP fragmentation */
        int mode_cfg;                   /* Gets config through mode config */
        int support_proxy;              /* support mip6/proxy */
+#define GENERATE_POLICY_NONE   0
+#define GENERATE_POLICY_REQUIRE        1
+#define GENERATE_POLICY_UNIQUE 2
        int gen_policy;                 /* generate policy if no policy found */
        int ini_contact;                /* initial contact */
        int pcheck_level;               /* level of propocl checking */
        int nat_traversal;              /* NAT-Traversal */
 #ifdef __APPLE__
        int natt_multiple_user; /* special handling of multiple users behind a nat - for VPN server */
+       int natt_keepalive;             /* do we need to send natt keep alive */
 #endif
-       int script[SCRIPT_MAX + 1];     /* script hooks index in script_paths */
+       vchar_t *script[SCRIPT_MAX + 1];        /* script hooks paths */
        int dh_group;                   /* use it when only aggressive mode */
        struct dhgroup *dhgrp;          /* use it when only aggressive mode */
                                        /* above two can't be defined by user*/
@@ -146,7 +163,14 @@ struct remoteconf {
        int dpd;                                /* Negociate DPD support ? */
        int dpd_retry;                  /* in seconds */
        int dpd_interval;               /* in seconds */
-       int dpd_maxfails; 
+       int dpd_maxfails;
+    int dpd_algo;
+    int idle_timeout;       /* in seconds */
+    int idle_timeout_dir;   /* direction to check */
+       
+       int ph1id; /* ph1id to be matched with sainfo sections */
+
+       int weak_phase1_check;          /* act on unencrypted deletions ? */
 
        struct isakmpsa *proposal;      /* proposal list */
        struct remoteconf *inherited_from;      /* the original rmconf 
@@ -156,6 +180,18 @@ struct remoteconf {
 
        struct genlist  *rsa_private,   /* lists of PlainRSA keys to use */
                        *rsa_public;
+
+#ifdef ENABLE_HYBRID
+       struct xauth_rmconf *xauth;
+#endif
+       int initiate_ph1rekey;
+
+#ifdef __APPLE__
+       int    to_remove;
+       int    to_delete;
+       int    linked_to_ph1;
+#endif
+
        TAILQ_ENTRY(remoteconf) chain;  /* next remote conf */
 };
 
@@ -192,6 +228,12 @@ typedef struct remoteconf * (rmconf_func_t)(struct remoteconf *rmconf, void *dat
 extern struct remoteconf *getrmconf __P((struct sockaddr *));
 extern struct remoteconf *getrmconf_strict
        __P((struct sockaddr *remote, int allow_anon));
+
+#ifdef __APPLE__
+extern int link_rmconf_to_ph1 __P((struct remoteconf *));
+extern int unlink_rmconf_from_ph1 __P((struct remoteconf *));
+#endif
+extern int no_remote_configs __P((void));
 extern struct remoteconf *copyrmconf __P((struct sockaddr *));
 extern struct remoteconf *newrmconf __P((void));
 extern struct remoteconf *duprmconf __P((struct remoteconf *));
@@ -217,7 +259,7 @@ extern void dumprmconf __P((void));
 
 extern struct idspec *newidspec __P((void));
 
-extern int script_path_add __P((vchar_t *));
+extern vchar_t *script_path_add __P((vchar_t *));
 
 extern void rsa_key_free __P((void *entry));
 
index 3db208de9f38c30fe3f25cf1de64806a382b17dd..850aa4c3ba94fd186870aad312ab513927b3704a 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: rsalist.c,v 1.3 2004/11/08 12:04:23 ludvigm Exp $ */
+/*     $NetBSD: rsalist.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */
+
+/* Id: rsalist.c,v 1.3 2004/11/08 12:04:23 ludvigm Exp */
 
 /*
  * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
index 4ee4c4c42bd3f2fad9f90b2d52d2ef9a81408feb..911670f6c11b2b0a5c5b0ecb2c9425ad3c158ea7 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: rsalist.h,v 1.2 2004/07/12 20:43:51 ludvigm Exp $ */
+/*     $NetBSD: rsalist.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */
+
+/* Id: rsalist.h,v 1.2 2004/07/12 20:43:51 ludvigm Exp */
 /*
  * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
  * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs
index b698fa765c3540bfcb4a6ef5a3bcf4f9fcd2bfa8..52410920f4dd66608bc0a1685e6890e15177e0d8 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: safefile.c,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
 /*     $KAME: safefile.c,v 1.5 2001/03/05 19:54:06 thorpej Exp $       */
 
 /*
index 2651e7efb3f0924d40be468ca09978e31cbb854a..c8d6a6c39f05ca7a6622e137b92e90d3c9b1947e 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: safefile.h,v 1.4 2004/07/12 18:32:12 ludvigm Exp $ */
+/*     $NetBSD: safefile.h,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
+/* Id: safefile.h,v 1.4 2004/07/12 18:32:12 ludvigm Exp */
 
 /*
  * Copyright (C) 2000 WIDE Project.
index 502914b981ab58a8f9db41a22267586707a82ee7..87093ab483669ea9da410f4a39d4bf556005feda 100644 (file)
@@ -90,10 +90,32 @@ getsainfo(src, dst, peer, use_nat_addr)
        if (use_nat_addr && lcconf->ext_nat_id == NULL)
                return NULL;
 
+       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - src id:\n");
+       if (src != NULL)
+               plogdump(LLV_DEBUG2, src->v, src->l);
+       else
+               plog(LLV_DEBUG2, LOCATION, NULL, " anonymous\n");
+       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - dst id:\n");
+       if (dst != NULL)
+               plogdump(LLV_DEBUG2, dst->v, dst->l);
+       else
+               plog(LLV_DEBUG2, LOCATION, NULL, " anonymous\n");
        if (peer == NULL)
                pass = 2;
     again:
        LIST_FOREACH(s, &sitree, chain) {
+#ifdef __APPLE__
+               if (s->to_delete || s->to_remove) {
+                       continue;
+               }
+#endif /* __APPLE__ */
+               if (s->idsrc != NULL) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - sainfo id - src & dst:\n");
+                       plogdump(LLV_DEBUG2, s->idsrc->v, s->idsrc->l);
+                       plogdump(LLV_DEBUG2, s->iddst->v, s->iddst->l);
+               } else {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - sainfo id = anonymous\n");
+               }
                if (s->id_i != NULL) {
                        if (pass == 2)
                                continue;
@@ -115,8 +137,12 @@ getsainfo(src, dst, peer, use_nat_addr)
 
                if (memcmp(src->v, s->idsrc->v, s->idsrc->l) == 0) {
                        if (use_nat_addr) {
-                               if (memcmp(lcconf->ext_nat_id->v, s->iddst->v, s->iddst->l) == 0)
+                               if (memcmp(lcconf->ext_nat_id->v, s->iddst->v, s->iddst->l) == 0) {
+                                       plog(LLV_DEBUG, LOCATION, NULL,
+                                               "matched external nat address.\n");
+                                       plogdump(LLV_DEBUG2, lcconf->ext_nat_id->v, lcconf->ext_nat_id->l);
                                        return s;
+                               }
                        } else if (memcmp(dst->v, s->iddst->v, s->iddst->l) == 0)
                                return s;
                }
@@ -133,6 +159,43 @@ getsainfo(src, dst, peer, use_nat_addr)
        return anonymous;
 }
 
+#ifdef __APPLE__
+int
+link_sainfo_to_ph2 (struct sainfo *new)
+{
+       if (!new) {
+               return(-1);
+       }
+       if (new->to_delete ||
+               new->to_remove) {
+               return(-1);
+       }
+       new->linked_to_ph2++;
+       return(0);
+}
+
+int
+unlink_sainfo_from_ph2 (struct sainfo *old)
+{
+       if (!old) {
+               return(-1);
+       }
+       if (old->linked_to_ph2 <= 0) {
+               return(-1);
+       }
+       old->linked_to_ph2--;
+       if (old->linked_to_ph2 == 0) {
+               if (old->to_remove) {
+                       remsainfo(old);
+               }
+               if (old->to_delete) {
+                       delsainfo(old);
+               }
+       }
+       return(0);
+}
+#endif
+
 struct sainfo *
 newsainfo()
 {
@@ -144,6 +207,11 @@ newsainfo()
 
        new->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
        new->lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX;
+#ifdef __APPLE__
+       new->to_remove = FALSE;
+       new->to_delete = FALSE;
+       new->linked_to_ph2 = 0;
+#endif
 
        return new;
 }
@@ -154,6 +222,13 @@ delsainfo(si)
 {
        int i;
 
+#ifdef __APPLE__
+       if (si->linked_to_ph2) {
+               si->to_delete = TRUE;
+               return;
+       }
+#endif
+       
        for (i = 0; i < MAXALGCLASS; i++)
                delsainfoalg(si->algs[i]);
 
@@ -162,6 +237,11 @@ delsainfo(si)
        if (si->iddst)
                vfree(si->iddst);
 
+#ifdef ENABLE_HYBRID
+       if (si->group)
+               vfree(si->group);
+#endif
+
        racoon_free(si);
 }
 
@@ -176,6 +256,12 @@ void
 remsainfo(si)
        struct sainfo *si;
 {
+#ifdef __APPLE__
+       if (si->linked_to_ph2) {
+               si->to_remove = TRUE;
+               return;
+       }
+#endif
        LIST_REMOVE(si, chain);
 }
 
@@ -186,8 +272,24 @@ flushsainfo()
 
        for (s = LIST_FIRST(&sitree); s; s = next) {
                next = LIST_NEXT(s, chain);
-               remsainfo(s);
-               delsainfo(s);
+               if (s->dynamic == 0) {
+                       remsainfo(s);
+                       delsainfo(s);
+               }
+       }
+}
+
+void
+flushsainfo_dynamic(u_int32_t addr)
+{
+       struct sainfo *s, *next;
+
+       for (s = LIST_FIRST(&sitree); s; s = next) {
+               next = LIST_NEXT(s, chain);
+               if (s->dynamic == addr) {
+                       remsainfo(s);
+                       delsainfo(s);
+               }
        }
 }
 
@@ -240,19 +342,35 @@ const char *
 sainfo2str(si)
        const struct sainfo *si;
 {
+    char *idsrc_str;
+    char *iddst_str;
+    char *idi_str;
        static char buf[256];
 
        if (si->idsrc == NULL)
                snprintf(buf, sizeof(buf), "anonymous");
        else {
-               snprintf(buf, sizeof(buf), "%s", ipsecdoi_id2str(si->idsrc));
-               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                       " %s", ipsecdoi_id2str(si->iddst));
+        idsrc_str = ipsecdoi_id2str(si->idsrc);
+        if (idsrc_str) {
+            snprintf(buf, sizeof(buf), "%s", idsrc_str);
+            racoon_free(idsrc_str);
+        }
+        iddst_str = ipsecdoi_id2str(si->iddst);
+        if (iddst_str) {
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                     " %s", iddst_str);
+            racoon_free(iddst_str);
+        }
        }
 
-       if (si->id_i != NULL)
-               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                       " from %s", ipsecdoi_id2str(si->id_i));
+       if (si->id_i != NULL) {
+        idi_str = ipsecdoi_id2str(si->id_i);
+        if (idi_str) {
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                     " from %s", idi_str);
+            racoon_free(idi_str);
+        }
+    }
 
        return buf;
 }
index 77fff23006cde1818aef3155826acb7e8c55bcaa..c9bf7f07cc63714ca64a9f453e0e4f15f3a12e0a 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: sainfo.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp $ */
+/*     $NetBSD: sainfo.h,v 1.5 2006/10/03 08:01:56 vanhu Exp $ */
+
+/* Id: sainfo.h,v 1.5 2006/07/09 17:19:38 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -44,29 +46,43 @@ struct sainfo {
                 * If idsrc == NULL, that is anonymous entry.
                 */
 
+#ifdef ENABLE_HYBRID
+       vchar_t *group;
+#endif
+
        time_t lifetime;
        int lifebyte;
        int pfs_group;          /* only use when pfs is required. */
        vchar_t *id_i;          /* identifier of the authorized initiator */
        struct sainfoalg *algs[MAXALGCLASS];
-
+       int     dynamic;                /* created through vpn control socket */
+#ifdef __APPLE__
+       int to_remove;
+       int to_delete;
+       int linked_to_ph2;
+#endif
        LIST_ENTRY(sainfo) chain;
 };
 
 /* algorithm type */
 struct sainfoalg {
        int alg;
-       int encklen;                    /* key length if encryption algorithm */
+       int encklen;                    /* key length of encryption algorithm */
        struct sainfoalg *next;
 };
 
 extern struct sainfo *getsainfo __P((const vchar_t *,
        const vchar_t *, const vchar_t *, int));
+#ifdef __APPLE__
+extern int            link_sainfo_to_ph2 __P((struct sainfo *));
+extern int            unlink_sainfo_from_ph2 __P((struct sainfo *));
+#endif
 extern struct sainfo *newsainfo __P((void));
 extern void delsainfo __P((struct sainfo *));
 extern void inssainfo __P((struct sainfo *));
 extern void remsainfo __P((struct sainfo *));
 extern void flushsainfo __P((void));
+extern void flushsainfo_dynamic __P((u_int32_t));
 extern void initsainfo __P((void));
 extern struct sainfoalg *newsainfoalg __P((void));
 extern void delsainfoalg __P((struct sainfoalg *));
index 705f4ce6437ea06a969ce7a5bea09a195bcf00a0..74f5f203e48d70ef019238a83543c910ffabc5b4 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: schedule.c,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
 /*     $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $       */
 
 /*
@@ -56,6 +58,7 @@
         for (elm = TAILQ_FIRST(head); elm; elm = TAILQ_NEXT(elm, field))
 #endif
 
+extern int             terminated;
 static struct timeval timeout;
 
 #ifdef FIXY2038PROBLEM
@@ -83,7 +86,7 @@ schedular()
 
        now = current_time();
 
-        for (p = TAILQ_FIRST(&sctree); p; p = next) {
+       for (p = TAILQ_FIRST(&sctree); p; p = next) {
                /* if the entry has been dead, remove it */
                if (p->dead)
                        goto next_schedule;
@@ -96,7 +99,7 @@ schedular()
 
                /* mark it with dead. and call the function. */
                p->dead = 1;
-               if (p->func != NULL)
+               if (p->func != NULL && !terminated)
                        (p->func)(p->param);
 
           next_schedule:
@@ -308,7 +311,7 @@ getstdin()
                struct scheddump *scbuf, *p;
                int len;
                sched_dump((caddr_t *)&scbuf, &len);
-               if (buf == NULL)
+               if (scbuf == NULL)
                        return;
                for (p = scbuf; len; p++) {
                        printf("xtime=%ld\n", p->xtime);
index bb2df2b5f4349adc04f6d88e7bb4b692428fc2e5..bd6659312e264a88c068f3c2f648495a7231e4ee 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: schedule.h,v 1.4 2004/11/18 15:14:44 ludvigm Exp $ */
+/*     $NetBSD: schedule.h,v 1.4.6.1 2007/03/21 14:29:48 vanhu Exp $   */
+
+/* Id: schedule.h,v 1.5 2006/05/03 21:53:42 vanhu Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -33,7 +35,7 @@
 #define _SCHEDULE_H
 
 #include <sys/queue.h>
-#include <gnuc.h>
+#include "gnuc.h"
 
 /* scheduling table */
 /* the head is the nearest event. */
@@ -57,8 +59,10 @@ struct sched {
 /* cancel schedule */
 #define SCHED_KILL(s)                                                          \
 do {                                                                           \
-       sched_kill(s);                                                         \
-       s = NULL;                                                              \
+       if(s != NULL){                                                                                                                  \
+               sched_kill(s);                                                         \
+               s = NULL;                                                              \
+       }\
 } while(0)
 
 /* must be called after it's called from scheduler. */
index 2f9f55786549e1249f315dd7da5088f83edc26f2..bcc4ad0615c2f34e88c4bbf0ff0e0900d0a497a7 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: session.c,v 1.7.6.2 2007/08/01 11:52:22 vanhu Exp $    */
+
 /*     $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $        */
 
 /*
 #include <sys/stat.h>
 #include <paths.h>
 
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+#include <resolv.h>
+#include <TargetConditionals.h>
+
 #include "libpfkey.h"
 
 #include "var.h"
@@ -76,6 +85,8 @@
 #include "evt.h"
 #include "cfparse_proto.h"
 #include "isakmp_var.h"
+#include "isakmp_xauth.h"
+#include "isakmp_cfg.h"
 #include "admin_var.h"
 #include "admin.h"
 #include "privsep.h"
 #endif
 #include "vpn_control_var.h"
 #include "policy.h"
+#include "algorithm.h" /* XXX ??? */
+
+#include "sainfo.h"
+
+
 
 extern pid_t racoon_pid;
 static void close_session __P((void));
@@ -109,6 +125,7 @@ static int nfds = 0;
 static volatile sig_atomic_t sigreq[NSIG + 1];
 static int dying = 0;
 static struct sched *check_rtsock_sched = NULL;
+int terminated = 0;
 
 int
 session(void)
@@ -126,7 +143,11 @@ session(void)
 
        initmyaddr();
 
+#ifndef __APPLE__
        if (isakmp_init() < 0) {
+#else
+       if (isakmp_init(false) < 0) {
+#endif /* __APPLE__ */
                plog(LLV_ERROR2, LOCATION, NULL,
                                "failed to initialize isakmp");
                exit(1);
@@ -145,6 +166,7 @@ session(void)
                        "failed to initialize vpn control port");
                exit(1);
        }
+       
 #endif
 
        init_signal();
@@ -169,12 +191,12 @@ session(void)
        if (!f_foreground) {
                racoon_pid = getpid();
                if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) 
-                       strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN);
+                       strlcpy(pid_file, _PATH_VARRUN "racoon.pid", sizeof(pid_file));
                else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') 
-                       strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
+                       strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file));
                else {
-                       strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN);
-                       strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
+                       strlcat(pid_file, _PATH_VARRUN, sizeof(pid_file));
+                       strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file));
                } 
                fp = fopen(pid_file, "w");
                if (fp) {
@@ -191,7 +213,7 @@ session(void)
                                "cannot open %s", pid_file);
                }
        }
-
+       
        while (1) {
                if (!TAILQ_EMPTY(&lcconf->saved_msg_queue))
                        pfkey_post_handler();
@@ -218,7 +240,17 @@ session(void)
                                plog(LLV_ERROR2, LOCATION, NULL,
                                        "failed select (%s)\n",
                                        strerror(errno));
-                               exit(1);
+                               /* serious socket problem - close all listening sockets and re-open */
+                               if (lcconf->autograbaddr) {
+                                       isakmp_close(); 
+                                       initfds();
+                                       sched_new(5, check_rtsock, NULL);
+                               } else {
+                                       isakmp_close_sockets();
+                                       isakmp_open();
+                                       initfds();
+                               }
+                               continue;
                        }
                        /*NOTREACHED*/
                }
@@ -249,7 +281,7 @@ session(void)
                                                update_fds = 1;         // socket closed by peer - update mask
                        }
                }
-#endif
+#endif                 
 
                for (p = lcconf->myaddrs; p; p = p->next) {
                        if (!p->addr)
@@ -294,7 +326,9 @@ session(void)
 static void
 close_session()
 {
-       flushph1();
+       if ( terminated )
+               flushph2(false);
+       flushph1(false);
        close_sockets();
        backupsa_clean();
 
@@ -367,7 +401,6 @@ initfds()
                        }
                }
        }
-
 #endif
 
        if (lcconf->sock_pfkey >= FD_SETSIZE) {
@@ -385,7 +418,7 @@ initfds()
                FD_SET(lcconf->rtsock, &mask0);
                nfds = (nfds > lcconf->rtsock ? nfds : lcconf->rtsock);
        }
-
+       
        for (p = lcconf->myaddrs; p; p = p->next) {
                if (!p->addr)
                        continue;
@@ -401,6 +434,7 @@ initfds()
        nfds++;
 }
 
+
 static int signals[] = {
        SIGHUP,
        SIGINT,
@@ -424,6 +458,9 @@ signal_handler(sig)
         * values to 0/1
         */
        sigreq[sig]++;
+       if ( sig == SIGTERM ){
+               terminated = 1;
+       }
 }
 
 static void
@@ -469,11 +506,23 @@ check_sigreq()
                        break;
 #endif
 
+               case SIGUSR1:
                case SIGHUP:
+#ifdef ENABLE_HYBRID
+                       if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM)) != 0) {
+                               plog(LLV_ERROR, LOCATION, NULL, 
+                                "ISAKMP mode config structure reset failed, "
+                                "not reloading\n");
+                               return;
+                       }
+#endif
+                       if ( terminated )
+                               break;
+                               
                        /* Save old configuration, load new one...  */
                        isakmp_close();
                        close(lcconf->rtsock);
-                       if (cfreparse()) {
+                       if (cfreparse(sig)) {
                                plog(LLV_ERROR2, LOCATION, NULL,
                                         "configuration read failed\n");
                                exit(1);
@@ -483,8 +532,24 @@ check_sigreq()
                                
                        initmyaddr();
                        isakmp_cleanup();
+#ifdef __APPLE__
+                       isakmp_init(true);
+#else
                        isakmp_init();
+#endif /* __APPLE__ */
                        initfds();
+#if TARGET_OS_EMBEDDED
+                       if (no_remote_configs()) {
+                               EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL);
+                               pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC);
+#ifdef ENABLE_FASTQUIT
+                               close_session();
+#else
+                               sched_new(1, check_flushsa_stub, NULL);
+#endif
+                               dying = 1;
+                       }
+#endif
                        break;
 
                case SIGINT:
@@ -494,8 +559,14 @@ check_sigreq()
                        EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL);
                        pfkey_send_flush(lcconf->sock_pfkey, 
                            SADB_SATYPE_UNSPEC);
-                       sched_new(1, check_flushsa_stub, NULL);
-                       dying = 1;
+                       if ( sig == SIGTERM ){
+                               terminated = 1;                 /* in case if it hasn't been set yet */
+                               close_session();
+                       }
+                       else
+                               sched_new(1, check_flushsa_stub, NULL);
+
+                               dying = 1;
                        break;
 
                default:
@@ -579,12 +650,18 @@ check_flushsa()
        }
 
        close_session();
+#if !TARGET_OS_EMBEDDED
+       if (lcconf->vt)
+               vproc_transaction_end(NULL, lcconf->vt);
+#endif
 }
 
 void
 auto_exit_do(void *p)
 {
        EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL);
+       plog(LLV_DEBUG, LOCATION, NULL,
+                               "performing auto exit\n");
        pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC);
        sched_new(1, check_flushsa_stub, NULL);
        dying = 1;
@@ -593,15 +670,14 @@ auto_exit_do(void *p)
 void
 check_auto_exit(void)
 {
-
        if (lcconf->auto_exit_sched != NULL) {  /* exit scheduled? */
                if (lcconf->auto_exit_state != LC_AUTOEXITSTATE_ENABLED
                        || vpn_control_connected()                              /* vpn control connected */
-                       || policies_installed())                                /* policies installed in kernel */
+                       || policies_installed())                        /* policies installed in kernel */
                        SCHED_KILL(lcconf->auto_exit_sched);
        } else {                                                                /* exit not scheduled */
                if (lcconf->auto_exit_state == LC_AUTOEXITSTATE_ENABLED
-                       && !vpn_control_connected()             
+                       && !vpn_control_connected()     
                        && !policies_installed())
                                if (lcconf->auto_exit_delay == 0)
                                        auto_exit_do(NULL);             /* immediate exit */
@@ -659,3 +735,4 @@ close_sockets()
        return 0;
 }
 
+
index 6625b0b9f5c6658c7e876546dd6af8c20a98f677..f410be959087df23ba1c2362f3eecc0d9c3d7639 100644 (file)
@@ -32,6 +32,8 @@
 #ifndef _SESSION_H
 #define _SESSION_H
 
+#include "handler.h"
+
 extern int session __P((void));
 extern RETSIGTYPE signal_handler __P((int));
 extern void check_auto_exit __P((void));
index 14399cc6b97d809cef9a0fd643bf309cc3d28c00..98d0a696b8cecb27be0b8f5e62d1e6137638812e 100644 (file)
@@ -43,7 +43,8 @@
 #include <netinet6/ipsec.h>
 #endif
 
-#if defined(IP_RECVDSTADDR) && !defined(IPV6_RECVDSTADDR)
+#if defined(INET6) && !defined(INET6_ADVAPI) && \
+       defined(IP_RECVDSTADDR) && !defined(IPV6_RECVDSTADDR)
 #define IPV6_RECVDSTADDR IP_RECVDSTADDR
 #endif
 
@@ -61,6 +62,7 @@
 #include "sockmisc.h"
 #include "debug.h"
 #include "gcmalloc.h"
+#include "debugrm.h"
 #include "libpfkey.h"
 
 #ifndef IP_IPSEC_POLICY
@@ -320,7 +322,7 @@ recvfromto(s, buf, buflen, flags, from, fromlen, to, tolen)
        u_int len;
        struct sockaddr_storage ss;
        struct msghdr m;
-       struct cmsghdr *cm;
+       struct cmsghdr *cm, *cm_prev;
        struct iovec iov[2];
        u_char cmsgbuf[256];
 #if defined(INET6) && defined(INET6_ADVAPI)
@@ -352,14 +354,16 @@ recvfromto(s, buf, buflen, flags, from, fromlen, to, tolen)
                plog(LLV_ERROR, LOCATION, NULL,
                        "recvmsg (%s)\n", strerror(errno));
                return -1;
+       } else if (len == 0) {
+               return 0;
        }
        *fromlen = m.msg_namelen;
 
        otolen = *tolen;
        *tolen = 0;
-       for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m);
-            m.msg_controllen != 0 && cm;
-            cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) {
+       for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m), cm_prev = NULL;
+            m.msg_controllen != 0 && cm && cm != cm_prev;
+            cm_prev = cm, cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) {
 #if 0
                plog(LLV_ERROR, LOCATION, NULL,
                        "cmsg %d %d\n", cm->cmsg_level, cm->cmsg_type);)
@@ -650,7 +654,8 @@ sendfromto(s, buf, buflen, src, dst, cnt)
 #endif
                                       (void *)&yes, sizeof(yes)) < 0) {
                                plog(LLV_ERROR, LOCATION, NULL,
-                                       "setsockopt (%s)\n", strerror(errno));
+                                       "setsockopt SO_REUSEPORT (%s)\n", 
+                                       strerror(errno));
                                close(sendsock);
                                return -1;
                        }
@@ -659,7 +664,8 @@ sendfromto(s, buf, buflen, src, dst, cnt)
                            setsockopt(sendsock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
                            (void *)&yes, sizeof(yes)) < 0) {
                                plog(LLV_ERROR, LOCATION, NULL,
-                                       "setsockopt (%s)\n", strerror(errno));
+                                       "setsockopt IPV6_USE_MIN_MTU (%s)\n", 
+                                       strerror(errno));
                                close(sendsock);
                                return -1;
                        }
@@ -738,7 +744,7 @@ setsockopt_bypass(so, family)
                                 IP_IPSEC_POLICY : IPV6_IPSEC_POLICY),
                       buf, ipsec_get_policylen(buf)) < 0) {
                plog(LLV_ERROR, LOCATION, NULL,
-                       "setsockopt (%s)\n",
+                       "setsockopt IP_IPSEC_POLICY (%s)\n",
                        strerror(errno));
                return -1;
        }
@@ -757,7 +763,7 @@ setsockopt_bypass(so, family)
                                 IP_IPSEC_POLICY : IPV6_IPSEC_POLICY),
                       buf, ipsec_get_policylen(buf)) < 0) {
                plog(LLV_ERROR, LOCATION, NULL,
-                       "setsockopt (%s)\n",
+                       "setsockopt IP_IPSEC_POLICY (%s)\n",
                        strerror(errno));
                return -1;
        }
@@ -772,10 +778,11 @@ newsaddr(len)
 {
        struct sockaddr *new;
 
-       new = racoon_calloc(1, len);
-       if (new == NULL)
+       if ((new = racoon_calloc(1, len)) == NULL) {
                plog(LLV_ERROR, LOCATION, NULL,
                        "%s\n", strerror(errno)); 
+               goto out;
+       }
 
 #ifdef __linux__
        if (len == sizeof (struct sockaddr_in6))
@@ -786,7 +793,7 @@ newsaddr(len)
        /* initial */
        new->sa_len = len;
 #endif
-
+out:
        return new;
 }
 
@@ -869,8 +876,10 @@ naddrwop2str_fromto(const char *format, const struct netaddr *saddr,
        static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100];
        char *src, *dst;
 
-       src = strdup(naddrwop2str(saddr));
-       dst = strdup(naddrwop2str(daddr));
+       src = racoon_strdup(naddrwop2str(saddr));
+       dst = racoon_strdup(naddrwop2str(daddr));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
        /* WARNING: Be careful about the format string! Don't 
           ever pass in something that a user can modify!!! */
        snprintf (buf, sizeof(buf), format, src, dst);
@@ -889,8 +898,10 @@ saddr2str_fromto(format, saddr, daddr)
        static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100];
        char *src, *dst;
 
-       src = strdup(saddr2str(saddr));
-       dst = strdup(saddr2str(daddr));
+       src = racoon_strdup(saddr2str(saddr));
+       dst = racoon_strdup(saddr2str(daddr));
+       STRDUP_FATAL(src);
+       STRDUP_FATAL(dst);
        /* WARNING: Be careful about the format string! Don't 
           ever pass in something that a user can modify!!! */
        snprintf (buf, sizeof(buf), format, src, dst);
@@ -995,7 +1006,7 @@ naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr)
 {
        static const struct netaddr naddr_any;  /* initialized to all-zeros */
        struct sockaddr sa;
-       uint16_t naddr_port, saddr_port;
+       u_int16_t naddr_port, saddr_port;
        int port_score;
 
        if (!naddr || !saddr) {
@@ -1027,9 +1038,12 @@ naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr)
        mask_sockaddr(&sa, saddr, naddr->prefix);
        if (loglevel >= LLV_DEBUG) {    /* debug only */
                char *a1, *a2, *a3;
-               a1 = strdup(naddrwop2str(naddr));
-               a2 = strdup(saddrwop2str(saddr));
-               a3 = strdup(saddrwop2str(&sa));
+               a1 = racoon_strdup(naddrwop2str(naddr));
+               a2 = racoon_strdup(saddrwop2str(saddr));
+               a3 = racoon_strdup(saddrwop2str(&sa));
+               STRDUP_FATAL(a1);
+               STRDUP_FATAL(a2);
+               STRDUP_FATAL(a3);
                plog(LLV_DEBUG, LOCATION, NULL,
                     "naddr=%s, saddr=%s (masked=%s)\n",
                     a1, a2, a3);
index 828c0b453850b7d2c454ad48ef2bde8fd8ed7539..5c940d6a5a833769473d9cd002846eba23ead9ba 100644 (file)
@@ -49,8 +49,10 @@ extern int cmpsaddrstrict __P((const struct sockaddr *, const struct sockaddr *)
 
 #ifdef ENABLE_NATT 
 #define CMPSADDR(saddr1, saddr2) cmpsaddrstrict((saddr1), (saddr2))
+#define CMPSADDR2(saddr1, saddr2) cmpsaddrwild((saddr1), (saddr2))
 #else 
 #define CMPSADDR(saddr1, saddr2) cmpsaddrwop((saddr1), (saddr2))
+#define CMPSADDR2(saddr1, saddr2) cmpsaddrwop((saddr1), (saddr2))
 #endif
 
 extern struct sockaddr *getlocaladdr __P((struct sockaddr *));
index 34562ee359ba756ffdfa8e8461f6b0f53b266211..ad6fea3b16000ed181432bf2d13fc6a16e34ebd9 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: strnames.c,v 1.7.6.1 2007/08/01 11:52:22 vanhu Exp $   */
+
 /*     $KAME: strnames.c,v 1.25 2003/11/13 10:53:26 itojun Exp $       */
 
 /*
@@ -45,6 +47,9 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
 
 #include "var.h"
 #include "misc.h"
 
 #include "isakmp_var.h"
 #include "isakmp.h"
+#ifdef ENABLE_HYBRID
+#  include "isakmp_xauth.h"
+#  include "isakmp_unity.h"
+#  include "isakmp_cfg.h"
+#endif
 #include "ipsec_doi.h"
 #include "oakley.h"
 #include "handler.h"
@@ -218,6 +228,7 @@ static struct ksmap name_isakmp_etype[] = {
 { ISAKMP_ETYPE_AUTH,   "Authentication Only",  NULL },
 { ISAKMP_ETYPE_AGG,    "Aggressive",           NULL },
 { ISAKMP_ETYPE_INFO,   "Informational",        NULL },
+{ ISAKMP_ETYPE_CFG,    "Mode config",          NULL },
 { ISAKMP_ETYPE_QUICK,  "Quick",                NULL },
 { ISAKMP_ETYPE_NEWGRP, "New Group",            NULL },
 { ISAKMP_ETYPE_ACKINFO,        "Acknowledged Informational",   NULL },
@@ -269,6 +280,9 @@ static struct ksmap name_isakmp_notify_msg[] = {
 { ISAKMP_NTYPE_RESPONDER_LIFETIME,     "RESPONDER-LIFETIME",           NULL },
 { ISAKMP_NTYPE_REPLAY_STATUS,          "REPLAY-STATUS",                NULL },
 { ISAKMP_NTYPE_INITIAL_CONTACT,                "INITIAL-CONTACT",              NULL },
+#ifdef ENABLE_HYBRID
+{ ISAKMP_NTYPE_UNITY_HEARTBEAT,                "HEARTBEAT (Unity)",            NULL },
+#endif
 { ISAKMP_LOG_RETRY_LIMIT_REACHED,      "RETRY-LIMIT-REACHED",          NULL },
 };
 
@@ -285,27 +299,27 @@ s_isakmp_notify_msg(k)
 }
 
 static struct ksmap name_isakmp_nptype[] = {
-{ ISAKMP_NPTYPE_NONE,  "none",         NULL },
-{ ISAKMP_NPTYPE_SA,    "sa",           NULL },
-{ ISAKMP_NPTYPE_P,     "prop",         NULL },
-{ ISAKMP_NPTYPE_T,     "trns",         NULL },
-{ ISAKMP_NPTYPE_KE,    "ke",           NULL },
-{ ISAKMP_NPTYPE_ID,    "id",           NULL },
-{ ISAKMP_NPTYPE_CERT,  "cert",         NULL },
-{ ISAKMP_NPTYPE_CR,    "cr",           NULL },
-{ ISAKMP_NPTYPE_HASH,  "hash",         NULL },
-{ ISAKMP_NPTYPE_SIG,   "sig",          NULL },
-{ ISAKMP_NPTYPE_NONCE, "nonce",        NULL },
-{ ISAKMP_NPTYPE_N,     "notify",       NULL },
-{ ISAKMP_NPTYPE_D,     "delete",       NULL },
-{ ISAKMP_NPTYPE_VID,   "vid",          NULL },
-{ ISAKMP_NPTYPE_GSS,   "gss id",       NULL },
+{ ISAKMP_NPTYPE_NONE,          "none",         NULL },
+{ ISAKMP_NPTYPE_SA,            "sa",           NULL },
+{ ISAKMP_NPTYPE_P,             "prop",         NULL },
+{ ISAKMP_NPTYPE_T,             "trns",         NULL },
+{ ISAKMP_NPTYPE_KE,            "ke",           NULL },
+{ ISAKMP_NPTYPE_ID,            "id",           NULL },
+{ ISAKMP_NPTYPE_CERT,          "cert",         NULL },
+{ ISAKMP_NPTYPE_CR,            "cr",           NULL },
+{ ISAKMP_NPTYPE_HASH,          "hash",         NULL },
+{ ISAKMP_NPTYPE_SIG,           "sig",          NULL },
+{ ISAKMP_NPTYPE_NONCE,         "nonce",        NULL },
+{ ISAKMP_NPTYPE_N,             "notify",       NULL },
+{ ISAKMP_NPTYPE_D,             "delete",       NULL },
+{ ISAKMP_NPTYPE_VID,           "vid",          NULL },
+{ ISAKMP_NPTYPE_ATTR,          "attr",         NULL },
+{ ISAKMP_NPTYPE_GSS,           "gss id",       NULL },
 { ISAKMP_NPTYPE_NATD_RFC,      "nat-d",        NULL },
 { ISAKMP_NPTYPE_NATOA_RFC,     "nat-oa",       NULL },
 { ISAKMP_NPTYPE_NATD_DRAFT,    "nat-d",        NULL },
 { ISAKMP_NPTYPE_NATOA_DRAFT,   "nat-oa",       NULL },
-{ ISAKMP_NPTYPE_NATD_BADDRAFT, "nat-d",        NULL },
-{ ISAKMP_NPTYPE_NATOA_BADDRAFT,        "nat-oa",       NULL }
+{ ISAKMP_NPTYPE_FRAG,          "ike frag",     NULL },
 };
 
 char *
@@ -319,6 +333,79 @@ s_isakmp_nptype(k)
        return num2str(k);
 }
 
+#ifdef ENABLE_HYBRID
+/* isakmp_cfg.h / isakmp_unity.h / isakmp_xauth.h */
+static struct ksmap name_isakmp_cfg_type[] = {
+{ INTERNAL_IP4_ADDRESS,                "INTERNAL_IP4_ADDRESS",         NULL },
+{ INTERNAL_IP4_NETMASK,                "INTERNAL_IP4_NETMASK",         NULL },
+{ INTERNAL_IP4_DNS,            "INTERNAL_IP4_DNS",             NULL },
+{ INTERNAL_IP4_NBNS,           "INTERNAL_IP4_NBNS",            NULL },
+{ INTERNAL_ADDRESS_EXPIRY,     "INTERNAL_ADDRESS_EXPIRY",      NULL },
+{ INTERNAL_IP4_DHCP,           "INTERNAL_IP4_DHCP",            NULL },
+{ APPLICATION_VERSION,         "APPLICATION_VERSION",          NULL },
+{ INTERNAL_IP6_ADDRESS,                "INTERNAL_IP6_ADDRESS",         NULL },
+{ INTERNAL_IP6_NETMASK,                "INTERNAL_IP6_NETMASK",         NULL },
+{ INTERNAL_IP6_DNS,            "INTERNAL_IP6_DNS",             NULL },
+{ INTERNAL_IP6_NBNS,           "INTERNAL_IP6_NBNS",            NULL },
+{ INTERNAL_IP6_DHCP,           "INTERNAL_IP6_DHCP",            NULL },
+{ INTERNAL_IP4_SUBNET,         "INTERNAL_IP4_SUBNET",          NULL },
+{ SUPPORTED_ATTRIBUTES,                "SUPPORTED_ATTRIBUTES",         NULL },
+{ INTERNAL_IP6_SUBNET,         "INTERNAL_IP6_SUBNET",          NULL },
+{ XAUTH_TYPE,                  "XAUTH_TYPE",                   NULL },
+{ XAUTH_USER_NAME,             "XAUTH_USER_NAME",              NULL },
+{ XAUTH_USER_PASSWORD,         "XAUTH_USER_PASSWORD",          NULL },
+{ XAUTH_PASSCODE,              "XAUTH_PASSCODE",               NULL },
+{ XAUTH_MESSAGE,               "XAUTH_MESSAGE",                NULL },
+{ XAUTH_CHALLENGE,             "XAUTH_CHALLENGE",              NULL },
+{ XAUTH_DOMAIN,                        "XAUTH_DOMAIN",                 NULL },
+{ XAUTH_STATUS,                        "XAUTH_STATUS",                 NULL },
+{ XAUTH_NEXT_PIN,              "XAUTH_NEXT_PIN",               NULL },
+{ XAUTH_ANSWER,                        "XAUTH_ANSWER",                 NULL },
+{ UNITY_BANNER,                        "UNITY_BANNER",                 NULL },
+{ UNITY_SAVE_PASSWD,           "UNITY_SAVE_PASSWD",            NULL },
+{ UNITY_DEF_DOMAIN,            "UNITY_DEF_DOMAIN",             NULL },
+{ UNITY_SPLITDNS_NAME,         "UNITY_SPLITDNS_NAME",          NULL },
+{ UNITY_SPLIT_INCLUDE,         "UNITY_SPLIT_INCLUDE",          NULL },
+{ UNITY_NATT_PORT,             "UNITY_NATT_PORT",              NULL },
+{ UNITY_LOCAL_LAN,             "UNITY_LOCAL_LAN",              NULL },
+{ UNITY_PFS,                   "UNITY_PFS",                    NULL },
+{ UNITY_FW_TYPE,               "UNITY_FW_TYPE",                NULL },
+{ UNITY_BACKUP_SERVERS,                "UNITY_BACKUP_SERVERS",         NULL },
+{ UNITY_DDNS_HOSTNAME,         "UNITY_DDNS_HOSTNAME",          NULL },
+};
+
+char *
+s_isakmp_cfg_type(k)
+       int k;
+{
+       int i;
+       for (i = 0; i < ARRAYLEN(name_isakmp_cfg_type); i++)
+               if (name_isakmp_cfg_type[i].key == k)
+                       return name_isakmp_cfg_type[i].str;
+       return num2str(k);
+}
+
+/* isakmp_cfg.h / isakmp_unity.h / isakmp_xauth.h */
+static struct ksmap name_isakmp_cfg_ptype[] = {
+{ ISAKMP_CFG_ACK,              "mode config ACK",              NULL },
+{ ISAKMP_CFG_SET,              "mode config SET",              NULL },
+{ ISAKMP_CFG_REQUEST,          "mode config REQUEST",          NULL },
+{ ISAKMP_CFG_REPLY,            "mode config REPLY",            NULL },
+};
+
+char *
+s_isakmp_cfg_ptype(k)
+       int k;
+{
+       int i;
+       for (i = 0; i < ARRAYLEN(name_isakmp_cfg_ptype); i++)
+               if (name_isakmp_cfg_ptype[i].key == k)
+                       return name_isakmp_cfg_ptype[i].str;
+       return num2str(k);
+}
+
+#endif
+
 /* ipsec_doi.h */
 static struct ksmap name_ipsecdoi_proto[] = {
 { IPSECDOI_PROTO_ISAKMP,       "ISAKMP",       s_ipsecdoi_trns_isakmp },
@@ -587,6 +674,7 @@ static struct ksmap name_attr_isakmp_enc[] = {
 { OAKLEY_ATTR_ENC_ALG_RC5,     "RC5-R16-B64-CBC",      NULL },
 { OAKLEY_ATTR_ENC_ALG_3DES,    "3DES-CBC",             NULL },
 { OAKLEY_ATTR_ENC_ALG_CAST,    "CAST-CBC",             NULL },
+{ OAKLEY_ATTR_ENC_ALG_AES,     "AES-CBC",              NULL },
 };
 
 char *
@@ -621,19 +709,25 @@ s_attr_isakmp_hash(k)
 }
 
 static struct ksmap name_attr_isakmp_method[] = {
-{ OAKLEY_ATTR_AUTH_METHOD_PSKEY,       "pre-shared key",       NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_DSSSIG,      "DSS signatures",       NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_RSASIG,      "RSA signatures",       NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_RSAENC,      "Encryption with RSA",  NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_RSAREV,      "Revised encryption with RSA",  NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_EGENC,       "Encryption with El-Gamal",     NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_EGREV,       "Revised encryption with El-Gamal",     NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB,  "GSS-API on Kerberos 5", NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_PSKEY,               "pre-shared key",       NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_DSSSIG,              "DSS signatures",       NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_RSASIG,              "RSA signatures",       NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_RSAENC,              "Encryption with RSA",  NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_RSAREV,              "Revised encryption with RSA",  NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_EGENC,               "Encryption with El-Gamal",     NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_EGREV,               "Revised encryption with El-Gamal",     NULL },
+#ifdef HAVE_GSSAPI
+{ OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB,          "GSS-API on Kerberos 5", NULL },
+#endif
 #ifdef ENABLE_HYBRID
-{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I,        "Hybrid DSS server",    NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I,        "Hybrid RSA server",    NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R,        "Hybrid DSS client",    NULL },
-{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R,        "Hybrid RSA client",    NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R,                "Hybrid DSS server",    NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R,                "Hybrid RSA server",    NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I,                "Hybrid DSS client",    NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I,                "Hybrid RSA client",    NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I,       "XAuth pskey client",   NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R,       "XAuth pskey server",   NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I,      "XAuth RSASIG client",  NULL },
+{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R,      "XAuth RSASIG server",  NULL },
 #endif
 };
 
@@ -780,7 +874,7 @@ static struct ksmap name_pfkey_type[] = {
 { SADB_EXPIRE,         "EXPIRE",       NULL },
 { SADB_FLUSH,          "FLUSH",        NULL },
 { SADB_DUMP,           "DUMP",         NULL },
-{ SADB_X_PROMISC,      "X_PRIMISC",    NULL },
+{ SADB_X_PROMISC,      "X_PROMISC",    NULL },
 { SADB_X_PCHANGE,      "X_PCHANGE",    NULL },
 { SADB_X_SPDUPDATE,    "X_SPDUPDATE",  NULL },
 { SADB_X_SPDADD,       "X_SPDADD",     NULL },
@@ -792,10 +886,12 @@ static struct ksmap name_pfkey_type[] = {
 { SADB_X_SPDSETIDX,    "X_SPDSETIDX",  NULL },
 { SADB_X_SPDEXPIRE,    "X_SPDEXPIRE",  NULL },
 { SADB_X_SPDDELETE2,   "X_SPDDELETE2", NULL },
-#ifndef __APPLE__
-#ifdef ENABLE_NATT
+{ SADB_GETSASTAT, "X_GETSASTAT", NULL },
+#ifdef SADB_X_NAT_T_NEW_MAPPING
 { SADB_X_NAT_T_NEW_MAPPING, "X_NAT_T_NEW_MAPPING", NULL },
 #endif
+#ifdef SADB_X_MIGRATE
+{ SADB_X_MIGRATE,      "X_MIGRATE",    NULL },
 #endif
 };
 
index ed60551112d212afa2c59c831a9a0ae522fcbae3..02ebbb5afadb25df9b63661f4b1ef841b8f7ed89 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: strnames.h,v 1.5 2004/07/12 20:37:13 ludvigm Exp $ */
+/*     $NetBSD: strnames.h,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
+/* Id: strnames.h,v 1.7 2005/04/18 10:04:26 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -70,5 +72,9 @@ extern char *s_doi __P((int));
 extern char *s_etype __P((int));
 extern char *s_idtype __P((int));
 extern char *s_switch __P((int));
+#ifdef ENABLE_HYBRID
+extern char *s_isakmp_cfg_type __P((int));
+extern char *s_isakmp_cfg_ptype __P((int));
+#endif
 
 #endif /* _STRNAMES_H */
index 73f6b9276f735bf83851d237e8f9e1162f186794..3a5dcb47db1294754c1bade19af7f04c9b0bb90d 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: throttle.c,v 1.2 2004/11/30 07:40:13 manubsd Exp $ */
+/*     $NetBSD: throttle.c,v 1.4 2006/09/09 16:22:10 manu Exp $        */
+
+/* Id: throttle.c,v 1.5 2006/04/05 20:54:50 manubsd Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
@@ -49,6 +51,7 @@
 #include <sys/socket.h>
 
 #include <netinet/in.h>
+#include <resolv.h>
 
 #include "vmbuf.h"
 #include "misc.h"
@@ -100,14 +103,15 @@ throttle_host(addr, authfail)
 
        now = time(NULL);
 
+restart:
        TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) {
-               /* 
-                * Remove outdated entries 
-                */
+         /*
+          * Remove outdated entries 
+          */
                if (te->penalty < now) {
                        TAILQ_REMOVE(&throttle_list, te, next);
                        racoon_free(te);
-                       continue;
+                       goto restart;
                }
                        
                if (cmpsaddrwop(addr, (struct sockaddr *)&te->host) == 0) {
index e2cb36fa878c0e37f13074f63585855a7121ea13..b9418a18e21810f23c137d95f0b3d74a8988d8e6 100644 (file)
@@ -1,4 +1,6 @@
-/* $Id: var.h,v 1.6 2004/11/20 16:16:59 monas Exp $ */
+/*     $NetBSD: var.h,v 1.4.6.1 2007/06/06 15:36:38 vanhu Exp $        */
+
+/* Id: var.h,v 1.6 2004/11/20 16:16:59 monas Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 do { \
        if (getnameinfo((x), sysdep_sa_len(x), (y), sizeof(y), (z), sizeof(z), \
                        NIFLAGS) != 0) { \
-               if (y) \
-                       strncpy((y), "(invalid)", sizeof(y)); \
-               if (z) \
-                       strncpy((z), "(invalid)", sizeof(z)); \
+               if (y != NULL) \
+                       strlcpy((y), "(invalid)", sizeof(y)); \
+               if (z != NULL) \
+                       strlcpy((z), "(invalid)", sizeof(z)); \
        } \
 } while (0);
 
@@ -87,8 +89,8 @@ do { \
 do { \
        if (getnameinfo((x), sysdep_sa_len(x), (y), sizeof(y), NULL, 0, \
                        NIFLAGS) != 0) { \
-               if (y) \
-                       strncpy((y), "(invalid)", sizeof(y)); \
+               if (y != NULL) \
+                       strlcpy((y), "(invalid)", sizeof(y)); \
        } \
 } while (0);
 
index e0204b64ebabb8b73af1556c83aa5a72263ceffa..6c1aed1fb5e44e7665de7e1e6966f59f1ae6bba9 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: vmbuf.c,v 1.4 2006/09/09 16:22:10 manu Exp $   */
+
 /*     $KAME: vmbuf.c,v 1.11 2001/11/26 16:54:29 sakane Exp $  */
 
 /*
@@ -44,6 +46,7 @@
 #include "misc.h"
 #include "vmbuf.h"
 #include "debug.h"
+#include "plog.h"
 #include "gcmalloc.h"
 
 vchar_t *
@@ -120,6 +123,11 @@ vdup(src)
 {
        vchar_t *new;
 
+       if (src == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL, "vdup(NULL) called\n");
+               return NULL;
+       }
+
        if ((new = vmalloc(src->l)) == NULL)
                return NULL;
 
index 5191be946a1ba356c21422498517227ec0f16c33..9bc69439812f6e68cfa5538c6a3c5ae33d5fb807 100644 (file)
@@ -60,6 +60,11 @@ do { \
        } \
 } while(0);
 
+#if defined(__APPLE__) && defined(__MACH__)
+/* vfree is already defined in Apple's system libraries */
+#define vfree   vmbuf_free
+#endif
+
 extern vchar_t *vmalloc __P((size_t));
 extern vchar_t *vrealloc __P((vchar_t *, size_t));
 extern void vfree __P((vchar_t *));
diff --git a/ipsec-tools/racoon/vpn.c b/ipsec-tools/racoon/vpn.c
new file mode 100644 (file)
index 0000000..4e6e8d2
--- /dev/null
@@ -0,0 +1,564 @@
+/*
+ * Copyright (c) 2007 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+
+#ifdef __APPLE__
+#include <System/net/pfkeyv2.h>
+#else
+#include <net/pfkeyv2.h>
+#endif
+
+#include <netinet/in.h>
+#ifndef HAVE_NETINET6_IPSEC
+#include <netinet/ipsec.h>
+#else 
+#include <netinet6/ipsec.h>
+#endif
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
+
+#include "var.h"
+#include "misc.h"
+#include "vmbuf.h"
+#include "plog.h"
+#include "sockmisc.h"
+#include "debug.h"
+#include "handler.h"
+#include "schedule.h"
+#include "localconf.h"
+#include "remoteconf.h"
+#include "grabmyaddr.h"
+#include "isakmp_var.h"
+#include "isakmp.h"
+#include "oakley.h"
+#include "evt.h"
+#include "pfkey.h"
+#include "ipsec_doi.h"
+#include "admin.h"
+#include "admin_var.h"
+#include "isakmp_inf.h"
+#ifdef ENABLE_HYBRID
+#include "isakmp_cfg.h"
+#include "isakmp_unity.h"
+#endif
+#include "session.h"
+#include "gcmalloc.h"
+#include "sainfo.h"
+#include "ipsec_doi.h"
+#include "nattraversal.h"
+
+#include "vpn_control.h"
+#include "vpn_control_var.h"
+#include "strnames.h"
+#include "ike_session.h"
+
+
+static int vpn_get_ph2pfs(struct ph1handle *);
+
+int
+vpn_connect(struct bound_addr *srv)
+{
+       int error = -1;
+       struct sockaddr *dst;
+       struct remoteconf *rmconf;
+       struct sockaddr *remote = NULL;
+       struct sockaddr *local = NULL;
+       u_int16_t port;
+
+       dst = racoon_calloc(1, sizeof(struct sockaddr));        // this should come from the bound_addr parameter
+       if (dst == NULL)
+               goto out;
+       ((struct sockaddr_in *)(dst))->sin_len = sizeof(struct sockaddr_in);
+       ((struct sockaddr_in *)(dst))->sin_family = AF_INET;
+       ((struct sockaddr_in *)(dst))->sin_port = 500;
+       ((struct sockaddr_in *)(dst))->sin_addr.s_addr = srv->address;
+
+       /*
+        * Find the source address
+        */      
+       if ((local = getlocaladdr(dst)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "cannot get local address\n");
+               goto out1;
+       }
+
+       /* find appropreate configuration */
+       rmconf = getrmconf(dst);
+       if (rmconf == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "no configuration found "
+                       "for %s\n", saddrwop2str(dst));
+               goto out1;
+       }
+
+       /* get remote IP address and port number. */
+       if ((remote = dupsaddr(dst)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "failed to duplicate address\n");
+               goto out1;
+       }
+
+       switch (remote->sa_family) {
+       case AF_INET:
+               ((struct sockaddr_in *)remote)->sin_port =
+                       ((struct sockaddr_in *)rmconf->remote)->sin_port;
+               break;
+#ifdef INET6
+       case AF_INET6:
+               ((struct sockaddr_in6 *)remote)->sin6_port =
+                       ((struct sockaddr_in6 *)rmconf->remote)->sin6_port;
+               break;
+#endif
+       default:
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "invalid family: %d\n",
+                       remote->sa_family);
+               goto out1;
+               break;
+       }
+
+       port = ntohs(getmyaddrsport(local));
+       if (set_port(local, port) == NULL) 
+               goto out1;
+
+       plog(LLV_INFO, LOCATION, NULL,
+               "accept a request to establish IKE-SA: "
+               "%s\n", saddrwop2str(remote));
+
+       /* begin ident mode */
+       if (isakmp_ph1begin_i(rmconf, remote, local, 1) < 0)
+               goto out1;
+               
+       error = 0;
+
+out1:
+       if (dst != NULL)
+               racoon_free(dst);
+       if (local != NULL)
+               racoon_free(local);
+       if (remote != NULL)
+               racoon_free(remote);
+out:
+
+       return error;
+}
+
+int
+vpn_disconnect(struct bound_addr *srv)
+{
+       struct sockaddr_in      saddr;
+
+       bzero(&saddr, sizeof(saddr));
+       saddr.sin_len = sizeof(saddr);
+       saddr.sin_addr.s_addr = srv->address;
+       saddr.sin_port = 0;
+       saddr.sin_family = AF_INET;
+       ike_sessions_stopped_by_controller(&saddr,
+                                       0,
+                                       ike_session_stopped_by_vpn_disconnect);
+       if (purgephXbydstaddrwop((struct sockaddr *)(&saddr)) > 0) {
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+int
+vpn_start_ph2(struct bound_addr *addr, struct vpnctl_cmd_start_ph2 *pkt)
+{
+       struct vpnctl_sa_selector *selector_ptr;
+       struct vpnctl_algo *algo_ptr, *next_algo;
+       int                                     i, j, defklen;
+       struct sainfoalg        *new_algo;
+       struct sainfo           *new_sainfo = NULL, *check;
+       u_int16_t                       class, algorithm, keylen;
+       struct ph1handle        *ph1;
+       struct sockaddr_in      saddr;
+       
+       struct id {
+               u_int8_t type;          /* ID Type */
+               u_int8_t proto_id;      /* Protocol ID */
+               u_int16_t port;         /* Port */
+               u_int32_t addr;         /* IPv4 address */
+               u_int32_t mask;
+       } *id_ptr;
+       
+       /* verify ph1 exists */ 
+       bzero(&saddr, sizeof(saddr));
+       saddr.sin_len = sizeof(saddr);
+       saddr.sin_addr.s_addr = addr->address;
+       saddr.sin_port = 0;
+       saddr.sin_family = AF_INET;
+       ph1 = getph1bydstaddrwop((struct sockaddr *)(&saddr));
+       if (ph1 == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "cannot start phase2 - no phase1 found.\n");
+               return -1;
+       }
+       if (ph1->status != PHASE1ST_ESTABLISHED) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "cannot start phase2 - phase1 not established.\n");
+               return -1;
+       }
+
+       selector_ptr = (struct vpnctl_sa_selector *)(pkt + 1);
+       algo_ptr = (struct vpnctl_algo *)(selector_ptr + ntohs(pkt->selector_count));
+
+       for (i = 0; i < ntohs(pkt->selector_count); i++, selector_ptr++) {
+               new_sainfo = newsainfo();
+               if (new_sainfo == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "unable to allocate sainfo struct.\n");
+                       goto fail;
+               }
+               
+               if (ntohl(selector_ptr->src_tunnel_mask) == 0xFFFFFFFF)
+                       new_sainfo->idsrc = vmalloc(sizeof(struct id) - sizeof(u_int32_t));
+               else
+                       new_sainfo->idsrc = vmalloc(sizeof(struct id));
+               if (new_sainfo->idsrc == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "unable to allocate id struct.\n");
+                       goto fail;
+               }
+               if (selector_ptr->dst_tunnel_mask == 0xFFFFFFFF)
+                       new_sainfo->iddst = vmalloc(sizeof(struct id) - sizeof(u_int32_t));
+               else
+                       new_sainfo->iddst = vmalloc(sizeof(struct id));
+               if (new_sainfo->iddst == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "unable to allocate id struct.\n");
+                       goto fail;
+               }                       
+               
+               id_ptr = (struct id *)new_sainfo->idsrc->v;
+               if (ntohl(selector_ptr->src_tunnel_mask) == 0xFFFFFFFF)
+                       id_ptr->type = IPSECDOI_ID_IPV4_ADDR;
+               else {
+                       id_ptr->type = IPSECDOI_ID_IPV4_ADDR_SUBNET;
+                       id_ptr->mask = selector_ptr->src_tunnel_mask;
+               }
+               id_ptr->addr = selector_ptr->src_tunnel_address;
+               id_ptr->port = selector_ptr->src_tunnel_port;
+               id_ptr->proto_id = selector_ptr->ul_protocol;
+                               
+               id_ptr = (struct id *)new_sainfo->iddst->v;
+               if (selector_ptr->dst_tunnel_mask == 0xFFFFFFFF)
+                       id_ptr->type = IPSECDOI_ID_IPV4_ADDR;
+               else {
+                       id_ptr->type = IPSECDOI_ID_IPV4_ADDR_SUBNET;
+                       id_ptr->mask = selector_ptr->dst_tunnel_mask;
+               }
+               id_ptr->addr = selector_ptr->dst_tunnel_address;
+               id_ptr->port = selector_ptr->dst_tunnel_port;
+               id_ptr->proto_id = selector_ptr->ul_protocol;           
+                               
+               new_sainfo->dynamic = addr->address;
+               new_sainfo->lifetime = ntohl(pkt->lifetime);
+               
+               if (ntohs(pkt->pfs_group) != 0) {
+                       new_sainfo->pfs_group = algtype2doi(algclass_isakmp_dh, ntohs(pkt->pfs_group));
+                       if (new_sainfo->pfs_group == -1) {
+                               plog(LLV_ERROR, LOCATION, NULL, "invalid dh group specified\n");
+                               goto fail;
+                       }
+               }
+               for (j = 0, next_algo = algo_ptr; j < ntohs(pkt->algo_count); j++, next_algo++) {
+
+                       new_algo = newsainfoalg();
+                       if (new_algo == NULL) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "failed to allocate algorithm structure\n");
+                               goto fail;
+                       }
+
+                       class = ntohs(next_algo->algo_class);
+                       algorithm = ntohs(next_algo->algo);
+                       keylen = ntohs(next_algo->key_len);
+                       
+                       new_algo->alg = algtype2doi(class, algorithm);
+                       if (new_algo->alg == -1) {
+                               plog(LLV_ERROR, LOCATION, NULL, "algorithm mismatched\n");
+                               racoon_free(new_algo);
+                               goto fail;
+                       }
+
+                       defklen = default_keylen(class, algorithm);
+                       if (defklen == 0) {
+                               if (keylen) {
+                                       plog(LLV_ERROR, LOCATION, NULL, "keylen not allowed\n");
+                                       racoon_free(new_algo);
+                                       goto fail;
+                               }
+                       } else {
+                               if (keylen && check_keylen(class, algorithm, keylen) < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL, "invalid keylen %d\n", keylen);
+                                       racoon_free(new_algo);
+                                       goto fail;
+                               }
+                       }
+
+                       if (keylen)
+                               new_algo->encklen = keylen;
+                       else
+                               new_algo->encklen = defklen;
+
+                       /* check if it's supported algorithm by kernel */
+                       if (!(class == algclass_ipsec_auth && algorithm == algtype_non_auth)
+                        && pk_checkalg(class, algorithm, new_algo->encklen)) {
+                               int a = algclass2doi(class);
+                               int b = new_algo->alg;
+                               if (a == IPSECDOI_ATTR_AUTH)
+                                       a = IPSECDOI_PROTO_IPSEC_AH;
+                               plog(LLV_ERROR, LOCATION, NULL, 
+                                       "algorithm %s not supported by the kernel (missing module?)\n", s_ipsecdoi_trns(a, b));
+                               racoon_free(new_algo);
+                               goto fail;
+                       }
+                       inssainfoalg(&new_sainfo->algs[class], new_algo);
+               }
+
+               if (new_sainfo->algs[algclass_ipsec_enc] == 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "no encryption algorithm at %s\n", sainfo2str(new_sainfo));
+                       goto fail;
+               }
+               if (new_sainfo->algs[algclass_ipsec_auth] == 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "no authentication algorithm at %s\n", sainfo2str(new_sainfo));
+                       goto fail;
+               }
+               if (new_sainfo->algs[algclass_ipsec_comp] == 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "no compression algorithm at %s\n", sainfo2str(new_sainfo));
+                       goto fail;
+               }
+
+               /* duplicate check */
+               check = getsainfo(new_sainfo->idsrc, new_sainfo->iddst, new_sainfo->id_i, 0);
+               if (check && (!check->idsrc && !new_sainfo->idsrc)) {
+                       plog(LLV_ERROR, LOCATION, NULL,"duplicated sainfo: %s\n", sainfo2str(new_sainfo));
+                       goto fail;
+               }
+               plog(LLV_DEBUG2, LOCATION, NULL, "create sainfo: %s\n", sainfo2str(new_sainfo));
+               inssainfo(new_sainfo);
+               new_sainfo = NULL;
+       }
+       
+       return 0;
+       
+fail:
+       if (new_sainfo)
+               delsainfo(new_sainfo);
+       flushsainfo_dynamic(addr);
+       return -1;
+}
+
+static int 
+vpn_get_ph2pfs(struct ph1handle *ph1)
+{
+}
+
+
+int
+vpn_get_config(struct ph1handle *iph1, struct vpnctl_status_phase_change **msg, size_t *msg_size)
+{
+
+       struct vpnctl_modecfg_params *params;
+       struct myaddrs *myaddr;
+       u_int16_t ifname_len, msize;
+       u_int8_t  *cptr;
+       
+       *msg = NULL;
+       msize = 0;
+       
+       if (((struct sockaddr_in *)iph1->local)->sin_family != AF_INET) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "IPv6 not supported for mode config.\n");
+               return -1;
+       }
+       
+       if (iph1->mode_cfg->attr_list == NULL)
+               return 1;       /* haven't received configuration yet */
+               
+       myaddr = find_myaddr(iph1->local, 0);
+       if (myaddr == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unable to find address structure.\n");
+               return -1;
+       }
+       
+       msize = sizeof(struct vpnctl_status_phase_change) 
+                       + sizeof(struct vpnctl_modecfg_params);
+       msize += iph1->mode_cfg->attr_list->l;
+
+       *msg = racoon_calloc(1, msize);
+       if (*msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "faled to allocate space for message.\n");
+               return -1;
+       }
+       
+       (*msg)->hdr.flags = htons(VPNCTL_FLAG_MODECFG_USED);
+       params = (struct vpnctl_modecfg_params *)(*msg + 1);
+       params->outer_local_addr = ((struct sockaddr_in *)iph1->local)->sin_addr.s_addr;
+       params->outer_remote_port = htons(0);
+       params->outer_local_port = htons(0);
+       ifname_len = strlen(myaddr->ifname);
+       memset(&params->ifname, 0, IFNAMSIZ);
+       memcpy(&params->ifname, myaddr->ifname, ifname_len < IFNAMSIZ ? ifname_len : IFNAMSIZ-1);
+       cptr = (u_int8_t *)(params + 1);
+       memcpy(cptr, iph1->mode_cfg->attr_list->v, iph1->mode_cfg->attr_list->l);
+       *msg_size = msize;
+
+       return 0;
+}
+
+
+int
+vpn_xauth_reply(u_int32_t address, void *attr_list, size_t attr_len)
+{
+
+       struct isakmp_pl_attr *reply;
+       void* attr_ptr;
+       vchar_t *payload = NULL;
+       struct ph1handle        *iph1;
+       struct sockaddr_in      saddr;
+       int error = -1;
+       int tlen = attr_len;
+       struct isakmp_data *attr;
+       char *dataptr = (char *)attr_list;
+
+       /* find ph1 */  
+       bzero(&saddr, sizeof(saddr));
+       saddr.sin_len = sizeof(saddr);
+       saddr.sin_addr.s_addr = address;
+       saddr.sin_port = 0;
+       saddr.sin_family = AF_INET;
+       iph1 = getph1bydstaddrwop((struct sockaddr *)(&saddr));
+       if (iph1 == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "cannot reply to xauth request - no ph1 found.\n");
+               goto end;
+       }
+
+       if (iph1->xauth_awaiting_userinput == 0) {
+               plog(LLV_ERROR, LOCATION, NULL, "Huh? recvd xauth reply data with no xauth reply pending \n");
+               goto end;
+       }
+       
+       /* validate attr lengths */
+       while (tlen > 0)
+       {
+               int tlv;
+               
+               attr = (struct isakmp_data *)dataptr;
+               tlv = (attr->type & htons(0x8000)) == 0;
+               
+               if (tlv) {
+                       tlen -= ntohs(attr->lorv);
+                       dataptr += ntohs(attr->lorv);
+               }
+               tlen -= sizeof(u_int32_t);
+               dataptr += sizeof(u_int32_t);
+       }
+       if (tlen != 0) {
+               plog(LLV_ERROR, LOCATION, NULL, "invalid auth info received from VPN Control socket.\n");
+               goto end;
+       }
+       
+       payload = vmalloc(sizeof(struct isakmp_pl_attr) + attr_len);
+       if (payload == NULL) {  
+               plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory for xauth reply\n");
+               goto end;
+       }
+       memset(payload->v, 0, sizeof(reply));
+
+       reply = (struct isakmp_pl_attr *)payload->v;
+       reply->h.len = htons(payload->l);
+       reply->type = ISAKMP_CFG_REPLY;
+       reply->id = iph1->pended_xauth_id;      /* network byte order */
+       iph1->xauth_awaiting_userinput = 0;     /* no longer waiting */
+       attr_ptr = reply + 1;
+       memcpy(attr_ptr, attr_list, attr_len);
+
+       plog(LLV_DEBUG, LOCATION, NULL, 
+                   "Sending MODE_CFG REPLY\n");
+       error = isakmp_cfg_send(iph1, payload, 
+           ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, iph1->xauth_awaiting_userinput_msg);
+       VPTRINIT(iph1->xauth_awaiting_userinput_msg);
+       ike_session_stop_xauth_timer(iph1);
+
+end:
+       if (payload)
+               vfree(payload);
+       return error;
+}
+
diff --git a/ipsec-tools/racoon/vpn.h b/ipsec-tools/racoon/vpn.h
new file mode 100644 (file)
index 0000000..ff8274b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+int vpn_connect __P((struct bound_addr *));
index f3217a0af206e957a58770a595bfb0c77f409835..cc81603469182354da1b1b11b79527db0f45a7b3 100644 (file)
@@ -78,6 +78,7 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#include <launch.h>
 
 #include "var.h"
 #include "misc.h"
@@ -113,7 +114,93 @@ static struct sockaddr_un sunaddr;
 static int vpncontrol_process(struct vpnctl_socket_elem *, char *);
 static int vpncontrol_reply(int, char *);
 static void vpncontrol_close_comm(struct vpnctl_socket_elem *);
+static int checklaunchd();
+extern int vpn_get_config __P((struct ph1handle *, struct vpnctl_status_phase_change **, size_t *));
+extern int vpn_xauth_reply __P((u_int32_t, void *, size_t));
+
+
+int                     
+checklaunchd()                  
+{               
+       launch_data_t checkin_response = NULL; 
+       launch_data_t checkin_request = NULL;
+       launch_data_t sockets_dict, listening_fd_array;
+       launch_data_t listening_fd;
+       struct sockaddr_storage fdsockaddr;
+       socklen_t fdsockaddrlen = sizeof(fdsockaddr);
+       int socketct;
+       int i;
+       int listenerct;
+       int returnval = 0;
+       int fd;
+       
+       /* check in with launchd */
+       if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to launch_data_new_string.\n");
+               goto done;
+       }
+       if ((checkin_response = launch_msg(checkin_request)) == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to launch_msg.\n");
+               goto done;
+       }
+       if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "launch_data_get_type error %d\n",
+                        launch_data_get_errno(checkin_response));
+               goto done;
+       }
+       if ( (sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS)) == NULL){
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to launch_data_dict_lookup.\n");
+               goto done;
+       }
+       if ( !(socketct = launch_data_dict_get_count(sockets_dict))){
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "launch_data_dict_get_count returns no socket defined.\n");
+               goto done;
+       }
+       
+       if ( (listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners")) == NULL ){
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "failed to launch_data_dict_lookup.\n");
+               goto done;
+       }
+       listenerct = launch_data_array_get_count(listening_fd_array);
+       for (i = 0; i < listenerct; i++) {
+               listening_fd = launch_data_array_get_index(listening_fd_array, i);
+               fd = launch_data_get_fd( listening_fd );
+               if ( getsockname( fd , (struct sockaddr*)&fdsockaddr, &fdsockaddrlen)){
+                       continue;
+               }
+               
+               /* Is this the VPN control socket? */ 
+               if ( (((struct sockaddr*)&fdsockaddr)->sa_family) == AF_UNIX && 
+                               (!(strcmp(vpncontrolsock_path, ((struct sockaddr_un *)&fdsockaddr)->sun_path))))
+               {       
+                       plog(LLV_INFO, LOCATION, NULL,
+                                "found launchd socket.\n");
+                       returnval = fd;
+                       break;
+               }
+       }
+       // TODO: check if we have any leaked fd
+       if ( listenerct == i){
+               plog(LLV_ERROR, LOCATION, NULL, 
+                        "failed to find launchd socket\n");               
+               returnval = 0;
+       }
+       
+done:   
+       if (checkin_request)
+               launch_data_free(checkin_request);
+       if (checkin_response)
+               launch_data_free(checkin_response);
+       return(returnval);
+}
 
+               
 int
 vpncontrol_handler()
 {
@@ -162,7 +249,7 @@ vpncontrol_comm_handler(struct vpnctl_socket_elem *elem)
                goto end;
        }
        if (len == 0) {
-               plog(LLV_NOTIFY, LOCATION, NULL,
+               plog(LLV_DEBUG, LOCATION, NULL,
                        "vpn_control socket closed by peer.\n");
                vpncontrol_close_comm(elem);
                return -1;
@@ -215,13 +302,23 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
                        
                                plog(LLV_DEBUG, LOCATION, NULL,
                                        "received bind command on vpn control socket.\n");
-                               addr = racoon_malloc(sizeof(struct bound_addr));
+                               addr = racoon_calloc(1, sizeof(struct bound_addr));
                                if (addr == NULL) {
                                        plog(LLV_ERROR, LOCATION, NULL, 
                                                "memory error: %s\n", strerror(errno));
                                        error = -1;
                                        break;
                                }
+                               if (ntohs(pkt->vers_len)) {
+                                       addr->version = vmalloc(ntohs(pkt->vers_len));
+                                       if (addr->version == NULL) {
+                                               plog(LLV_ERROR, LOCATION, NULL, 
+                                                       "memory error: %s\n", strerror(errno));
+                                               error = -1;
+                                               break;
+                                       }
+                                       memcpy(addr->version->v, pkt + 1, ntohs(pkt->vers_len));
+                               }
                                addr->address = pkt->address;
                                LIST_INSERT_HEAD(&elem->bound_addresses, addr, chain);
                                lcconf->auto_exit_state |= LC_AUTOEXITSTATE_CLIENT;     /* client side */
@@ -239,7 +336,10 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
                                LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
                                        if (pkt->address == 0xFFFFFFFF ||
                                                pkt->address == addr->address) {
+                                               flushsainfo_dynamic(addr->address);
                                                LIST_REMOVE(addr, chain);
+                                               if (addr->version)
+                                                       vfree(addr->version);
                                                racoon_free(addr);
                                        }
                                }
@@ -287,7 +387,108 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
                        break;
                        
                case VPNCTL_CMD_PING:
-                       break;  // just reply for now
+                       break;  /* just reply for now */
+
+               case VPNCTL_CMD_XAUTH_INFO:
+                       {
+                               struct vpnctl_cmd_xauth_info *pkt = (struct vpnctl_cmd_xauth_info *)combuf;
+                               struct bound_addr *addr;
+                               struct bound_addr *t_addr;
+                               void *attr_list;
+
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                       "received xauth info command vpn control socket.\n");
+                               LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
+                                       if (pkt->address == addr->address) {
+                                               /* reply to the last xauth request */
+                                               attr_list = pkt + 1;
+                                               error = vpn_xauth_reply(pkt->address, attr_list, ntohs(pkt->hdr.len) - sizeof(u_int32_t));
+                                               break;
+                                       }
+                               }
+                       }
+                       break;
+                               
+               case VPNCTL_CMD_CONNECT:
+                       {
+                               struct vpnctl_cmd_connect *pkt = (struct vpnctl_cmd_connect *)combuf;
+                               struct bound_addr *addr;
+                               struct bound_addr *t_addr;
+
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                       "received connect command on vpn control socket.\n");
+                               LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
+                                       if (pkt->address == addr->address) {
+                                               /* start the connection */
+                                               error = vpn_connect(addr);
+                                               break;
+                                       }
+                               }
+                       }
+                       break;
+                       
+               case VPNCTL_CMD_DISCONNECT:
+                       {
+                               struct vpnctl_cmd_connect *pkt = (struct vpnctl_cmd_connect *)combuf;
+                               struct bound_addr *addr;
+                               struct bound_addr *t_addr;
+
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                       "received disconnect command on vpn control socket.\n");
+                               LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
+                                       if (pkt->address == addr->address) {
+                                               /* stop the connection */
+                                               error = vpn_disconnect(addr);
+                                               break;
+                                       }
+                               }
+                       }
+                       break;
+                       
+               case VPNCTL_CMD_START_PH2:
+                       {
+                               struct vpnctl_cmd_start_ph2 *pkt = (struct vpnctl_cmd_start_ph2 *)combuf;
+                               struct bound_addr *addr;
+                               struct bound_addr *t_addr;
+
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                       "received start_ph2 command on vpn control socket.\n");
+                               plogdump(LLV_DEBUG2, pkt, ntohs(hdr->len) + sizeof(struct vpnctl_hdr));
+                               LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
+                                       if (pkt->address == addr->address) {
+                                               /* start the connection */
+                                               error = vpn_start_ph2(addr, pkt);
+                                               break;
+                                       }
+                               }
+                       }
+                       break;
+
+               case VPNCTL_CMD_START_DPD:
+            {
+                struct vpnctl_cmd_start_dpd *pkt = (struct vpnctl_cmd_start_dpd *)combuf;
+                struct bound_addr *srv;
+                struct bound_addr *t_addr;
+
+                plog(LLV_DEBUG, LOCATION, NULL,
+                     "received start_dpd command on vpn control socket.\n");
+                LIST_FOREACH_SAFE(srv, &elem->bound_addresses, chain, t_addr) {
+                    if (pkt->address == srv->address) {
+                        struct sockaddr_in     daddr;
+
+                        bzero(&daddr, sizeof(daddr));
+                        daddr.sin_len = sizeof(daddr);
+                        daddr.sin_addr.s_addr = srv->address;
+                        daddr.sin_port = 0;
+                        daddr.sin_family = AF_INET;
+
+                        /* start the dpd */
+                        error = ph1_force_dpd(&daddr);
+                        break;
+                    }
+                }
+            }
+                       break;
 
                default:
                        plog(LLV_ERROR, LOCATION, NULL,
@@ -320,10 +521,73 @@ vpncontrol_reply(int so, char *combuf)
        return 0;
 }
 
+int
+vpncontrol_notify_need_authinfo(struct ph1handle *iph1, void* attr_list, size_t attr_len)
+{
+       struct vpnctl_status_need_authinfo *msg = NULL; 
+       struct vpnctl_socket_elem *sock_elem;
+       struct bound_addr *bound_addr;
+       size_t tlen, msg_size;  
+       u_int32_t address;
+       void *ptr;
+       
+       if (!iph1)
+               goto end;
+
+       plog(LLV_DEBUG, LOCATION, NULL,
+               "sending vpn_control xauth need info status\n");
+
+       msg = (struct vpnctl_status_need_authinfo *)racoon_malloc(msg_size = sizeof(struct vpnctl_status_need_authinfo) + attr_len);
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "unable to allocate space for vpn control message.\n");
+               return -1;
+       }
+       msg->hdr.flags = 0;
+                               
+       if (iph1->remote->sa_family == AF_INET)
+               address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
+       else
+               goto end;               // for now              
+
+       msg->hdr.cookie = msg->hdr.reserved = msg->hdr.result = 0;
+       msg->hdr.len = htons((msg_size) - sizeof(struct vpnctl_hdr));   
+       if (!ike_session_is_client_ph1_rekey(iph1)) {
+               msg->hdr.msg_type = htons(VPNCTL_STATUS_NEED_AUTHINFO);
+       } else {
+               msg->hdr.msg_type = htons(VPNCTL_STATUS_NEED_REAUTHINFO);
+       }
+       msg->address = address;
+       ptr = msg + 1;
+       memcpy(ptr, attr_list, attr_len);
+
+       LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
+               LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
+                       if (bound_addr->address == 0xFFFFFFFF ||
+                               bound_addr->address == address) {
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                               "vpn control writing %d bytes\n", msg_size);
+                               plogdump(LLV_DEBUG, msg, msg_size);
+                               tlen = send(sock_elem->sock, msg, msg_size, 0);
+                               if (tlen < 0) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                               "failed to send vpn_control need authinfo status: %s\n", strerror(errno));
+                               }
+                               break;
+                       }
+               }
+       }
+
+end:
+       if (msg)
+               racoon_free(msg);
+       return 0;
+}
+
 int
 vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t address, u_int16_t data_len, u_int8_t *data)
 {
-       struct vpnctl_status_failed *msg; 
+       struct vpnctl_status_failed *msg = NULL
        struct vpnctl_socket_elem *sock_elem;
        struct bound_addr *bound_addr;
        size_t tlen, len;
@@ -346,7 +610,7 @@ vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t ad
        if (data_len > 0)
                memcpy(msg->data, data, data_len);      
        plog(LLV_DEBUG, LOCATION, NULL,
-                       "sending vpn_control ike notify failed message - code=%d  from=%s.\n", notify_code,
+                       "sending vpn_control ike failed message - code=%d  from=%s.\n", notify_code,
                                        (from == FROM_LOCAL ? "local" : "remote"));
 
        LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
@@ -362,6 +626,9 @@ vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t ad
                        }
                }
        }
+
+       if (msg)
+               racoon_free(msg);
        return 0;
 }
 
@@ -369,36 +636,55 @@ vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t ad
 int
 vpncontrol_notify_phase_change(int start, u_int16_t from, struct ph1handle *iph1, struct ph2handle *iph2)
 {
-       struct vpnctl_status_phase_change msg; 
+       struct vpnctl_status_phase_change *msg; 
        struct vpnctl_socket_elem *sock_elem;
        struct bound_addr *bound_addr;
-       size_t tlen;    
+       size_t tlen, msg_size;  
        u_int32_t address;
+       
+       plog(LLV_DEBUG, LOCATION, NULL,
+               "sending vpn_control phase change status\n");
+
+       if (iph1 && !start && iph1->mode_cfg) {
+               if (vpn_get_config(iph1, &msg, &msg_size) == 1)
+                       return 0;       /* mode config not finished yet */
+       } else {
+               msg = racoon_malloc(msg_size = sizeof(struct vpnctl_status_phase_change));
+               msg->hdr.flags = 0;
+       }
                
+       if (msg == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                                               "unable to allocate space for vpn control message.\n");
+               return -1;
+       }
        if (iph1) {
                if (iph1->remote->sa_family == AF_INET)
                        address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
                else
-                       return 0;               // for now
-               msg.hdr.msg_type = htons(start ? 
+                       goto end;               // for now              
+               msg->hdr.msg_type = htons(start ? 
                        (from == FROM_LOCAL ? VPNCTL_STATUS_PH1_START_US : VPNCTL_STATUS_PH1_START_PEER) 
                        : VPNCTL_STATUS_PH1_ESTABLISHED);
        } else {
                if (iph2->dst->sa_family == AF_INET)
                        address = ((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr;
                else
-                       return 0;               // for now
-               msg.hdr.msg_type = htons(start ? VPNCTL_STATUS_PH2_START : VPNCTL_STATUS_PH2_ESTABLISHED);
+                       goto end;               // for now
+               msg->hdr.msg_type = htons(start ? VPNCTL_STATUS_PH2_START : VPNCTL_STATUS_PH2_ESTABLISHED);
        }
-       msg.hdr.flags = msg.hdr.cookie = msg.hdr.reserved = msg.hdr.result = 0;
-       msg.hdr.len = htons(sizeof(struct vpnctl_status_phase_change) - sizeof(struct vpnctl_hdr));
-       msg.address = address;
+       msg->hdr.cookie = msg->hdr.reserved = msg->hdr.result = 0;
+       msg->hdr.len = htons((msg_size) - sizeof(struct vpnctl_hdr));
+       msg->address = address;
 
        LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
                LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
                        if (bound_addr->address == 0xFFFFFFFF ||
                                bound_addr->address == address) {
-                               tlen = send(sock_elem->sock, &msg, sizeof(struct vpnctl_status_phase_change), 0);
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                               "vpn control writing %d bytes\n", msg_size);
+                               plogdump(LLV_DEBUG, msg, msg_size);
+                               tlen = send(sock_elem->sock, msg, msg_size, 0);
                                if (tlen < 0) {
                                        plog(LLV_ERROR, LOCATION, NULL,
                                                "failed to send vpn_control phase change status: %s\n", strerror(errno));
@@ -408,6 +694,9 @@ vpncontrol_notify_phase_change(int start, u_int16_t from, struct ph1handle *iph1
                }
        }
 
+end:
+       if (msg)
+               racoon_free(msg);
        return 0;
 }
 
@@ -420,56 +709,62 @@ vpncontrol_init()
                return 0;
        }
 
-       memset(&sunaddr, 0, sizeof(sunaddr));
-       sunaddr.sun_family = AF_UNIX;
-       snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path),
-               "%s", vpncontrolsock_path);
-
-       lcconf->sock_vpncontrol = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (lcconf->sock_vpncontrol == -1) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "socket: %s\n", strerror(errno));
-               return -1;
+       if ( (lcconf->sock_vpncontrol = checklaunchd()) ){
+               return 0;
        }
+       else {  
+               
+               memset(&sunaddr, 0, sizeof(sunaddr));
+               sunaddr.sun_family = AF_UNIX;
+               snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path),
+                       "%s", vpncontrolsock_path);
 
-       unlink(sunaddr.sun_path);
-       if (bind(lcconf->sock_vpncontrol, (struct sockaddr *)&sunaddr,
-                       sizeof(sunaddr)) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "bind(sockname:%s): %s\n",
-                       sunaddr.sun_path, strerror(errno));
-               (void)close(lcconf->sock_vpncontrol);
-               return -1;
-       }
+               lcconf->sock_vpncontrol = socket(AF_UNIX, SOCK_STREAM, 0);
+               if (lcconf->sock_vpncontrol == -1) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "socket: %s\n", strerror(errno));
+                       return -1;
+               }
 
-       if (chown(sunaddr.sun_path, vpncontrolsock_owner, vpncontrolsock_group) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL, 
-                   "chown(%s, %d, %d): %s\n", 
-                   sunaddr.sun_path, vpncontrolsock_owner, 
-                   vpncontrolsock_group, strerror(errno));
-               (void)close(lcconf->sock_vpncontrol);
-               return -1;
-       }
+               unlink(sunaddr.sun_path);
+               if (bind(lcconf->sock_vpncontrol, (struct sockaddr *)&sunaddr,
+                               sizeof(sunaddr)) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "bind(sockname:%s): %s\n",
+                               sunaddr.sun_path, strerror(errno));
+                       (void)close(lcconf->sock_vpncontrol);
+                       return -1;
+               }
 
-       if (chmod(sunaddr.sun_path, vpncontrolsock_mode) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL, 
-                   "chmod(%s, 0%03o): %s\n", 
-                   sunaddr.sun_path, vpncontrolsock_mode, strerror(errno));
-               (void)close(lcconf->sock_vpncontrol);
-               return -1;
-       }
+               if (chown(sunaddr.sun_path, vpncontrolsock_owner, vpncontrolsock_group) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                               "chown(%s, %d, %d): %s\n", 
+                               sunaddr.sun_path, vpncontrolsock_owner, 
+                               vpncontrolsock_group, strerror(errno));
+                       (void)close(lcconf->sock_vpncontrol);
+                       return -1;
+               }
 
-       if (listen(lcconf->sock_vpncontrol, 5) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "listen(sockname:%s): %s\n",
-                       sunaddr.sun_path, strerror(errno));
-               (void)close(lcconf->sock_vpncontrol);
-               return -1;
-       }
-       plog(LLV_DEBUG, LOCATION, NULL,
-               "opened %s as racoon management.\n", sunaddr.sun_path);
+               if (chmod(sunaddr.sun_path, vpncontrolsock_mode) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL, 
+                               "chmod(%s, 0%03o): %s\n", 
+                               sunaddr.sun_path, vpncontrolsock_mode, strerror(errno));
+                       (void)close(lcconf->sock_vpncontrol);
+                       return -1;
+               }
 
-       return 0;
+               if (listen(lcconf->sock_vpncontrol, 5) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "listen(sockname:%s): %s\n",
+                               sunaddr.sun_path, strerror(errno));
+                       (void)close(lcconf->sock_vpncontrol);
+                       return -1;
+               }
+               plog(LLV_DEBUG, LOCATION, NULL,
+                       "opened %s as racoon management.\n", sunaddr.sun_path);
+
+               return 0;
+       }
 }
 
 
@@ -479,12 +774,16 @@ vpncontrol_close()
        struct vpnctl_socket_elem *elem;
        struct vpnctl_socket_elem *t_elem;
        
+       plog(LLV_DEBUG, LOCATION, NULL,
+               "vpncontrol_close.\n");
+
        if (lcconf->sock_vpncontrol != -1) {
                close(lcconf->sock_vpncontrol);
                lcconf->sock_vpncontrol = -1;
        }
        LIST_FOREACH_SAFE(elem, &lcconf->vpnctl_comm_socks, chain, t_elem)
                vpncontrol_close_comm(elem);
+               
 }
 
 static void
@@ -492,12 +791,18 @@ vpncontrol_close_comm(struct vpnctl_socket_elem *elem)
 {
        struct bound_addr *addr;
        struct bound_addr *t_addr;
+
+       plog(LLV_DEBUG, LOCATION, NULL,
+               "vpncontrol_close_comm.\n");
        
        LIST_REMOVE(elem, chain);
        if (elem->sock != -1)   
                close(elem->sock);
        LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
+               flushsainfo_dynamic(addr->address);
                LIST_REMOVE(addr, chain);
+               if (addr->version)
+                       vfree(addr->version);
                racoon_free(addr);
        }
        racoon_free(elem);
index cabbb16b6fc8aa4983e09129f71c91468ad0caa5..fd545d8b4abd916e04feb5f04cb24c296232fe3d 100644 (file)
 #ifndef _VPN_CONTROL_H
 #define _VPN_CONTROL_H
 
+#include "algorithm_types.h"
+#include <net/if.h>
+
 #define VPNCONTROLSOCK_PATH ADMINPORTDIR "/vpncontrol.sock"
 
 #define FROM_LOCAL     0
 #define FROM_REMOTE 1
 
+
 extern char *vpncontrolsock_path;
 extern uid_t vpncontrolsock_owner;
 extern gid_t vpncontrolsock_group;
@@ -72,13 +76,94 @@ extern mode_t vpncontrolsock_mode;
 #define VPNCTL_CMD_UNBIND                              0x0002
 #define VPNCTL_CMD_REDIRECT                            0x0003
 #define VPNCTL_CMD_PING                                        0x0004
+#define VPNCTL_CMD_CONNECT                             0x0011
+#define VPNCTL_CMD_DISCONNECT                  0x0012
+#define VPNCTL_CMD_START_PH2                   0x0013
+#define VPNCTL_CMD_XAUTH_INFO                  0x0014
+#define VPNCTL_CMD_START_DPD                   0x0015
 #define VPNCTL_STATUS_IKE_FAILED               0x8001
 #define VPNCTL_STATUS_PH1_START_US             0x8011
 #define VPNCTL_STATUS_PH1_START_PEER   0x8012
 #define VPNCTL_STATUS_PH1_ESTABLISHED  0x8013
 #define VPNCTL_STATUS_PH2_START                        0x8021
 #define VPNCTL_STATUS_PH2_ESTABLISHED  0x8022
+#define VPNCTL_STATUS_NEED_AUTHINFO            0x8101
+#define VPNCTL_STATUS_NEED_REAUTHINFO  0x8102
+
+/*
+ * Flags
+ */
+#define VPNCTL_FLAG_MODECFG_USED               0x0001
+
+/*
+ * XAUTH Attribute Types
+ */
+#ifndef __IPSEC_BUILD__
+#define        XAUTH_TYPE                16520
+#define        XAUTH_USER_NAME           16521
+#define        XAUTH_USER_PASSWORD       16522
+#define        XAUTH_PASSCODE            16523
+#define        XAUTH_MESSAGE             16524
+#define        XAUTH_CHALLENGE           16525
+#define        XAUTH_DOMAIN              16526
+#define        XAUTH_STATUS              16527
+#define        XAUTH_NEXT_PIN            16528
+#define        XAUTH_ANSWER              16529
+
+
+/* Types for XAUTH_TYPE */
+#define        XAUTH_TYPE_GENERIC      0
+#define        XAUTH_TYPE_CHAP         1
+#define        XAUTH_TYPE_OTP          2
+#define        XAUTH_TYPE_SKEY         3
+
+
+/* Mode cfg Attribute types */
+#define INTERNAL_IP4_ADDRESS        1
+#define INTERNAL_IP4_NETMASK        2
+#define INTERNAL_IP4_DNS            3
+#define INTERNAL_IP4_NBNS           4
+#define INTERNAL_ADDRESS_EXPIRY     5
+#define INTERNAL_IP4_DHCP           6
+#define APPLICATION_VERSION         7
+#define INTERNAL_IP6_ADDRESS        8
+#define INTERNAL_IP6_NETMASK        9
+#define INTERNAL_IP6_DNS           10
+#define INTERNAL_IP6_NBNS          11
+#define INTERNAL_IP6_DHCP          12
+#define INTERNAL_IP4_SUBNET        13
+#define SUPPORTED_ATTRIBUTES       14
+#define INTERNAL_IP6_SUBNET        15
 
+#define UNITY_BANNER                   28672
+#define UNITY_SAVE_PASSWD              28673
+#define UNITY_DEF_DOMAIN               28674
+#define UNITY_SPLITDNS_NAME            28675
+#define UNITY_SPLIT_INCLUDE            28676
+#define UNITY_NATT_PORT                        28677
+#define UNITY_LOCAL_LAN                        28678
+#define UNITY_PFS                              28679
+#define UNITY_FW_TYPE                  28680
+#define UNITY_BACKUP_SERVERS   28681
+#define UNITY_DDNS_HOSTNAME            28682
+
+/* 3.3 Data Attributes
+         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        !A!       Attribute Type        !    AF=0  Attribute Length     !
+        !F!                             !    AF=1  Attribute Value      !
+        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        .                   AF=0  Attribute Value                       .
+        .                   AF=1  Not Transmitted                       .
+        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct isakmp_data {
+       u_int16_t type;         /* defined by DOI-spec, and Attribute Format */
+       u_int16_t lorv;         /* if f equal 1, Attribute Length */
+       /* if f equal 0, Attribute Value */
+       /* if f equal 1, Attribute Value */
+};
+#endif
 
 /* commands and status for vpn control. */
 /* network byte order. */
@@ -99,6 +184,8 @@ struct vpnctl_hdr {
 struct vpnctl_cmd_bind {
        struct vpnctl_hdr               hdr;
        u_int32_t                               address;        /* 0xFFFFFFFF = all */
+       u_int16_t                               vers_len;       /* if zero - no version provided */
+       /* name/version string of length vers_len */
 };
 
 /* unbind to stop receiving status for specified address */
@@ -107,14 +194,64 @@ struct vpnctl_cmd_unbind {
        u_int32_t                               address;        /* 0xFFFFFFFF = all */
 };
 
-/* redirect client to specified address */
-struct vpnctl_cmd_redirect {
+
+/* connect to specified address */
+struct vpnctl_cmd_connect{
        struct vpnctl_hdr               hdr;
        u_int32_t                               address;
+};
+
+struct vpnctl_sa_selector {
+       u_int32_t               src_tunnel_address;
+       u_int32_t               src_tunnel_mask;
+       u_int32_t               dst_tunnel_address;
+       u_int32_t               dst_tunnel_mask;
+       u_int16_t               src_tunnel_port;
+       u_int16_t               dst_tunnel_port;
+       u_int16_t               ul_protocol;
+       u_int16_t               reserved;
+};
+
+struct vpnctl_algo {
+       u_int16_t       algo_class;
+       u_int16_t       algo;
+       u_int16_t       key_len;        /* for enc algorithms only */
+       u_int16_t       reserved;
+};
+
+/* start phase 2 */
+struct vpnctl_cmd_start_ph2 {
+       struct vpnctl_hdr               hdr;
+       u_int32_t                               address;
+       u_int32_t                               lifetime;  /* seconds */
+       u_int16_t                               pfs_group;      /* defined in algorithm_types.h */
+       u_int16_t                               selector_count;
+       u_int16_t                               algo_count;
+       u_int16_t                               reserved;
+       /* array of struct vpnctl_sa_selector */
+       /* array of struct vpnctl_algo */
+};
+
+/* set xauth info */
+struct vpnctl_cmd_xauth_info { 
+       struct vpnctl_hdr               hdr;
+       u_int32_t                               address;
+       /* packed array of variable sized struct isakmp_data */
+};
+
+/* redirect client to specified address */
+struct vpnctl_cmd_redirect {   
+       struct vpnctl_hdr               hdr;
+       u_int32_t                               address;
        u_int32_t                               redirect_address;
        u_int16_t                               force;
 };
 
+/* start dpd */
+struct vpnctl_cmd_start_dpd {
+       struct vpnctl_hdr               hdr;
+       u_int32_t               address;
+};
 
 /*
  * IKE Notify codes - mirrors codes in isakmp.h
@@ -150,6 +287,9 @@ struct vpnctl_cmd_redirect {
 #define VPNCTL_NTYPE_UNSUPPORTED_EXCHANGE_TYPE 29
 #define VPNCTL_NTYPE_UNEQUAL_PAYLOAD_LENGTHS   30
 #define VPNCTL_NTYPE_LOAD_BALANCE                              40501
+#define VPNCTL_NTYPE_PEER_DEAD                                 50001   /* detected by DPD */
+#define VPNCTL_NTYPE_PH1_DELETE                                        50002   /* received a delete payload leaving no PH1 SA for the remote address */
+#define VPNCTL_NTYPE_IDLE_TIMEOUT                              50003
 #define VPNCTL_NTYPE_INTERNAL_ERROR                            -1
 
 
@@ -157,8 +297,37 @@ struct vpnctl_cmd_redirect {
 struct vpnctl_status_phase_change {
        struct vpnctl_hdr                       hdr;
        u_int32_t                                       address;
+       /* The following is included when VPNCTL_FLAG_MODECFG_USED flag set */
+       // struct vpnctl_modecfg_params mode_cfg;
+
+};
+
+
+/* packet format for auth needed status */
+struct vpnctl_status_need_authinfo {
+       struct vpnctl_hdr                       hdr;
+       u_int32_t                                       address;
+       /* packed array of variable sized struct isakmp_data */
 };
 
+
+struct split_address {
+       u_int32_t       splitaddr;
+       u_int32_t       splitmask;
+};
+
+struct vpnctl_modecfg_params { 
+       u_int32_t                                       outer_local_addr;
+       u_int16_t                                       outer_remote_port;
+       u_int16_t                                       outer_local_port;
+       u_int8_t                                        ifname[IFNAMSIZ];
+       /*
+        *      ifname for outer_local_addr (not null terminated)
+        *      followed by packed array of attributes (struct isakmp_data)
+        */
+};
+
+
 /* Packet formats for failed status */
 struct vpnctl_status_failed {
        struct vpnctl_hdr                       hdr;
index 59ad69e2f16aacc034b46fb4f6585a419df95e54..79cf6675e259a83e632b3b3ad4c941ff150873f8 100644 (file)
@@ -54,6 +54,8 @@
 #ifndef _VPN_CONTROL_VAR_H
 #define _VPN_CONTROL_VAR_H
 
+#include "vpn_control.h"
+
 extern int vpncontrol_handler __P((void));
 extern int vpncontrol_comm_handler __P((struct vpnctl_socket_elem *));
 extern int vpncontrol_notify_ike_failed __P((u_int16_t, u_int16_t, u_int32_t, u_int16_t, u_int8_t*));
@@ -61,5 +63,9 @@ extern int vpncontrol_notify_phase_change __P((int, u_int16_t, struct ph1handle*
 extern int vpncontrol_init __P((void));
 extern void vpncontrol_close __P((void));
 extern int vpn_control_connected __P((void));
+extern int vpn_connect __P((struct bound_addr *));
+extern int vpn_disconnect __P((struct bound_addr *));
+extern int vpn_start_ph2 __P((struct bound_addr *, struct vpnctl_cmd_start_ph2 *));
+extern int vpncontrol_notify_need_authinfo __P((struct ph1handle *, void*, size_t));
 
 #endif /* _VPN_CONTROL_VAR_H */
diff --git a/ipsec-tools/setkey/ipsecPolicyTracer.c b/ipsec-tools/setkey/ipsecPolicyTracer.c
new file mode 100644 (file)
index 0000000..9b06ac5
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#import         <asl.h>
+#include <sys/types.h>
+#include "ipsecPolicyTracer.h"
+#include "ipsecMessageTracer.h"
+
+const char *ipsecConfigTracerFailedString = "Tracer Failed";
+const char *ipsecPolicyInvalidEventString = "Invalid Event";
+const char *ipsecPolicyString                    = "IPSEC";
+
+const char * const ipsecPolicyEventStrings[IPSECPOLICYEVENTCODE_MAX] = {       CONSTSTR("NONE") /* index place holder */,
+                                                                                                                                                       CONSTSTR("setkey Error"),
+                                                                                                                                               };
+
+const char *
+ipsecPolicyEventCodeToString (ipsecPolicyEventCode_t eventCode)
+{
+       if (eventCode <= IPSECPOLICYEVENTCODE_NONE || eventCode >= IPSECPOLICYEVENTCODE_MAX)
+               return ipsecPolicyInvalidEventString;
+       return(ipsecPolicyEventStrings[eventCode]);
+}
+
+static
+void
+ipsecPolicyLogEvent (const char *event_msg, const char *failure_signature)
+{
+       aslmsg m;
+
+       if (!event_msg) {
+               return;
+       }
+
+       m = asl_new(ASL_TYPE_MSG);
+       asl_set(m, ASL_KEY_FACILITY, PLAINIPSECDOMAIN);
+       asl_set(m, ASL_KEY_MSG, ipsecPolicyString);
+#if 0 /* we don't want to send filenames to MessageTracer server */
+    if (failure_signature) {
+        asl_set(m, "com.apple.message.domain", PLAINIPSECDOMAIN);
+        asl_set(m, "com.apple.message.result", "failure");     // failure
+        asl_set(m, "com.apple.message.signature", failure_signature);
+    }
+    asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg);
+#else
+    if (failure_signature) {
+        asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s (failure: %s)", event_msg, failure_signature);
+    } else {
+        asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg);
+    }
+#endif
+       asl_free(m);
+}
+
+void
+ipsecPolicyTracerEvent (const char *filename, ipsecPolicyEventCode_t eventCode, const char *event, const char *failure_reason)
+{
+       char buf[1024];
+
+       if (filename == NULL) {
+               ipsecPolicyLogEvent(CONSTSTR("tracer failed. (Invalid filename)."), ipsecConfigTracerFailedString);
+               return;
+       }
+       if (eventCode <= IPSECPOLICYEVENTCODE_NONE || eventCode >= IPSECPOLICYEVENTCODE_MAX) {
+               ipsecPolicyLogEvent(CONSTSTR("tracer failed. (Invalid event code)."), ipsecConfigTracerFailedString);
+               return;
+       }
+       if (event == NULL) {
+               ipsecPolicyLogEvent(CONSTSTR("tracer failed. (Invalid event)."), ipsecConfigTracerFailedString);
+               return;
+       }
+
+       buf[0] = (char)0;
+       snprintf(buf, sizeof(buf), "%s. (%s, filename %s).", ipsecPolicyEventCodeToString(eventCode), failure_reason, filename);
+       ipsecPolicyLogEvent(CONSTSTR(buf), event);      
+}
diff --git a/ipsec-tools/setkey/ipsecPolicyTracer.h b/ipsec-tools/setkey/ipsecPolicyTracer.h
new file mode 100644 (file)
index 0000000..4e9ff3b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _IPSECPOLICYTRACER_H
+#define _IPSECPOLICYTRACER_H
+
+typedef enum ipsecPolicyEventCode {
+       IPSECPOLICYEVENTCODE_NONE = 0,
+       IPSECPOLICYEVENTCODE_SETKEY_ERROR,
+       IPSECPOLICYEVENTCODE_MAX,
+} ipsecPolicyEventCode_t;
+       
+const char * ipsecPolicyEventCodeToString (ipsecPolicyEventCode_t);
+void ipsecPolicyTracerEvent (const char *, ipsecPolicyEventCode_t, const char *, const char *);
+
+#endif /* _IPSECPOLICYTRACER_H */
index 1c9445fdfb31f8c8a5148be9ab8c022f7ed18a16..5afba1b4768d7a50e5215ace7345d3325c7089ba 100644 (file)
@@ -74,8 +74,9 @@
 //#include "package_version.h"
 #define extern /* so that variables in extern.h are not extern... */
 #include "extern.h"
+#include "ipsecPolicyTracer.h"
+#include "ipsecMessageTracer.h"
 
-#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0')
 
 void usage __P((/*int*/));
 int main __P((int, char **));
@@ -172,6 +173,10 @@ main(argc, argv)
                case 'f':
                        f_mode = MODE_SCRIPT;
                        if ((fp = fopen(optarg, "r")) == NULL) {
+                IPSECPOLICYTRACEREVENT(optarg,
+                                       IPSECPOLICYEVENTCODE_SETKEY_ERROR,
+                                       CONSTSTR("could not open policy file"),
+                                       CONSTSTR("setkey -f : fopen erred"));
                                err(1, "fopen");
                                /*NOTREACHED*/
                        }
@@ -244,6 +249,10 @@ main(argc, argv)
        if (argc > 0) {
                while (argc--)
                        if (fileproc(*argv++) < 0) {
+                IPSECPOLICYTRACEREVENT(argv[-1],
+                                       IPSECPOLICYEVENTCODE_SETKEY_ERROR,
+                                       CONSTSTR("could not parse policy file"),
+                                       CONSTSTR("setkey: fileproc erred"));
                                err(1, "%s", argv[-1]);
                                /*NOTREACHED*/
                        }
@@ -252,6 +261,10 @@ main(argc, argv)
 
        so = pfkey_open();
        if (so < 0) {
+        IPSECPOLICYTRACEREVENT(argv[-1],
+                               IPSECPOLICYEVENTCODE_SETKEY_ERROR,
+                               CONSTSTR("couldn't open pfkey socket"),
+                               CONSTSTR("setkey: pfkey_open erred"));
                perror("pfkey_open");
                exit(1);
        }
@@ -273,6 +286,10 @@ main(argc, argv)
                break;
        case MODE_STDIN:
                if (get_supported() < 0) {
+            IPSECPOLICYTRACEREVENT("STDIN",
+                                   IPSECPOLICYEVENTCODE_SETKEY_ERROR,
+                                   CONSTSTR(ipsec_strerror()),
+                                   CONSTSTR("setkey: get_supported erred"));
                        errx(1, "%s", ipsec_strerror());
                        /*NOTREACHED*/
                }
diff --git a/ipsec.plist b/ipsec.plist
new file mode 100644 (file)
index 0000000..2b0ea9c
--- /dev/null
@@ -0,0 +1,29 @@
+(
+       {
+               "OpenSourceModifications" = (
+                       "Several security updates, memory leak fixes from 0.7.1 (ported by Les Aug/08)",
+               );
+               OpenSourceProject = racoon;
+               OpenSourceVersion = "0.6.7";
+               OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools";
+               OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src";
+       },
+       {
+               OpenSourceProject = libipsec;
+               OpenSourceVersion = "0.6.5";
+               OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools";
+               OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src";
+       },
+       {
+               OpenSourceProject = setkey;
+               OpenSourceVersion = "0.6.5";
+               OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools";
+               OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src";
+       },
+       {
+               OpenSourceProject = racoonctl;
+               OpenSourceVersion = "0.6.5";
+               OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools";
+               OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src";
+       },
+)
\ No newline at end of file
index 964f919c183eaa46e09be3db56d31b5b9596f68d..57d947839812db32b511adf12d254e4b4719c08f 100644 (file)
@@ -3,7 +3,7 @@
        archiveVersion = 1;
        classes = {
        };
-       objectVersion = 42;
+       objectVersion = 45;
        objects = {
 
 /* Begin PBXAggregateTarget section */
@@ -11,6 +11,7 @@
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 25D3DAB8098952B20025F703 /* Build configuration list for PBXAggregateTarget "IPSec (Aggregate)" */;
                        buildPhases = (
+                               72265DD80F818ED700730A7D /* CopyFiles */,
                        );
                        dependencies = (
                                25D3DDE30989AFDE0025F703 /* PBXTargetDependency */,
                        name = "IPSec (Aggregate)";
                        productName = "IPSec (Aggregate)";
                };
+               812530AA0D3FE994006BDF4F /* IPSec Embedded (Aggregate) */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 812530B50D3FE994006BDF4F /* Build configuration list for PBXAggregateTarget "IPSec Embedded (Aggregate)" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               812531110D3FEA28006BDF4F /* PBXTargetDependency */,
+                               81DDFDD90D622C4E00C5CB87 /* PBXTargetDependency */,
+                               8125312C0D3FEA44006BDF4F /* PBXTargetDependency */,
+                               81DDFDDB0D622C5100C5CB87 /* PBXTargetDependency */,
+                               81DDFDF10D627DE300C5CB87 /* PBXTargetDependency */,
+                       );
+                       name = "IPSec Embedded (Aggregate)";
+                       productName = "IPSec (Aggregate) Embedded";
+               };
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
@@ -59,9 +75,6 @@
                258CF2D40A191A5000166B38 /* plainrsa-gen.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F258FB0988657000D15623 /* plainrsa-gen.8 */; };
                258CF2E10A191A9200166B38 /* racoon.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F259090988657000D15623 /* racoon.8 */; };
                258CF2E40A191AD500166B38 /* racoon.conf.5 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2590A0988657000D15623 /* racoon.conf.5 */; };
-               258CF2E60A191B1800166B38 /* racoon.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2589A098864D700D15623 /* racoon.conf */; };
-               258CF2FB0A191B4F00166B38 /* anonymous.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F25898098864D700D15623 /* anonymous.conf */; };
-               258CF2FC0A191B5400166B38 /* psk.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F25899098864D700D15623 /* psk.txt */; };
                25BC48740A0BC7B000A181A0 /* eaytest.c in Sources */ = {isa = PBXBuildFile; fileRef = 25BC48730A0BC7B000A181A0 /* eaytest.c */; };
                25BE7E0109E5D3F4009B6B84 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; };
                25BE7E1209E5D550009B6B84 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE84709D879700042CC7F /* libssl.dylib */; };
                25DE2DE90A8BD40E0010A46D /* vpn_control.c in Sources */ = {isa = PBXBuildFile; fileRef = 25DE2DE60A8BD40E0010A46D /* vpn_control.c */; };
                25E08C9E09D9E681001A11CF /* prsa_par.y in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBA809D8B727002DC960 /* prsa_par.y */; };
                25E08C9F09D9E682001A11CF /* prsa_tok.l in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBAA09D8B727002DC960 /* prsa_tok.l */; };
-               25EAE83209D875790042CC7F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83109D875790042CC7F /* Security.framework */; };
-               25EAE83809D875BF0042CC7F /* DirectoryService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83709D875BF0042CC7F /* DirectoryService.framework */; };
                25EAE84809D879700042CC7F /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE84709D879700042CC7F /* libssl.dylib */; };
                25EAE84B09D879DE0042CC7F /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE84A09D879DE0042CC7F /* libcrypto.dylib */; };
-               25EAE87209D87A160042CC7F /* libgssapi_krb5.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87109D87A160042CC7F /* libgssapi_krb5.dylib */; };
-               25EAE87409D87A390042CC7F /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87309D87A390042CC7F /* libpam.dylib */; };
                25EAE87709D87A770042CC7F /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87609D87A770042CC7F /* libiconv.dylib */; };
                25EAE8C109D87B080042CC7F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE8C009D87B080042CC7F /* CoreFoundation.framework */; };
                25EAE8C609D87B990042CC7F /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; };
                25F2592A0988657000D15623 /* backupsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B10988657000D15623 /* backupsa.c */; };
                25F2592B0988657000D15623 /* cfparse.y in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B40988657000D15623 /* cfparse.y */; };
                25F2592C0988657000D15623 /* cftoken.l in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B60988657000D15623 /* cftoken.l */; };
-               25F2592D0988657000D15623 /* crypto_cssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B70988657000D15623 /* crypto_cssm.c */; };
                25F2592E0988657000D15623 /* crypto_openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B90988657000D15623 /* crypto_openssl.c */; };
                25F2592F0988657000D15623 /* dnssec.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258BE0988657000D15623 /* dnssec.c */; };
                25F259310988657000D15623 /* evt.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C20988657000D15623 /* evt.c */; };
                25F259460988657000D15623 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258ED0988657000D15623 /* main.c */; };
                25F259470988657000D15623 /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EE0988657000D15623 /* misc.c */; };
                25F259490988657000D15623 /* oakley.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F30988657000D15623 /* oakley.c */; };
-               25F2594A0988657000D15623 /* open_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F50988657000D15623 /* open_dir.c */; };
                25F2594C0988657000D15623 /* pfkey_racoon.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F80988657000D15623 /* pfkey_racoon.c */; };
                25F2594F0988657000D15623 /* plog.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FD0988657000D15623 /* plog.c */; };
                25F259500988657000D15623 /* policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FF0988657000D15623 /* policy.c */; };
                25F259610988657000D15623 /* throttle.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259210988657000D15623 /* throttle.c */; };
                25F259620988657000D15623 /* vendorid.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259240988657000D15623 /* vendorid.c */; };
                25F259630988657000D15623 /* vmbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259260988657000D15623 /* vmbuf.c */; };
+               72265DDC0F818F9300730A7D /* ipsec.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 72265DDB0F818F9300730A7D /* ipsec.plist */; };
+               72B433770E3677D800D67508 /* com.apple.racoon.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 724F99500E3672FD00C56897 /* com.apple.racoon.plist */; };
+               812530C00D3FE9DC006BDF4F /* rijndael-alg-fst.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258A10988651000D15623 /* rijndael-alg-fst.c */; };
+               812530C10D3FE9DC006BDF4F /* rijndael-api-fst.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258A30988651000D15623 /* rijndael-api-fst.c */; };
+               812530C20D3FE9DC006BDF4F /* admin.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258AC0988657000D15623 /* admin.c */; };
+               812530C30D3FE9DC006BDF4F /* algorithm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258AE0988657000D15623 /* algorithm.c */; };
+               812530C40D3FE9DC006BDF4F /* backupsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B10988657000D15623 /* backupsa.c */; };
+               812530C50D3FE9DC006BDF4F /* cfparse.y in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B40988657000D15623 /* cfparse.y */; };
+               812530C60D3FE9DC006BDF4F /* cftoken.l in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B60988657000D15623 /* cftoken.l */; };
+               812530C70D3FE9DC006BDF4F /* crypto_openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B90988657000D15623 /* crypto_openssl.c */; };
+               812530C80D3FE9DC006BDF4F /* dnssec.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258BE0988657000D15623 /* dnssec.c */; };
+               812530C90D3FE9DC006BDF4F /* evt.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C20988657000D15623 /* evt.c */; };
+               812530CA0D3FE9DC006BDF4F /* genlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C50988657000D15623 /* genlist.c */; };
+               812530CB0D3FE9DC006BDF4F /* getcertsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C70988657000D15623 /* getcertsbyname.c */; };
+               812530CC0D3FE9DC006BDF4F /* grabmyaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C90988657000D15623 /* grabmyaddr.c */; };
+               812530CD0D3FE9DC006BDF4F /* gssapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258CB0988657000D15623 /* gssapi.c */; };
+               812530CE0D3FE9DC006BDF4F /* handler.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258CD0988657000D15623 /* handler.c */; };
+               812530CF0D3FE9DC006BDF4F /* ipsec_doi.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258CF0988657000D15623 /* ipsec_doi.c */; };
+               812530D00D3FE9DC006BDF4F /* isakmp_agg.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D10988657000D15623 /* isakmp_agg.c */; };
+               812530D10D3FE9DC006BDF4F /* isakmp_base.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D30988657000D15623 /* isakmp_base.c */; };
+               812530D20D3FE9DC006BDF4F /* isakmp_ident.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D90988657000D15623 /* isakmp_ident.c */; };
+               812530D30D3FE9DC006BDF4F /* isakmp_inf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258DB0988657000D15623 /* isakmp_inf.c */; };
+               812530D40D3FE9DC006BDF4F /* isakmp_newg.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258DD0988657000D15623 /* isakmp_newg.c */; };
+               812530D50D3FE9DC006BDF4F /* isakmp_quick.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258DF0988657000D15623 /* isakmp_quick.c */; };
+               812530D60D3FE9DC006BDF4F /* isakmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E60988657000D15623 /* isakmp.c */; };
+               812530D70D3FE9DC006BDF4F /* localconf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E90988657000D15623 /* localconf.c */; };
+               812530D80D3FE9DC006BDF4F /* logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EB0988657000D15623 /* logger.c */; };
+               812530D90D3FE9DC006BDF4F /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258ED0988657000D15623 /* main.c */; };
+               812530DA0D3FE9DC006BDF4F /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EE0988657000D15623 /* misc.c */; };
+               812530DB0D3FE9DC006BDF4F /* oakley.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F30988657000D15623 /* oakley.c */; };
+               812530DC0D3FE9DC006BDF4F /* pfkey_racoon.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F80988657000D15623 /* pfkey_racoon.c */; };
+               812530DD0D3FE9DC006BDF4F /* plog.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FD0988657000D15623 /* plog.c */; };
+               812530DE0D3FE9DC006BDF4F /* policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FF0988657000D15623 /* policy.c */; };
+               812530DF0D3FE9DC006BDF4F /* privsep.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259010988657000D15623 /* privsep.c */; };
+               812530E00D3FE9DC006BDF4F /* proposal.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259030988657000D15623 /* proposal.c */; };
+               812530E10D3FE9DC006BDF4F /* remoteconf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2590E0988657000D15623 /* remoteconf.c */; };
+               812530E20D3FE9DC006BDF4F /* safefile.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259120988657000D15623 /* safefile.c */; };
+               812530E30D3FE9DC006BDF4F /* sainfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259140988657000D15623 /* sainfo.c */; };
+               812530E40D3FE9DC006BDF4F /* schedule.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259160988657000D15623 /* schedule.c */; };
+               812530E50D3FE9DC006BDF4F /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259180988657000D15623 /* session.c */; };
+               812530E60D3FE9DC006BDF4F /* sockmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591A0988657000D15623 /* sockmisc.c */; };
+               812530E70D3FE9DC006BDF4F /* str2val.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591D0988657000D15623 /* str2val.c */; };
+               812530E80D3FE9DC006BDF4F /* strnames.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591F0988657000D15623 /* strnames.c */; };
+               812530E90D3FE9DC006BDF4F /* throttle.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259210988657000D15623 /* throttle.c */; };
+               812530EA0D3FE9DC006BDF4F /* vendorid.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259240988657000D15623 /* vendorid.c */; };
+               812530EB0D3FE9DC006BDF4F /* vmbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259260988657000D15623 /* vmbuf.c */; };
+               812530EC0D3FE9DC006BDF4F /* nattraversal.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F00988657000D15623 /* nattraversal.c */; };
+               812530ED0D3FE9DC006BDF4F /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; };
+               812530EE0D3FE9DC006BDF4F /* rsalist.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259100988657000D15623 /* rsalist.c */; };
+               812530EF0D3FE9DC006BDF4F /* isakmp_cfg.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D50988657000D15623 /* isakmp_cfg.c */; };
+               812530F00D3FE9DC006BDF4F /* isakmp_unity.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E10988657000D15623 /* isakmp_unity.c */; };
+               812530F10D3FE9DC006BDF4F /* isakmp_xauth.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E40988657000D15623 /* isakmp_xauth.c */; };
+               812530F20D3FE9DC006BDF4F /* vpn_control.c in Sources */ = {isa = PBXBuildFile; fileRef = 25DE2DE60A8BD40E0010A46D /* vpn_control.c */; };
+               812530F30D3FE9DC006BDF4F /* vpn.c in Sources */ = {isa = PBXBuildFile; fileRef = 81CA08910CE3BC870055C0AF /* vpn.c */; };
+               812530F80D3FE9DC006BDF4F /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87609D87A770042CC7F /* libiconv.dylib */; };
+               812530F90D3FE9DC006BDF4F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE8C009D87B080042CC7F /* CoreFoundation.framework */; };
+               812530FC0D3FE9DC006BDF4F /* racoon.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F259090988657000D15623 /* racoon.8 */; };
+               812530FE0D3FE9DC006BDF4F /* racoon.conf.5 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2590A0988657000D15623 /* racoon.conf.5 */; };
+               812531160D3FEA33006BDF4F /* racoonctl.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2590C0988657000D15623 /* racoonctl.c */; };
+               812531170D3FEA33006BDF4F /* str2val.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591D0988657000D15623 /* str2val.c */; };
+               812531180D3FEA33006BDF4F /* kmpstat.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E80988657000D15623 /* kmpstat.c */; };
+               812531190D3FEA33006BDF4F /* vmbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259260988657000D15623 /* vmbuf.c */; };
+               8125311A0D3FEA33006BDF4F /* sockmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591A0988657000D15623 /* sockmisc.c */; };
+               8125311B0D3FEA33006BDF4F /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EE0988657000D15623 /* misc.c */; };
+               8125311C0D3FEA33006BDF4F /* pfkey_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777ED09ABE58400C99783 /* pfkey_dump.c */; };
+               8125311D0D3FEA33006BDF4F /* key_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777B909ABE3E100C99783 /* key_debug.c */; };
+               8125311E0D3FEA33006BDF4F /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; };
+               812531220D3FEA33006BDF4F /* racoonctl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2590B0988657000D15623 /* racoonctl.8 */; };
+               812A64ED0D4AA082004CB7EB /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 812A64EC0D4AA082004CB7EB /* Security.framework */; };
+               8167917B0D650BAA006B523F /* racoon.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103A0D5BE18800C7B441 /* racoon.conf */; };
+               8176A6B90D45661700BC5251 /* libldap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8176A6B80D45661700BC5251 /* libldap.dylib */; };
+               817FFC4E0D6134A7004A8DD8 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; };
+               817FFC4F0D6134AD004A8DD8 /* rsaparse.o in Frameworks */ = {isa = PBXBuildFile; fileRef = 25E08C9A09D9E64A001A11CF /* rsaparse.o */; };
+               817FFC5A0D613729004A8DD8 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; };
+               818710410D5BE22B00C7B441 /* psk.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103D0D5BE1CF00C7B441 /* psk.txt */; };
+               818710420D5BE22F00C7B441 /* racoon.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103B0D5BE1B400C7B441 /* racoon.conf */; };
+               818710510D5BE29300C7B441 /* psk.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103D0D5BE1CF00C7B441 /* psk.txt */; };
+               818710530D5BE2B500C7B441 /* anonymous.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103C0D5BE1CF00C7B441 /* anonymous.conf */; };
+               81C325A80D46A36900E65EB7 /* crypto_cssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B70988657000D15623 /* crypto_cssm.c */; };
+               81C386AA0D451EC300975D5E /* crypto_cssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B70988657000D15623 /* crypto_cssm.c */; };
+               81C387560D45208700975D5E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83109D875790042CC7F /* Security.framework */; };
+               81C387570D45208700975D5E /* DirectoryService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83709D875BF0042CC7F /* DirectoryService.framework */; };
+               81C3877A0D4524E700975D5E /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87309D87A390042CC7F /* libpam.dylib */; };
+               81C387890D4524F600975D5E /* libgssapi_krb5.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87109D87A160042CC7F /* libgssapi_krb5.dylib */; };
+               81C387EC0D45268300975D5E /* open_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F50988657000D15623 /* open_dir.c */; };
+               81C964590DA2CBEF00257BC8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C964580DA2CBEF00257BC8 /* SystemConfiguration.framework */; };
+               81C9645E0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */; };
+               81C9645F0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */; };
+               81CA08920CE3BC870055C0AF /* vpn.c in Sources */ = {isa = PBXBuildFile; fileRef = 81CA08910CE3BC870055C0AF /* vpn.c */; };
+               81DDFD9B0D622C1700C5CB87 /* parse.y in Sources */ = {isa = PBXBuildFile; fileRef = 25F258870988648C00D15623 /* parse.y */; };
+               81DDFD9C0D622C1700C5CB87 /* pfkey_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777ED09ABE58400C99783 /* pfkey_dump.c */; };
+               81DDFD9D0D622C1700C5CB87 /* key_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777B909ABE3E100C99783 /* key_debug.c */; };
+               81DDFD9E0D622C1700C5CB87 /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; };
+               81DDFD9F0D622C1700C5CB87 /* setkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2588A0988648C00D15623 /* setkey.c */; };
+               81DDFDA00D622C1700C5CB87 /* token.l in Sources */ = {isa = PBXBuildFile; fileRef = 25F2588D0988648C00D15623 /* token.l */; };
+               81DDFDA20D622C1700C5CB87 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; };
+               81DDFDA40D622C1700C5CB87 /* setkey.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F258890988648C00D15623 /* setkey.8 */; };
+               81DDFDBA0D622C2700C5CB87 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 25D9499F09A6AAD700CA0F24 /* config.h */; };
+               81DDFDBB0D622C2700C5CB87 /* ipsec_strerror.h in Headers */ = {isa = PBXBuildFile; fileRef = 252DF9570989B4EE00E5B678 /* ipsec_strerror.h */; };
+               81DDFDBD0D622C2700C5CB87 /* ipsec_dump_policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9520989B4EE00E5B678 /* ipsec_dump_policy.c */; };
+               81DDFDBE0D622C2700C5CB87 /* ipsec_get_policylen.c in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9530989B4EE00E5B678 /* ipsec_get_policylen.c */; };
+               81DDFDBF0D622C2700C5CB87 /* ipsec_strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9560989B4EE00E5B678 /* ipsec_strerror.c */; };
+               81DDFDC00D622C2700C5CB87 /* policy_parse.y in Sources */ = {isa = PBXBuildFile; fileRef = 252DF95E0989B4EE00E5B678 /* policy_parse.y */; };
+               81DDFDC10D622C2700C5CB87 /* policy_token.l in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9600989B4EE00E5B678 /* policy_token.l */; };
+               81DDFDC40D622C2700C5CB87 /* ipsec_set_policy.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 252DF9540989B4EE00E5B678 /* ipsec_set_policy.3 */; };
+               81DDFDC50D622C2700C5CB87 /* ipsec_strerror.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 252DF9550989B4EE00E5B678 /* ipsec_strerror.3 */; };
+               81DDFDC60D622C2700C5CB87 /* ipsec_get_policylen.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0680B5D8D8900840BC7 /* ipsec_get_policylen.3 */; };
+               81DDFDC70D622C2700C5CB87 /* ipsec_dump_policy.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0670B5D8D7000840BC7 /* ipsec_dump_policy.3 */; };
+               81DDFDD00D622C3500C5CB87 /* prsa_par.y in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBA809D8B727002DC960 /* prsa_par.y */; };
+               81DDFDD10D622C3500C5CB87 /* prsa_tok.l in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBAA09D8B727002DC960 /* prsa_tok.l */; };
                81EDB0690B5D8D9600840BC7 /* ipsec_get_policylen.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0680B5D8D8900840BC7 /* ipsec_get_policylen.3 */; };
                81EDB06A0B5D8D9A00840BC7 /* ipsec_dump_policy.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0670B5D8D7000840BC7 /* ipsec_dump_policy.3 */; };
+               834072A90EDCC5AC00B6CCE8 /* com.apple.racoon.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 724F99500E3672FD00C56897 /* com.apple.racoon.plist */; };
+               8D5B16750E5F7F4E00E72675 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5B16230E5F7E9300E72675 /* libresolv.dylib */; };
+               8D5B167D0E5F7F9F00E72675 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5B16230E5F7E9300E72675 /* libresolv.dylib */; };
+               BA5B6F2A0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */; };
+               BA5B6F2B0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */; };
+               BA5B6F2C0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */; };
+               BA5B6F2D0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */; };
+               BA5B6F310EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */; };
+               BA5B6F320EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */; };
+               BA6F109B0EA1DEC200546773 /* ike_session.c in Sources */ = {isa = PBXBuildFile; fileRef = BA6F109A0EA1DEC200546773 /* ike_session.c */; };
+               BA6F109C0EA1DEC200546773 /* ike_session.c in Sources */ = {isa = PBXBuildFile; fileRef = BA6F109A0EA1DEC200546773 /* ike_session.c */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                        remoteGlobalIDString = 25E08C9909D9E64A001A11CF;
                        remoteInfo = rsaparse;
                };
+               812531100D3FEA28006BDF4F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 812530BA0D3FE9DC006BDF4F;
+                       remoteInfo = "racoon arm";
+               };
+               8125312B0D3FEA44006BDF4F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 812531120D3FEA33006BDF4F;
+                       remoteInfo = "racoonctl arm";
+               };
+               81DDFDD80D622C4E00C5CB87 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 81DDFDB80D622C2700C5CB87;
+                       remoteInfo = "libipsec Embedded";
+               };
+               81DDFDDA0D622C5100C5CB87 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 81DDFDCE0D622C3500C5CB87;
+                       remoteInfo = "rsaparse Embedded";
+               };
+               81DDFDDE0D622D1700C5CB87 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 81DDFDB80D622C2700C5CB87;
+                       remoteInfo = "libipsec Embedded";
+               };
+               81DDFDE00D622D2A00C5CB87 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 81DDFDCE0D622C3500C5CB87;
+                       remoteInfo = "rsaparse Embedded";
+               };
+               81DDFDE30D622D8C00C5CB87 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 81DDFDB80D622C2700C5CB87;
+                       remoteInfo = "libipsec Embedded";
+               };
+               81DDFDF00D627DE300C5CB87 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 23D2D790087071FC00C51098 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 81DDFD970D622C1700C5CB87;
+                       remoteInfo = "setkey Embedded";
+               };
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
                258CF2F80A191B3900166B38 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
-                       dstPath = /usr/share/man/man5;
-                       dstSubfolderSpec = 0;
+                       dstPath = usr/share/man/man5;
+                       dstSubfolderSpec = 16;
                        files = (
                                258CF2E40A191AD500166B38 /* racoon.conf.5 in CopyFiles */,
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               258CF2F90A191B3900166B38 /* CopyFiles */ = {
+               258CF2FA0A191B3900166B38 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        dstPath = /private/etc/racoon;
                        dstSubfolderSpec = 0;
                        files = (
-                               258CF2FC0A191B5400166B38 /* psk.txt in CopyFiles */,
-                               258CF2E60A191B1800166B38 /* racoon.conf in CopyFiles */,
+                               818710410D5BE22B00C7B441 /* psk.txt in CopyFiles */,
+                               818710420D5BE22F00C7B441 /* racoon.conf in CopyFiles */,
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               258CF2FA0A191B3900166B38 /* CopyFiles */ = {
+               72265DD80F818ED700730A7D /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/local/OpenSourceVersions/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               72265DDC0F818F9300730A7D /* ipsec.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               724A38A20E3676FB00F6B25F /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /System/Library/LaunchDaemons;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               72B433770E3677D800D67508 /* com.apple.racoon.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               725F453B0E36A15C005BB55C /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /System/Library/LaunchDaemons;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               834072A90EDCC5AC00B6CCE8 /* com.apple.racoon.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               812530FB0D3FE9DC006BDF4F /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man8;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               812530FC0D3FE9DC006BDF4F /* racoon.8 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               812530FD0D3FE9DC006BDF4F /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man5;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               812530FE0D3FE9DC006BDF4F /* racoon.conf.5 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               812530FF0D3FE9DC006BDF4F /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        dstPath = /private/etc/racoon/remote;
                        dstSubfolderSpec = 0;
                        files = (
-                               258CF2FB0A191B4F00166B38 /* anonymous.conf in CopyFiles */,
+                               818710530D5BE2B500C7B441 /* anonymous.conf in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               812531020D3FE9DC006BDF4F /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /private/etc/racoon;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               818710510D5BE29300C7B441 /* psk.txt in CopyFiles */,
+                               8167917B0D650BAA006B523F /* racoon.conf in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               812531210D3FEA33006BDF4F /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man8;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               812531220D3FEA33006BDF4F /* racoonctl.8 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               81DDFDA30D622C1700C5CB87 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man8;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               81DDFDA40D622C1700C5CB87 /* setkey.8 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               81DDFDC30D622C2700C5CB87 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man3;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               81DDFDC40D622C2700C5CB87 /* ipsec_set_policy.3 in CopyFiles */,
+                               81DDFDC50D622C2700C5CB87 /* ipsec_strerror.3 in CopyFiles */,
+                               81DDFDC60D622C2700C5CB87 /* ipsec_get_policylen.3 in CopyFiles */,
+                               81DDFDC70D622C2700C5CB87 /* ipsec_dump_policy.3 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               834072BB0EDCC5C400B6CCE8 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /System/Library/LaunchDaemons;
+                       dstSubfolderSpec = 0;
+                       files = (
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                25F25895098864AB00D15623 /* sample-policy01.cf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "sample-policy01.cf"; sourceTree = "<group>"; };
                25F25896098864AB00D15623 /* sample-policy02.cf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "sample-policy02.cf"; sourceTree = "<group>"; };
                25F25897098864AB00D15623 /* sample.cf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = sample.cf; sourceTree = "<group>"; };
-               25F25898098864D700D15623 /* anonymous.conf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = anonymous.conf; sourceTree = "<group>"; };
-               25F25899098864D700D15623 /* psk.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = psk.txt; sourceTree = "<group>"; };
-               25F2589A098864D700D15623 /* racoon.conf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = racoon.conf; sourceTree = "<group>"; };
                25F2589B098864F500D15623 /* FAQ */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = FAQ; sourceTree = "<group>"; };
                25F2589C098864F500D15623 /* README.certificate */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.certificate; sourceTree = "<group>"; };
                25F2589D098864F500D15623 /* README.gssapi */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.gssapi; sourceTree = "<group>"; };
                25F259270988657000D15623 /* vmbuf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vmbuf.h; sourceTree = "<group>"; };
                25F777B909ABE3E100C99783 /* key_debug.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = key_debug.c; path = Common/key_debug.c; sourceTree = "<group>"; };
                25F777ED09ABE58400C99783 /* pfkey_dump.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pfkey_dump.c; path = Common/pfkey_dump.c; sourceTree = "<group>"; };
+               72265DDB0F818F9300730A7D /* ipsec.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = ipsec.plist; sourceTree = "<group>"; };
+               724F99500E3672FD00C56897 /* com.apple.racoon.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.racoon.plist; sourceTree = "<group>"; };
+               8125310A0D3FE9DC006BDF4F /* racoon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = racoon; sourceTree = BUILT_PRODUCTS_DIR; };
+               812531290D3FEA33006BDF4F /* racoonctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = racoonctl; sourceTree = BUILT_PRODUCTS_DIR; };
+               812A64EC0D4AA082004CB7EB /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = SDKs/Purple/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
+               8176A6B80D45661700BC5251 /* libldap.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libldap.dylib; path = /usr/lib/libldap.dylib; sourceTree = "<absolute>"; };
+               81856B700D6B8BC5001DAE21 /* algorithm_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = algorithm_types.h; sourceTree = "<group>"; };
+               8187103A0D5BE18800C7B441 /* racoon.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = racoon.conf; path = Sample/Embedded/racoon.conf; sourceTree = "<group>"; };
+               8187103B0D5BE1B400C7B441 /* racoon.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = racoon.conf; path = Sample/racoon.conf; sourceTree = "<group>"; };
+               8187103C0D5BE1CF00C7B441 /* anonymous.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = anonymous.conf; path = Sample/anonymous.conf; sourceTree = "<group>"; };
+               8187103D0D5BE1CF00C7B441 /* psk.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = psk.txt; path = Sample/psk.txt; sourceTree = "<group>"; };
+               81C964580DA2CBEF00257BC8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; };
+               81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = "<absolute>"; };
+               81CA08910CE3BC870055C0AF /* vpn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vpn.c; sourceTree = "<group>"; };
+               81DDFDAA0D622C1700C5CB87 /* setkey */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = setkey; sourceTree = BUILT_PRODUCTS_DIR; };
+               81DDFDCD0D622C2700C5CB87 /* libipsec.A.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libipsec.A.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               81DDFDD70D622C3500C5CB87 /* rsaparse.o */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.objfile"; includeInIndex = 0; path = rsaparse.o; sourceTree = BUILT_PRODUCTS_DIR; };
                81EDB0670B5D8D7000840BC7 /* ipsec_dump_policy.3 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = ipsec_dump_policy.3; path = libipsec/ipsec_dump_policy.3; sourceTree = "<group>"; };
                81EDB0680B5D8D8900840BC7 /* ipsec_get_policylen.3 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = ipsec_get_policylen.3; path = libipsec/ipsec_get_policylen.3; sourceTree = "<group>"; };
+               8D5B16230E5F7E9300E72675 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.dylib; path = /usr/lib/libresolv.dylib; sourceTree = "<absolute>"; };
+               BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipsecConfigTracer.c; sourceTree = "<group>"; };
+               BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipsecSessionTracer.c; sourceTree = "<group>"; };
+               BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipsecPolicyTracer.c; sourceTree = "<group>"; };
+               BA5B6F350EC1A03C003774E7 /* ipsecMessageTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ipsecMessageTracer.h; path = Common/ipsecMessageTracer.h; sourceTree = "<group>"; };
+               BA5B6F360EC1A03C003774E7 /* ipsecConfigTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipsecConfigTracer.h; sourceTree = "<group>"; };
+               BA5B6F370EC1A03C003774E7 /* ipsecSessionTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipsecSessionTracer.h; sourceTree = "<group>"; };
+               BA5B6F380EC1A03C003774E7 /* ipsecPolicyTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipsecPolicyTracer.h; sourceTree = "<group>"; };
+               BA5B6F4F0EC1A136003774E7 /* vpn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vpn.h; sourceTree = "<group>"; };
+               BA6F10940EA1D67700546773 /* ike_session.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ike_session.h; sourceTree = "<group>"; };
+               BA6F109A0EA1DEC200546773 /* ike_session.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ike_session.c; sourceTree = "<group>"; };
+               C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = AspenSDK.xcconfig; path = AppleInternal/XcodeConfig/AspenSDK.xcconfig; sourceTree = DEVELOPER_DIR; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               81C387570D45208700975D5E /* DirectoryService.framework in Frameworks */,
+                               81C387560D45208700975D5E /* Security.framework in Frameworks */,
+                               25EAE8C109D87B080042CC7F /* CoreFoundation.framework in Frameworks */,
+                               8D5B16750E5F7F4E00E72675 /* libresolv.dylib in Frameworks */,
                                2537A1C709E49D0600D0ECDA /* libipsec.A.dylib in Frameworks */,
-                               25EAE83209D875790042CC7F /* Security.framework in Frameworks */,
-                               25EAE83809D875BF0042CC7F /* DirectoryService.framework in Frameworks */,
                                25EAE84809D879700042CC7F /* libssl.dylib in Frameworks */,
                                25EAE84B09D879DE0042CC7F /* libcrypto.dylib in Frameworks */,
-                               25EAE87209D87A160042CC7F /* libgssapi_krb5.dylib in Frameworks */,
-                               25EAE87409D87A390042CC7F /* libpam.dylib in Frameworks */,
+                               81C387890D4524F600975D5E /* libgssapi_krb5.dylib in Frameworks */,
+                               81C3877A0D4524E700975D5E /* libpam.dylib in Frameworks */,
                                25EAE87709D87A770042CC7F /* libiconv.dylib in Frameworks */,
-                               25EAE8C109D87B080042CC7F /* CoreFoundation.framework in Frameworks */,
                                25DC9ED709DB170800C89F86 /* rsaparse.o in Frameworks */,
+                               8176A6B90D45661700BC5251 /* libldap.dylib in Frameworks */,
+                               81C9645F0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               812530F40D3FE9DC006BDF4F /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               817FFC4F0D6134AD004A8DD8 /* rsaparse.o in Frameworks */,
+                               8D5B167D0E5F7F9F00E72675 /* libresolv.dylib in Frameworks */,
+                               817FFC4E0D6134A7004A8DD8 /* libipsec.A.dylib in Frameworks */,
+                               812530F80D3FE9DC006BDF4F /* libiconv.dylib in Frameworks */,
+                               812530F90D3FE9DC006BDF4F /* CoreFoundation.framework in Frameworks */,
+                               812A64ED0D4AA082004CB7EB /* Security.framework in Frameworks */,
+                               81C964590DA2CBEF00257BC8 /* SystemConfiguration.framework in Frameworks */,
+                               81C9645E0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               8125311F0D3FEA33006BDF4F /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               817FFC5A0D613729004A8DD8 /* libipsec.A.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               81DDFDA10D622C1700C5CB87 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               81DDFDA20D622C1700C5CB87 /* libipsec.A.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               81DDFDC20D622C2700C5CB87 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               81DDFDD20D622C3500C5CB87 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
                23D2D78C087071FC00C51098 = {
                        isa = PBXGroup;
                        children = (
+                               72265DDB0F818F9300730A7D /* ipsec.plist */,
+                               C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */,
                                25E5E82D0981A61900F2834C /* ipsec-tools */,
                                2589CB5409D8AE95002DC960 /* Libraries */,
                                25D3DB4C098998230025F703 /* Frameworks */,
                                254347B609DCB839007943DE /* test-policy */,
                                254347C509DCBA07007943DE /* test-pfkey */,
                                2537A1A809E4864800D0ECDA /* libipsec.A.dylib */,
+                               8125310A0D3FE9DC006BDF4F /* racoon */,
+                               812531290D3FEA33006BDF4F /* racoonctl */,
+                               81DDFDAA0D622C1700C5CB87 /* setkey */,
+                               81DDFDCD0D622C2700C5CB87 /* libipsec.A.dylib */,
+                               81DDFDD70D622C3500C5CB87 /* rsaparse.o */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                2589CB5409D8AE95002DC960 /* Libraries */ = {
                        isa = PBXGroup;
                        children = (
+                               8176A6B80D45661700BC5251 /* libldap.dylib */,
+                               8D5B16230E5F7E9300E72675 /* libresolv.dylib */,
                                25EAE87609D87A770042CC7F /* libiconv.dylib */,
                                25EAE87309D87A390042CC7F /* libpam.dylib */,
                                25EAE87109D87A160042CC7F /* libgssapi_krb5.dylib */,
                25D3DB4C098998230025F703 /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
+                               81C964580DA2CBEF00257BC8 /* SystemConfiguration.framework */,
+                               81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */,
+                               812A64EC0D4AA082004CB7EB /* Security.framework */,
                                25EAE83109D875790042CC7F /* Security.framework */,
                                25EAE83709D875BF0042CC7F /* DirectoryService.framework */,
                                25EAE8C009D87B080042CC7F /* CoreFoundation.framework */,
                25D9497C09A6AA7600CA0F24 /* Common */ = {
                        isa = PBXGroup;
                        children = (
+                               BA5B6F350EC1A03C003774E7 /* ipsecMessageTracer.h */,
                                25F777ED09ABE58400C99783 /* pfkey_dump.c */,
                                25F777B909ABE3E100C99783 /* key_debug.c */,
                                25D9499F09A6AAD700CA0F24 /* config.h */,
                25F257FF0987FB0E00D15623 /* setkey */ = {
                        isa = PBXGroup;
                        children = (
+                               BA5B6F380EC1A03C003774E7 /* ipsecPolicyTracer.h */,
+                               BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */,
                                254347C709DCBA1B007943DE /* test-pfkey.c */,
                                25F258840988648C00D15623 /* extern.h */,
                                25F258870988648C00D15623 /* parse.y */,
                25F258000987FB1600D15623 /* racoon */ = {
                        isa = PBXGroup;
                        children = (
+                               BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */,
+                               BA5B6F360EC1A03C003774E7 /* ipsecConfigTracer.h */,
+                               BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */,
+                               BA5B6F370EC1A03C003774E7 /* ipsecSessionTracer.h */,
+                               BA6F109A0EA1DEC200546773 /* ike_session.c */,
+                               BA6F10940EA1D67700546773 /* ike_session.h */,
                                2589CBA809D8B727002DC960 /* prsa_par.y */,
                                2589CBAA09D8B727002DC960 /* prsa_tok.l */,
                                25F258AB0988657000D15623 /* admin_var.h */,
                                25F258AC0988657000D15623 /* admin.c */,
                                25F258AD0988657000D15623 /* admin.h */,
                                25F258AE0988657000D15623 /* algorithm.c */,
+                               81856B700D6B8BC5001DAE21 /* algorithm_types.h */,
                                25F258AF0988657000D15623 /* algorithm.h */,
                                25F258B00988657000D15623 /* arc4random.h */,
                                25F258B10988657000D15623 /* backupsa.c */,
                                25F258B40988657000D15623 /* cfparse.y */,
                                25F258B50988657000D15623 /* cftoken_proto.h */,
                                25F258B60988657000D15623 /* cftoken.l */,
+                               724F99500E3672FD00C56897 /* com.apple.racoon.plist */,
                                25F258B70988657000D15623 /* crypto_cssm.c */,
                                25F258B80988657000D15623 /* crypto_cssm.h */,
                                25F258B90988657000D15623 /* crypto_openssl.c */,
                                25DE2DE50A8BD40E0010A46D /* vpn_control_var.h */,
                                25DE2DE60A8BD40E0010A46D /* vpn_control.c */,
                                25DE2DE70A8BD40E0010A46D /* vpn_control.h */,
-                               25F2584E0988620300D15623 /* Sample */,
+                               81CA08910CE3BC870055C0AF /* vpn.c */,
+                               BA5B6F4F0EC1A136003774E7 /* vpn.h */,
+                               818710380D5BE15400C7B441 /* Sample */,
                                25F2584D098861F500D15623 /* Documents */,
                                25F2584C098861ED00D15623 /* Crypto */,
                        );
                        path = Documents;
                        sourceTree = "<group>";
                };
-               25F2584E0988620300D15623 /* Sample */ = {
+               818710380D5BE15400C7B441 /* Sample */ = {
                        isa = PBXGroup;
                        children = (
-                               25F25898098864D700D15623 /* anonymous.conf */,
-                               25F25899098864D700D15623 /* psk.txt */,
-                               25F2589A098864D700D15623 /* racoon.conf */,
+                               8187103C0D5BE1CF00C7B441 /* anonymous.conf */,
+                               8187103D0D5BE1CF00C7B441 /* psk.txt */,
+                               8187103B0D5BE1B400C7B441 /* racoon.conf */,
+                               818710390D5BE16600C7B441 /* Embedded */,
                        );
-                       path = Sample;
+                       name = Sample;
+                       sourceTree = "<group>";
+               };
+               818710390D5BE16600C7B441 /* Embedded */ = {
+                       isa = PBXGroup;
+                       children = (
+                               8187103A0D5BE18800C7B441 /* racoon.conf */,
+                       );
+                       name = Embedded;
                        sourceTree = "<group>";
                };
 /* End PBXGroup section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               81DDFDB90D622C2700C5CB87 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               81DDFDBA0D622C2700C5CB87 /* config.h in Headers */,
+                               81DDFDBB0D622C2700C5CB87 /* ipsec_strerror.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
                                25F258020987FBFA00D15623 /* Sources */,
                                25F258030987FBFA00D15623 /* Frameworks */,
                                258CF2E20A191AB000166B38 /* CopyFiles */,
+                               724A38A20E3676FB00F6B25F /* CopyFiles */,
                                258CF2F80A191B3900166B38 /* CopyFiles */,
-                               258CF2F90A191B3900166B38 /* CopyFiles */,
                                258CF2FA0A191B3900166B38 /* CopyFiles */,
                                258CF31B0A1941A200166B38 /* ShellScript */,
                        );
                        productReference = 25F2580F0987FC3400D15623 /* racoonctl */;
                        productType = "com.apple.product-type.tool";
                };
+               812530BA0D3FE9DC006BDF4F /* racoon Embedded */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 812531050D3FE9DC006BDF4F /* Build configuration list for PBXNativeTarget "racoon Embedded" */;
+                       buildPhases = (
+                               812530BF0D3FE9DC006BDF4F /* Sources */,
+                               812530F40D3FE9DC006BDF4F /* Frameworks */,
+                               812530FB0D3FE9DC006BDF4F /* CopyFiles */,
+                               812530FD0D3FE9DC006BDF4F /* CopyFiles */,
+                               812530FF0D3FE9DC006BDF4F /* CopyFiles */,
+                               812531020D3FE9DC006BDF4F /* CopyFiles */,
+                               725F453B0E36A15C005BB55C /* CopyFiles */,
+                               812531040D3FE9DC006BDF4F /* ShellScript */,
+                               834072BB0EDCC5C400B6CCE8 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               81DDFDDF0D622D1700C5CB87 /* PBXTargetDependency */,
+                               81DDFDE10D622D2A00C5CB87 /* PBXTargetDependency */,
+                       );
+                       name = "racoon Embedded";
+                       productName = racoon;
+                       productReference = 8125310A0D3FE9DC006BDF4F /* racoon */;
+                       productType = "com.apple.product-type.tool";
+               };
+               812531120D3FEA33006BDF4F /* racoonctl Embedded */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 812531240D3FEA33006BDF4F /* Build configuration list for PBXNativeTarget "racoonctl Embedded" */;
+                       buildPhases = (
+                               812531150D3FEA33006BDF4F /* Sources */,
+                               8125311F0D3FEA33006BDF4F /* Frameworks */,
+                               812531210D3FEA33006BDF4F /* CopyFiles */,
+                               812531230D3FEA33006BDF4F /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "racoonctl Embedded";
+                       productName = racoonctl;
+                       productReference = 812531290D3FEA33006BDF4F /* racoonctl */;
+                       productType = "com.apple.product-type.tool";
+               };
+               81DDFD970D622C1700C5CB87 /* setkey Embedded */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 81DDFDA60D622C1700C5CB87 /* Build configuration list for PBXNativeTarget "setkey Embedded" */;
+                       buildPhases = (
+                               81DDFD9A0D622C1700C5CB87 /* Sources */,
+                               81DDFDA10D622C1700C5CB87 /* Frameworks */,
+                               81DDFDA30D622C1700C5CB87 /* CopyFiles */,
+                               81DDFDA50D622C1700C5CB87 /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               81DDFDE40D622D8C00C5CB87 /* PBXTargetDependency */,
+                       );
+                       name = "setkey Embedded";
+                       productName = setkey;
+                       productReference = 81DDFDAA0D622C1700C5CB87 /* setkey */;
+                       productType = "com.apple.product-type.tool";
+               };
+               81DDFDB80D622C2700C5CB87 /* libipsec Embedded */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 81DDFDC90D622C2700C5CB87 /* Build configuration list for PBXNativeTarget "libipsec Embedded" */;
+                       buildPhases = (
+                               81DDFDB90D622C2700C5CB87 /* Headers */,
+                               81DDFDBC0D622C2700C5CB87 /* Sources */,
+                               81DDFDC20D622C2700C5CB87 /* Frameworks */,
+                               81DDFDC30D622C2700C5CB87 /* CopyFiles */,
+                               81DDFDC80D622C2700C5CB87 /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "libipsec Embedded";
+                       productName = libipsec;
+                       productReference = 81DDFDCD0D622C2700C5CB87 /* libipsec.A.dylib */;
+                       productType = "com.apple.product-type.library.dynamic";
+               };
+               81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 81DDFDD30D622C3500C5CB87 /* Build configuration list for PBXNativeTarget "rsaparse Embedded" */;
+                       buildPhases = (
+                               81DDFDCF0D622C3500C5CB87 /* Sources */,
+                               81DDFDD20D622C3500C5CB87 /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "rsaparse Embedded";
+                       productName = rsaparse;
+                       productReference = 81DDFDD70D622C3500C5CB87 /* rsaparse.o */;
+                       productType = "com.apple.product-type.objfile";
+               };
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
                23D2D790087071FC00C51098 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 25D3DACC098952B20025F703 /* Build configuration list for PBXProject "ipsec" */;
-                       compatibilityVersion = "Xcode 2.4";
+                       compatibilityVersion = "Xcode 3.0";
                        hasScannedForEncodings = 0;
                        mainGroup = 23D2D78C087071FC00C51098;
                        productRefGroup = 23D2D79C087074CC00C51098 /* Products */;
                                254347B509DCB839007943DE /* test-policy */,
                                254347C409DCBA07007943DE /* test-pfkey */,
                                2537A1A709E4864800D0ECDA /* libipsec */,
+                               812530AA0D3FE994006BDF4F /* IPSec Embedded (Aggregate) */,
+                               812530BA0D3FE9DC006BDF4F /* racoon Embedded */,
+                               812531120D3FEA33006BDF4F /* racoonctl Embedded */,
+                               81DDFD970D622C1700C5CB87 /* setkey Embedded */,
+                               81DDFDB80D622C2700C5CB87 /* libipsec Embedded */,
+                               81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */,
                        );
                };
 /* End PBXProject section */
                        shellPath = /bin/sh;
                        shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_set_policy.3\n/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_strerror.3\n/bin/ln -s libipsec.A.dylib $DSTROOT/usr/lib/libipsec.dylib\n";
                };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
-               2537A1A509E4864800D0ECDA /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
+               812531040D3FE9DC006BDF4F /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
                        files = (
-                               2537A1B509E4867700D0ECDA /* ipsec_dump_policy.c in Sources */,
-                               2537A1B609E4867700D0ECDA /* ipsec_get_policylen.c in Sources */,
-                               2537A1B709E4867800D0ECDA /* ipsec_strerror.c in Sources */,
-                               2537A1B909E4867900D0ECDA /* policy_parse.y in Sources */,
-                               2537A1BA09E4867A00D0ECDA /* policy_token.l in Sources */,
                        );
-                       runOnlyForDeploymentPostprocessing = 0;
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "/bin/chmod 600 $DSTROOT/private/etc/racoon/psk.txt\n/bin/chmod 644 $DSTROOT/private/etc/racoon/racoon.conf\n/bin/chmod 600 $DSTROOT/private/etc/racoon/remote/anonymous.conf\n/bin/chmod 444 $DSTROOT/usr/share/man/man5/racoon.conf.5\n/bin/chmod 444 $DSTROOT/usr/share/man/man8/racoon.8\n";
                };
-               2543476C09DCB477007943DE /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
+               812531230D3FEA33006BDF4F /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
                        files = (
-                               2543477109DCB492007943DE /* plainrsa-gen.c in Sources */,
-                               2543478A09DCB49C007943DE /* plog.c in Sources */,
-                               2543478C09DCB4A6007943DE /* logger.c in Sources */,
-                               25BE7E7F09E5DE4C009B6B84 /* pfkey_dump.c in Sources */,
-                               25BE7E8809E5E499009B6B84 /* pfkey.c in Sources */,
-                               25BE7E8A09E5E4A6009B6B84 /* key_debug.c in Sources */,
-                               25BE7E8E09E5E5BE009B6B84 /* crypto_openssl.c in Sources */,
-                               25BE7E9009E5E61F009B6B84 /* misc.c in Sources */,
-                               25BE7E9209E5E635009B6B84 /* vmbuf.c in Sources */,
                        );
-                       runOnlyForDeploymentPostprocessing = 0;
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man8/racoonctl.8";
                };
-               2543479009DCB57E007943DE /* Sources */ = {
+               81DDFDA50D622C1700C5CB87 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man8/setkey.8";
+               };
+               81DDFDC80D622C2700C5CB87 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_set_policy.3\n/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_strerror.3\n/bin/ln -s libipsec.A.dylib $DSTROOT/usr/lib/libipsec.dylib\n";
+               };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               2537A1A509E4864800D0ECDA /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               2537A1B509E4867700D0ECDA /* ipsec_dump_policy.c in Sources */,
+                               2537A1B609E4867700D0ECDA /* ipsec_get_policylen.c in Sources */,
+                               2537A1B709E4867800D0ECDA /* ipsec_strerror.c in Sources */,
+                               2537A1B909E4867900D0ECDA /* policy_parse.y in Sources */,
+                               2537A1BA09E4867A00D0ECDA /* policy_token.l in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               2543476C09DCB477007943DE /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               2543477109DCB492007943DE /* plainrsa-gen.c in Sources */,
+                               2543478A09DCB49C007943DE /* plog.c in Sources */,
+                               2543478C09DCB4A6007943DE /* logger.c in Sources */,
+                               25BE7E7F09E5DE4C009B6B84 /* pfkey_dump.c in Sources */,
+                               25BE7E8809E5E499009B6B84 /* pfkey.c in Sources */,
+                               25BE7E8A09E5E4A6009B6B84 /* key_debug.c in Sources */,
+                               25BE7E8E09E5E5BE009B6B84 /* crypto_openssl.c in Sources */,
+                               25BE7E9009E5E61F009B6B84 /* misc.c in Sources */,
+                               25BE7E9209E5E635009B6B84 /* vmbuf.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               2543479009DCB57E007943DE /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                                25F2592A0988657000D15623 /* backupsa.c in Sources */,
                                25F2592B0988657000D15623 /* cfparse.y in Sources */,
                                25F2592C0988657000D15623 /* cftoken.l in Sources */,
-                               25F2592D0988657000D15623 /* crypto_cssm.c in Sources */,
+                               81C386AA0D451EC300975D5E /* crypto_cssm.c in Sources */,
                                25F2592E0988657000D15623 /* crypto_openssl.c in Sources */,
                                25F2592F0988657000D15623 /* dnssec.c in Sources */,
                                25F259310988657000D15623 /* evt.c in Sources */,
                                25F259460988657000D15623 /* main.c in Sources */,
                                25F259470988657000D15623 /* misc.c in Sources */,
                                25F259490988657000D15623 /* oakley.c in Sources */,
-                               25F2594A0988657000D15623 /* open_dir.c in Sources */,
+                               81C387EC0D45268300975D5E /* open_dir.c in Sources */,
                                25F2594C0988657000D15623 /* pfkey_racoon.c in Sources */,
                                25F2594F0988657000D15623 /* plog.c in Sources */,
                                25F259500988657000D15623 /* policy.c in Sources */,
                                25DC9ED509DB16F800C89F86 /* isakmp_unity.c in Sources */,
                                25DC9ED609DB16FA00C89F86 /* isakmp_xauth.c in Sources */,
                                25DE2DE90A8BD40E0010A46D /* vpn_control.c in Sources */,
+                               81CA08920CE3BC870055C0AF /* vpn.c in Sources */,
+                               BA6F109B0EA1DEC200546773 /* ike_session.c in Sources */,
+                               BA5B6F2A0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */,
+                               BA5B6F2B0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                25ECCDA209AD479A00883CA3 /* pfkey.c in Sources */,
                                25F258910988648C00D15623 /* setkey.c in Sources */,
                                25F258940988648C00D15623 /* token.l in Sources */,
+                               BA5B6F310EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               812530BF0D3FE9DC006BDF4F /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               812530C00D3FE9DC006BDF4F /* rijndael-alg-fst.c in Sources */,
+                               812530C10D3FE9DC006BDF4F /* rijndael-api-fst.c in Sources */,
+                               812530C20D3FE9DC006BDF4F /* admin.c in Sources */,
+                               812530C30D3FE9DC006BDF4F /* algorithm.c in Sources */,
+                               812530C40D3FE9DC006BDF4F /* backupsa.c in Sources */,
+                               812530C50D3FE9DC006BDF4F /* cfparse.y in Sources */,
+                               812530C60D3FE9DC006BDF4F /* cftoken.l in Sources */,
+                               81C325A80D46A36900E65EB7 /* crypto_cssm.c in Sources */,
+                               812530C70D3FE9DC006BDF4F /* crypto_openssl.c in Sources */,
+                               812530C80D3FE9DC006BDF4F /* dnssec.c in Sources */,
+                               812530C90D3FE9DC006BDF4F /* evt.c in Sources */,
+                               812530CA0D3FE9DC006BDF4F /* genlist.c in Sources */,
+                               812530CB0D3FE9DC006BDF4F /* getcertsbyname.c in Sources */,
+                               812530CC0D3FE9DC006BDF4F /* grabmyaddr.c in Sources */,
+                               812530CD0D3FE9DC006BDF4F /* gssapi.c in Sources */,
+                               812530CE0D3FE9DC006BDF4F /* handler.c in Sources */,
+                               812530CF0D3FE9DC006BDF4F /* ipsec_doi.c in Sources */,
+                               812530D00D3FE9DC006BDF4F /* isakmp_agg.c in Sources */,
+                               812530D10D3FE9DC006BDF4F /* isakmp_base.c in Sources */,
+                               812530D20D3FE9DC006BDF4F /* isakmp_ident.c in Sources */,
+                               812530D30D3FE9DC006BDF4F /* isakmp_inf.c in Sources */,
+                               812530D40D3FE9DC006BDF4F /* isakmp_newg.c in Sources */,
+                               812530D50D3FE9DC006BDF4F /* isakmp_quick.c in Sources */,
+                               812530D60D3FE9DC006BDF4F /* isakmp.c in Sources */,
+                               812530D70D3FE9DC006BDF4F /* localconf.c in Sources */,
+                               812530D80D3FE9DC006BDF4F /* logger.c in Sources */,
+                               812530D90D3FE9DC006BDF4F /* main.c in Sources */,
+                               812530DA0D3FE9DC006BDF4F /* misc.c in Sources */,
+                               812530DB0D3FE9DC006BDF4F /* oakley.c in Sources */,
+                               812530DC0D3FE9DC006BDF4F /* pfkey_racoon.c in Sources */,
+                               812530DD0D3FE9DC006BDF4F /* plog.c in Sources */,
+                               812530DE0D3FE9DC006BDF4F /* policy.c in Sources */,
+                               812530DF0D3FE9DC006BDF4F /* privsep.c in Sources */,
+                               812530E00D3FE9DC006BDF4F /* proposal.c in Sources */,
+                               812530E10D3FE9DC006BDF4F /* remoteconf.c in Sources */,
+                               812530E20D3FE9DC006BDF4F /* safefile.c in Sources */,
+                               812530E30D3FE9DC006BDF4F /* sainfo.c in Sources */,
+                               812530E40D3FE9DC006BDF4F /* schedule.c in Sources */,
+                               812530E50D3FE9DC006BDF4F /* session.c in Sources */,
+                               812530E60D3FE9DC006BDF4F /* sockmisc.c in Sources */,
+                               812530E70D3FE9DC006BDF4F /* str2val.c in Sources */,
+                               812530E80D3FE9DC006BDF4F /* strnames.c in Sources */,
+                               812530E90D3FE9DC006BDF4F /* throttle.c in Sources */,
+                               812530EA0D3FE9DC006BDF4F /* vendorid.c in Sources */,
+                               812530EB0D3FE9DC006BDF4F /* vmbuf.c in Sources */,
+                               812530EC0D3FE9DC006BDF4F /* nattraversal.c in Sources */,
+                               812530ED0D3FE9DC006BDF4F /* pfkey.c in Sources */,
+                               812530EE0D3FE9DC006BDF4F /* rsalist.c in Sources */,
+                               812530EF0D3FE9DC006BDF4F /* isakmp_cfg.c in Sources */,
+                               812530F00D3FE9DC006BDF4F /* isakmp_unity.c in Sources */,
+                               812530F10D3FE9DC006BDF4F /* isakmp_xauth.c in Sources */,
+                               812530F20D3FE9DC006BDF4F /* vpn_control.c in Sources */,
+                               812530F30D3FE9DC006BDF4F /* vpn.c in Sources */,
+                               BA6F109C0EA1DEC200546773 /* ike_session.c in Sources */,
+                               BA5B6F2C0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */,
+                               BA5B6F2D0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               812531150D3FEA33006BDF4F /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               812531160D3FEA33006BDF4F /* racoonctl.c in Sources */,
+                               812531170D3FEA33006BDF4F /* str2val.c in Sources */,
+                               812531180D3FEA33006BDF4F /* kmpstat.c in Sources */,
+                               812531190D3FEA33006BDF4F /* vmbuf.c in Sources */,
+                               8125311A0D3FEA33006BDF4F /* sockmisc.c in Sources */,
+                               8125311B0D3FEA33006BDF4F /* misc.c in Sources */,
+                               8125311C0D3FEA33006BDF4F /* pfkey_dump.c in Sources */,
+                               8125311D0D3FEA33006BDF4F /* key_debug.c in Sources */,
+                               8125311E0D3FEA33006BDF4F /* pfkey.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               81DDFD9A0D622C1700C5CB87 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               81DDFD9B0D622C1700C5CB87 /* parse.y in Sources */,
+                               81DDFD9C0D622C1700C5CB87 /* pfkey_dump.c in Sources */,
+                               81DDFD9D0D622C1700C5CB87 /* key_debug.c in Sources */,
+                               81DDFD9E0D622C1700C5CB87 /* pfkey.c in Sources */,
+                               81DDFD9F0D622C1700C5CB87 /* setkey.c in Sources */,
+                               81DDFDA00D622C1700C5CB87 /* token.l in Sources */,
+                               BA5B6F320EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               81DDFDBC0D622C2700C5CB87 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               81DDFDBD0D622C2700C5CB87 /* ipsec_dump_policy.c in Sources */,
+                               81DDFDBE0D622C2700C5CB87 /* ipsec_get_policylen.c in Sources */,
+                               81DDFDBF0D622C2700C5CB87 /* ipsec_strerror.c in Sources */,
+                               81DDFDC00D622C2700C5CB87 /* policy_parse.y in Sources */,
+                               81DDFDC10D622C2700C5CB87 /* policy_token.l in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               81DDFDCF0D622C3500C5CB87 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               81DDFDD00D622C3500C5CB87 /* prsa_par.y in Sources */,
+                               81DDFDD10D622C3500C5CB87 /* prsa_tok.l in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
                        target = 25E08C9909D9E64A001A11CF /* rsaparse */;
                        targetProxy = 25E08CE909D9F0A2001A11CF /* PBXContainerItemProxy */;
                };
+               812531110D3FEA28006BDF4F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 812530BA0D3FE9DC006BDF4F /* racoon Embedded */;
+                       targetProxy = 812531100D3FEA28006BDF4F /* PBXContainerItemProxy */;
+               };
+               8125312C0D3FEA44006BDF4F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 812531120D3FEA33006BDF4F /* racoonctl Embedded */;
+                       targetProxy = 8125312B0D3FEA44006BDF4F /* PBXContainerItemProxy */;
+               };
+               81DDFDD90D622C4E00C5CB87 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */;
+                       targetProxy = 81DDFDD80D622C4E00C5CB87 /* PBXContainerItemProxy */;
+               };
+               81DDFDDB0D622C5100C5CB87 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */;
+                       targetProxy = 81DDFDDA0D622C5100C5CB87 /* PBXContainerItemProxy */;
+               };
+               81DDFDDF0D622D1700C5CB87 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */;
+                       targetProxy = 81DDFDDE0D622D1700C5CB87 /* PBXContainerItemProxy */;
+               };
+               81DDFDE10D622D2A00C5CB87 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */;
+                       targetProxy = 81DDFDE00D622D2A00C5CB87 /* PBXContainerItemProxy */;
+               };
+               81DDFDE40D622D8C00C5CB87 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */;
+                       targetProxy = 81DDFDE30D622D8C00C5CB87 /* PBXContainerItemProxy */;
+               };
+               81DDFDF10D627DE300C5CB87 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 81DDFD970D622C1700C5CB87 /* setkey Embedded */;
+                       targetProxy = 81DDFDF00D627DE300C5CB87 /* PBXContainerItemProxy */;
+               };
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
                                DYLIB_CURRENT_VERSION = 300;
                                EXECUTABLE_PREFIX = lib;
                                GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "HAVE_CONFIG_H=1",
                                ALTERNATE_MODE = "";
                                ALTERNATE_OWNER = "$(inherited)";
                                ARCHS = (
+                                       armv6,
                                        i386,
                                        ppc,
                                        ppc64,
                                LEXFLAGS = "$(LEXFLAGS) -P__libipsec";
                                PREBINDING = NO;
                                PRODUCT_NAME = ipsec.A;
-                               VALID_ARCHS = "ppc64 i386 x86_64 ppc";
+                               VALID_ARCHS = "armv6 ppc64 i386 x86_64 ppc";
                                YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec";
                                ZERO_LINK = YES;
                        };
                                        i386,
                                );
                                COPY_PHASE_STRIP = NO;
-                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_DYNAMIC_NO_PIC = YES;
                                GCC_ENABLE_FIX_AND_CONTINUE = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                PREBINDING = NO;
                                PRODUCT_NAME = "plainrsa-gen";
                                SKIP_INSTALL = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Development;
                                );
                                COPY_PHASE_STRIP = YES;
                                GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "HAVE_CONFIG_H=1",
                                INSTALL_GROUP = wheel;
                                INSTALL_MODE_FLAG = 555;
                                INSTALL_OWNER = root;
-                               INSTALL_PATH = /use/sbin;
+                               INSTALL_PATH = /usr/sbin;
                                PREBINDING = NO;
                                PRODUCT_NAME = "plainrsa-gen";
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Deployment;
                                PREBINDING = NO;
                                PRODUCT_NAME = "plainrsa-gen";
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Default;
                                PREBINDING = NO;
                                PRODUCT_NAME = eaytest;
                                SKIP_INSTALL = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Development;
                                PRODUCT_NAME = eaytest;
                                SKIP_INSTALL = YES;
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Deployment;
                                PRODUCT_NAME = eaytest;
                                SKIP_INSTALL = YES;
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Default;
                                PREBINDING = NO;
                                PRODUCT_NAME = "test-policy";
                                SKIP_INSTALL = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Development;
                                PRODUCT_NAME = "test-policy";
                                SKIP_INSTALL = YES;
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Deployment;
                                PRODUCT_NAME = "test-policy";
                                SKIP_INSTALL = YES;
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Default;
                                PREBINDING = NO;
                                PRODUCT_NAME = "test-pfkey";
                                SKIP_INSTALL = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Development;
                                PRODUCT_NAME = "test-pfkey";
                                SKIP_INSTALL = YES;
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Deployment;
                                PRODUCT_NAME = "test-pfkey";
                                SKIP_INSTALL = YES;
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                ZERO_LINK = NO;
                        };
                        name = Default;
                                OTHER_REZFLAGS = "";
                                PRODUCT_NAME = "IPSec (Aggregate)";
                                SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = NO;
+                               VALID_ARCHS = "ppc64 ppc7400 ppc970 i386 x86_64 ppc";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                25D3DABA098952B20025F703 /* Deployment */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               COPY_PHASE_STRIP = YES;
+                               COPY_PHASE_STRIP = NO;
                                OTHER_CFLAGS = "";
                                OTHER_LDFLAGS = "";
                                OTHER_REZFLAGS = "";
                                PRODUCT_NAME = "IPSec (Aggregate)";
                                SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = NO;
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                25D3DABB098952B20025F703 /* Default */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               COPY_PHASE_STRIP = NO;
                                OTHER_CFLAGS = "";
                                OTHER_LDFLAGS = "";
                                OTHER_REZFLAGS = "";
                                PRODUCT_NAME = "IPSec (Aggregate)";
                                SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = NO;
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                        "$(OTHER_CFLAGS_QUOTED_3)",
                                );
                                OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\"";
-                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\"";
                                OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\"";
                                OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
                                OTHER_LDFLAGS = "";
                                PRODUCT_NAME = racoon;
                                SECTORDER_FLAGS = "";
                                SKIP_INSTALL = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                );
                                COPY_PHASE_STRIP = NO;
                                DSTROOT = "/tmp/$(PROJECT_NAME).dst";
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                GCC_PREFIX_HEADER = "";
                                        "$(OTHER_CFLAGS_QUOTED_3)",
                                );
                                OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\"";
-                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\"";
                                OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\"";
                                OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
                                OTHER_LDFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = racoon;
                                SECTORDER_FLAGS = "";
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                );
                                COPY_PHASE_STRIP = NO;
                                DSTROOT = "/tmp/$(PROJECT_NAME).dst";
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                GCC_PREFIX_HEADER = "";
                                        "$(OTHER_CFLAGS_QUOTED_3)",
                                );
                                OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\"";
-                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\"";
                                OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\"";
                                OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
                                OTHER_LDFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = racoon;
                                SECTORDER_FLAGS = "";
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                        i386,
                                );
                                COPY_PHASE_STRIP = NO;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1",
                                PRODUCT_NAME = setkey;
                                SECTORDER_FLAGS = "";
                                SKIP_INSTALL = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "armv6 i386 ppc x86_64";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                        i386,
                                );
                                COPY_PHASE_STRIP = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1",
                                SECTORDER_FLAGS = "";
                                SKIP_INSTALL = NO;
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "armv6 i386 ppc x86_64";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ARCHS = (
-                                       ppc,
                                        i386,
+                                       ppc,
+                                       armv6,
                                );
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1",
                                PRODUCT_NAME = setkey;
                                SECTORDER_FLAGS = "";
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "armv6 i386 ppc x86_64";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                INSTALL_MODE_FLAG = 555;
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /usr/sbin;
-                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/var/run\\\"";
                                OTHER_LDFLAGS = "";
                                OTHER_REZFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = racoonctl;
                                SECTORDER_FLAGS = "";
                                SKIP_INSTALL = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                        i386,
                                );
                                COPY_PHASE_STRIP = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "HAVE_CONFIG_H=1",
                                INSTALL_MODE_FLAG = 555;
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /usr/sbin;
-                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/var/run\\\"";
                                OTHER_LDFLAGS = "";
                                OTHER_REZFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = racoonctl;
                                SECTORDER_FLAGS = "";
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                                        ppc,
                                        i386,
                                );
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "HAVE_CONFIG_H=1",
                                INSTALL_MODE_FLAG = 555;
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /usr/sbin;
-                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/var/run\\\"";
                                OTHER_LDFLAGS = "";
                                OTHER_REZFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = racoonctl;
                                SECTORDER_FLAGS = "";
                                STRIP_INSTALLED_PRODUCT = YES;
-                               VALID_ARCHS = "i386 ppc";
+                               VALID_ARCHS = "x86_64 i386 ppc";
                                WARNING_CFLAGS = (
                                        "-Wmost",
                                        "-Wno-four-char-constants",
                25D3DACD098952B20025F703 /* Development */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               ADDITIONAL_SDKS = "";
                                ARCHS = (
+                                       armv6,
                                        i386,
+                                       ppc64,
+                                       arm,
+                                       x86_64,
                                        ppc,
                                );
                        };
                25D3DACE098952B20025F703 /* Deployment */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               ADDITIONAL_SDKS = "";
                                ARCHS = (
+                                       armv6,
                                        i386,
+                                       ppc64,
+                                       arm,
+                                       x86_64,
                                        ppc,
                                );
                        };
                25D3DACF098952B20025F703 /* Default */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               ADDITIONAL_SDKS = "";
                                ARCHS = (
+                                       armv6,
                                        i386,
+                                       ppc64,
+                                       arm,
+                                       x86_64,
                                        ppc,
                                );
                        };
                                LEXFLAGS = "$(LEXFLAGS) -Pprsa";
                                PREBINDING = NO;
                                PRODUCT_NAME = rsaparse;
-                               VALID_ARCHS = "i386 ppc";
+                               SKIP_INSTALL = NO;
+                               VALID_ARCHS = "i386 ppc x86_64 armv6";
                                YACCFLAGS = "$(YACCFLAGS) -pprsa";
                        };
                        name = Development;
                                LEXFLAGS = "$(LEXFLAGS) -Pprsa";
                                PREBINDING = NO;
                                PRODUCT_NAME = rsaparse;
-                               VALID_ARCHS = "i386 ppc";
+                               SKIP_INSTALL = NO;
+                               VALID_ARCHS = "i386 ppc x86_64 armv6";
                                YACCFLAGS = "$(YACCFLAGS) -pprsa";
                                ZERO_LINK = NO;
                        };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ARCHS = (
-                                       ppc,
                                        i386,
+                                       ppc,
+                                       armv6,
                                );
                                COPY_PHASE_STRIP = NO;
                                GCC_MODEL_TUNING = G5;
                                LEXFLAGS = "$(LEXFLAGS) -Pprsa";
                                PREBINDING = NO;
                                PRODUCT_NAME = rsaparse;
-                               VALID_ARCHS = "i386 ppc";
+                               SKIP_INSTALL = NO;
+                               VALID_ARCHS = "i386 ppc x86_64 armv6";
                                YACCFLAGS = "$(YACCFLAGS) -pprsa";
                        };
                        name = Default;
                };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-               2537A1A909E4866800D0ECDA /* Build configuration list for PBXNativeTarget "libipsec" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               2537A1AA09E4866800D0ECDA /* Development */,
-                               2537A1AB09E4866800D0ECDA /* Deployment */,
-                               2537A1AC09E4866800D0ECDA /* Default */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
-               };
-               2543478609DCB494007943DE /* Build configuration list for PBXNativeTarget "plainrsa-gen" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               2543478709DCB494007943DE /* Development */,
-                               2543478809DCB494007943DE /* Deployment */,
-                               2543478909DCB494007943DE /* Default */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
-               };
-               2543479909DCB596007943DE /* Build configuration list for PBXNativeTarget "eaytest" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               2543479A09DCB596007943DE /* Development */,
-                               2543479B09DCB596007943DE /* Deployment */,
-                               2543479C09DCB596007943DE /* Default */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
-               };
-               254347BD09DCB851007943DE /* Build configuration list for PBXNativeTarget "test-policy" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               254347BE09DCB851007943DE /* Development */,
-                               254347BF09DCB851007943DE /* Deployment */,
-                               254347C009DCB851007943DE /* Default */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
-               };
-               254347C909DCBA1B007943DE /* Build configuration list for PBXNativeTarget "test-pfkey" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               254347CA09DCBA1B007943DE /* Development */,
-                               254347CB09DCBA1B007943DE /* Deployment */,
-                               254347CC09DCBA1B007943DE /* Default */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
+               812530B60D3FE994006BDF4F /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ADDITIONAL_SDKS = "";
+                               COPY_PHASE_STRIP = NO;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = "IPSec Embedded (Aggregate)";
+                               SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = NO;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Development;
                };
-               25D3DAB8098952B20025F703 /* Build configuration list for PBXAggregateTarget "IPSec (Aggregate)" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               25D3DAB9098952B20025F703 /* Development */,
-                               25D3DABA098952B20025F703 /* Deployment */,
-                               25D3DABB098952B20025F703 /* Default */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
+               812530B70D3FE994006BDF4F /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ADDITIONAL_SDKS = "";
+                               COPY_PHASE_STRIP = NO;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = "IPSec Embedded (Aggregate)";
+                               SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = NO;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Deployment;
                };
-               25D3DABC098952B20025F703 /* Build configuration list for PBXNativeTarget "racoon" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               25D3DABD098952B20025F703 /* Development */,
-                               25D3DABE098952B20025F703 /* Deployment */,
-                               25D3DABF098952B20025F703 /* Default */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
+               812530B90D3FE994006BDF4F /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ADDITIONAL_SDKS = "";
+                               COPY_PHASE_STRIP = NO;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = "IPSec Embedded (Aggregate)";
+                               SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = NO;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Default;
                };
-               25D3DAC0098952B20025F703 /* Build configuration list for PBXNativeTarget "setkey" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               25D3DAC1098952B20025F703 /* Development */,
-                               25D3DAC2098952B20025F703 /* Deployment */,
-                               25D3DAC3098952B20025F703 /* Default */,
+               812531060D3FE9DC006BDF4F /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "$(inherited)";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/entitlements.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = NO;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "\\\"$(SDKROOT)/System/Library/Frameworks\\\"",
+                                       "\\\"$(DEVELOPER_DIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks\\\"",
+                               );
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "";
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       ../Common,
+                                       Crypto,
+                                       /tmp/ipsec.dst/usr/include,
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               LEXFLAGS = "";
+                               OTHER_CFLAGS = (
+                                       "$(OTHER_CFLAGS_QUOTED_1)",
+                                       "$(OTHER_CFLAGS_QUOTED_2)",
+                                       "$(OTHER_CFLAGS_QUOTED_3)",
+                               );
+                               OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\"";
+                               OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\"";
+                               OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
+                               OTHER_LDFLAGS = "-lcrypto";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = racoon;
+                               SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               YACCFLAGS = "$(YACCFLAGS) -d";
+                               YACC_GENERATE_DEBUGGING_DIRECTIVES = NO;
+                       };
+                       name = Development;
+               };
+               812531070D3FE9DC006BDF4F /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "$(inherited)";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/entitlements.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = NO;
+                               DSTROOT = "/tmp/$(PROJECT_NAME).dst";
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "\\\"$(SDKROOT)/System/Library/Frameworks\\\"",
+                                       "\\\"$(DEVELOPER_DIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks\\\"",
+                               );
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "";
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       ../Common,
+                                       Crypto,
+                                       /tmp/ipsec.dst/usr/include,
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               OTHER_CFLAGS = (
+                                       "$(OTHER_CFLAGS_QUOTED_1)",
+                                       "$(OTHER_CFLAGS_QUOTED_2)",
+                                       "$(OTHER_CFLAGS_QUOTED_3)",
+                               );
+                               OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\"";
+                               OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\"";
+                               OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
+                               OTHER_LDFLAGS = "-lcrypto";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = racoon;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               YACCFLAGS = "$(YACCFLAGS) -d";
+                       };
+                       name = Deployment;
+               };
+               812531090D3FE9DC006BDF4F /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "$(inherited)";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/entitlements.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = NO;
+                               DSTROOT = "/tmp/$(PROJECT_NAME).dst";
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "\\\"$(SDKROOT)/System/Library/Frameworks\\\"",
+                                       "\\\"$(DEVELOPER_DIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks\\\"",
+                               );
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "";
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       ../Common,
+                                       Crypto,
+                                       /tmp/ipsec.dst/usr/include,
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               OTHER_CFLAGS = (
+                                       "$(OTHER_CFLAGS_QUOTED_1)",
+                                       "$(OTHER_CFLAGS_QUOTED_2)",
+                                       "$(OTHER_CFLAGS_QUOTED_3)",
+                               );
+                               OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\"";
+                               OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\"";
+                               OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\"";
+                               OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
+                               OTHER_LDFLAGS = "-lcrypto";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = racoon;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               YACCFLAGS = "$(YACCFLAGS) -d";
+                       };
+                       name = Default;
+               };
+               812531250D3FEA33006BDF4F /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "$(inherited)";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               COPY_PHASE_STRIP = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       "$(DSTROOT)/usr/include",
+                                       "$(inherited)",
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/tmp/racoon\\\"";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = racoonctl;
+                               SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Development;
+               };
+               812531260D3FEA33006BDF4F /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "$(inherited)";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               COPY_PHASE_STRIP = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       "$(DSTROOT)/usr/include",
+                                       "$(inherited)",
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/tmp/racoon\\\"";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = racoonctl;
+                               SECTORDER_FLAGS = "";
+                               STRIP_INSTALLED_PRODUCT = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Deployment;
+               };
+               812531280D3FEA33006BDF4F /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "$(inherited)";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       "$(DSTROOT)/usr/include",
+                                       "$(inherited)",
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/tmp/racoon\\\"";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = racoonctl;
+                               SECTORDER_FLAGS = "";
+                               STRIP_INSTALLED_PRODUCT = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Default;
+               };
+               81DDFDA70D622C1700C5CB87 /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       "$(DSTROOT)/usr/include",
+                                       ../Common,
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               LIBRARY_SEARCH_PATHS = "";
+                               MACH_O_TYPE = mh_execute;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRELINK_LIBS = "";
+                               PRODUCT_NAME = setkey;
+                               SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               YACCFLAGS = "";
+                       };
+                       name = Development;
+               };
+               81DDFDA80D622C1700C5CB87 /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       "$(DSTROOT)/usr/include",
+                                       ../Common,
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               LIBRARY_SEARCH_PATHS = "";
+                               MACH_O_TYPE = mh_execute;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRELINK_LIBS = "";
+                               PRODUCT_NAME = setkey;
+                               SECTORDER_FLAGS = "";
+                               SKIP_INSTALL = NO;
+                               STRIP_INSTALLED_PRODUCT = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Deployment;
+               };
+               81DDFDA90D622C1700C5CB87 /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       "$(DSTROOT)/usr/include",
+                                       ../Common,
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/sbin;
+                               LIBRARY_SEARCH_PATHS = "";
+                               MACH_O_TYPE = mh_execute;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRELINK_LIBS = "";
+                               PRODUCT_NAME = setkey;
+                               SECTORDER_FLAGS = "";
+                               STRIP_INSTALLED_PRODUCT = YES;
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Default;
+               };
+               81DDFDCA0D622C2700C5CB87 /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               COPY_PHASE_STRIP = NO;
+                               CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
+                               DYLIB_CURRENT_VERSION = 300;
+                               EXECUTABLE_PREFIX = lib;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       ../Common,
+                                       "$(HEADER_SEARCH_PATHS)",
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/lib;
+                               LEXFLAGS = "$(LEXFLAGS) -P__libipsec";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = ipsec.A;
+                               SKIP_INSTALL = YES;
+                               YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec";
+                               ZERO_LINK = YES;
+                       };
+                       name = Development;
+               };
+               81DDFDCB0D622C2700C5CB87 /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               COPY_PHASE_STRIP = NO;
+                               CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
+                               DYLIB_CURRENT_VERSION = 300;
+                               EXECUTABLE_PREFIX = lib;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       ../Common,
+                                       "$(HEADER_SEARCH_PATHS)",
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/lib;
+                               LEXFLAGS = "$(LEXFLAGS) -P__libipsec";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = ipsec.A;
+                               YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec";
+                               ZERO_LINK = YES;
+                       };
+                       name = Deployment;
+               };
+               81DDFDCC0D622C2700C5CB87 /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               ALTERNATE_GROUP = "$(inherited)";
+                               ALTERNATE_MODE = "";
+                               ALTERNATE_OWNER = "$(inherited)";
+                               COPY_PHASE_STRIP = NO;
+                               CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
+                               DYLIB_CURRENT_VERSION = 300;
+                               EXECUTABLE_PREFIX = lib;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "HAVE_CONFIG_H=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               HEADER_SEARCH_PATHS = (
+                                       ../Common,
+                                       "$(HEADER_SEARCH_PATHS)",
+                               );
+                               INSTALL_GROUP = wheel;
+                               INSTALL_MODE_FLAG = 555;
+                               INSTALL_OWNER = root;
+                               INSTALL_PATH = /usr/lib;
+                               LEXFLAGS = "$(LEXFLAGS) -P__libipsec";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = ipsec.A;
+                               YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec";
+                               ZERO_LINK = YES;
+                       };
+                       name = Default;
+               };
+               81DDFDD40D622C3500C5CB87 /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               INSTALL_PATH = "";
+                               LEXFLAGS = "$(LEXFLAGS) -Pprsa";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = rsaparse;
+                               SKIP_INSTALL = NO;
+                               YACCFLAGS = "$(YACCFLAGS) -pprsa";
+                       };
+                       name = Development;
+               };
+               81DDFDD50D622C3500C5CB87 /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_MODEL_TUNING = G5;
+                               INSTALL_PATH = "";
+                               LEXFLAGS = "$(LEXFLAGS) -Pprsa";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = rsaparse;
+                               SKIP_INSTALL = NO;
+                               YACCFLAGS = "$(YACCFLAGS) -pprsa";
+                               ZERO_LINK = NO;
+                       };
+                       name = Deployment;
+               };
+               81DDFDD60D622C3500C5CB87 /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_MODEL_TUNING = G5;
+                               INSTALL_PATH = "";
+                               LEXFLAGS = "$(LEXFLAGS) -Pprsa";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = rsaparse;
+                               SKIP_INSTALL = NO;
+                               YACCFLAGS = "$(YACCFLAGS) -pprsa";
+                       };
+                       name = Default;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               2537A1A909E4866800D0ECDA /* Build configuration list for PBXNativeTarget "libipsec" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               2537A1AA09E4866800D0ECDA /* Development */,
+                               2537A1AB09E4866800D0ECDA /* Deployment */,
+                               2537A1AC09E4866800D0ECDA /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               2543478609DCB494007943DE /* Build configuration list for PBXNativeTarget "plainrsa-gen" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               2543478709DCB494007943DE /* Development */,
+                               2543478809DCB494007943DE /* Deployment */,
+                               2543478909DCB494007943DE /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               2543479909DCB596007943DE /* Build configuration list for PBXNativeTarget "eaytest" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               2543479A09DCB596007943DE /* Development */,
+                               2543479B09DCB596007943DE /* Deployment */,
+                               2543479C09DCB596007943DE /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               254347BD09DCB851007943DE /* Build configuration list for PBXNativeTarget "test-policy" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               254347BE09DCB851007943DE /* Development */,
+                               254347BF09DCB851007943DE /* Deployment */,
+                               254347C009DCB851007943DE /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               254347C909DCBA1B007943DE /* Build configuration list for PBXNativeTarget "test-pfkey" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               254347CA09DCBA1B007943DE /* Development */,
+                               254347CB09DCBA1B007943DE /* Deployment */,
+                               254347CC09DCBA1B007943DE /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               25D3DAB8098952B20025F703 /* Build configuration list for PBXAggregateTarget "IPSec (Aggregate)" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               25D3DAB9098952B20025F703 /* Development */,
+                               25D3DABA098952B20025F703 /* Deployment */,
+                               25D3DABB098952B20025F703 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               25D3DABC098952B20025F703 /* Build configuration list for PBXNativeTarget "racoon" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               25D3DABD098952B20025F703 /* Development */,
+                               25D3DABE098952B20025F703 /* Deployment */,
+                               25D3DABF098952B20025F703 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               25D3DAC0098952B20025F703 /* Build configuration list for PBXNativeTarget "setkey" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               25D3DAC1098952B20025F703 /* Development */,
+                               25D3DAC2098952B20025F703 /* Deployment */,
+                               25D3DAC3098952B20025F703 /* Default */,
                        );
                        defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
+                       defaultConfigurationName = Deployment;
                };
                25D3DAC4098952B20025F703 /* Build configuration list for PBXNativeTarget "racoonctl" */ = {
                        isa = XCConfigurationList;
                                25D3DAC7098952B20025F703 /* Default */,
                        );
                        defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
+                       defaultConfigurationName = Deployment;
                };
                25D3DACC098952B20025F703 /* Build configuration list for PBXProject "ipsec" */ = {
                        isa = XCConfigurationList;
                                25D3DACF098952B20025F703 /* Default */,
                        );
                        defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
+                       defaultConfigurationName = Deployment;
                };
                25E08CA209D9E6A4001A11CF /* Build configuration list for PBXNativeTarget "rsaparse" */ = {
                        isa = XCConfigurationList;
                                25E08CA509D9E6A4001A11CF /* Default */,
                        );
                        defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Default;
+                       defaultConfigurationName = Deployment;
+               };
+               812530B50D3FE994006BDF4F /* Build configuration list for PBXAggregateTarget "IPSec Embedded (Aggregate)" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               812530B60D3FE994006BDF4F /* Development */,
+                               812530B70D3FE994006BDF4F /* Deployment */,
+                               812530B90D3FE994006BDF4F /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               812531050D3FE9DC006BDF4F /* Build configuration list for PBXNativeTarget "racoon Embedded" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               812531060D3FE9DC006BDF4F /* Development */,
+                               812531070D3FE9DC006BDF4F /* Deployment */,
+                               812531090D3FE9DC006BDF4F /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               812531240D3FEA33006BDF4F /* Build configuration list for PBXNativeTarget "racoonctl Embedded" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               812531250D3FEA33006BDF4F /* Development */,
+                               812531260D3FEA33006BDF4F /* Deployment */,
+                               812531280D3FEA33006BDF4F /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               81DDFDA60D622C1700C5CB87 /* Build configuration list for PBXNativeTarget "setkey Embedded" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               81DDFDA70D622C1700C5CB87 /* Development */,
+                               81DDFDA80D622C1700C5CB87 /* Deployment */,
+                               81DDFDA90D622C1700C5CB87 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               81DDFDC90D622C2700C5CB87 /* Build configuration list for PBXNativeTarget "libipsec Embedded" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               81DDFDCA0D622C2700C5CB87 /* Development */,
+                               81DDFDCB0D622C2700C5CB87 /* Deployment */,
+                               81DDFDCC0D622C2700C5CB87 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
+               };
+               81DDFDD30D622C3500C5CB87 /* Build configuration list for PBXNativeTarget "rsaparse Embedded" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               81DDFDD40D622C3500C5CB87 /* Development */,
+                               81DDFDD50D622C3500C5CB87 /* Deployment */,
+                               81DDFDD60D622C3500C5CB87 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Deployment;
                };
 /* End XCConfigurationList section */
        };