diff -up ipsec-tools-0.7.1/src/racoon/pfkey.c.dpd-fixes ipsec-tools-0.7.1/src/racoon/pfkey.c --- ipsec-tools-0.7.1/src/racoon/pfkey.c.dpd-fixes 2008-11-10 12:56:46.000000000 +0100 +++ ipsec-tools-0.7.1/src/racoon/pfkey.c 2008-11-10 12:57:45.000000000 +0100 @@ -902,13 +902,19 @@ pk_sendgetspi(iph2) /* for mobile IPv6 */ if (proxy && iph2->src_id && iph2->dst_id && ipsecdoi_transportmode(pp)) { - src = iph2->src_id; - dst = iph2->dst_id; + src = dupsaddr(iph2->src_id); + dst = dupsaddr(iph2->dst_id); } else { - src = iph2->src; - dst = iph2->dst; + src = dupsaddr(iph2->src); + dst = dupsaddr(iph2->dst); } - + + if (src == NULL || dst == NULL) { + racoon_free(src); + racoon_free(dst); + return -1; + } + for (pr = pp->head; pr != NULL; pr = pr->next) { /* validity check */ @@ -916,6 +922,8 @@ pk_sendgetspi(iph2) if (satype == ~0) { plog(LLV_ERROR, LOCATION, NULL, "invalid proto_id %d\n", pr->proto_id); + racoon_free(src); + racoon_free(dst); return -1; } /* this works around a bug in Linux kernel where it allocates 4 byte @@ -932,12 +940,12 @@ pk_sendgetspi(iph2) if (mode == ~0) { plog(LLV_ERROR, LOCATION, NULL, "invalid encmode %d\n", pr->encmode); + racoon_free(src); + racoon_free(dst); return -1; } #ifdef ENABLE_NATT - /* XXX should we do a copy of src/dst for each pr ? - */ if (! pr->udp_encap) { /* Remove port information, that SA doesn't use it */ set_port(src, 0); @@ -956,6 +964,8 @@ pk_sendgetspi(iph2) plog(LLV_ERROR, LOCATION, NULL, "ipseclib failed send getspi (%s)\n", ipsec_strerror()); + racoon_free(src); + racoon_free(dst); return -1; } plog(LLV_DEBUG, LOCATION, NULL, @@ -963,6 +973,8 @@ pk_sendgetspi(iph2) sadbsecas2str(dst, src, satype, 0, mode)); } + racoon_free(src); + racoon_free(dst); return 0; } @@ -1146,11 +1158,17 @@ pk_sendupdate(iph2) /* for mobile IPv6 */ if (proxy && iph2->src_id && iph2->dst_id && ipsecdoi_transportmode(iph2->approval)) { - sa_args.dst = iph2->src_id; - sa_args.src = iph2->dst_id; + sa_args.dst = dupsaddr(iph2->src_id); + sa_args.src = dupsaddr(iph2->dst_id); } else { - sa_args.dst = iph2->src; - sa_args.src = iph2->dst; + sa_args.dst = dupsaddr(iph2->src); + sa_args.src = dupsaddr(iph2->dst); + } + + if (sa_args.src == NULL || sa_args.dst == NULL) { + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; } for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { @@ -1159,6 +1177,8 @@ pk_sendupdate(iph2) if (sa_args.satype == ~0) { plog(LLV_ERROR, LOCATION, NULL, "invalid proto_id %d\n", pr->proto_id); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; } else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) { @@ -1172,6 +1192,8 @@ pk_sendupdate(iph2) if (sa_args.mode == ~0) { plog(LLV_ERROR, LOCATION, NULL, "invalid encmode %d\n", pr->encmode); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; } #endif @@ -1183,8 +1205,11 @@ pk_sendupdate(iph2) pr->head->authtype, &sa_args.e_type, &sa_args.e_keylen, &sa_args.a_type, &sa_args.a_keylen, - &sa_args.flags) < 0) + &sa_args.flags) < 0) { + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; + } #if 0 sa_args.l_bytes = iph2->approval->lifebyte * 1024, @@ -1227,6 +1252,8 @@ pk_sendupdate(iph2) plog(LLV_ERROR, LOCATION, NULL, "libipsec failed send update (%s)\n", ipsec_strerror()); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; } @@ -1256,6 +1283,8 @@ pk_sendupdate(iph2) sa_args.satype, sa_args.spi, sa_args.mode)); } + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return 0; } @@ -1449,11 +1478,17 @@ pk_sendadd(iph2) /* for mobile IPv6 */ if (proxy && iph2->src_id && iph2->dst_id && ipsecdoi_transportmode(iph2->approval)) { - sa_args.src = iph2->src_id; - sa_args.dst = iph2->dst_id; + sa_args.src = dupsaddr(iph2->src_id); + sa_args.dst = dupsaddr(iph2->dst_id); } else { - sa_args.src = iph2->src; - sa_args.dst = iph2->dst; + sa_args.src = dupsaddr(iph2->src); + sa_args.dst = dupsaddr(iph2->dst); + } + + if (sa_args.src == NULL || sa_args.dst == NULL) { + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; } for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { @@ -1462,6 +1497,8 @@ pk_sendadd(iph2) if (sa_args.satype == ~0) { plog(LLV_ERROR, LOCATION, NULL, "invalid proto_id %d\n", pr->proto_id); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; } else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) { @@ -1475,6 +1512,8 @@ pk_sendadd(iph2) if (sa_args.mode == ~0) { plog(LLV_ERROR, LOCATION, NULL, "invalid encmode %d\n", pr->encmode); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; } #endif @@ -1487,8 +1526,11 @@ pk_sendadd(iph2) pr->head->authtype, &sa_args.e_type, &sa_args.e_keylen, &sa_args.a_type, &sa_args.a_keylen, - &sa_args.flags) < 0) + &sa_args.flags) < 0) { + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; + } #if 0 sa_args.l_bytes = iph2->approval->lifebyte * 1024, @@ -1539,6 +1581,8 @@ pk_sendadd(iph2) plog(LLV_ERROR, LOCATION, NULL, "libipsec failed send add (%s)\n", ipsec_strerror()); + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return -1; } @@ -1566,6 +1610,8 @@ pk_sendadd(iph2) sa_args.satype, sa_args.spi, sa_args.mode)); } iph2->sa_count = sa_sent; + racoon_free(sa_args.src); + racoon_free(sa_args.dst); return 0; } diff -up ipsec-tools-0.7.1/src/racoon/isakmp.c.dpd-fixes ipsec-tools-0.7.1/src/racoon/isakmp.c --- ipsec-tools-0.7.1/src/racoon/isakmp.c.dpd-fixes 2008-11-10 12:56:46.000000000 +0100 +++ ipsec-tools-0.7.1/src/racoon/isakmp.c 2008-11-10 12:56:46.000000000 +0100 @@ -3255,6 +3255,14 @@ purge_remote(iph1) continue; } +#ifdef ENABLE_NATT + if (extract_port(src) == 0 && extract_port(dst) == 0 && + extract_port(iph1->local) == PORT_ISAKMP && extract_port(iph1->remote) == PORT_ISAKMP) { + set_port(src, PORT_ISAKMP); + set_port(dst, PORT_ISAKMP); + } +#endif + /* * check in/outbound SAs. * Select only SAs where src == local and dst == remote (outgoing)