summaryrefslogtreecommitdiff
path: root/programs/pluto/ipsec_doi.c
diff options
context:
space:
mode:
Diffstat (limited to 'programs/pluto/ipsec_doi.c')
-rw-r--r--programs/pluto/ipsec_doi.c137
1 files changed, 92 insertions, 45 deletions
diff --git a/programs/pluto/ipsec_doi.c b/programs/pluto/ipsec_doi.c
index fe5c846a7..e627f98b2 100644
--- a/programs/pluto/ipsec_doi.c
+++ b/programs/pluto/ipsec_doi.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: ipsec_doi.c,v 1.39 2006/04/22 21:59:20 as Exp $
+ * RCSID $Id: ipsec_doi.c,v 1.42 2007/01/10 00:36:19 as Exp $
*/
#include <stdio.h>
@@ -84,13 +84,13 @@
#endif /* !VENDORID */
/*
- * are we sending an XAUTH VID (Cisco Mode Config Interoperability)?
+ * are we sending a Cisco Unity VID?
*/
-#ifdef XAUTH_VID
-#define SEND_XAUTH_VID 1
-#else /* !XAUTH_VID */
-#define SEND_XAUTH_VID 0
-#endif /* !XAUTH_VID */
+#ifdef CISCO_QUIRKS
+#define SEND_CISCO_UNITY_VID 1
+#else /* !CISCO_QUIRKS */
+#define SEND_CISCO_UNITY_VID 0
+#endif /* !CISCO_QUIRKS */
/* MAGIC: perform f, a function that returns notification_t
* and return from the ENCLOSING stf_status returning function if it fails.
@@ -896,10 +896,12 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
/* determine how many Vendor ID payloads we will be sending */
if (SEND_PLUTO_VID)
vids_to_send++;
- if (SEND_XAUTH_VID)
+ if (SEND_CISCO_UNITY_VID)
vids_to_send++;
if (c->spd.this.cert.type == CERT_PGP)
vids_to_send++;
+ /* always send XAUTH Vendor ID */
+ vids_to_send++;
/* always send DPD Vendor ID */
vids_to_send++;
#ifdef NAT_TRAVERSAL
@@ -946,8 +948,8 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
u_char *sa_start = rbody.cur;
lset_t auth_policy = policy & POLICY_ID_AUTH_MASK;
- if (!out_sa(&rbody, &oakley_sadb[auth_policy >> POLICY_ISAKMP_SHIFT]
- , st, TRUE, vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
+ if (!out_sa(&rbody, &oakley_sadb, st, TRUE
+ , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
{
reset_cur_state();
return STF_INTERNAL_ERROR;
@@ -970,17 +972,16 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
}
}
- /* if enabled send XAUTH Vendor ID */
- if (SEND_XAUTH_VID)
+ /* if enabled send Cisco Unity Vendor ID */
+ if (SEND_CISCO_UNITY_VID)
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_MISC_XAUTH))
+ , &rbody, VID_CISCO_UNITY))
{
reset_cur_state();
return STF_INTERNAL_ERROR;
}
}
-
/* if we have an OpenPGP certificate we assume an
* OpenPGP peer and have to send the Vendor ID
*/
@@ -994,6 +995,14 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
}
}
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_MISC_XAUTH))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
+
/* Announce our ability to do Dead Peer Detection to the peer */
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
@@ -1199,11 +1208,15 @@ generate_skeyids_iv(struct state *st)
switch (st->st_oakley.auth)
{
case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
if (!skeyid_preshared(st))
return FALSE;
break;
case OAKLEY_RSA_SIG:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
if (!skeyid_digisig(st))
return FALSE;
break;
@@ -2972,8 +2985,7 @@ main_inI1_outR1(struct msg_digest *md)
{
struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
struct state *st;
- struct connection *c = find_host_connection(&md->iface->addr, pluto_port
- , &md->sender, md->sender_port, LEMPTY);
+ struct connection *c;
struct isakmp_proposal proposal;
pb_stream proposal_pbs;
pb_stream r_sa_pbs;
@@ -2981,14 +2993,28 @@ main_inI1_outR1(struct msg_digest *md)
lset_t policy = LEMPTY;
int vids_to_send = 0;
+ /* We preparse the peer's proposal in order to determine
+ * the requested authentication policy (RSA or PSK)
+ */
RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sa_pd->payload.sa
, &sa_pd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
+ backup_pbs(&proposal_pbs);
+ RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
+ , proposal.isap_notrans, &policy));
+ restore_pbs(&proposal_pbs);
+
+ /* We are only considering candidate connections that match
+ * the requested authentication policy (RSA or PSK)
+ */
+ c = find_host_connection(&md->iface->addr, pluto_port
+ , &md->sender, md->sender_port, policy);
+
#ifdef NAT_TRAVERSAL
if (c == NULL && md->iface->ike_float)
{
c = find_host_connection(&md->iface->addr, NAT_T_IKE_FLOAT_PORT
- , &md->sender, md->sender_port, LEMPTY);
+ , &md->sender, md->sender_port, policy);
}
#endif
@@ -3007,11 +3033,6 @@ main_inI1_outR1(struct msg_digest *md)
{
struct connection *d;
- backup_pbs(&proposal_pbs);
- RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
- , proposal.isap_notrans, &policy));
- restore_pbs(&proposal_pbs);
-
d = find_host_connection(&md->iface->addr
, pluto_port, (ip_address*)NULL, md->sender_port, policy);
@@ -3071,6 +3092,13 @@ main_inI1_outR1(struct msg_digest *md)
NULL);
}
}
+ else if (c->kind == CK_TEMPLATE)
+ {
+ /* Create an instance
+ * This is a rare case: wildcard peer ID but static peer IP address
+ */
+ c = rw_instantiate(c, &md->sender, md->sender_port, NULL, &c->spd.that.id);
+ }
/* Set up state */
md->st = st = new_state();
@@ -3109,10 +3137,12 @@ main_inI1_outR1(struct msg_digest *md)
/* determine how many Vendor ID payloads we will be sending */
if (SEND_PLUTO_VID)
vids_to_send++;
- if (SEND_XAUTH_VID)
+ if (SEND_CISCO_UNITY_VID)
vids_to_send++;
if (md->openpgp)
vids_to_send++;
+ /* always send XAUTH Vendor ID */
+ vids_to_send++;
/* always send DPD Vendor ID */
vids_to_send++;
#ifdef NAT_TRAVERSAL
@@ -3146,7 +3176,7 @@ main_inI1_outR1(struct msg_digest *md)
/* SA body in and out */
RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
- ,&proposal, &r_sa_pbs, st));
+ ,&proposal, &r_sa_pbs, st, FALSE));
/* if enabled send Pluto Vendor ID */
if (SEND_PLUTO_VID)
@@ -3158,11 +3188,11 @@ main_inI1_outR1(struct msg_digest *md)
}
}
- /* if enabled send XAUTH Vendor ID */
- if (SEND_XAUTH_VID)
+ /* if enabled send Cisco Unity Vendor ID */
+ if (SEND_CISCO_UNITY_VID)
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_XAUTH))
+ , &md->rbody, VID_CISCO_UNITY))
{
return STF_INTERNAL_ERROR;
}
@@ -3180,13 +3210,18 @@ main_inI1_outR1(struct msg_digest *md)
}
}
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_XAUTH))
+ {
+ return STF_INTERNAL_ERROR;
+ }
+
/* Announce our ability to do Dead Peer Detection to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_DPD))
{
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_DPD))
- {
- return STF_INTERNAL_ERROR;
- }
+ return STF_INTERNAL_ERROR;
}
#ifdef NAT_TRAVERSAL
@@ -3249,7 +3284,7 @@ main_inR1_outI2(struct msg_digest *md)
RETURN_STF_FAILURE(BAD_PROPOSAL_SYNTAX);
}
RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
- , &proposal_pbs, &proposal, NULL, st));
+ , &proposal_pbs, &proposal, NULL, st, TRUE));
}
#ifdef NAT_TRAVERSAL
@@ -3342,9 +3377,11 @@ main_inI2_outR2(struct msg_digest *md)
pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
/* send CR if auth is RSA and no preloaded RSA public key exists*/
- bool send_cr = !no_cr_send && (st->st_oakley.auth == OAKLEY_RSA_SIG) &&
- !has_preloaded_public_key(st);
-
+ bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+ || st->st_oakley.auth == XAUTHInitRSA
+ || st->st_oakley.auth == XAUTHRespRSA;
+ bool send_cr = !no_cr_send && RSA_auth && !has_preloaded_public_key(st);
+
u_int8_t np = ISAKMP_NEXT_NONE;
/* KE in */
@@ -3487,14 +3524,18 @@ main_inR2_outI3(struct msg_digest *md)
{
struct state *const st = md->st;
pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
- int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
- ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
pb_stream id_pbs; /* ID Payload; also used for hash calculation */
certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
cert_t mycert = st->st_connection->spd.this.cert;
bool requested, send_cert, send_cr;
+ bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+ || st->st_oakley.auth == XAUTHInitRSA
+ || st->st_oakley.auth == XAUTHRespRSA;
+
+ int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
+
/* KE in */
RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
@@ -3516,8 +3557,7 @@ main_inR2_outI3(struct msg_digest *md)
*/
requested = cert_policy == CERT_SEND_IF_ASKED
&& st->st_connection->got_certrequest;
- send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
- && mycert.type != CERT_NONE
+ send_cert = RSA_auth && mycert.type != CERT_NONE
&& (cert_policy == CERT_ALWAYS_SEND || requested);
/* send certificate request if we don't have a preloaded RSA public key */
@@ -3560,7 +3600,7 @@ main_inR2_outI3(struct msg_digest *md)
}
/* CERT out */
- if ( st->st_oakley.auth == OAKLEY_RSA_SIG)
+ if (RSA_auth)
{
DBG(DBG_CONTROL,
DBG_log("our certificate policy is %s"
@@ -3716,6 +3756,8 @@ main_id_and_auth(struct msg_digest *md
switch (st->st_oakley.auth)
{
case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
{
pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
@@ -3732,6 +3774,8 @@ main_id_and_auth(struct msg_digest *md
break;
case OAKLEY_RSA_SIG:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
r = RSA_check_signature(&peer, st, hash_val, hash_len
, &md->chain[ISAKMP_NEXT_SIG]->pbs
#ifdef USE_KEYRR
@@ -3909,6 +3953,7 @@ main_inI3_outR3_tail(struct msg_digest *md
pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
certpolicy_t cert_policy;
cert_t mycert;
+ bool RSA_auth;
bool send_cert;
bool requested;
@@ -3931,7 +3976,10 @@ main_inI3_outR3_tail(struct msg_digest *md
mycert = st->st_connection->spd.this.cert;
requested = cert_policy == CERT_SEND_IF_ASKED
&& st->st_connection->got_certrequest;
- send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
+ RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+ || st->st_oakley.auth == XAUTHInitRSA
+ || st->st_oakley.auth == XAUTHRespRSA;
+ send_cert = RSA_auth
&& mycert.type != CERT_NONE
&& (cert_policy == CERT_ALWAYS_SEND || requested);
@@ -3949,8 +3997,7 @@ main_inI3_outR3_tail(struct msg_digest *md
*/
echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
- auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
- ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
+ auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
/* IDir out */
{
@@ -3969,7 +4016,7 @@ main_inI3_outR3_tail(struct msg_digest *md
}
/* CERT out */
- if (st->st_oakley.auth == OAKLEY_RSA_SIG)
+ if (RSA_auth)
{
DBG(DBG_CONTROL,
DBG_log("our certificate policy is %s"