[redhat-lspp] [PoC PATCH 1/1] Allow racoon to negotiate with the same instance of itself
Joy Latten
latten at austin.ibm.com
Mon Jan 29 20:13:54 UTC 2007
Thanks! I'll apply the patch and run an ipv4 and ipv6 stress test using
racoon to ensure no regression. Maybe I should try stress test over
loopback too. :-)
Regards,
Joy
On Mon, 2007-01-29 at 14:23 -0500, Paul Moore wrote:
> plain text document attachment (localhost-ike)
> This patch allows racoon to negotiate with the same instance of itself. This
> means that IKE negotiations over local addresses, including localhost, are now
> possibile. The only major change in this patch is to include
> side/directionality in the phase-1 and phase-2 SA lookup functions, the other
> changes in this patch are either results of this extra search field or some
> simple logic to pick the correct SA for a negotiation when two SA exist for the
> same IKE cookie pair.
>
> Please be warned that this is a proof of concept patch and has not been
> throughly tested or reviewed. In face, with certain configure flags it may not
> even compile.
>
> ---
> src/racoon/admin.c | 4 +-
> src/racoon/handler.c | 35 ++++++++++++++++----
> src/racoon/handler.h | 15 ++++----
> src/racoon/isakmp.c | 80 +++++++++++++++++++++++++++++++++++++++-------
> src/racoon/isakmp.h | 2 +
> src/racoon/isakmp_inf.c | 6 +--
> src/racoon/isakmp_xauth.c | 2 -
> 7 files changed, 112 insertions(+), 32 deletions(-)
>
> Index: ipsec-tools-0.6.5-6/src/racoon/admin.c
> ===================================================================
> --- ipsec-tools-0.6.5-6.orig/src/racoon/admin.c
> +++ ipsec-tools-0.6.5-6/src/racoon/admin.c
> @@ -289,7 +289,7 @@ admin_process(so2, combuf)
> break;
> }
>
> - if ((iph1 = getph1byaddrwop(src, dst)) == NULL) {
> + if ((iph1 = getph1byaddrwop(src, dst, ANYSIDE)) == NULL) {
> plog(LLV_ERROR, LOCATION, NULL,
> "phase 1 for %s -> %s not found\n", loc, rem);
> } else {
> @@ -322,7 +322,7 @@ admin_process(so2, combuf)
> plog(LLV_INFO, LOCATION, NULL,
> "Flushing all SAs for peer %s\n", rem);
>
> - while ((iph1 = getph1bydstaddrwop(dst)) != NULL) {
> + while ((iph1 = getph1bydstaddrwop(dst, ANYSIDE)) != NULL) {
> if ((loc = strdup(saddrwop2str(iph1->local))) == NULL) {
> plog(LLV_ERROR, LOCATION, NULL,
> "cannot allocate memory\n");
> Index: ipsec-tools-0.6.5-6/src/racoon/handler.c
> ===================================================================
> --- ipsec-tools-0.6.5-6.orig/src/racoon/handler.c
> +++ ipsec-tools-0.6.5-6/src/racoon/handler.c
> @@ -93,14 +93,17 @@ static void sweep_recvdpkt __P((void *))
> extern caddr_t val2str(const char *, size_t);
>
> struct ph1handle *
> -getph1byindex(index)
> +getph1byindex(index, side)
> isakmp_index *index;
> + int side;
> {
> struct ph1handle *p;
>
> LIST_FOREACH(p, &ph1tree, chain) {
> if (p->status == PHASE1ST_EXPIRED)
> continue;
> + if (p->side != side && side != ANYSIDE)
> + continue;
> if (memcmp(&p->index, index, sizeof(*index)) == 0)
> return p;
> }
> @@ -112,14 +115,17 @@ getph1byindex(index)
> * search for isakmp handler by i_ck in index.
> */
> struct ph1handle *
> -getph1byindex0(index)
> +getph1byindex0(index, side)
> isakmp_index *index;
> + int side;
> {
> struct ph1handle *p;
>
> LIST_FOREACH(p, &ph1tree, chain) {
> if (p->status == PHASE1ST_EXPIRED)
> continue;
> + if (p->side != side && side != ANYSIDE)
> + continue;
> if (memcmp(&p->index, index, sizeof(cookie_t)) == 0)
> return p;
> }
> @@ -133,14 +139,17 @@ getph1byindex0(index)
> * with phase 2's destinaion.
> */
> struct ph1handle *
> -getph1byaddr(local, remote)
> +getph1byaddr(local, remote, side)
> struct sockaddr *local, *remote;
> + int side;
> {
> struct ph1handle *p;
>
> LIST_FOREACH(p, &ph1tree, chain) {
> if (p->status == PHASE1ST_EXPIRED)
> continue;
> + if (p->side != side && side != ANYSIDE)
> + continue;
> if (CMPSADDR(local, p->local) == 0
> && CMPSADDR(remote, p->remote) == 0)
> return p;
> @@ -150,14 +159,17 @@ getph1byaddr(local, remote)
> }
>
> struct ph1handle *
> -getph1byaddrwop(local, remote)
> +getph1byaddrwop(local, remote, side)
> struct sockaddr *local, *remote;
> + int side;
> {
> struct ph1handle *p;
>
> LIST_FOREACH(p, &ph1tree, chain) {
> if (p->status == PHASE1ST_EXPIRED)
> continue;
> + if (p->side != side && side != ANYSIDE)
> + continue;
> if (cmpsaddrwop(local, p->local) == 0
> && cmpsaddrwop(remote, p->remote) == 0)
> return p;
> @@ -172,14 +184,17 @@ getph1byaddrwop(local, remote)
> * with phase 2's destinaion.
> */
> struct ph1handle *
> -getph1bydstaddrwop(remote)
> +getph1bydstaddrwop(remote, side)
> struct sockaddr *remote;
> + int side;
> {
> struct ph1handle *p;
>
> LIST_FOREACH(p, &ph1tree, chain) {
> if (p->status == PHASE1ST_EXPIRED)
> continue;
> + if (p->side != side && side != ANYSIDE)
> + continue;
> if (cmpsaddrwop(remote, p->remote) == 0)
> return p;
> }
> @@ -444,13 +459,16 @@ getph2byseq(seq)
> * search ph2handle with message id.
> */
> struct ph2handle *
> -getph2bymsgid(iph1, msgid)
> +getph2bymsgid(iph1, msgid, side)
> struct ph1handle *iph1;
> u_int32_t msgid;
> + int side;
> {
> struct ph2handle *p;
>
> LIST_FOREACH(p, &ph2tree, chain) {
> + if (p->side != side && side != ANYSIDE)
> + continue;
> if (p->msgid == msgid)
> return p;
> }
> @@ -476,12 +494,15 @@ getph2byid(src, dst, spid)
> }
>
> struct ph2handle *
> -getph2bysaddr(src, dst)
> +getph2bysaddr(src, dst, side)
> struct sockaddr *src, *dst;
> + int side;
> {
> struct ph2handle *p;
>
> LIST_FOREACH(p, &ph2tree, chain) {
> + if (p->side != side && side != ANYSIDE)
> + continue;
> if (cmpsaddrstrict(src, p->src) == 0 &&
> cmpsaddrstrict(dst, p->dst) == 0)
> return p;
> Index: ipsec-tools-0.6.5-6/src/racoon/handler.h
> ===================================================================
> --- ipsec-tools-0.6.5-6.orig/src/racoon/handler.h
> +++ ipsec-tools-0.6.5-6/src/racoon/handler.h
> @@ -417,13 +417,13 @@ struct ph1handle;
> struct ph2handle;
> struct policyindex;
>
> -extern struct ph1handle *getph1byindex __P((isakmp_index *));
> -extern struct ph1handle *getph1byindex0 __P((isakmp_index *));
> +extern struct ph1handle *getph1byindex __P((isakmp_index *, int));
> +extern struct ph1handle *getph1byindex0 __P((isakmp_index *, int));
> extern struct ph1handle *getph1byaddr __P((struct sockaddr *,
> - struct sockaddr *));
> + struct sockaddr *, int));
> extern struct ph1handle *getph1byaddrwop __P((struct sockaddr *,
> - struct sockaddr *));
> -extern struct ph1handle *getph1bydstaddrwop __P((struct sockaddr *));
> + struct sockaddr *, int));
> +extern struct ph1handle *getph1bydstaddrwop __P((struct sockaddr *, int));
> extern vchar_t *dumpph1 __P((void));
> extern struct ph1handle *newph1 __P((void));
> extern void delph1 __P((struct ph1handle *));
> @@ -436,8 +436,9 @@ extern struct ph2handle *getph2byspidx _
> extern struct ph2handle *getph2byspid __P((u_int32_t));
> extern struct ph2handle *getph2byseq __P((u_int32_t));
> extern struct ph2handle *getph2bysaddr __P((struct sockaddr *,
> - struct sockaddr *));
> -extern struct ph2handle *getph2bymsgid __P((struct ph1handle *, u_int32_t));
> + struct sockaddr *, int));
> +extern struct ph2handle *getph2bymsgid __P((struct ph1handle *, u_int32_t,
> + int));
> extern struct ph2handle *getph2byid __P((struct sockaddr *,
> struct sockaddr *, u_int32_t));
> extern struct ph2handle *getph2bysaidx __P((struct sockaddr *,
> Index: ipsec-tools-0.6.5-6/src/racoon/isakmp.c
> ===================================================================
> --- ipsec-tools-0.6.5-6.orig/src/racoon/isakmp.c
> +++ ipsec-tools-0.6.5-6/src/racoon/isakmp.c
> @@ -369,6 +369,34 @@ end:
> }
>
> /*
> + * isakmp phase 1 search helper
> + */
> +static struct ph1handle *
> +isakmp_ph1pickside(iph1_i, iph1_r, local)
> + struct ph1handle *iph1_i, *iph1_r;
> + struct sockaddr *local;
> +{
> + if (iph1_i == NULL && iph1_r != NULL) {
> + if (cmpsaddrstrict(iph1_r->remote, local) != 0)
> + return iph1_r;
> + else
> + return NULL;
> + } else if (iph1_i != NULL && iph1_r == NULL) {
> + if (cmpsaddrstrict(iph1_i->remote, local) != 0)
> + return iph1_i;
> + else
> + return NULL;
> + } else if (iph1_i != NULL && iph1_r != NULL) {
> + if (iph1_r->status < iph1_i->status)
> + return iph1_r;
> + else
> + return iph1_i;
> + }
> +
> + return NULL;
> +}
> +
> +/*
> * main processing to handle isakmp payload
> */
> static int
> @@ -434,7 +462,9 @@ isakmp_main(msg, remote, local)
> }
> }
>
> - iph1 = getph1byindex(index);
> + iph1 = isakmp_ph1pickside(getph1byindex(index, INITIATOR),
> + getph1byindex(index, RESPONDER),
> + local);
> if (iph1 != NULL) {
> /* validity check */
> if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 &&
> @@ -516,7 +546,10 @@ isakmp_main(msg, remote, local)
> */
>
> /* search for phase1 handle by index without r_ck */
> - iph1 = getph1byindex0(index);
> + iph1 = isakmp_ph1pickside(
> + getph1byindex0(index, INITIATOR),
> + getph1byindex0(index, RESPONDER),
> + local);
> if (iph1 == NULL) {
> /*it must be the 1st message from a initiator.*/
> if (memcmp(&isakmp->r_ck, r_ck0,
> @@ -592,7 +625,7 @@ isakmp_main(msg, remote, local)
> * NOTE: We think such informational exchange should be ignored.
> */
> if (iph1 == NULL) {
> - iph1 = getph1byindex0(index);
> + iph1 = getph1byindex0(index, INITIATOR);
> if (iph1 == NULL) {
> plog(LLV_ERROR, LOCATION, remote,
> "unknown Informational "
> @@ -619,6 +652,7 @@ isakmp_main(msg, remote, local)
> case ISAKMP_ETYPE_QUICK:
> {
> struct ph2handle *iph2;
> + struct ph2handle *iph2_i, *iph2_r;
>
> if (iph1 == NULL) {
> isakmp_info_send_nx(isakmp, remote, local,
> @@ -646,7 +680,25 @@ isakmp_main(msg, remote, local)
> }
>
> /* search isakmp phase 2 stauts record. */
> - iph2 = getph2bymsgid(iph1, msgid);
> + iph2_i = getph2bymsgid(iph1, msgid, INITIATOR);
> + iph2_r = getph2bymsgid(iph1, msgid, RESPONDER);
> + if (iph2_i == NULL && iph2_r != NULL) {
> + if (cmpsaddrstrict(iph1->remote, local) != 0)
> + iph2 = iph2_r;
> + else
> + iph2 = NULL;
> + } else if (iph2_i != NULL && iph2_r == NULL) {
> + if (cmpsaddrstrict(iph1->remote, local) != 0)
> + iph2 = iph2_i;
> + else
> + iph2 = NULL;
> + } else if (iph2_i != NULL && iph2_r != NULL) {
> + if (iph2_r->status < iph2_i->status)
> + iph2 = iph2_r;
> + else
> + iph2 = iph2_i;
> + } else
> + iph2 = NULL;
> if (iph2 == NULL) {
> /* it must be new negotiation as responder */
> if (isakmp_ph2begin_r(iph1, msg) < 0)
> @@ -2041,15 +2093,17 @@ isakmp_post_acquire(iph2)
> */
> #ifdef ENABLE_NATT
> if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
> - if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) {
> + if ((iph1 = getph1byaddrwop(iph2->src,
> + iph2->dst,
> + ANYSIDE)) != NULL) {
> set_port(iph2->src, extract_port(iph1->local));
> set_port(iph2->dst, extract_port(iph1->remote));
> }
> } else {
> - iph1 = getph1byaddr(iph2->src, iph2->dst);
> + iph1 = getph1byaddr(iph2->src, iph2->dst, ANYSIDE);
> }
> #else
> - iph1 = getph1byaddr(iph2->src, iph2->dst);
> + iph1 = getph1byaddr(iph2->src, iph2->dst, ANYSIDE);
> #endif
>
> /* no ISAKMP-SA found. */
> @@ -2175,15 +2229,17 @@ isakmp_chkph1there(iph2)
> */
> #ifdef ENABLE_NATT
> if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
> - if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) {
> + if ((iph1 = getph1byaddrwop(iph2->src,
> + iph2->dst,
> + ANYSIDE)) != NULL) {
> set_port(iph2->src, extract_port(iph1->local));
> set_port(iph2->dst, extract_port(iph1->remote));
> }
> } else {
> - iph1 = getph1byaddr(iph2->src, iph2->dst);
> + iph1 = getph1byaddr(iph2->src, iph2->dst, ANYSIDE);
> }
> #else
> - iph1 = getph1byaddr(iph2->src, iph2->dst);
> + iph1 = getph1byaddr(iph2->src, iph2->dst, ANYSIDE);
> #endif
>
> /* XXX Even if ph1 as responder is there, should we not start
> @@ -2432,7 +2488,7 @@ isakmp_newmsgid2(iph1)
>
> do {
> msgid2 = eay_random();
> - } while (getph2bymsgid(iph1, msgid2));
> + } while (getph2bymsgid(iph1, msgid2, iph1->side));
>
> return msgid2;
> }
> @@ -3094,7 +3150,7 @@ purge_remote(iph1)
> iph1->status = PHASE1ST_EXPIRED;
>
> /* Check if we have another, still valid, phase1 SA. */
> - new_iph1 = getph1byaddr(iph1->local, iph1->remote);
> + new_iph1 = getph1byaddr(iph1->local, iph1->remote, ANYSIDE);
>
> /*
> * Delete all orphaned or binded to the deleting ph1handle phase2 SAs.
> Index: ipsec-tools-0.6.5-6/src/racoon/isakmp.h
> ===================================================================
> --- ipsec-tools-0.6.5-6.orig/src/racoon/isakmp.h
> +++ ipsec-tools-0.6.5-6/src/racoon/isakmp.h
> @@ -37,6 +37,8 @@
> /* must include <netinet/in.h> first. */
> /* must include "isakmp_var.h" first. */
>
> +#define ANYSIDE -1 /* either INITIATOR or RESPONDER */
> +
> #define INITIATOR 0 /* synonym sender */
> #define RESPONDER 1 /* synonym receiver */
>
> Index: ipsec-tools-0.6.5-6/src/racoon/isakmp_inf.c
> ===================================================================
> --- ipsec-tools-0.6.5-6.orig/src/racoon/isakmp_inf.c
> +++ ipsec-tools-0.6.5-6/src/racoon/isakmp_inf.c
> @@ -363,7 +363,7 @@ isakmp_info_send_d2(iph2)
> * don't send delete information if there is no phase 1 handler.
> * It's nonsensical to negotiate phase 1 to send the information.
> */
> - iph1 = getph1byaddr(iph2->src, iph2->dst);
> + iph1 = getph1byaddr(iph2->src, iph2->dst, ANYSIDE);
> if (iph1 == NULL)
> return 0;
>
> @@ -892,7 +892,7 @@ isakmp_info_recv_n(iph1, msg)
> "delete phase1 handle.\n");
> return -1;
> } else {
> - iph2 = getph2bymsgid(iph1, msgid);
> + iph2 = getph2bymsgid(iph1, msgid, iph1->side);
> if (iph2 == NULL) {
> plog(LLV_ERROR, LOCATION, iph1->remote,
> "unknown notify message, "
> @@ -937,7 +937,7 @@ purge_isakmp_spi(proto, spi, n)
> size_t i;
>
> for (i = 0; i < n; i++) {
> - iph1 = getph1byindex(&spi[i]);
> + iph1 = getph1byindex(&spi[i], ANYSIDE);
> if (!iph1)
> continue;
>
> Index: ipsec-tools-0.6.5-6/src/racoon/isakmp_xauth.c
> ===================================================================
> --- ipsec-tools-0.6.5-6.orig/src/racoon/isakmp_xauth.c
> +++ ipsec-tools-0.6.5-6/src/racoon/isakmp_xauth.c
> @@ -338,7 +338,7 @@ xauth_reply_stub(args)
> struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
> struct ph1handle *iph1;
>
> - if ((iph1 = getph1byindex(&xra->index)) != NULL)
> + if ((iph1 = getph1byindex(&xra->index, ANYSIDE)) != NULL)
> xauth_reply(iph1, xra->port, xra->id, xra->res);
> else
> plog(LLV_ERROR, LOCATION, NULL,
>
> --
> paul moore
> linux security @ hp
>
> --
> redhat-lspp mailing list
> redhat-lspp at redhat.com
> https://www.redhat.com/mailman/listinfo/redhat-lspp
More information about the redhat-lspp
mailing list