diff -Naur openswan-2.6.32-orig/include/constants.h openswan-2.6.32/include/constants.h --- openswan-2.6.32-orig/include/constants.h 2010-12-17 20:23:54.000000000 -0500 +++ openswan-2.6.32/include/constants.h 2014-02-06 20:42:31.931053337 -0500 @@ -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 -Naur openswan-2.6.32-orig/include/ietf_constants.h openswan-2.6.32/include/ietf_constants.h --- openswan-2.6.32-orig/include/ietf_constants.h 2014-02-06 20:41:37.149028756 -0500 +++ openswan-2.6.32/include/ietf_constants.h 2014-02-06 20:42:31.932053356 -0500 @@ -2,7 +2,7 @@ * * Copyright (C) 2004 Michael Richardson * 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 @@ -382,6 +382,8 @@ 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 -Naur openswan-2.6.32-orig/include/names_constant.h openswan-2.6.32/include/names_constant.h --- openswan-2.6.32-orig/include/names_constant.h 2014-02-06 20:41:37.138028550 -0500 +++ openswan-2.6.32/include/names_constant.h 2014-02-06 20:42:31.932053356 -0500 @@ -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 -Naur openswan-2.6.32-orig/include/packet.h openswan-2.6.32/include/packet.h --- openswan-2.6.32-orig/include/packet.h 2014-02-06 20:41:37.135028494 -0500 +++ openswan-2.6.32/include/packet.h 2014-02-06 20:42:31.933053375 -0500 @@ -667,7 +667,7 @@ * 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 -Naur openswan-2.6.32-orig/lib/libopenswan/constants.c openswan-2.6.32/lib/libopenswan/constants.c --- openswan-2.6.32-orig/lib/libopenswan/constants.c 2014-02-06 20:41:37.158028925 -0500 +++ openswan-2.6.32/lib/libopenswan/constants.c 2014-02-06 20:45:20.277178223 -0500 @@ -157,7 +157,8 @@ 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", @@ -174,22 +175,24 @@ "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", /* 0 */ }; -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 -Naur openswan-2.6.32-orig/lib/libpluto/packet.c openswan-2.6.32/lib/libpluto/packet.c --- openswan-2.6.32-orig/lib/libpluto/packet.c 2014-02-06 20:41:37.159028943 -0500 +++ openswan-2.6.32/lib/libpluto/packet.c 2014-02-06 20:46:01.336935414 -0500 @@ -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. * * 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 @@ -1107,7 +1107,7 @@ * 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) */ @@ -1147,6 +1147,11 @@ &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 -Naur openswan-2.6.32-orig/programs/pluto/demux.h openswan-2.6.32/programs/pluto/demux.h --- openswan-2.6.32-orig/programs/pluto/demux.h 2010-12-17 20:23:54.000000000 -0500 +++ openswan-2.6.32/programs/pluto/demux.h 2014-02-06 20:42:31.934053393 -0500 @@ -83,8 +83,9 @@ # 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 -Naur openswan-2.6.32-orig/programs/pluto/ikev1.c openswan-2.6.32/programs/pluto/ikev1.c --- openswan-2.6.32-orig/programs/pluto/ikev1.c 2014-02-06 20:41:37.104027912 -0500 +++ openswan-2.6.32/programs/pluto/ikev1.c 2014-02-06 20:42:31.935053412 -0500 @@ -1556,7 +1556,7 @@ 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]) { @@ -1603,12 +1603,12 @@ #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; case ISAKMP_NEXT_NATD_BADDRAFTS: @@ -1618,7 +1618,7 @@ * the bad drafts of the RFC */ np = ISAKMP_NEXT_NATD_RFC; /* NAT-D relocated */ - sd = payload_descs[np]; + sd = payload_desc(np); break; } #endif @@ -1629,6 +1629,7 @@ SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE); return; } + passert(sd != NULL); } { diff -Naur openswan-2.6.32-orig/programs/pluto/ikev2.c openswan-2.6.32/programs/pluto/ikev2.c --- openswan-2.6.32-orig/programs/pluto/ikev2.c 2014-02-06 20:41:37.145028681 -0500 +++ openswan-2.6.32/programs/pluto/ikev2.c 2014-02-06 20:42:31.936053431 -0500 @@ -79,20 +79,18 @@ 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), }; /* @@ -131,18 +129,26 @@ * */ -/* 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, }, @@ -150,6 +156,9 @@ { .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, @@ -157,14 +166,18 @@ { .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, @@ -174,6 +187,8 @@ { .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, }, @@ -183,6 +198,8 @@ { .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, }, @@ -191,6 +208,8 @@ { .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, }, @@ -199,6 +218,8 @@ { .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, }, @@ -207,6 +228,8 @@ { .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, }, @@ -216,107 +239,142 @@ { .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; - err_t excuse = "not sure"; - - /* 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 + 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 + 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 + 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 + 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 + INVALID_SYNTAX; + } + seen |= s; } - + if (!in_struct(&pd->payload, sd, in_pbs, &pd->pbs)) { - loglog(RC_LOG_SERIOUS, "%smalformed payload in packet", excuse); - SEND_NOTIFICATION(PAYLOAD_MALFORMED); - return STF_FAIL; + loglog(RC_LOG_SERIOUS, "malformed payload in packet"); + return STF_FAIL + 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 + 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. * @@ -458,7 +516,7 @@ 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; } @@ -484,10 +542,15 @@ 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); @@ -501,26 +564,7 @@ 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 @@ -1021,10 +1065,25 @@ 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 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 INVALID_SYNTAX; /* ??? */ + } + clonereplacechunk(*dest, nonce_pbs->cur, len, "nonce"); + return NOTHING_WRONG; +} /* * Local Variables: diff -Naur openswan-2.6.32-orig/programs/pluto/ikev2.h openswan-2.6.32/programs/pluto/ikev2.h --- openswan-2.6.32-orig/programs/pluto/ikev2.h 2014-02-06 20:41:37.146028700 -0500 +++ openswan-2.6.32/programs/pluto/ikev2.h 2014-02-06 20:42:31.936053431 -0500 @@ -40,7 +40,7 @@ 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 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_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 -Naur openswan-2.6.32-orig/programs/pluto/ikev2_parent.c openswan-2.6.32/programs/pluto/ikev2_parent.c --- openswan-2.6.32-orig/programs/pluto/ikev2_parent.c 2014-02-06 20:41:37.158028925 -0500 +++ openswan-2.6.32/programs/pluto/ikev2_parent.c 2014-02-06 20:42:31.937053449 -0500 @@ -216,7 +216,7 @@ 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); @@ -877,7 +877,7 @@ 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; @@ -888,21 +888,6 @@ } /* - * 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; - } - - /* * the responder sent us back KE, Gr, Nr, and it's our time to calculate * the shared key values. */ @@ -1204,14 +1189,7 @@ 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