re-introduced the XAUTH_VID compile option
[strongswan.git] / src / pluto / ipsec_doi.c
index a4e86a9..14aec44 100644 (file)
 #include "alg_info.h"
 #include "ike_alg.h"
 #include "kernel_alg.h"
-#ifdef NAT_TRAVERSAL
 #include "nat_traversal.h"
-#endif
-#ifdef VIRTUAL_IP
 #include "virtual.h"
-#endif
 
 /*
  * are we sending Pluto's Vendor ID?
@@ -84,7 +80,7 @@
 #endif /* !VENDORID */
 
 /*
- * are we sending an XAUTH VID (Cisco Mode Config Interoperability)?
+ * are we sending an XAUTH VID?
  */
 #ifdef XAUTH_VID
 #define SEND_XAUTH_VID 1
 #define SEND_XAUTH_VID 0
 #endif /* !XAUTH_VID */
 
+/*
+ * are we sending a Cisco Unity VID?
+ */
+#ifdef CISCO_QUIRKS
+#define SEND_CISCO_UNITY_VID   1
+#else /* !CISCO_QUIRKS */
+#define SEND_CISCO_UNITY_VID   0
+#endif /* !CISCO_QUIRKS */
+
 /* MAGIC: perform f, a function that returns notification_t
  * and return from the ENCLOSING stf_status returning function if it fails.
  */
@@ -457,9 +462,11 @@ send_notification_from_state(struct state *st, enum state_kind state,
     if (state == STATE_UNDEFINED)
        state = st->st_state;
 
-    if (IS_QUICK(state)) {
+    if (IS_QUICK(state))
+    {
        p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
-       if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state))) {
+       if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)))
+       {
            loglog(RC_LOG_SERIOUS,
                "no Phase1 state for Quick mode notification");
            return;
@@ -467,11 +474,13 @@ send_notification_from_state(struct state *st, enum state_kind state,
        send_notification(st, type, p1st, generate_msgid(p1st),
            st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
     }
-    else if (IS_ISAKMP_ENCRYPTED(state)) {
+    else if (IS_ISAKMP_ENCRYPTED(state) && st->st_enc_key.ptr != NULL)
+    {
        send_notification(st, type, st, generate_msgid(st),
            st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
     }
-    else {
+    else
+    {
        /* no ISAKMP SA established - don't encrypt notification */
        send_notification(st, type, NULL, 0,
            st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
@@ -769,10 +778,10 @@ accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
                
                oldc = cur_connection;
                set_cur_connection(dst->st_connection);
-#ifdef NAT_TRAVERSAL
+
                if (nat_traversal_enabled)
                    nat_traversal_change_port_lookup(md, dst);
-#endif
+
                loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
                    "deleting ISAKMP State #%lu", dst->st_serialno);
                delete_state(dst);
@@ -806,10 +815,9 @@ accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
                oldc = cur_connection;
                set_cur_connection(rc);
 
-#ifdef NAT_TRAVERSAL
                if (nat_traversal_enabled)
                    nat_traversal_change_port_lookup(md, dst);
-#endif
+
                if (rc->newest_ipsec_sa == dst->st_serialno
                && (rc->policy & POLICY_UP))
                    {
@@ -896,16 +904,16 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
     /* determine how many Vendor ID payloads we will be sending */
     if (SEND_PLUTO_VID)
        vids_to_send++;
-    if (SEND_XAUTH_VID)
+    if (SEND_CISCO_UNITY_VID)
        vids_to_send++;
     if (c->spd.this.cert.type == CERT_PGP)
        vids_to_send++;
+    if (SEND_XAUTH_VID)
+       vids_to_send++;
     /* always send DPD Vendor ID */
        vids_to_send++;
-#ifdef NAT_TRAVERSAL
     if (nat_traversal_enabled)
        vids_to_send++;
-#endif
 
    get_cookie(TRUE, st->st_icookie, COOKIE_SIZE, &c->spd.that.host_addr);
 
@@ -946,8 +954,8 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
        u_char *sa_start = rbody.cur;
        lset_t auth_policy = policy & POLICY_ID_AUTH_MASK;
 
-       if (!out_sa(&rbody, &oakley_sadb[auth_policy >> POLICY_ISAKMP_SHIFT]
-       , st, TRUE, vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
+       if (!out_sa(&rbody, &oakley_sadb, st, TRUE
+       , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
        {
            reset_cur_state();
            return STF_INTERNAL_ERROR;
@@ -970,17 +978,16 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
        }
     }
 
-    /* if enabled send XAUTH Vendor ID */
-    if (SEND_XAUTH_VID)
+    /* if enabled send Cisco Unity Vendor ID */
+    if (SEND_CISCO_UNITY_VID)
     {
        if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-       , &rbody, VID_MISC_XAUTH))
+       , &rbody, VID_CISCO_UNITY))
        {
            reset_cur_state();
            return STF_INTERNAL_ERROR;
        }
     }
-
     /* if we  have an OpenPGP certificate we assume an
      * OpenPGP peer and have to send the Vendor ID
      */
@@ -994,6 +1001,17 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
        }
     }
 
+    /* Announce our ability to do eXtended AUTHentication to the peer */
+    if (SEND_XAUTH_VID)
+    {
+       if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+       , &rbody, VID_MISC_XAUTH))
+       {
+           reset_cur_state();
+           return STF_INTERNAL_ERROR;
+       }
+    }
+
     /* Announce our ability to do Dead Peer Detection to the peer */
     {
        if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
@@ -1004,7 +1022,6 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
        }
     }
 
-#ifdef NAT_TRAVERSAL
     if (nat_traversal_enabled)
     {
        /* Add supported NAT-Traversal VID */
@@ -1015,7 +1032,6 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
            return STF_INTERNAL_ERROR;
        }
     }
-#endif
 
     close_message(&rbody);
     close_output_pbs(&reply);
@@ -1199,11 +1215,15 @@ generate_skeyids_iv(struct state *st)
     switch (st->st_oakley.auth)
     {
        case OAKLEY_PRESHARED_KEY:
+       case XAUTHInitPreShared:
+       case XAUTHRespPreShared:
            if (!skeyid_preshared(st))
                return FALSE;
            break;
 
        case OAKLEY_RSA_SIG:
+       case XAUTHInitRSA:
+       case XAUTHRespRSA:
            if (!skeyid_digisig(st))
                return FALSE;
            break;
@@ -1768,7 +1788,7 @@ RSA_check_signature(const struct id* peer
     {
        char id_buf[BUF_LEN];   /* arbitrary limit on length of ID reported */
 
-       (void) idtoa(&st->st_connection->spd.that.id, id_buf, sizeof(id_buf));
+       (void) idtoa(peer, id_buf, sizeof(id_buf));
 
        if (s.best_ugh == NULL)
        {
@@ -2043,7 +2063,6 @@ quick_outI1(int whack_sock
             , replacing
             , isakmp_sa->st_serialno);
 
-#ifdef NAT_TRAVERSAL
     if (isakmp_sa->nat_traversal & NAT_T_DETECTED)
     {
        /* Duplicate nat_traversal status in new state */
@@ -2066,7 +2085,6 @@ quick_outI1(int whack_sock
        np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
                  ISAKMP_NEXT_NATOA_RFC : ISAKMP_NEXT_NATOA_DRAFTS;
     }
-#endif
 
     /* set up reply */
     init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
@@ -2162,7 +2180,6 @@ quick_outI1(int whack_sock
        }
     }
 
-#ifdef NAT_TRAVERSAL
     /* Send NAT-OA if our address is NATed */
     if (send_natoa)
     {
@@ -2172,7 +2189,6 @@ quick_outI1(int whack_sock
            return STF_INTERNAL_ERROR;
        }
     }
-#endif
 
     /* finish computing  HASH(1), inserting it in output */
     (void) quick_mode_hash12(r_hashval, r_hash_start, rbody.cur
@@ -2341,7 +2357,6 @@ decode_peer_id(struct msg_digest *md, struct id *peer)
      * Besides, there is no good reason for allowing these to be
      * other than 0 in Phase 1.
      */
-#ifdef NAT_TRAVERSAL
     if ((st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
     &&  id->isaid_doi_specific_a == IPPROTO_UDP
     &&  (id->isaid_doi_specific_b == 0 || id->isaid_doi_specific_b == NAT_T_IKE_FLOAT_PORT))
@@ -2350,10 +2365,8 @@ decode_peer_id(struct msg_digest *md, struct id *peer)
                "accepted with port_floating NAT-T",
                id->isaid_doi_specific_a, id->isaid_doi_specific_b);
     }
-    else
-#endif
-    if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)
-    &&  !(id->isaid_doi_specific_a == IPPROTO_UDP && id->isaid_doi_specific_b == IKE_UDP_PORT))
+    else if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)
+        &&  !(id->isaid_doi_specific_a == IPPROTO_UDP && id->isaid_doi_specific_b == IKE_UDP_PORT))
     {
        loglog(RC_LOG_SERIOUS, "protocol/port in Phase 1 ID Payload must be 0/0 or %d/%d"
            " but are %d/%d"
@@ -2478,7 +2491,7 @@ switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
        DBG(DBG_CONTROL,
            char buf[BUF_LEN];
 
-           dntoa_or_null(buf, BUF_LEN, c->spd.this.ca, "%none");
+           dntoa_or_null(buf, BUF_LEN, c->spd.that.ca, "%none");
            DBG_log("required CA:  '%s'", buf);
         )
 
@@ -2527,14 +2540,8 @@ switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
            if (r->kind == CK_TEMPLATE)
            {
                /* instantiate it, filling in peer's ID */
-               r = rw_instantiate(r, &c->spd.that.host_addr,
-#ifdef NAT_TRAVERSAL
-                       c->spd.that.host_port,
-#endif
-#ifdef VIRTUAL_IP
-                       NULL,
-#endif
-                       peer);
+               r = rw_instantiate(r, &c->spd.that.host_addr
+                       , c->spd.that.host_port, NULL, peer);
            }
 
            /* copy certificate request info */
@@ -2972,8 +2979,7 @@ main_inI1_outR1(struct msg_digest *md)
 {
     struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
     struct state *st;
-    struct connection *c = find_host_connection(&md->iface->addr, pluto_port
-                               , &md->sender, md->sender_port, LEMPTY);
+    struct connection *c;
     struct isakmp_proposal proposal;
     pb_stream proposal_pbs;
     pb_stream r_sa_pbs;
@@ -2981,16 +2987,28 @@ main_inI1_outR1(struct msg_digest *md)
     lset_t policy = LEMPTY;
     int vids_to_send = 0;
 
+    /* We preparse the peer's proposal in order to determine
+     * the requested authentication policy (RSA or PSK)
+     */
     RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sa_pd->payload.sa
        , &sa_pd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
 
-#ifdef NAT_TRAVERSAL
+    backup_pbs(&proposal_pbs);
+    RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
+                    , proposal.isap_notrans, &policy));
+    restore_pbs(&proposal_pbs);
+
+    /* We are only considering candidate connections that match
+     * the requested authentication policy (RSA or PSK)
+     */
+    c = find_host_connection(&md->iface->addr, pluto_port
+                          , &md->sender, md->sender_port, policy);
+
     if (c == NULL && md->iface->ike_float)
     {
        c = find_host_connection(&md->iface->addr, NAT_T_IKE_FLOAT_PORT
-               , &md->sender, md->sender_port, LEMPTY);
+               , &md->sender, md->sender_port, policy);
     }
-#endif
 
     if (c == NULL)
     {
@@ -3007,11 +3025,6 @@ main_inI1_outR1(struct msg_digest *md)
        {
            struct connection *d;
 
-           backup_pbs(&proposal_pbs);
-           RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
-               , proposal.isap_notrans, &policy));
-           restore_pbs(&proposal_pbs);
-
            d = find_host_connection(&md->iface->addr
                , pluto_port, (ip_address*)NULL, md->sender_port, policy);
 
@@ -3061,16 +3074,16 @@ main_inI1_outR1(struct msg_digest *md)
            /* Create a temporary connection that is a copy of this one.
             * His ID isn't declared yet.
             */
-           c = rw_instantiate(c, &md->sender,
-#ifdef NAT_TRAVERSAL
-                       md->sender_port,
-#endif
-#ifdef VIRTUAL_IP
-                       NULL,
-#endif
-                       NULL);
+           c = rw_instantiate(c, &md->sender, md->sender_port, NULL, NULL);
        }
     }
+    else if (c->kind == CK_TEMPLATE)
+    {
+       /* Create an instance
+        * This is a rare case: wildcard peer ID but static peer IP address
+        */
+        c = rw_instantiate(c, &md->sender, md->sender_port, NULL, &c->spd.that.id);
+    }
 
     /* Set up state */
     md->st = st = new_state();
@@ -3109,16 +3122,16 @@ main_inI1_outR1(struct msg_digest *md)
     /* determine how many Vendor ID payloads we will be sending */
     if (SEND_PLUTO_VID)
        vids_to_send++;
-    if (SEND_XAUTH_VID)
+    if (SEND_CISCO_UNITY_VID)
        vids_to_send++;
     if (md->openpgp)
        vids_to_send++;
+    if (SEND_XAUTH_VID)
+       vids_to_send++;
     /* always send DPD Vendor ID */
        vids_to_send++;
-#ifdef NAT_TRAVERSAL
     if (md->nat_traversal_vid && nat_traversal_enabled)
        vids_to_send++;
-#endif
 
     /* HDR out.
      * We can't leave this to comm_handle() because we must
@@ -3146,7 +3159,7 @@ main_inI1_outR1(struct msg_digest *md)
 
     /* SA body in and out */
     RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
-       ,&proposal, &r_sa_pbs, st));
+       ,&proposal, &r_sa_pbs, st, FALSE));
 
     /* if enabled send Pluto Vendor ID */
     if (SEND_PLUTO_VID)
@@ -3158,11 +3171,11 @@ main_inI1_outR1(struct msg_digest *md)
        }
     }
 
-    /* if enabled send XAUTH Vendor ID */
-    if (SEND_XAUTH_VID)
+    /* if enabled send Cisco Unity Vendor ID */
+    if (SEND_CISCO_UNITY_VID)
     {
        if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-       , &md->rbody, VID_MISC_XAUTH))
+       , &md->rbody, VID_CISCO_UNITY))
        {
            return STF_INTERNAL_ERROR;
        }
@@ -3180,20 +3193,23 @@ main_inI1_outR1(struct msg_digest *md)
        }
     }
 
-    /* Announce our ability to do Dead Peer Detection to the peer */
+    /* Announce our ability to do eXtended AUTHentication to the peer */
+    if (SEND_XAUTH_VID)
     {
        if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-       , &md->rbody, VID_MISC_DPD))
+       , &md->rbody, VID_MISC_XAUTH))
        {
            return STF_INTERNAL_ERROR;
        }
     }
 
-#ifdef NAT_TRAVERSAL
-    DBG(DBG_CONTROLMORE,
-       DBG_log("sender checking NAT-t: %d and %d"
-               , nat_traversal_enabled, md->nat_traversal_vid)
-    )
+    /* Announce our ability to do Dead Peer Detection to the peer */
+    if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+    , &md->rbody, VID_MISC_DPD))
+    {
+       return STF_INTERNAL_ERROR;
+    }
+
     if (md->nat_traversal_vid && nat_traversal_enabled)
     {
        /* reply if NAT-Traversal draft is supported */
@@ -3206,7 +3222,6 @@ main_inI1_outR1(struct msg_digest *md)
            return STF_INTERNAL_ERROR;
        }
     }
-#endif
 
     close_message(&md->rbody);
 
@@ -3249,14 +3264,9 @@ main_inR1_outI2(struct msg_digest *md)
            RETURN_STF_FAILURE(BAD_PROPOSAL_SYNTAX);
         }
        RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
-           , &proposal_pbs, &proposal, NULL, st));
+           , &proposal_pbs, &proposal, NULL, st, TRUE));
     }
 
-#ifdef NAT_TRAVERSAL
-    DBG(DBG_CONTROLMORE,
-       DBG_log("sender checking NAT-t: %d and %d"
-               , nat_traversal_enabled, md->nat_traversal_vid)
-    )
     if (nat_traversal_enabled && md->nat_traversal_vid)
     {
        st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
@@ -3268,7 +3278,6 @@ main_inR1_outI2(struct msg_digest *md)
        np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
                ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
     }
- #endif
 
     /**************** build output packet HDR;KE;Ni ****************/
 
@@ -3306,13 +3315,11 @@ main_inR1_outI2(struct msg_digest *md)
        return STF_INTERNAL_ERROR;
 #endif
 
-#ifdef NAT_TRAVERSAL
     if (st->nat_traversal & NAT_T_WITH_NATD)
     {
        if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
            return STF_INTERNAL_ERROR;
     }
-#endif
 
     /* finish message */
     close_message(&md->rbody);
@@ -3342,9 +3349,11 @@ main_inI2_outR2(struct msg_digest *md)
     pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
  
     /* send CR if auth is RSA and no preloaded RSA public key exists*/
-    bool send_cr = !no_cr_send && (st->st_oakley.auth == OAKLEY_RSA_SIG) &&
-                  !has_preloaded_public_key(st);
-   
+    bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+                || st->st_oakley.auth == XAUTHInitRSA
+                || st->st_oakley.auth == XAUTHRespRSA;
+    bool send_cr = !no_cr_send && RSA_auth && !has_preloaded_public_key(st);
+
     u_int8_t np = ISAKMP_NEXT_NONE;
 
     /* KE in */
@@ -3353,11 +3362,6 @@ main_inI2_outR2(struct msg_digest *md)
     /* Ni in */
     RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
 
-#ifdef NAT_TRAVERSAL
-    DBG(DBG_CONTROLMORE,
-       DBG_log("inI2: checking NAT-t: %d and %d"
-               , nat_traversal_enabled, st->nat_traversal)
-    )
     if (st->nat_traversal & NAT_T_WITH_NATD)
     {
        nat_traversal_natd_lookup(md);
@@ -3373,7 +3377,6 @@ main_inI2_outR2(struct msg_digest *md)
     {
        nat_traversal_new_ka_event();
     }
-#endif
 
     /* decode certificate requests */
     st->st_connection->got_certrequest = FALSE;
@@ -3449,14 +3452,12 @@ main_inI2_outR2(struct msg_digest *md)
            }
        }
     }
-    
-#ifdef NAT_TRAVERSAL
+
     if (st->nat_traversal & NAT_T_WITH_NATD)
     {
        if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
           return STF_INTERNAL_ERROR;
     }
-#endif
 
     /* finish message */
     close_message(&md->rbody);
@@ -3487,14 +3488,18 @@ main_inR2_outI3(struct msg_digest *md)
 {
     struct state *const st = md->st;
     pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
-    int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
-       ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
     pb_stream id_pbs;  /* ID Payload; also used for hash calculation */
 
     certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
     cert_t mycert = st->st_connection->spd.this.cert;
     bool requested, send_cert, send_cr;
 
+    bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+                || st->st_oakley.auth == XAUTHInitRSA
+                || st->st_oakley.auth == XAUTHRespRSA;
+
+    int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
+
     /* KE in */
     RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
 
@@ -3516,30 +3521,29 @@ main_inR2_outI3(struct msg_digest *md)
      */
     requested = cert_policy == CERT_SEND_IF_ASKED
                && st->st_connection->got_certrequest;
-    send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
-               && mycert.type != CERT_NONE
+    send_cert = RSA_auth && mycert.type != CERT_NONE
                && (cert_policy == CERT_ALWAYS_SEND || requested);
 
     /* send certificate request if we don't have a preloaded RSA public key */
     send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
 
     /* done parsing; initialize crypto  */
-
     compute_dh_shared(st, st->st_gr, st->st_oakley.group);
     if (!generate_skeyids_iv(st))
        return STF_FAIL + AUTHENTICATION_FAILED;
 
-#ifdef NAT_TRAVERSAL
-       if (st->nat_traversal & NAT_T_WITH_NATD) {
-           nat_traversal_natd_lookup(md);
-       }
-       if (st->nat_traversal) {
-           nat_traversal_show_result(st->nat_traversal, md->sender_port);
-       }
-       if (st->nat_traversal & NAT_T_WITH_KA) {
-           nat_traversal_new_ka_event();
-       }
-#endif
+    if (st->nat_traversal & NAT_T_WITH_NATD)
+    {
+       nat_traversal_natd_lookup(md);
+    }
+    if (st->nat_traversal)
+    {
+       nat_traversal_show_result(st->nat_traversal, md->sender_port);
+    }
+    if (st->nat_traversal & NAT_T_WITH_KA)
+    {
+       nat_traversal_new_ka_event();
+    }
 
     /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/
     /* ??? NOTE: this is almost the same as main_inI3_outR3's code */
@@ -3560,7 +3564,7 @@ main_inR2_outI3(struct msg_digest *md)
     }
 
     /* CERT out */
-    if ( st->st_oakley.auth == OAKLEY_RSA_SIG)
+    if (RSA_auth)
     {
        DBG(DBG_CONTROL,
            DBG_log("our certificate policy is %s"
@@ -3716,6 +3720,8 @@ main_id_and_auth(struct msg_digest *md
     switch (st->st_oakley.auth)
     {
     case OAKLEY_PRESHARED_KEY:
+    case XAUTHInitPreShared:
+    case XAUTHRespPreShared:
        {
            pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
 
@@ -3732,6 +3738,8 @@ main_id_and_auth(struct msg_digest *md
        break;
 
     case OAKLEY_RSA_SIG:
+    case XAUTHInitRSA:
+    case XAUTHRespRSA:
        r = RSA_check_signature(&peer, st, hash_val, hash_len
            , &md->chain[ISAKMP_NEXT_SIG]->pbs
 #ifdef USE_KEYRR
@@ -3909,6 +3917,7 @@ main_inI3_outR3_tail(struct msg_digest *md
     pb_stream r_id_pbs;        /* ID Payload; also used for hash calculation */
     certpolicy_t cert_policy;
     cert_t mycert;
+    bool RSA_auth;
     bool send_cert;
     bool requested;
 
@@ -3931,7 +3940,10 @@ main_inI3_outR3_tail(struct msg_digest *md
     mycert = st->st_connection->spd.this.cert;
     requested = cert_policy == CERT_SEND_IF_ASKED
                && st->st_connection->got_certrequest;
-    send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
+    RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+           || st->st_oakley.auth == XAUTHInitRSA
+            || st->st_oakley.auth == XAUTHRespRSA;
+    send_cert = RSA_auth
                && mycert.type != CERT_NONE
                && (cert_policy == CERT_ALWAYS_SEND || requested);
 
@@ -3949,8 +3961,7 @@ main_inI3_outR3_tail(struct msg_digest *md
      */
     echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
 
-    auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
-       ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
+    auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
 
     /* IDir out */
     {
@@ -3969,7 +3980,7 @@ main_inI3_outR3_tail(struct msg_digest *md
     }
 
     /* CERT out */
-    if (st->st_oakley.auth == OAKLEY_RSA_SIG)
+    if (RSA_auth)
     {
        DBG(DBG_CONTROL,
            DBG_log("our certificate policy is %s"
@@ -4772,14 +4783,8 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
                    /* Plain Road Warrior:
                     * instantiate, carrying over authenticated peer ID
                     */
-                   p = rw_instantiate(p, &c->spd.that.host_addr,
-#ifdef NAT_TRAVERSAL
-                               md->sender_port,
-#endif
-#ifdef VIRTUAL_IP
-                               his_net, 
-#endif
-                               &c->spd.that.id);
+                   p = rw_instantiate(p, &c->spd.that.host_addr, md->sender_port
+                               , his_net, &c->spd.that.id);
                }
            }
 #ifdef DEBUG
@@ -4802,8 +4807,6 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
            p->spd.that.client = *his_net;
            p->spd.that.has_client_wildcard = FALSE;
        }
-
-#ifdef VIRTUAL_IP
        else if (is_virtual_connection(c))
        {
            c->spd.that.client = *his_net;
@@ -4811,7 +4814,6 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
            if (subnetishost(his_net) && addrinsubnet(&c->spd.that.host_addr, his_net))
                c->spd.that.has_client = FALSE;
        }
-#endif
 
        /* fill in the client's true port */
        if (p->spd.that.has_port_wildcard)
@@ -4870,7 +4872,6 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
        st->st_policy = (p1st->st_policy & POLICY_ISAKMP_MASK)
            | (c->policy & ~POLICY_ISAKMP_MASK);
 
-#ifdef NAT_TRAVERSAL
        if (p1st->nat_traversal & NAT_T_DETECTED)
        {
            st->nat_traversal = p1st->nat_traversal;
@@ -4880,12 +4881,11 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
        {
            st->nat_traversal = 0;
        }
-       if ((st->nat_traversal & NAT_T_DETECTED) &&
-           (st->nat_traversal & NAT_T_WITH_NATOA))
+       if ((st->nat_traversal & NAT_T_DETECTED)
+       &&  (st->nat_traversal & NAT_T_WITH_NATOA))
        {
            nat_traversal_natoa_lookup(md);
        }
-#endif
 
        /* Start the output packet.
         *
@@ -4973,7 +4973,6 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
            p->isaiid_np = ISAKMP_NEXT_NONE;
        }
 
-#ifdef NAT_TRAVERSAL
        if ((st->nat_traversal & NAT_T_WITH_NATOA)
        && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
        && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT))
@@ -4992,7 +4991,6 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
            addrtosubnet(&c->spd.that.host_addr, &c->spd.that.client);
            c->spd.that.has_client = FALSE;
        }
-#endif
 
        /* Compute reply HASH(2) and insert in output */
        (void)quick_mode_hash12(r_hashval, r_hash_start, md->rbody.cur
@@ -5132,13 +5130,11 @@ quick_inR1_outI2(struct msg_digest *md)
        }
     }
 
-#ifdef NAT_TRAVERSAL
        if ((st->nat_traversal & NAT_T_DETECTED)
        &&  (st->nat_traversal & NAT_T_WITH_NATOA))
        {
            nat_traversal_natoa_lookup(md);
        }
-#endif
 
     /* ??? We used to copy the accepted proposal into the state, but it was
      * never used.  From sa_pd->pbs.start, length pbs_room(&sa_pd->pbs).