From b36d3109d05f1b069a0a712de7777cef6f6a48e4 Mon Sep 17 00:00:00 2001 From: Patrick Naubert <patrickn@xelerance.com> Date: Tue, 18 Feb 2014 18:55:39 -0500 Subject: [PATCH] Fix for CVE-2014-2037 CVE-2014-2037 is a continuation of CVE-2013-6466. We missed some cases. This patch was taken from RedHat's Openswan patch cluster. Original authors of this patch are Paul Wouters and Hugh Redelmeier. --- include/constants.h | 1 + include/ietf_constants.h | 4 +- include/names_constant.h | 3 + include/packet.h | 2 +- lib/libopenswan/constants.c | 25 ++--- lib/libpluto/packet.c | 9 +- programs/pluto/demux.h | 5 +- programs/pluto/ikev1.c | 7 +- programs/pluto/ikev2.c | 234 ++++++++++++++++++++++++++---------------- programs/pluto/ikev2.h | 5 +- programs/pluto/ikev2_parent.c | 30 +----- 11 files changed, 186 insertions(+), 139 deletions(-) diff --git a/include/constants.h b/include/constants.h index ac89852..ed27cf2 100644 --- a/include/constants.h +++ b/include/constants.h @@ -76,6 +76,7 @@ */ typedef unsigned long long lset_t; +#define LELEM_ROOF 64 /* all elements must be less than this */ #define LEMPTY 0ULL #define LELEM(opt) (1ULL << (opt)) #define LRANGE(lwb, upb) LRANGES(LELEM(lwb), LELEM(upb)) diff --git a/include/ietf_constants.h b/include/ietf_constants.h index a897d40..3a0e023 100644 --- a/include/ietf_constants.h +++ b/include/ietf_constants.h @@ -4,7 +4,7 @@ * Copyright (C) 2012 Paul Wouters <pwouters@redhat.com> * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com> * Copyright (C) 1997 Angelos D. Keromytis. - * Copyright (C) 1998-2002 D. Hugh Redelmeier. + * Copyright (C) 1998-2002,2014 D. Hugh Redelmeier. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -388,6 +388,8 @@ enum next_payload_types { ISAKMP_NEXT_NATOA_DRAFTS = 131 /* NAT-Traversal: NAT-OA (drafts) */ }; +#define ISAKMP_v2PAYLOAD_TYPE_BASE ISAKMP_NEXT_v2SA /* lowest value of a v2 payload type */ + /* These values are to be used within the Type field of an Attribute (14) * ISAKMP payload. */ #define ISAKMP_CFG_REQUEST 1 diff --git a/include/names_constant.h b/include/names_constant.h index 96515a2..e22e517 100644 --- a/include/names_constant.h +++ b/include/names_constant.h @@ -30,7 +30,10 @@ extern enum_names version_names; extern enum_names doi_names; extern enum_names payload_names; +extern enum_names payload_names_ikev2; extern const char *const payload_name[]; +extern const char *const payload_name_ikev2[]; +extern const char *const payload_name_ikev2_main[]; extern enum_names attr_msg_type_names; extern enum_names modecfg_attr_names; extern enum_names xauth_type_names; diff --git a/include/packet.h b/include/packet.h index 4aa647a..c5c7d51 100644 --- a/include/packet.h +++ b/include/packet.h @@ -671,7 +671,7 @@ struct isakmp_nat_oa * That leaves only Identification payloads as a problem. * We make all these entries NULL */ -extern struct_desc *const payload_descs[ISAKMP_NEXT_ROOF]; +extern const struct_desc *payload_desc(unsigned p); /* * IKEv2 structures diff --git a/lib/libopenswan/constants.c b/lib/libopenswan/constants.c index 3bfb22b..932b205 100644 --- a/lib/libopenswan/constants.c +++ b/lib/libopenswan/constants.c @@ -146,7 +146,8 @@ enum_names connection_kind_names = NULL }; -const char *const payload_names_ikev2[] = { +/* dual-use: for enum_name and for bitnamesof */ +const char *const payload_name_ikev2_main[] = { "ISAKMP_NEXT_v2SA", /* 33 */ "ISAKMP_NEXT_v2KE", "ISAKMP_NEXT_v2IDi", @@ -163,23 +164,23 @@ enum_names connection_kind_names = "ISAKMP_NEXT_v2E", "ISAKMP_NEXT_v2CP", "ISAKMP_NEXT_v2EAP", - NULL + NULL /* termination for bitnamesof() */ }; -const char *const payload_name_nat_d[] = { - "ISAKMP_NEXT_NAT-D", - "ISAKMP_NEXT_NAT-OA", - NULL +static enum_names payload_names_ikev2_main = +{ ISAKMP_NEXT_v2SA, ISAKMP_NEXT_v2EAP, payload_name_ikev2_main, + NULL }; + +const char *const payload_name_ikev2[] = { + "ISAKMP_NEXT_v2NONE", /* 33 */ }; -static enum_names payload_names_nat_d = -{ ISAKMP_NEXT_NATD_DRAFTS, ISAKMP_NEXT_NATOA_DRAFTS, payload_name_nat_d, NULL }; -static enum_names payload_names_ikev2_d = -{ ISAKMP_NEXT_v2SA, ISAKMP_NEXT_v2EAP, payload_names_ikev2, &payload_names_nat_d }; +enum_names payload_names_ikev2 = +{ ISAKMP_NEXT_NONE, ISAKMP_NEXT_NONE, payload_name_ikev2, + &payload_names_ikev2_main }; enum_names payload_names = -{ ISAKMP_NEXT_NONE, ISAKMP_NEXT_NATOA_RFC, payload_name, &payload_names_ikev2_d }; - +{ ISAKMP_NEXT_NONE, ISAKMP_NEXT_NATOA_RFC, payload_name, &payload_names_ikev2_main }; /* Exchange types (note: two discontinuous ranges) */ diff --git a/lib/libpluto/packet.c b/lib/libpluto/packet.c index 1675507..ce312b9 100644 --- a/lib/libpluto/packet.c +++ b/lib/libpluto/packet.c @@ -1,6 +1,6 @@ /* parsing packets: formats and tools * Copyright (C) 1997 Angelos D. Keromytis. - * Copyright (C) 1998-2001 D. Hugh Redelmeier. + * Copyright (C) 1998-2001,2013-2014 D. Hugh Redelmeier. * Copyright (C) 2012 Avesh Agarwal <avagarwa@redhat.com> * Copyright (C) 2012 Paul Wouters <pwouters@redhat.com> * @@ -1106,7 +1106,7 @@ struct_desc ikev2_e_desc = { "IKEv2 Encryption Payload", * That leaves only Identification payloads as a problem. * We make all these entries NULL */ -struct_desc *const payload_descs[ISAKMP_NEXT_ROOF] = { +static struct_desc *const payload_descs[] = { NULL, /* 0 ISAKMP_NEXT_NONE (No other payload following) */ &isakmp_sa_desc, /* 1 ISAKMP_NEXT_SA (Security Association) */ NULL, /* 2 ISAKMP_NEXT_P (Proposal) */ @@ -1146,6 +1146,11 @@ struct_desc *const payload_descs[ISAKMP_NEXT_ROOF] = { &ikev2_e_desc, /* 46 */ }; +const struct_desc *payload_desc(unsigned p) +{ + return p < elemsof(payload_descs) ? payload_descs[p] : NULL; +} + void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name) { diff --git a/programs/pluto/demux.h b/programs/pluto/demux.h index 520577c..296395e 100644 --- a/programs/pluto/demux.h +++ b/programs/pluto/demux.h @@ -81,8 +81,9 @@ struct msg_digest { # define PAYLIMIT 30 struct payload_digest digest[PAYLIMIT], - *digest_roof, - *chain[ISAKMP_NEXT_ROOF]; + *digest_roof; + struct payload_digest + *chain[(unsigned)ISAKMP_NEXT_ROOF]; struct isakmp_quirks quirks; }; diff --git a/programs/pluto/ikev1.c b/programs/pluto/ikev1.c index 13ae193..cb0b370 100644 --- a/programs/pluto/ikev1.c +++ b/programs/pluto/ikev1.c @@ -1557,7 +1557,7 @@ void process_packet_tail(struct msg_digest **mdp) while (np != ISAKMP_NEXT_NONE) { - struct_desc *sd = np < ISAKMP_NEXT_ROOF? payload_descs[np] : NULL; + struct_desc *sd = payload_desc(np); if (pd == &md->digest[PAYLIMIT]) { @@ -1604,12 +1604,12 @@ void process_packet_tail(struct msg_digest **mdp) #ifdef NAT_TRAVERSAL case ISAKMP_NEXT_NATD_DRAFTS: np = ISAKMP_NEXT_NATD_RFC; /* NAT-D relocated */ - sd = payload_descs[np]; + sd = payload_desc(np); break; case ISAKMP_NEXT_NATOA_DRAFTS: np = ISAKMP_NEXT_NATOA_RFC; /* NAT-OA relocated */ - sd = payload_descs[np]; + sd = payload_desc(np); break; #endif default: @@ -1619,6 +1619,7 @@ void process_packet_tail(struct msg_digest **mdp) SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE); return; } + passert(sd != NULL); } { diff --git a/programs/pluto/ikev2.c b/programs/pluto/ikev2.c index f88956a..b667df1 100644 --- a/programs/pluto/ikev2.c +++ b/programs/pluto/ikev2.c @@ -81,20 +81,18 @@ struct state_v2_microcode { enum state_kind state, next_state; enum isakmp_xchg_types recv_type; lset_t flags; - lset_t req_payloads; /* required payloads (allows just one) */ - lset_t opt_payloads; /* optional payloads (any mumber) */ + lset_t req_clear_payloads; /* required unencrypted payloads (allows just one) for received packet */ + lset_t opt_clear_payloads; /* optional unencrypted payloads (none or one) for received packet */ + lset_t req_enc_payloads; /* required encrypted payloads (allows just one) for received packet */ + lset_t opt_enc_payloads; /* optional encrypted payloads (none or one) for received packet */ enum event_type timeout_event; state_transition_fn *processor; }; enum smf2_flags { SMF2_INITIATOR = LELEM(1), - SMF2_RESPONDER = 0, - - SMF2_STATENEEDED=LELEM(2), - SMF2_NEWSTATE = 0, - - SMF2_REPLY = LELEM(3), + SMF2_STATENEEDED = LELEM(2), + SMF2_REPLY = LELEM(3), }; /* @@ -133,18 +131,26 @@ enum smf2_flags { * */ -/* it is not clear how the flags will be used yet, if at all */ +#define PT(n) ISAKMP_NEXT_v2 ## n +#define P(n) LELEM(PT(n) - ISAKMP_v2PAYLOAD_TYPE_BASE) +static const lset_t everywhere_payloads = P(N) | P(V); /* can appear in any packet */ +static const lset_t repeatable_payloads = P(N) | P(D) | P(CP) | P(V); /* if one can appear, many can appear */ -static const struct state_v2_microcode state_microcode_table[] = { +/* microcode to parent first initiator state: not associated with an input packet */ +const struct state_v2_microcode ikev2_parent_firststate_microcode = { .state = STATE_UNDEFINED, .next_state = STATE_PARENT_I1, .flags = SMF2_INITIATOR, .processor = NULL, - }, +}; +/* microcode for input packet processing */ +static const struct state_v2_microcode v2_state_microcode_table[] = { { .state = STATE_PARENT_I1, .next_state = STATE_PARENT_I2, .flags = SMF2_INITIATOR|SMF2_STATENEEDED|SMF2_REPLY, + .req_clear_payloads = P(SA) | P(KE) | P(Nr), + .opt_clear_payloads = P(CERTREQ), .processor = ikev2parent_inR1outI2, .recv_type = ISAKMP_v2_SA_INIT, }, @@ -152,6 +158,9 @@ enum smf2_flags { { .state = STATE_PARENT_I2, .next_state = STATE_PARENT_I3, .flags = SMF2_INITIATOR|SMF2_STATENEEDED, + .req_clear_payloads = P(E), + .req_enc_payloads = P(IDr) | P(AUTH) | P(SA) | P(TSi) | P(TSr), + .opt_enc_payloads = P(CERT), .processor = ikev2parent_inR2, .recv_type = ISAKMP_v2_AUTH, .timeout_event = EVENT_SA_REPLACE, @@ -159,14 +168,18 @@ enum smf2_flags { { .state = STATE_UNDEFINED, .next_state = STATE_PARENT_R1, - .flags = SMF2_RESPONDER|SMF2_NEWSTATE|SMF2_REPLY, + .flags = /* not SMF2_INITIATOR, not SMF2_STATENEEDED */ SMF2_REPLY, + .req_clear_payloads = P(SA) | P(KE) | P(Ni), .processor = ikev2parent_inI1outR1, .recv_type = ISAKMP_v2_SA_INIT, }, { .state = STATE_PARENT_R1, .next_state = STATE_PARENT_R2, - .flags = SMF2_RESPONDER|SMF2_STATENEEDED|SMF2_REPLY, + .flags = /* not SMF2_INITIATOR */ SMF2_STATENEEDED | SMF2_REPLY, + .req_clear_payloads = P(E), + .req_enc_payloads = P(IDi) | P(AUTH) | P(SA) | P(TSi) | P(TSr), + .opt_enc_payloads = P(CERT) | P(CERTREQ) | P(IDr), .processor = ikev2parent_inI2outR2, .recv_type = ISAKMP_v2_AUTH, .timeout_event = EVENT_SA_REPLACE, @@ -176,6 +189,8 @@ enum smf2_flags { { .state = STATE_PARENT_I2, .next_state = STATE_PARENT_I2, .flags = SMF2_STATENEEDED, + .req_clear_payloads = P(E), + .opt_enc_payloads = P(N) | P(D) | P(CP), .processor = process_informational_ikev2, .recv_type = ISAKMP_v2_INFORMATIONAL, }, @@ -185,6 +200,8 @@ enum smf2_flags { { .state = STATE_PARENT_R1, .next_state = STATE_PARENT_R1, .flags = SMF2_STATENEEDED, + .req_clear_payloads = P(E), + .opt_enc_payloads = P(N) | P(D) | P(CP), .processor = process_informational_ikev2, .recv_type = ISAKMP_v2_INFORMATIONAL, }, @@ -193,6 +210,8 @@ enum smf2_flags { { .state = STATE_PARENT_I3, .next_state = STATE_PARENT_I3, .flags = SMF2_STATENEEDED, + .req_clear_payloads = P(E), + .opt_enc_payloads = P(N) | P(D) | P(CP), .processor = process_informational_ikev2, .recv_type = ISAKMP_v2_INFORMATIONAL, }, @@ -201,6 +220,8 @@ enum smf2_flags { { .state = STATE_PARENT_R2, .next_state = STATE_PARENT_R2, .flags = SMF2_STATENEEDED, + .req_clear_payloads = P(E), + .opt_enc_payloads = P(N) | P(D) | P(CP), .processor = process_informational_ikev2, .recv_type = ISAKMP_v2_INFORMATIONAL, }, @@ -209,6 +230,8 @@ enum smf2_flags { { .state = STATE_IKESA_DEL, .next_state = STATE_IKESA_DEL, .flags = SMF2_STATENEEDED, + .req_clear_payloads = P(E), + .opt_enc_payloads = P(N) | P(D) | P(CP), .processor = process_informational_ikev2, .recv_type = ISAKMP_v2_INFORMATIONAL, }, @@ -218,105 +241,143 @@ enum smf2_flags { { .state = STATE_IKEv2_ROOF } }; - -const struct state_v2_microcode *ikev2_parent_firststate() -{ - return &state_microcode_table[0]; -} - +#undef P +#undef PT /* * split up an incoming message into payloads */ -stf_status +static stf_status ikev2_process_payloads(struct msg_digest *md, pb_stream *in_pbs, - unsigned int from_state, - unsigned int np) + unsigned int np, + lset_t req_payloads, + lset_t opt_payloads) { struct payload_digest *pd = md->digest_roof; - struct state *st = md->st; - - /* lset_t needed = smc->req_payloads; */ - - /* zero out the digest descriptors -- might nuke [v2E] digest! */ + lset_t seen = LEMPTY; + /* ??? zero out the digest descriptors -- might nuke ISAKMP_NEXT_v2E digest! */ while (np != ISAKMP_NEXT_NONE) { - struct_desc *sd = np < ISAKMP_NEXT_ROOF? payload_descs[np] : NULL; - int thisp = np; - bool unknown_payload = FALSE; + struct_desc *sd = payload_desc(np); memset(pd, 0, sizeof(*pd)); if (pd == &md->digest[PAYLIMIT]) { loglog(RC_LOG_SERIOUS, "more than %d payloads in message; ignored", PAYLIMIT); - SEND_NOTIFICATION(PAYLOAD_MALFORMED); - return STF_FAIL; + return STF_FAIL + v2N_INVALID_SYNTAX; } - if (sd == NULL) - { - unknown_payload = TRUE; - sd = &ikev2_generic_desc; + + memset(pd, 0, sizeof(*pd)); /* ??? is this needed? */ + + + if (sd == NULL || np < ISAKMP_v2PAYLOAD_TYPE_BASE) { + /* This payload is unknown to us. + * RFCs 4306 and 5996 2.5 say that if the payload + * has the Critical Bit, we should be upset + * but if it does not, we should just ignore it. + */ + if (!in_struct(&pd->payload, &ikev2_generic_desc, in_pbs, &pd->pbs)) { + loglog(RC_LOG_SERIOUS, "malformed payload in packet"); + return STF_FAIL + v2N_INVALID_SYNTAX; + } + if (pd->payload.v2gen.isag_critical & ISAKMP_PAYLOAD_CRITICAL) { + /* It was critical. + * See RFC 5996 1.5 "Version Numbers and Forward Compatibility" + * ??? we are supposed to send the offending np byte back in the + * notify payload. + */ + loglog(RC_LOG_SERIOUS, + "critical payload (%s) was not understood. Message dropped.", + enum_show(&payload_names_ikev2, np)); + return STF_FAIL + v2N_UNSUPPORTED_CRITICAL_PAYLOAD; + } + loglog(RC_COMMENT, "non-critical payload ignored because it contains an unknown or" + " unexpected payload type (%s) at the outermost level", + enum_show(&payload_names_ikev2, np)); + np = pd->payload.generic.isag_np; + continue; } - /* why to process an unknown payload*/ - /* critical bit in RFC 4306/5996 is just 1 bit not a byte*/ - /* As per RFC other 7 bits are RESERVED and should be ignored*/ - if(unknown_payload) { - if(pd->payload.v2gen.isag_critical & ISAKMP_PAYLOAD_CRITICAL) { - /* it was critical */ - loglog(RC_LOG_SERIOUS, "critical payload (%s) was not understood. Message dropped." - , enum_show(&payload_names, thisp)); - return STF_FATAL; - } - loglog(RC_COMMENT, "non-critical payload ignored because it contains an unknown or" - " unexpected payload type (%s) at the outermost level" - , enum_show(&payload_names, thisp)); + passert(np - ISAKMP_v2PAYLOAD_TYPE_BASE < LELEM_ROOF); + + { + lset_t s = LELEM(np - ISAKMP_v2PAYLOAD_TYPE_BASE); + + if (s & seen & ~repeatable_payloads) { + /* improperly repeated payload */ + loglog(RC_LOG_SERIOUS, + "payload (%s) unexpectedly repeated. Message dropped.", + enum_show(&payload_names_ikev2, np)); + return STF_FAIL + v2N_INVALID_SYNTAX; + } + if ((s & (req_payloads | opt_payloads | everywhere_payloads)) == LEMPTY) { + /* unexpected payload */ + loglog(RC_LOG_SERIOUS, + "payload (%s) unexpected. Message dropped.", + enum_show(&payload_names_ikev2, np)); + return STF_FAIL + v2N_INVALID_SYNTAX; + } + seen |= s; } if (!in_struct(&pd->payload, sd, in_pbs, &pd->pbs)) { - loglog(RC_LOG_SERIOUS, "malformed payload in packet"); - SEND_NOTIFICATION(PAYLOAD_MALFORMED); - return STF_FAIL; + loglog(RC_LOG_SERIOUS, "malformed payload in packet"); + return STF_FAIL + v2N_INVALID_SYNTAX; } DBG(DBG_PARSING , DBG_log("processing payload: %s (len=%u)\n" - , enum_show(&payload_names, thisp) + , enum_show(&payload_names, np) , pd->payload.generic.isag_length)); /* place this payload at the end of the chain for this type */ { struct payload_digest **p; - for (p = &md->chain[thisp]; *p != NULL; p = &(*p)->next) + for (p = &md->chain[np]; *p != NULL; p = &(*p)->next) ; *p = pd; pd->next = NULL; } - np = pd->payload.generic.isag_np; - - /* do payload-type specific things that need to be here. */ - switch(thisp) { + switch(np) { case ISAKMP_NEXT_v2E: np = ISAKMP_NEXT_NONE; break; - default: /* nothing special */ + default: + np = pd->payload.generic.isag_np; break; } pd++; } + + if (req_payloads & ~seen) { + /* improperly repeated payload */ + loglog(RC_LOG_SERIOUS, + "missing payload(s) (%s). Message dropped.", + bitnamesof(payload_name_ikev2_main, req_payloads & ~seen)); + return STF_FAIL + v2N_INVALID_SYNTAX; + } + md->digest_roof = pd; return STF_OK; } +/* this stub is needed because struct state_v2_microcode is local to this file */ +stf_status ikev2_process_encrypted_payloads(struct msg_digest *md, + pb_stream *in_pbs, + unsigned int np) +{ + return ikev2_process_payloads(md, in_pbs, np, md->svm->req_enc_payloads, md->svm->opt_enc_payloads); +} + /* * process an input packet, possibly generating a reply. * @@ -468,7 +526,7 @@ const struct state_v2_microcode *ikev2_parent_firststate() from_state = st->st_state; } - for(svm = state_microcode_table; svm->state != STATE_IKEv2_ROOF; svm++) { + for(svm = v2_state_microcode_table; svm->state != STATE_IKEv2_ROOF; svm++) { if(svm->flags & SMF2_STATENEEDED) { if(st==NULL) continue; } @@ -502,10 +560,15 @@ const struct state_v2_microcode *ikev2_parent_firststate() return; } + md->svm = svm; + md->from_state = from_state; + md->st = st; + { stf_status stf; - stf = ikev2_process_payloads(md, &md->message_pbs - , from_state, md->hdr.isa_np); + stf = ikev2_process_payloads(md, &md->message_pbs, + md->hdr.isa_np, + svm->req_clear_payloads, svm->opt_clear_payloads); if(stf != STF_OK) { complete_v2_state_transition(mdp, stf); return; @@ -521,26 +583,7 @@ const struct state_v2_microcode *ikev2_parent_firststate() md->message_pbs.roof = md->message_pbs.cur; -#if 0 - /* check that all mandatory payloads appeared */ - if (needed != 0) - { - loglog(RC_LOG_SERIOUS, "message for %s is missing payloads %s" - , enum_show(&state_names, from_state) - , bitnamesof(payload_name, needed)); - SEND_NOTIFICATION(PAYLOAD_MALFORMED); - return; -#endif - - md->svm = svm; - md->from_state = from_state; - md->st = st; - - { - stf_status stf; - stf = (svm->processor)(md); - complete_v2_state_transition(mdp, stf); - } + complete_v2_state_transition(mdp, (svm->processor)(md)); } bool @@ -1077,10 +1120,25 @@ void complete_v2_state_transition(struct msg_digest **mdp v2_notification_t accept_v2_nonce(struct msg_digest *md, chunk_t *dest, const char *name) { - return accept_nonce(md, dest, name, ISAKMP_NEXT_v2Ni); -} + pb_stream *nonce_pbs; + size_t len; + + if(md->chain[ISAKMP_NEXT_v2Ni] == NULL) { + loglog(RC_LOG_SERIOUS, "missing nonce Ni"); + return v2N_INVALID_SYNTAX; + } + nonce_pbs = &md->chain[ISAKMP_NEXT_v2Ni]->pbs; + len = pbs_left(nonce_pbs); + if (len < MINIMUM_NONCE_SIZE || MAXIMUM_NONCE_SIZE < len) { + loglog(RC_LOG_SERIOUS, "%s length not between %d and %d", + name, MINIMUM_NONCE_SIZE, MAXIMUM_NONCE_SIZE); + return v2N_INVALID_SYNTAX; /* ??? */ + } + clonereplacechunk(*dest, nonce_pbs->cur, len, "nonce"); + return NOTHING_WRONG; +} /* * Local Variables: diff --git a/programs/pluto/ikev2.h b/programs/pluto/ikev2.h index 15ed6a4..355c3d5 100644 --- a/programs/pluto/ikev2.h +++ b/programs/pluto/ikev2.h @@ -40,7 +40,7 @@ extern void complete_v2_state_transition(struct msg_digest **mdp extern stf_status ikev2parent_inI2outR2(struct msg_digest *md); extern stf_status ikev2parent_inR2(struct msg_digest *md); -extern const struct state_v2_microcode *ikev2_parent_firststate(void); +extern const struct state_v2_microcode ikev2_parent_firststate_microcode; extern v2_notification_t accept_v2_nonce(struct msg_digest *md, chunk_t *dest , const char *name); @@ -88,9 +88,8 @@ extern void send_v2_notification_from_state(struct state *st extern void send_v2_notification_from_md(struct msg_digest *md,u_int16_t type , chunk_t *data); -extern stf_status ikev2_process_payloads(struct msg_digest *md, +extern stf_status ikev2_process_encrypted_payloads(struct msg_digest *md, pb_stream *in_pbs, - unsigned int from_state, unsigned int np); extern bool ikev2_decode_peer_id(struct msg_digest *md diff --git a/programs/pluto/ikev2_parent.c b/programs/pluto/ikev2_parent.c index 1b22eda..475508b 100644 --- a/programs/pluto/ikev2_parent.c +++ b/programs/pluto/ikev2_parent.c @@ -216,7 +216,7 @@ static stf_status ikev2_parent_outI1_common(struct msg_digest *md ke->md = alloc_md(); ke->md->from_state = STATE_IKEv2_BASE; - ke->md->svm = ikev2_parent_firststate(); + ke->md->svm = &ikev2_parent_firststate_microcode; ke->md->st = st; set_suspended(st, ke->md); @@ -928,7 +928,7 @@ stf_status ikev2parent_inR1outI2(struct msg_digest *md) st->st_dcookie); DBG_log("next STATE_PARENT_I1 resend I1 with the dcookie")); - md->svm = ikev2_parent_firststate(); + md->svm = &ikev2_parent_firststate_microcode; change_state(st, STATE_PARENT_I1); st->st_msgid_last_localreq = INVALID_MSGID; @@ -947,23 +947,6 @@ stf_status ikev2parent_inR1outI2(struct msg_digest *md) } /* - * If we did not get a KE payload, we cannot continue. There * should be - * a Notify telling us why. We inform the user, but continue to try this - * connection via regular retransmit intervals. - */ - if( md->chain[ISAKMP_NEXT_v2N] && (md->chain[ISAKMP_NEXT_v2KE] == NULL)) - { - const char *from_state_name = enum_name(&state_names, st->st_state); - const u_int16_t isan_type = md->chain[ISAKMP_NEXT_v2N]->payload.v2n.isan_type; - openswan_log("%s: received %s" - , from_state_name - , enum_name(&ikev2_notify_names , isan_type)); - return STF_FAIL + isan_type; - } else if( md->chain[ISAKMP_NEXT_v2N]) { - DBG(DBG_CONTROL,DBG_log("received a notify..")); - } - - /* * the responder sent us back KE, Gr, Nr, and it's our time to calculate * the shared key values. */ @@ -1265,14 +1248,7 @@ stf_status ikev2_decrypt_msg(struct msg_digest *md init_pbs(&md->clr_pbs, encstart, enclen - (padlen+1), "cleartext"); } - { stf_status ret; - ret = ikev2_process_payloads(md, &md->clr_pbs, st->st_state, np); - if(ret != STF_OK) { - return ret; - } - } - - return STF_OK; + return ikev2_process_encrypted_payloads(md, &md->clr_pbs, np); } static stf_status ikev2_send_auth(struct connection *c -- 1.8.5.5