X-Git-Url: https://git.saurik.com/apple/ipsec.git/blobdiff_plain/52b7d2ce06d68d0a9160d16f6e7c08c21c149d0d..f255a978ed5a0b035176fe69ed5a30007f5708d0:/ipsec-tools/racoon/proposal.c?ds=sidebyside diff --git a/ipsec-tools/racoon/proposal.c b/ipsec-tools/racoon/proposal.c index a2f053a..62d3db6 100644 --- a/ipsec-tools/racoon/proposal.c +++ b/ipsec-tools/racoon/proposal.c @@ -180,6 +180,71 @@ inssatrns(pr, new) return; } +int +satrns_remove_from_list(struct satrns **listptr, struct satrns *trns) +{ + + struct satrns **ptr = listptr; + + if (ptr == NULL) + return -1; + + while (*ptr) { + if (*ptr == trns) { + *ptr = trns->next; + ptr = &trns->next; + trns->next = NULL; + return 0; + } + ptr = &((*ptr)->next); + } + return -1; +} + +#ifdef ENABLE_NATT +static void +saprop_udp_encap (struct saproto *pr) +{ + switch (pr->encmode) { + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT: + pr->encmode = IPSECDOI_ATTR_ENC_MODE_TUNNEL; + pr->udp_encap = 1; + break; + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC: + case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT: + pr->encmode = IPSECDOI_ATTR_ENC_MODE_TRNS; + pr->udp_encap = 1; + break; + } +} + +static void +saprop_adjust_encmode (struct saproto *pr2, struct saproto *pr1) +{ + int prev; + + if (natt_udp_encap(pr2->encmode)) { + prev = pr2->encmode; + saprop_udp_encap(pr2); + plog(ASL_LEVEL_INFO, "Adjusting my encmode %s(%d)->%s(%d)\n", + s_ipsecdoi_encmode(prev), + prev, + s_ipsecdoi_encmode(pr2->encmode), + pr2->encmode); + } + if (natt_udp_encap(pr1->encmode)) { + prev = pr1->encmode; + saprop_udp_encap(pr1); + plog(ASL_LEVEL_INFO, "Adjusting peer's encmode %s(%d)->%s(%d)\n", + s_ipsecdoi_encmode(prev), + prev, + s_ipsecdoi_encmode(pr1->encmode), + pr1->encmode); + } +} +#endif // ENABLE_NATT + /* * take a single match between saprop. allocate a new proposal and return it * for future use (like picking single proposal from a bundle). @@ -192,7 +257,7 @@ inssatrns(pr, new) */ struct saprop * cmpsaprop_alloc(ph1, pp1, pp2, side) - struct ph1handle *ph1; + phase1_handle_t *ph1; const struct saprop *pp1, *pp2; int side; { @@ -205,7 +270,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) newpp = newsaprop(); if (newpp == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saprop.\n"); return NULL; } @@ -223,14 +288,14 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) case PROP_CHECK_STRICT: if (pp1->lifetime > pp2->lifetime) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "long lifetime proposed: " "my:%d peer:%d\n", (int)pp2->lifetime, (int)pp1->lifetime); goto err; } if (pp1->lifebyte > pp2->lifebyte) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "long lifebyte proposed: " "my:%d peer:%d\n", pp2->lifebyte, pp1->lifebyte); @@ -241,7 +306,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) prop_pfs_check: if (pp2->pfs_group != 0 && pp1->pfs_group != pp2->pfs_group) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "pfs group mismatched: " "my:%d peer:%d\n", pp2->pfs_group, pp1->pfs_group); @@ -257,7 +322,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) } else { newpp->lifetime = pp2->lifetime; newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC; - plog(LLV_NOTIFY, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "use own lifetime: " "my:%d peer:%d\n", (int)pp2->lifetime, (int)pp1->lifetime); @@ -267,7 +332,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) if (pp1->lifebyte > pp2->lifebyte) { newpp->lifebyte = pp2->lifebyte; newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC; - plog(LLV_NOTIFY, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "use own lifebyte: " "my:%d peer:%d\n", pp2->lifebyte, pp1->lifebyte); @@ -279,7 +344,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) case PROP_CHECK_EXACT: if (pp1->lifetime != pp2->lifetime) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "lifetime mismatched: " "my:%d peer:%d\n", (int)pp2->lifetime, (int)pp1->lifetime); @@ -287,14 +352,14 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) } if (pp1->lifebyte != pp2->lifebyte) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "lifebyte mismatched: " "my:%d peer:%d\n", pp2->lifebyte, pp1->lifebyte); goto err; } if (pp1->pfs_group != pp2->pfs_group) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "pfs group mismatched: " "my:%d peer:%d\n", pp2->pfs_group, pp1->pfs_group); @@ -306,7 +371,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) break; default: - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "invalid pcheck_level why?.\n"); goto err; } @@ -352,7 +417,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) break; if (pr1->proto_id != pr2->proto_id) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "proto_id mismatched: " "my:%s peer:%s\n", s_ipsecdoi_proto(pr2->proto_id), @@ -375,45 +440,27 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) spisizematch = 1; } if (spisizematch) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "IPComp SPI size promoted " "from 16bit to 32bit\n"); } } if (!spisizematch) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "spisize mismatched: " "my:%d peer:%d\n", (int)pr2->spisize, (int)pr1->spisize); goto err; } -#ifdef ENABLE_NATT - if ((ph1->natt_flags & NAT_DETECTED) && - natt_udp_encap (pr2->encmode)) - { - plog(LLV_INFO, LOCATION, NULL, "Adjusting my encmode %s->%s\n", - s_ipsecdoi_encmode(pr2->encmode), - s_ipsecdoi_encmode(pr2->encmode - ph1->natt_options->mode_udp_diff)); - pr2->encmode -= ph1->natt_options->mode_udp_diff; - pr2->udp_encap = 1; - } - - if ((ph1->natt_flags & NAT_DETECTED) && - natt_udp_encap (pr1->encmode)) - { - plog(LLV_INFO, LOCATION, NULL, "Adjusting peer's encmode %s(%d)->%s(%d)\n", - s_ipsecdoi_encmode(pr1->encmode), - pr1->encmode, - s_ipsecdoi_encmode(pr1->encmode - ph1->natt_options->mode_udp_diff), - pr1->encmode - ph1->natt_options->mode_udp_diff); - pr1->encmode -= ph1->natt_options->mode_udp_diff; - pr1->udp_encap = 1; +#ifdef ENABLE_NATT + if (ph1->natt_flags & NAT_DETECTED) { + saprop_adjust_encmode(pr2, pr1); } #endif if (pr1->encmode != pr2->encmode) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "encmode mismatched: " "my:%s peer:%s\n", s_ipsecdoi_encmode(pr2->encmode), @@ -433,7 +480,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) found: newpr = newsaproto(); if (newpr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saproto.\n"); goto err; } @@ -450,8 +497,9 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) newtr = newsatrns(); if (newtr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate satrns.\n"); + racoon_free(newpr); goto err; } newtr->trns_no = tr1->trns_no; @@ -497,20 +545,20 @@ cmpsaprop(pp1, pp2) const struct saprop *pp1, *pp2; { if (pp1->pfs_group != pp2->pfs_group) { - plog(LLV_WARNING, LOCATION, NULL, + plog(ASL_LEVEL_WARNING, "pfs_group mismatch. mine:%d peer:%d\n", pp1->pfs_group, pp2->pfs_group); /* FALLTHRU */ } if (pp1->lifetime > pp2->lifetime) { - plog(LLV_WARNING, LOCATION, NULL, + plog(ASL_LEVEL_WARNING, "less lifetime proposed. mine:%d peer:%d\n", (int)pp1->lifetime, (int)pp2->lifetime); /* FALLTHRU */ } if (pp1->lifebyte > pp2->lifebyte) { - plog(LLV_WARNING, LOCATION, NULL, + plog(ASL_LEVEL_WARNING, "less lifebyte proposed. mine:%d peer:%d\n", pp1->lifebyte, pp2->lifebyte); /* FALLTHRU */ @@ -530,7 +578,7 @@ cmpsatrns(proto_id, tr1, tr2) const struct satrns *tr1, *tr2; { if (tr1->trns_id != tr2->trns_id) { - plog(LLV_WARNING, LOCATION, NULL, + plog(ASL_LEVEL_DEBUG, "trns_id mismatched: " "my:%s peer:%s\n", s_ipsecdoi_trns(proto_id, tr2->trns_id), @@ -539,7 +587,7 @@ cmpsatrns(proto_id, tr1, tr2) } if (tr1->authtype != tr2->authtype) { - plog(LLV_WARNING, LOCATION, NULL, + plog(ASL_LEVEL_DEBUG, "authtype mismatched: " "my:%s peer:%s\n", s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr2->authtype), @@ -552,7 +600,7 @@ cmpsatrns(proto_id, tr1, tr2) * the initiator. It should be defined a notify message. */ if (tr1->encklen > tr2->encklen) { - plog(LLV_WARNING, LOCATION, NULL, + plog(ASL_LEVEL_WARNING, "less key length proposed, " "mine:%d peer:%d. Use initiaotr's one.\n", tr2->encklen, tr1->encklen); @@ -563,9 +611,7 @@ cmpsatrns(proto_id, tr1, tr2) } int -set_satrnsbysainfo(pr, sainfo) - struct saproto *pr; - struct sainfo *sainfo; +set_satrnsbysainfo(struct saproto *pr, struct sainfo *sainfo, u_int8_t ike_version, int pfs_group) { struct sainfoalg *a, *b; struct satrns *newtr; @@ -574,7 +620,7 @@ set_satrnsbysainfo(pr, sainfo) switch (pr->proto_id) { case IPSECDOI_PROTO_IPSEC_AH: if (sainfo->algs[algclass_ipsec_auth] == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "no auth algorithm found\n"); goto err; } @@ -587,13 +633,13 @@ set_satrnsbysainfo(pr, sainfo) /* allocate satrns */ newtr = newsatrns(); if (newtr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate satrns.\n"); goto err; } newtr->trns_no = t++; - newtr->trns_id = ipsecdoi_authalg2trnsid(a->alg); + newtr->trns_id = ipsecdoi_authalg2trnsid(a->alg); // IKEv1 only newtr->authtype = a->alg; inssatrns(pr, newtr); @@ -601,33 +647,35 @@ set_satrnsbysainfo(pr, sainfo) break; case IPSECDOI_PROTO_IPSEC_ESP: if (sainfo->algs[algclass_ipsec_enc] == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "no encryption algorithm found\n"); goto err; } t = 1; - for (a = sainfo->algs[algclass_ipsec_enc]; a; a = a->next) { - for (b = sainfo->algs[algclass_ipsec_auth]; b; b = b->next) { - /* allocate satrns */ - newtr = newsatrns(); - if (newtr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to allocate satrns.\n"); - goto err; - } - - newtr->trns_no = t++; - newtr->trns_id = a->alg; - newtr->encklen = a->encklen; - newtr->authtype = b->alg; - - inssatrns(pr, newtr); - } - } + if (ike_version == ISAKMP_VERSION_NUMBER_IKEV1) { + for (a = sainfo->algs[algclass_ipsec_enc]; a; a = a->next) { + for (b = sainfo->algs[algclass_ipsec_auth]; b; b = b->next) { + /* allocate satrns */ + newtr = newsatrns(); + if (newtr == NULL) { + plog(ASL_LEVEL_ERR, + "failed to allocate satrns.\n"); + goto err; + } + + newtr->trns_no = t++; + newtr->trns_id = a->alg; + newtr->encklen = a->encklen; + newtr->authtype = b->alg; + + inssatrns(pr, newtr); + } + } + } break; case IPSECDOI_PROTO_IPCOMP: if (sainfo->algs[algclass_ipsec_comp] == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "no ipcomp algorithm found\n"); goto err; } @@ -637,7 +685,7 @@ set_satrnsbysainfo(pr, sainfo) /* allocate satrns */ newtr = newsatrns(); if (newtr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate satrns.\n"); goto err; } @@ -650,14 +698,14 @@ set_satrnsbysainfo(pr, sainfo) } break; default: - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "unknown proto_id (%d).\n", pr->proto_id); goto err; } - + /* no proposal found */ if (pr->head == NULL) { - plog(LLV_ERROR, LOCATION, NULL, "no algorithms found.\n"); + plog(ASL_LEVEL_ERR, "no algorithms found.\n"); return -1; } @@ -684,7 +732,7 @@ aproppair2saprop(p0) /* allocate ipsec a sa proposal */ newpp = newsaprop(); if (newpp == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saprop.\n"); return NULL; } @@ -696,7 +744,7 @@ aproppair2saprop(p0) /* allocate ipsec sa protocol */ newpr = newsaproto(); if (newpr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saproto.\n"); goto err; } @@ -704,8 +752,9 @@ aproppair2saprop(p0) /* check spi size */ /* XXX should be handled isakmp cookie */ if (sizeof(newpr->spi) < p->prop->spi_size) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "invalid spi size %d.\n", p->prop->spi_size); + racoon_free(newpr); goto err; } @@ -725,7 +774,7 @@ aproppair2saprop(p0) for (t = p; t; t = t->tnext) { - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_DEBUG, "prop#=%d prot-id=%s spi-size=%d " "#trns=%d trns#=%d trns-id=%s\n", t->prop->p_no, @@ -738,13 +787,17 @@ aproppair2saprop(p0) /* allocate ipsec sa transform */ newtr = newsatrns(); if (newtr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "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; } @@ -828,7 +881,7 @@ printsaprop(pri, pp) const struct saprop *p; if (pp == NULL) { - plog(pri, LOCATION, NULL, "(null)"); + plog(pri, "(null)"); return; } @@ -869,7 +922,7 @@ printsaproto(pri, pr) if (pr == NULL) return; - plog(pri, LOCATION, NULL, + plog(pri, " (proto_id=%s spisize=%d spi=%08lx spi_p=%08lx " "encmode=%s reqid=%d:%d)\n", s_ipsecdoi_proto(pr->proto_id), @@ -897,25 +950,25 @@ printsatrns(pri, proto_id, tr) switch (proto_id) { case IPSECDOI_PROTO_IPSEC_AH: - plog(pri, LOCATION, NULL, + plog(pri, " (trns_id=%s authtype=%s)\n", s_ipsecdoi_trns(proto_id, tr->trns_id), s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype)); break; case IPSECDOI_PROTO_IPSEC_ESP: - plog(pri, LOCATION, NULL, + plog(pri, " (trns_id=%s encklen=%d authtype=%s)\n", s_ipsecdoi_trns(proto_id, tr->trns_id), tr->encklen, s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype)); break; case IPSECDOI_PROTO_IPCOMP: - plog(pri, LOCATION, NULL, + plog(pri, " (trns_id=%s)\n", s_ipsecdoi_trns(proto_id, tr->trns_id)); break; default: - plog(pri, LOCATION, NULL, + plog(pri, "(unknown proto_id %d)\n", proto_id); } @@ -936,7 +989,7 @@ print_proppair0(pri, p, level) spc[level] = '\0'; } - plog(pri, LOCATION, NULL, + plog(pri, "%s%p: next=%p tnext=%p\n", spc, p, p->next, p->tnext); if (p->next) print_proppair0(pri, p->next, level + 1); @@ -954,7 +1007,7 @@ print_proppair(pri, p) int set_proposal_from_policy(iph2, sp_main, sp_sub) - struct ph2handle *iph2; + phase2_handle_t *iph2; struct secpolicy *sp_main, *sp_sub; { struct saprop *newpp; @@ -963,15 +1016,17 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) newpp = newsaprop(); if (newpp == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saprop.\n"); goto err; } newpp->prop_no = 1; newpp->lifetime = iph2->sainfo->lifetime; newpp->lifebyte = iph2->sainfo->lifebyte; - newpp->pfs_group = iph2->sainfo->pfs_group; + newpp->pfs_group = iph2->sainfo->pfs_group; + //%%%% to do - verify DH group is OK - tried that here and iphone failed to connect + if (lcconf->complex_bundle) goto skip1; @@ -1004,11 +1059,7 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) * me +--- SA1 ---+ peer1 * me +--- SA2 --------------+ peer2 */ -#ifdef __linux__ - if (req->saidx.src.ss_family && req->saidx.dst.ss_family) { -#else if (req->saidx.src.ss_len && req->saidx.dst.ss_len) { -#endif /* check the end of ip addresses of SA */ if (iph2->side == INITIATOR) paddr = (caddr_t)&req->saidx.dst; @@ -1019,7 +1070,7 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) /* allocate ipsec sa protocol */ newpr = newsaproto(); if (newpr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saproto.\n"); goto err; } @@ -1030,23 +1081,23 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) else newpr->spisize = 4; if (lcconf->complex_bundle) { - newpr->encmode = pfkey2ipsecdoi_mode(req->saidx.mode); + encmodesv = newpr->encmode = pfkey2ipsecdoi_mode(req->saidx.mode); #ifdef ENABLE_NATT if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED)) newpr->encmode += iph2->ph1->natt_options->mode_udp_diff; #endif } else - newpr->encmode = encmodesv; - + encmodesv = newpr->encmode = encmodesv; if (iph2->side == INITIATOR) newpr->reqid_out = req->saidx.reqid; else newpr->reqid_in = req->saidx.reqid; - if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) { - plog(LLV_ERROR, LOCATION, NULL, + if (set_satrnsbysainfo(newpr, iph2->sainfo, iph2->version, newpp->pfs_group) < 0) { + plog(ASL_LEVEL_ERR, "failed to get algorithms.\n"); + racoon_free(newpr); goto err; } @@ -1069,7 +1120,7 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) req = req->next; } if (pr || req) { - plog(LLV_NOTIFY, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "There is a difference " "between the in/out bound policies in SPD.\n"); } @@ -1077,10 +1128,14 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) iph2->proposal = newpp; - printsaprop0(LLV_DEBUG, newpp); + ike_session_update_mode(iph2); + + printsaprop0(ASL_LEVEL_DEBUG, newpp); return 0; err: + if (newpp) + flushsaprop(newpp); return -1; } @@ -1091,16 +1146,18 @@ err: */ int set_proposal_from_proposal(iph2) - struct ph2handle *iph2; + phase2_handle_t *iph2; { struct saprop *newpp = NULL, *pp0, *pp_peer = NULL; struct saproto *newpr = NULL, *pr; - struct prop_pair **pair; + struct prop_pair **pair = NULL; int error = -1; int i; /* get proposal pair */ - pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2); + if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1) + pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2); + if (pair == NULL) goto end; @@ -1111,13 +1168,17 @@ 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; pp0 = newsaprop(); if (pp0 == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saprop.\n"); goto end; } @@ -1127,7 +1188,7 @@ set_proposal_from_proposal(iph2) pp0->pfs_group = iph2->sainfo->pfs_group; if (pp_peer->next != NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "pp_peer is inconsistency, ignore it.\n"); /*FALLTHROUGH*/ } @@ -1136,8 +1197,9 @@ set_proposal_from_proposal(iph2) newpr = newsaproto(); if (newpr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate saproto.\n"); + racoon_free(pp0); goto end; } newpr->proto_id = pr->proto_id; @@ -1147,23 +1209,27 @@ 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, iph2->version, 0) < 0) { + plog(ASL_LEVEL_ERR, + "failed to get algorithms.\n"); + racoon_free(newpr); + racoon_free(pp0); + goto end; + } + inssaproto(pp0, newpr); } - inssaproto(pp0, newpr); inssaprop(&newpp, pp0); } - plog(LLV_DEBUG, LOCATION, NULL, "make a proposal from peer's:\n"); - printsaprop0(LLV_DEBUG, newpp); + plog(ASL_LEVEL_DEBUG, "make a proposal from peer's:\n"); + printsaprop0(ASL_LEVEL_DEBUG, newpp); iph2->proposal = newpp; + ike_session_update_mode(iph2); + error = 0; end: @@ -1172,7 +1238,8 @@ end: if (pp_peer) flushsaprop(pp_peer); - free_proppair(pair); + if (pair) + free_proppair(pair); return error; } @@ -1187,3 +1254,100 @@ tunnel_mode_prop(p) return 1; return 0; } + +struct satrns * +dupsatrns_1(struct satrns *tr) +{ + struct satrns *newtr; + + newtr = racoon_calloc(1, sizeof(*newtr)); + if (newtr == NULL) + return NULL; + newtr->trns_no = tr->trns_no; + newtr->trns_id = tr->trns_id; + newtr->encklen = tr->encklen; + newtr->authtype = tr->authtype; + + return newtr; +} + +void +dupsatrns(newpr, head) + struct saproto *newpr; + struct satrns *head; +{ + struct satrns *p, *newtr; + + for (p = head; p != NULL; p = p->next) { + newtr = newsatrns(); + if (newtr) { + newtr->trns_no = p->trns_no; + newtr->trns_id = p->trns_id; + newtr->encklen = p->encklen; + newtr->authtype = p->authtype; + inssatrns(newpr, newtr); + } else { + break; + } + + } + + return; +} + +void +dupsaproto(newpp, head, ignore_spis) + struct saprop *newpp; + struct saproto *head; + int ignore_spis; +{ + struct saproto *p, *newpr; + + for (p = head; p != NULL; p = p->next) { + newpr = newsaproto(); + if (newpr) { + newpr->proto_id = p->proto_id; + newpr->spisize = p->spisize; + newpr->encmode = p->encmode; + newpr->udp_encap = p->udp_encap; + if (!ignore_spis) { + newpr->spi = p->spi; + newpr->spi_p = p->spi_p; + newpr->reqid_in = p->reqid_in; + newpr->reqid_out = p->reqid_out; + } + dupsatrns(newpr, p->head); + inssaproto(newpp, newpr); + } else { + break; + } + + } + + return; +} + +struct saprop * +dupsaprop(head, ignore_spis) + struct saprop *head; + int ignore_spis; +{ + struct saprop *p, *newpp; + + for (p = head, newpp = NULL; p != NULL; p = p->next) { + struct saprop *tmp = newsaprop(); + if (tmp) { + tmp->prop_no = p->prop_no; + tmp->lifetime = p->lifetime; + tmp->lifebyte = p->lifebyte; + tmp->pfs_group = p->pfs_group; + tmp->claim = p->claim; + dupsaproto(tmp, p->head, ignore_spis); + inssaprop(&newpp, tmp); + } else { + break; + } + } + + return newpp; +}