From 067ce84045064bf0a10d78432d04171d62364789 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 28 Mar 2010 16:58:17 +0000 Subject: [PATCH] [package] add GRE support to ipsec-tools, so that opennhrp can work (#6926) git-svn-id: svn://svn.openwrt.org/openwrt/packages@20544 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- net/ipsec-tools/Makefile | 2 +- net/ipsec-tools/patches/004-opennhrp.patch | 1659 ++++++++++++++++++++++++++++ 2 files changed, 1660 insertions(+), 1 deletion(-) create mode 100644 net/ipsec-tools/patches/004-opennhrp.patch diff --git a/net/ipsec-tools/Makefile b/net/ipsec-tools/Makefile index 7b0577e9a..4aff93e8f 100644 --- a/net/ipsec-tools/Makefile +++ b/net/ipsec-tools/Makefile @@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=ipsec-tools PKG_VERSION:=0.7.3 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=@SF/ipsec-tools diff --git a/net/ipsec-tools/patches/004-opennhrp.patch b/net/ipsec-tools/patches/004-opennhrp.patch new file mode 100644 index 000000000..aa76f9fbb --- /dev/null +++ b/net/ipsec-tools/patches/004-opennhrp.patch @@ -0,0 +1,1659 @@ +Index: ipsec-tools-0.7.3/src/racoon/admin.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/admin.c 2009-04-20 15:32:57.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/admin.c 2010-03-28 17:07:57.000000000 +0200 +@@ -76,6 +76,7 @@ + #include "evt.h" + #include "pfkey.h" + #include "ipsec_doi.h" ++#include "policy.h" + #include "admin.h" + #include "admin_var.h" + #include "isakmp_inf.h" +@@ -147,16 +148,18 @@ + goto end; + } + +- if (com.ac_cmd == ADMIN_RELOAD_CONF) { +- /* reload does not work at all! */ +- signal_handler(SIGHUP); +- goto end; +- } ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "[%d] admin connection established\n", so2); + + error = admin_process(so2, combuf); + +- end: +- (void)close(so2); ++end: ++ if (error != -2) { ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "[%d] admin connection closed\n", so2); ++ (void)close(so2); ++ } ++ + if (combuf) + racoon_free(combuf); + +@@ -177,6 +180,8 @@ + vchar_t *key = NULL; + int idtype = 0; + int error = -1; ++ int send_events = 0; ++ struct evt_listener_list *event_list = NULL; + + com->ac_errno = 0; + +@@ -208,9 +213,7 @@ + } + + case ADMIN_SHOW_EVT: +- /* It's not really an error, don't force racoonctl to quit */ +- if ((buf = evt_dump()) == NULL) +- com->ac_errno = 0; ++ send_events = 1; + break; + + case ADMIN_SHOW_SA: +@@ -393,17 +396,17 @@ + /* FALLTHROUGH */ + case ADMIN_ESTABLISH_SA: + { ++ struct admin_com_indexes *ndx; + struct sockaddr *dst; + struct sockaddr *src; +- src = (struct sockaddr *) +- &((struct admin_com_indexes *) +- ((caddr_t)com + sizeof(*com)))->src; +- dst = (struct sockaddr *) +- &((struct admin_com_indexes *) +- ((caddr_t)com + sizeof(*com)))->dst; ++ ++ ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)); ++ src = (struct sockaddr *) &ndx->src; ++ dst = (struct sockaddr *) &ndx->dst; + + switch (com->ac_proto) { + case ADMIN_PROTO_ISAKMP: { ++ struct ph1handle *ph1; + struct remoteconf *rmconf; + struct sockaddr *remote = NULL; + struct sockaddr *local = NULL; +@@ -411,6 +414,17 @@ + + com->ac_errno = -1; + ++ /* connected already? */ ++ ph1 = getph1byaddrwop(src, dst); ++ if (ph1 != NULL) { ++ event_list = &ph1->evt_listeners; ++ if (ph1->status == PHASE1ST_ESTABLISHED) ++ com->ac_errno = EEXIST; ++ else ++ com->ac_errno = 0; ++ break; ++ } ++ + /* search appropreate configuration */ + rmconf = getrmconf(dst); + if (rmconf == NULL) { +@@ -461,9 +475,11 @@ + "%s\n", saddrwop2str(remote)); + + /* begin ident mode */ +- if (isakmp_ph1begin_i(rmconf, remote, local) < 0) ++ ph1 = isakmp_ph1begin_i(rmconf, remote, local); ++ if (ph1 == NULL) + goto out1; + ++ event_list = &ph1->evt_listeners; + com->ac_errno = 0; + out1: + if (local != NULL) +@@ -473,8 +489,105 @@ + break; + } + case ADMIN_PROTO_AH: +- case ADMIN_PROTO_ESP: ++ case ADMIN_PROTO_ESP: { ++ struct ph2handle *iph2; ++ struct secpolicy *sp_out = NULL, *sp_in = NULL; ++ struct policyindex spidx; ++ ++ com->ac_errno = -1; ++ ++ /* got outbound policy */ ++ memset(&spidx, 0, sizeof(spidx)); ++ spidx.dir = IPSEC_DIR_OUTBOUND; ++ memcpy(&spidx.src, src, sizeof(spidx.src)); ++ memcpy(&spidx.dst, dst, sizeof(spidx.dst)); ++ spidx.prefs = ndx->prefs; ++ spidx.prefd = ndx->prefd; ++ spidx.ul_proto = ndx->ul_proto; ++ ++ sp_out = getsp_r(&spidx); ++ if (sp_out) { ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "suitable outbound SP found: %s.\n", ++ spidx2str(&sp_out->spidx)); ++ } else { ++ com->ac_errno = ENOENT; ++ plog(LLV_NOTIFY, LOCATION, NULL, ++ "no outbound policy found: %s\n", ++ spidx2str(&spidx)); ++ break; ++ } ++ ++ iph2 = getph2byid(src, dst, sp_out->id); ++ if (iph2 != NULL) { ++ event_list = &iph2->evt_listeners; ++ if (iph2->status == PHASE2ST_ESTABLISHED) ++ com->ac_errno = EEXIST; ++ else ++ com->ac_errno = 0; ++ break; ++ } ++ ++ /* get inbound policy */ ++ memset(&spidx, 0, sizeof(spidx)); ++ spidx.dir = IPSEC_DIR_INBOUND; ++ memcpy(&spidx.src, dst, sizeof(spidx.src)); ++ memcpy(&spidx.dst, src, sizeof(spidx.dst)); ++ spidx.prefs = ndx->prefd; ++ spidx.prefd = ndx->prefs; ++ spidx.ul_proto = ndx->ul_proto; ++ ++ sp_in = getsp_r(&spidx); ++ if (sp_in) { ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "suitable inbound SP found: %s.\n", ++ spidx2str(&sp_in->spidx)); ++ } else { ++ com->ac_errno = ENOENT; ++ plog(LLV_NOTIFY, LOCATION, NULL, ++ "no inbound policy found: %s\n", ++ spidx2str(&spidx)); ++ break; ++ } ++ ++ /* allocate a phase 2 */ ++ iph2 = newph2(); ++ if (iph2 == NULL) { ++ plog(LLV_ERROR, LOCATION, NULL, ++ "failed to allocate phase2 entry.\n"); ++ break; ++ } ++ iph2->side = INITIATOR; ++ iph2->satype = admin2pfkey_proto(com->ac_proto); ++ iph2->spid = sp_out->id; ++ iph2->seq = pk_getseq(); ++ iph2->status = PHASE2ST_STATUS2; ++ ++ /* set end addresses of SA */ ++ iph2->dst = dupsaddr(dst); ++ iph2->src = dupsaddr(src); ++ if (iph2->dst == NULL || iph2->src == NULL) { ++ delph2(iph2); ++ break; ++ } ++ ++ if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) { ++ delph2(iph2); ++ break; ++ } ++ ++ insph2(iph2); ++ if (isakmp_post_acquire(iph2) < 0) { ++ unbindph12(iph2); ++ remph2(iph2); ++ delph2(iph2); ++ break; ++ } ++ ++ event_list = &iph2->evt_listeners; ++ com->ac_errno = 0; + break; ++ } + default: + /* ignore */ + com->ac_errno = -1; +@@ -491,7 +604,8 @@ + if ((error = admin_reply(so2, com, buf)) != 0) + goto out; + +- error = 0; ++ if (send_events || event_list != NULL) ++ error = evt_subscribe(event_list, so2); + out: + if (buf != NULL) + vfree(buf); +Index: ipsec-tools-0.7.3/src/racoon/evt.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/evt.c 2006-09-09 18:22:09.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/evt.c 2010-03-28 17:07:57.000000000 +0200 +@@ -46,113 +46,219 @@ + #include "plog.h" + #include "misc.h" + #include "admin.h" ++#include "handler.h" + #include "gcmalloc.h" + #include "evt.h" + + #ifdef ENABLE_ADMINPORT +-struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist); +-int evtlist_len = 0; ++static EVT_LISTENER_LIST(evt_listeners); ++static EVT_LISTENER_LIST(evt_fds); + +-void +-evt_push(src, dst, type, optdata) +- struct sockaddr *src; +- struct sockaddr *dst; ++struct evtdump { ++ struct admin_com adm; ++ struct evt_common evt; ++}; ++ ++static struct evtdump * ++evtdump_create(type, optdata) + int type; + vchar_t *optdata; + { +- struct evtdump *evtdump; +- struct evt *evt; ++ struct evtdump *e; + size_t len; + +- /* If admin socket is disabled, silently discard anything */ +- if (adminsock_path == NULL) ++ len = sizeof(struct admin_com) + sizeof(struct evt_common); ++ if (optdata != NULL) ++ len += optdata->l; ++ ++ if ((e = racoon_malloc(len)) == NULL) { ++ plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate event: %s\n", ++ strerror(errno)); ++ return NULL; ++ } ++ ++ memset(e, 0, sizeof(struct evtdump)); ++ e->adm.ac_len = len; ++ e->adm.ac_cmd = ADMIN_SHOW_EVT; ++ e->adm.ac_errno = 0; ++ e->adm.ac_proto = 0; ++ e->evt.ec_type = type; ++ time(&e->evt.ec_timestamp); ++ if (optdata != NULL) ++ memcpy(e + 1, optdata->v, optdata->l); ++ ++ return e; ++} ++ ++static void ++evt_unsubscribe(l) ++ struct evt_listener *l; ++{ ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "[%d] admin connection released\n", l->fd); ++ ++ LIST_REMOVE(l, ll_chain); ++ LIST_REMOVE(l, fd_chain); ++ close(l->fd); ++ racoon_free(l); ++} ++ ++static void ++evtdump_broadcast(ll, e) ++ const struct evt_listener_list *ll; ++ struct evtdump *e; ++{ ++ struct evt_listener *l, *nl; ++ ++ for (l = LIST_FIRST(ll); l != NULL; l = nl) { ++ nl = LIST_NEXT(l, ll_chain); ++ ++ if (send(l->fd, e, e->adm.ac_len, ++ MSG_NOSIGNAL | MSG_DONTWAIT) < 0) { ++ plog(LLV_DEBUG, LOCATION, NULL, "Cannot send event to fd: %s\n", ++ strerror(errno)); ++ evt_unsubscribe(l); ++ } ++ ++ } ++ ++} ++ ++void ++evt_generic(type, optdata) ++ int type; ++ vchar_t *optdata; ++{ ++ struct evtdump *e; ++ ++ ++ if ((e = evtdump_create(type, optdata)) == NULL) + return; + +- /* If we are above the limit, don't record anything */ +- if (evtlist_len > EVTLIST_MAX) { +- plog(LLV_DEBUG, LOCATION, NULL, +- "Cannot record event: event queue overflowed\n"); ++ evtdump_broadcast(&evt_listeners, e); ++ ++ racoon_free(e); ++} ++ ++void ++evt_phase1(ph1, type, optdata) ++ const struct ph1handle *ph1; ++ int type; ++ vchar_t *optdata; ++{ ++ struct evtdump *e; ++ ++ if ((e = evtdump_create(type, optdata)) == NULL) ++ return; ++ ++ if (ph1->local) ++ memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local)); ++ if (ph1->remote) ++ memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote)); ++ ++ evtdump_broadcast(&ph1->evt_listeners, e); ++ evtdump_broadcast(&evt_listeners, e); ++ ++ racoon_free(e); ++ } ++ ++void ++evt_phase2(ph2, type, optdata) ++ const struct ph2handle *ph2; ++ int type; ++ vchar_t *optdata; ++{ ++ struct evtdump *e; ++ struct ph1handle *ph1 = ph2->ph1; ++ ++ if ((e = evtdump_create(type, optdata)) == NULL) + return; ++ ++ if (ph1) { ++ if (ph1->local) ++ memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local)); ++ if (ph1->remote) ++ memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote)); + } ++ e->evt.ec_ph2msgid = ph2->msgid; + +- /* If we hit the limit, record an overflow event instead */ +- if (evtlist_len == EVTLIST_MAX) { +- plog(LLV_ERROR, LOCATION, NULL, +- "Cannot record event: event queue overflow\n"); +- src = NULL; +- dst = NULL; +- type = EVTT_OVERFLOW; +- optdata = NULL; +- } +- +- len = sizeof(*evtdump); +- if (optdata) +- len += optdata->l; +- +- if ((evtdump = racoon_malloc(len)) == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n", +- strerror(errno)); +- return; ++ evtdump_broadcast(&ph2->evt_listeners, e); ++ if (ph1) ++ evtdump_broadcast(&ph1->evt_listeners, e); ++ evtdump_broadcast(&evt_listeners, e); ++ ++ racoon_free(e); + } + +- if ((evt = racoon_malloc(sizeof(*evt))) == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n", +- strerror(errno)); +- racoon_free(evtdump); +- return; ++int ++evt_subscribe(list, fd) ++ struct evt_listener_list *list; ++ int fd; ++{ ++ struct evt_listener *l; ++ ++ if ((l = racoon_malloc(sizeof(*l))) == NULL) { ++ plog(LLV_ERROR, LOCATION, NULL, ++ "Cannot allocate event listener: %s\n", ++ strerror(errno)); ++ return errno; + } + +- if (src) +- memcpy(&evtdump->src, src, sysdep_sa_len(src)); +- if (dst) +- memcpy(&evtdump->dst, dst, sysdep_sa_len(dst)); +- evtdump->len = len; +- evtdump->type = type; +- time(&evtdump->timestamp); ++ if (list == NULL) ++ list = &evt_listeners; + +- if (optdata) +- memcpy(evtdump + 1, optdata->v, optdata->l); ++ LIST_INSERT_HEAD(list, l, ll_chain); ++ LIST_INSERT_HEAD(&evt_fds, l, fd_chain); ++ l->fd = fd; + +- evt->dump = evtdump; +- TAILQ_INSERT_TAIL(&evtlist, evt, next); ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "[%d] admin connection is polling events\n", fd); + +- evtlist_len++; ++ return -2; ++} + +- return; ++void ++evt_list_init(list) ++ struct evt_listener_list *list; ++{ ++ LIST_INIT(list); + } + +-struct evtdump * +-evt_pop(void) { +- struct evtdump *evtdump; +- struct evt *evt; + +- if ((evt = TAILQ_FIRST(&evtlist)) == NULL) +- return NULL; ++void ++evt_list_cleanup(list) ++ struct evt_listener_list *list; ++{ ++ while (!LIST_EMPTY(list)) ++ evt_unsubscribe(LIST_FIRST(list)); ++} + +- evtdump = evt->dump; +- TAILQ_REMOVE(&evtlist, evt, next); +- racoon_free(evt); +- evtlist_len--; +- +- return evtdump; +-} +- +-vchar_t * +-evt_dump(void) { +- struct evtdump *evtdump; +- vchar_t *buf = NULL; +- +- if ((evtdump = evt_pop()) != NULL) { +- if ((buf = vmalloc(evtdump->len)) == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "evt_dump failed: %s\n", strerror(errno)); +- return NULL; +- } +- memcpy(buf->v, evtdump, evtdump->len); +- racoon_free(evtdump); ++int ++evt_get_fdmask(nfds, fdset) ++ int nfds; ++ fd_set *fdset; ++{ ++ struct evt_listener *l; ++ LIST_FOREACH(l, &evt_fds, fd_chain) { ++ FD_SET(l->fd, fdset); ++ if (l->fd + 1 > nfds) ++ nfds = l->fd + 1; + } ++ return nfds; ++} + +- return buf; ++void ++evt_handle_fdmask(fdset) ++ fd_set *fdset; ++{ ++ struct evt_listener *l, *nl; ++ ++ for (l = LIST_FIRST(&evt_fds); l != NULL; l = nl) { ++ nl = LIST_NEXT(l, ll_chain); ++ ++ if (FD_ISSET(l->fd, fdset)) ++ evt_unsubscribe(l); ++ } + } + + #endif /* ENABLE_ADMINPORT */ +Index: ipsec-tools-0.7.3/src/racoon/evt.h +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/evt.h 2006-09-09 18:22:09.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/evt.h 2010-03-28 17:07:57.000000000 +0200 +@@ -34,12 +34,27 @@ + #ifndef _EVT_H + #define _EVT_H + +-struct evtdump { +- size_t len; +- struct sockaddr_storage src; +- struct sockaddr_storage dst; +- time_t timestamp; +- int type; ++#ifdef ENABLE_ADMINPORT ++ ++struct evt_listener { ++ LIST_ENTRY(evt_listener) ll_chain; ++ LIST_ENTRY(evt_listener) fd_chain; ++ int fd; ++}; ++LIST_HEAD(evt_listener_list, evt_listener); ++#define EVT_LISTENER_LIST(x) struct evt_listener_list x; ++ ++struct ph1handle; ++struct ph2handle; ++ ++struct evt_common { ++ uint32_t ec_type; ++ time_t ec_timestamp; ++ ++ struct sockaddr_storage ec_ph1src; ++ struct sockaddr_storage ec_ph1dst; ++ u_int32_t ec_ph2msgid; ++ + /* + * Optionnal list of struct isakmp_data + * for type EVTT_ISAKMP_CFG_DONE +@@ -47,42 +62,46 @@ + }; + + /* type */ +-#define EVTT_UNSEPC 0 +-#define EVTT_PHASE1_UP 1 +-#define EVTT_PHASE1_DOWN 2 +-#define EVTT_XAUTH_SUCCESS 3 +-#define EVTT_ISAKMP_CFG_DONE 4 +-#define EVTT_PHASE2_UP 5 +-#define EVTT_PHASE2_DOWN 6 +-#define EVTT_DPD_TIMEOUT 7 +-#define EVTT_PEER_NO_RESPONSE 8 +-#define EVTT_PEER_DELETE 9 +-#define EVTT_RACOON_QUIT 10 +-#define EVTT_XAUTH_FAILED 11 +-#define EVTT_OVERFLOW 12 /* Event queue overflowed */ +-#define EVTT_PEERPH1AUTH_FAILED 13 +-#define EVTT_PEERPH1_NOPROP 14 /* NO_PROPOSAL_CHOSEN & friends */ +-#define EVTT_NO_ISAKMP_CFG 15 /* no need to wait for mode_cfg */ +- +-struct evt { +- struct evtdump *dump; +- TAILQ_ENTRY(evt) next; +-}; +- +-TAILQ_HEAD(evtlist, evt); +- +-#define EVTLIST_MAX 32 ++#define EVTT_RACOON_QUIT 0x0001 ++#define EVTT_PHASE1_UP 0x0100 ++#define EVTT_PHASE1_DOWN 0x0101 ++#define EVTT_PHASE1_NO_RESPONSE 0x0102 ++#define EVTT_PHASE1_NO_PROPOSAL 0x0103 ++#define EVTT_PHASE1_AUTH_FAILED 0x0104 ++#define EVTT_PHASE1_DPD_TIMEOUT 0x0105 ++#define EVTT_PHASE1_PEER_DELETED 0x0106 ++#define EVTT_PHASE1_MODE_CFG 0x0107 ++#define EVTT_PHASE1_XAUTH_SUCCESS 0x0108 ++#define EVTT_PHASE1_XAUTH_FAILED 0x0109 ++ ++#define EVTT_PHASE2_NO_PHASE1 0x0200 ++#define EVTT_PHASE2_UP 0x0201 ++#define EVTT_PHASE2_DOWN 0x0202 ++#define EVTT_PHASE2_NO_RESPONSE 0x0203 ++ ++void evt_generic __P((int type, vchar_t *optdata)); ++void evt_phase1 __P((const struct ph1handle *ph1, int type, vchar_t *optdata)); ++void evt_phase2 __P((const struct ph2handle *ph2, int type, vchar_t *optdata)); ++ ++int evt_subscribe __P((struct evt_listener_list *list, int fd)); ++void evt_list_init __P((struct evt_listener_list *list)); ++void evt_list_cleanup __P((struct evt_listener_list *list)); ++int evt_get_fdmask __P((int nfds, fd_set *fdset)); ++void evt_handle_fdmask __P((fd_set *fdset)); ++ ++#else + +-#ifdef ENABLE_ADMINPORT +-struct evtdump *evt_pop(void); +-vchar_t *evt_dump(void); +-void evt_push(struct sockaddr *, struct sockaddr *, int, vchar_t *); +-#endif ++#define EVT_LISTENER_LIST(x) ++#define evt_generic(type, optdata) ; ++#define evt_phase1(ph1, type, optdata) ; ++#define evt_phase2(ph2, type, optdata) ; ++ ++#define evt_subscribe(eventlist, fd) ; ++#define evt_list_init(eventlist) ; ++#define evt_list_cleanup(eventlist) ; ++#define evt_get_fdmask(nfds, fdset) nfds ++#define evt_handle_fdmask(fdset) ; + +-#ifdef ENABLE_ADMINPORT +-#define EVT_PUSH(src, dst, type, optdata) evt_push(src, dst, type, optdata); +-#else +-#define EVT_PUSH(src, dst, type, optdata) ; +-#endif ++#endif /* ENABLE_ADMINPORT */ + + #endif /* _EVT_H */ +Index: ipsec-tools-0.7.3/src/racoon/handler.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/handler.c 2009-04-20 15:25:27.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/handler.c 2010-03-28 17:07:57.000000000 +0200 +@@ -289,8 +289,7 @@ + + /* SA down shell script hook */ + script_hook(iph1, SCRIPT_PHASE1_DOWN); +- +- EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL); ++ evt_list_cleanup(&iph1->evt_listeners); + + #ifdef ENABLE_NATT + if (iph1->natt_flags & NAT_KA_QUEUED) +Index: ipsec-tools-0.7.3/src/racoon/handler.h +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/handler.h 2008-01-11 15:12:01.000000000 +0100 ++++ ipsec-tools-0.7.3/src/racoon/handler.h 2010-03-28 17:07:57.000000000 +0200 +@@ -41,6 +41,7 @@ + + #include "isakmp_var.h" + #include "oakley.h" ++#include "evt.h" + + /* Phase 1 handler */ + /* +@@ -211,7 +212,7 @@ + #ifdef ENABLE_HYBRID + struct isakmp_cfg_state *mode_cfg; /* ISAKMP mode config state */ + #endif +- ++ EVT_LISTENER_LIST(evt_listeners); + }; + + /* Phase 2 handler */ +@@ -320,6 +321,7 @@ + + LIST_ENTRY(ph2handle) chain; + LIST_ENTRY(ph2handle) ph1bind; /* chain to ph1handle */ ++ EVT_LISTENER_LIST(evt_listeners); + }; + + /* +Index: ipsec-tools-0.7.3/src/racoon/isakmp_agg.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_agg.c 2006-09-30 23:49:37.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/isakmp_agg.c 2010-03-28 17:07:57.000000000 +0200 +@@ -587,8 +587,7 @@ + /* message printed inner oakley_validate_auth() */ + goto end; + } +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEERPH1AUTH_FAILED, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } +@@ -1486,8 +1485,7 @@ + /* message printed inner oakley_validate_auth() */ + goto end; + } +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEERPH1AUTH_FAILED, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } +Index: ipsec-tools-0.7.3/src/racoon/isakmp_base.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_base.c 2006-10-02 23:51:33.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/isakmp_base.c 2010-03-28 17:07:57.000000000 +0200 +@@ -716,8 +716,7 @@ + /* message printed inner oakley_validate_auth() */ + goto end; + } +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEERPH1AUTH_FAILED, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } +@@ -1242,8 +1241,7 @@ + /* message printed inner oakley_validate_auth() */ + goto end; + } +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEERPH1AUTH_FAILED, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, ptype, NULL); + goto end; + } +Index: ipsec-tools-0.7.3/src/racoon/isakmp.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp.c 2008-09-25 11:34:39.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/isakmp.c 2010-03-28 17:10:11.000000000 +0200 +@@ -88,6 +88,9 @@ + #include "pfkey.h" + #include "crypto_openssl.h" + #include "policy.h" ++#include "algorithm.h" ++#include "proposal.h" ++#include "sainfo.h" + #include "isakmp_ident.h" + #include "isakmp_agg.h" + #include "isakmp_base.h" +@@ -1015,7 +1018,7 @@ + } + + /* new negotiation of phase 1 for initiator */ +-int ++struct ph1handle * + isakmp_ph1begin_i(rmconf, remote, local) + struct remoteconf *rmconf; + struct sockaddr *remote, *local; +@@ -1028,7 +1031,7 @@ + /* get new entry to isakmp status table. */ + iph1 = newph1(); + if (iph1 == NULL) +- return -1; ++ return NULL; + + iph1->status = PHASE1ST_START; + iph1->rmconf = rmconf; +@@ -1043,7 +1046,7 @@ + #ifdef ENABLE_HYBRID + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + delph1(iph1); +- return -1; ++ return NULL; + } + #endif + #ifdef ENABLE_FRAG +@@ -1059,7 +1062,7 @@ + /* XXX copy remote address */ + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + delph1(iph1); +- return -1; ++ return NULL; + } + + (void)insph1(iph1); +@@ -1095,7 +1098,7 @@ + remph1(iph1); + delph1(iph1); + +- return -1; ++ return NULL; + } + + #ifdef ENABLE_STATS +@@ -1106,7 +1109,7 @@ + timedelta(&start, &end)); + #endif + +- return 0; ++ return iph1; + } + + /* new negotiation of phase 1 for responder */ +@@ -1887,8 +1890,7 @@ + plog(LLV_ERROR, LOCATION, NULL, + "phase1 negotiation failed due to time up. %s\n", + isakmp_pindex(&iph1->index, iph1->msgid)); +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEER_NO_RESPONSE, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_NO_RESPONSE, NULL); + + return -1; + } +@@ -1897,8 +1899,7 @@ + plog(LLV_ERROR, LOCATION, NULL, + "phase1 negotiation failed due to send error. %s\n", + isakmp_pindex(&iph1->index, iph1->msgid)); +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEER_NO_RESPONSE, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_NO_RESPONSE, NULL); + return -1; + } + +@@ -1947,7 +1948,7 @@ + plog(LLV_ERROR, LOCATION, NULL, + "phase2 negotiation failed due to time up. %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); +- EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL); ++ evt_phase2(iph2, EVTT_PHASE2_NO_RESPONSE, NULL); + unbindph12(iph2); + return -1; + } +@@ -1956,8 +1957,7 @@ + plog(LLV_ERROR, LOCATION, NULL, + "phase2 negotiation failed due to send error. %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); +- EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL); +- ++ evt_phase2(iph2, EVTT_PHASE2_NO_RESPONSE, NULL); + return -1; + } + +@@ -2048,7 +2048,7 @@ + plog(LLV_INFO, LOCATION, NULL, + "ISAKMP-SA deleted %s-%s spi:%s\n", + src, dst, isakmp_pindex(&iph1->index, 0)); +- EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_DOWN, NULL); + racoon_free(src); + racoon_free(dst); + +@@ -2195,7 +2195,7 @@ + saddrwop2str(iph2->dst)); + + /* start phase 1 negotiation as a initiator. */ +- if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) < 0) { ++ if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) == NULL) { + SCHED_KILL(sc); + return -1; + } +@@ -2228,6 +2228,71 @@ + return 0; + } + ++int ++isakmp_get_sainfo(iph2, sp_out, sp_in) ++ struct ph2handle *iph2; ++ struct secpolicy *sp_out, *sp_in; ++{ ++ int remoteid=0; ++ ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "new acquire %s\n", spidx2str(&sp_out->spidx)); ++ ++ /* get sainfo */ ++ { ++ vchar_t *idsrc, *iddst; ++ ++ idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src, ++ sp_out->spidx.prefs, sp_out->spidx.ul_proto); ++ if (idsrc == NULL) { ++ plog(LLV_ERROR, LOCATION, NULL, ++ "failed to get ID for %s\n", ++ spidx2str(&sp_out->spidx)); ++ return -1; ++ } ++ iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst, ++ sp_out->spidx.prefd, sp_out->spidx.ul_proto); ++ if (iddst == NULL) { ++ plog(LLV_ERROR, LOCATION, NULL, ++ "failed to get ID for %s\n", ++ spidx2str(&sp_out->spidx)); ++ vfree(idsrc); ++ return -1; ++ } ++ { ++ struct remoteconf *conf; ++ conf = getrmconf(iph2->dst); ++ if (conf != NULL) ++ remoteid=conf->ph1id; ++ else{ ++ plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n"); ++ remoteid=0; ++ } ++ } ++ iph2->sainfo = getsainfo(idsrc, iddst, NULL, remoteid); ++ vfree(idsrc); ++ vfree(iddst); ++ if (iph2->sainfo == NULL) { ++ plog(LLV_ERROR, LOCATION, NULL, ++ "failed to get sainfo.\n"); ++ return -1; ++ /* XXX should use the algorithm list from register message */ ++ } ++ ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); ++ } ++ ++ if (set_proposal_from_policy(iph2, sp_out, sp_in) < 0) { ++ plog(LLV_ERROR, LOCATION, NULL, ++ "failed to create saprop.\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + /* + * receive GETSPI from kernel. + */ +@@ -2931,9 +2996,9 @@ + src, dst, + isakmp_pindex(&iph1->index, 0)); + +- EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_UP, NULL); + if(!iph1->rmconf->mode_cfg) +- EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_MODE_CFG, NULL); + + racoon_free(src); + racoon_free(dst); +Index: ipsec-tools-0.7.3/src/racoon/isakmp_cfg.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_cfg.c 2008-11-27 16:25:20.000000000 +0100 ++++ ipsec-tools-0.7.3/src/racoon/isakmp_cfg.c 2010-03-28 17:07:57.000000000 +0200 +@@ -473,8 +473,7 @@ + "Cannot allocate memory: %s\n", strerror(errno)); + } else { + memcpy(buf->v, attrpl + 1, buf->l); +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_ISAKMP_CFG_DONE, buf); ++ evt_phase1(iph1, EVTT_PHASE1_MODE_CFG, buf); + vfree(buf); + } + } +Index: ipsec-tools-0.7.3/src/racoon/isakmp_ident.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_ident.c 2006-10-02 23:41:59.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/isakmp_ident.c 2010-03-28 17:07:57.000000000 +0200 +@@ -788,8 +788,7 @@ + /* msg printed inner oakley_validate_auth() */ + goto end; + } +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEERPH1AUTH_FAILED, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, type, NULL); + goto end; + } +@@ -1537,8 +1536,7 @@ + /* msg printed inner oakley_validate_auth() */ + goto end; + } +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEERPH1AUTH_FAILED, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_AUTH_FAILED, NULL); + isakmp_info_send_n1(iph1, type, NULL); + goto end; + } +Index: ipsec-tools-0.7.3/src/racoon/isakmp_inf.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_inf.c 2009-05-18 19:07:46.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/isakmp_inf.c 2010-03-28 17:07:57.000000000 +0200 +@@ -510,8 +510,7 @@ + del_ph1=getph1byindex((isakmp_index *)(delete + 1)); + if(del_ph1 != NULL){ + +- EVT_PUSH(del_ph1->local, del_ph1->remote, +- EVTT_PEERPH1_NOPROP, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_PEER_DELETED, NULL); + if (del_ph1->scr) + SCHED_KILL(del_ph1->scr); + +@@ -532,8 +531,6 @@ + delete->spi_size, delete->proto_id); + return 0; + } +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_PEER_DELETE, NULL); + purge_ipsec_spi(iph1->remote, delete->proto_id, + (u_int32_t *)(delete + 1), num_spi); + break; +@@ -1630,7 +1627,7 @@ + "DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n", + isakmp_pindex(&iph1->index, 0)); + +- EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_DPD_TIMEOUT, NULL); + purge_remote(iph1); + + /* Do not reschedule here: phase1 is deleted, +Index: ipsec-tools-0.7.3/src/racoon/isakmp_var.h +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_var.h 2007-02-20 10:08:49.000000000 +0100 ++++ ipsec-tools-0.7.3/src/racoon/isakmp_var.h 2010-03-28 17:07:57.000000000 +0200 +@@ -35,6 +35,7 @@ + #define _ISAKMP_VAR_H + + #include "vmbuf.h" ++#include "policy.h" + + #define PORT_ISAKMP 500 + #define PORT_ISAKMP_NATT 4500 +@@ -62,8 +63,8 @@ + struct isakmp_pl_nonce; /* XXX */ + + extern int isakmp_handler __P((int)); +-extern int isakmp_ph1begin_i __P((struct remoteconf *, struct sockaddr *, +- struct sockaddr *)); ++extern struct ph1handle *isakmp_ph1begin_i __P((struct remoteconf *, ++ struct sockaddr *, struct sockaddr *)); + + extern vchar_t *isakmp_parsewoh __P((int, struct isakmp_gen *, int)); + extern vchar_t *isakmp_parse __P((vchar_t *)); +@@ -87,6 +88,7 @@ + extern void isakmp_ph2delete_stub __P((void *)); + extern void isakmp_ph2delete __P((struct ph2handle *)); + ++extern int isakmp_get_sainfo __P((struct ph2handle *, struct secpolicy *, struct secpolicy *)); + extern int isakmp_post_acquire __P((struct ph2handle *)); + extern int isakmp_post_getspi __P((struct ph2handle *)); + extern void isakmp_chkph1there_stub __P((void *)); +Index: ipsec-tools-0.7.3/src/racoon/isakmp_xauth.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_xauth.c 2009-04-20 15:35:36.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/isakmp_xauth.c 2010-03-28 17:07:57.000000000 +0200 +@@ -1568,13 +1568,11 @@ + plog(LLV_ERROR, LOCATION, NULL, + "Xauth authentication failed\n"); + +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_XAUTH_FAILED, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_XAUTH_FAILED, NULL); + + iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1; + } else { +- EVT_PUSH(iph1->local, iph1->remote, +- EVTT_XAUTH_SUCCESS, NULL); ++ evt_phase1(iph1, EVTT_PHASE1_XAUTH_SUCCESS, NULL); + } + + +Index: ipsec-tools-0.7.3/src/racoon/pfkey.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/pfkey.c 2008-03-05 23:14:24.000000000 +0100 ++++ ipsec-tools-0.7.3/src/racoon/pfkey.c 2010-03-28 17:07:57.000000000 +0200 +@@ -92,6 +92,7 @@ + #include "algorithm.h" + #include "sainfo.h" + #include "admin.h" ++#include "evt.h" + #include "privsep.h" + #include "strnames.h" + #include "backupsa.h" +@@ -1266,6 +1267,7 @@ + + /* update status */ + iph2->status = PHASE2ST_ESTABLISHED; ++ evt_phase2(iph2, EVTT_PHASE2_UP, NULL); + + #ifdef ENABLE_STATS + gettimeofday(&iph2->end, NULL); +@@ -1636,7 +1638,6 @@ + struct ph2handle *iph2[MAXNESTEDSA]; + struct sockaddr *src, *dst; + int n; /* # of phase 2 handler */ +- int remoteid=0; + #ifdef HAVE_SECCTX + struct sadb_x_sec_ctx *m_sec_ctx; + #endif /* HAVE_SECCTX */ +@@ -1825,63 +1826,11 @@ + return -1; + } + +- plog(LLV_DEBUG, LOCATION, NULL, +- "new acquire %s\n", spidx2str(&sp_out->spidx)); +- +- /* get sainfo */ +- { +- vchar_t *idsrc, *iddst; +- +- idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src, +- sp_out->spidx.prefs, sp_out->spidx.ul_proto); +- if (idsrc == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "failed to get ID for %s\n", +- spidx2str(&sp_out->spidx)); +- delph2(iph2[n]); +- return -1; +- } +- iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst, +- sp_out->spidx.prefd, sp_out->spidx.ul_proto); +- if (iddst == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "failed to get ID for %s\n", +- spidx2str(&sp_out->spidx)); +- vfree(idsrc); +- delph2(iph2[n]); +- return -1; +- } +- { +- struct remoteconf *conf; +- conf = getrmconf(iph2[n]->dst); +- if (conf != NULL) +- remoteid=conf->ph1id; +- else{ +- plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n"); +- remoteid=0; +- } +- } +- iph2[n]->sainfo = getsainfo(idsrc, iddst, NULL, remoteid); +- vfree(idsrc); +- vfree(iddst); +- if (iph2[n]->sainfo == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "failed to get sainfo.\n"); ++ if (isakmp_get_sainfo(iph2[n], sp_out, sp_in) < 0) { + delph2(iph2[n]); + return -1; +- /* XXX should use the algorithm list from register message */ + } + +- plog(LLV_DEBUG, LOCATION, NULL, +- "selected sainfo: %s\n", sainfo2str(iph2[n]->sainfo)); +- } +- +- if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) { +- plog(LLV_ERROR, LOCATION, NULL, +- "failed to create saprop.\n"); +- delph2(iph2[n]); +- return -1; +- } + #ifdef HAVE_SECCTX + if (m_sec_ctx) { + set_secctx_in_proposal(iph2[n], spidx); +Index: ipsec-tools-0.7.3/src/racoon/racoonctl.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/racoonctl.c 2009-04-20 15:32:57.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/racoonctl.c 2010-03-28 17:07:57.000000000 +0200 +@@ -135,26 +135,24 @@ + struct evtmsg { + int type; + char *msg; +- enum { UNSPEC, ERROR, INFO } level; + } evtmsg[] = { +- { EVTT_PHASE1_UP, "Phase 1 established", INFO }, +- { EVTT_PHASE1_DOWN, "Phase 1 deleted", INFO }, +- { EVTT_XAUTH_SUCCESS, "Xauth exchange passed", INFO }, +- { EVTT_ISAKMP_CFG_DONE, "ISAKMP mode config done", INFO }, +- { EVTT_PHASE2_UP, "Phase 2 established", INFO }, +- { EVTT_PHASE2_DOWN, "Phase 2 deleted", INFO }, +- { EVTT_DPD_TIMEOUT, "Peer not reachable anymore", ERROR }, +- { EVTT_PEER_NO_RESPONSE, "Peer not responding", ERROR }, +- { EVTT_PEER_DELETE, "Peer terminated security association", ERROR }, +- { EVTT_RACOON_QUIT, "Raccon terminated", ERROR }, +- { EVTT_OVERFLOW, "Event queue overflow", ERROR }, +- { EVTT_XAUTH_FAILED, "Xauth exchange failed", ERROR }, +- { EVTT_PEERPH1AUTH_FAILED, "Peer failed phase 1 authentication " +- "(certificate problem?)", ERROR }, +- { EVTT_PEERPH1_NOPROP, "Peer failed phase 1 initiation " +- "(proposal problem?)", ERROR }, +- { 0, NULL, UNSPEC }, +- { EVTT_NO_ISAKMP_CFG, "No need for ISAKMP mode config ", INFO }, ++ { EVTT_RACOON_QUIT, "Racoon terminated" }, ++ ++ { EVTT_PHASE1_UP, "Phase 1 established" }, ++ { EVTT_PHASE1_DOWN, "Phase 1 deleted" }, ++ { EVTT_PHASE1_NO_RESPONSE, "Phase 1 error: peer not responding" }, ++ { EVTT_PHASE1_NO_PROPOSAL, "Phase 1 error: no proposal chosen" }, ++ { EVTT_PHASE1_AUTH_FAILED, ++ "Phase 1 error: authentication failed (bad certificate?)" }, ++ { EVTT_PHASE1_DPD_TIMEOUT, "Phase 1 error: dead peer detected" }, ++ { EVTT_PHASE1_MODE_CFG, "Phase 1 mode configuration done" }, ++ { EVTT_PHASE1_XAUTH_SUCCESS, "Phase 1 Xauth succeeded" }, ++ { EVTT_PHASE1_XAUTH_FAILED, "Phase 1 Xauth failed" }, ++ ++ { EVTT_PHASE2_NO_PHASE1, "Phase 2 error: no suitable phase 1" }, ++ { EVTT_PHASE2_UP, "Phase 2 established" }, ++ { EVTT_PHASE2_DOWN, "Phase 2 deleted" }, ++ { EVTT_PHASE2_NO_RESPONSE, "Phase 2 error: no response" }, + }; + + static int get_proto __P((char *)); +@@ -184,6 +182,7 @@ + { IPPROTO_ICMP, "icmp" }, + { IPPROTO_TCP, "tcp" }, + { IPPROTO_UDP, "udp" }, ++ { IPPROTO_GRE, "gre" }, + { 0, NULL }, + }; + +@@ -193,31 +192,13 @@ + + char *pname; + int long_format = 0; +- +-#define EVTF_NONE 0x0000 /* Ignore any events */ +-#define EVTF_LOOP 0x0001 /* Loop awaiting for new events */ +-#define EVTF_CFG_STOP 0x0002 /* Stop after ISAKMP mode config */ +-#define EVTF_CFG 0x0004 /* Print ISAKMP mode config info */ +-#define EVTF_ALL 0x0008 /* Print any events */ +-#define EVTF_PURGE 0x0010 /* Print all available events */ +-#define EVTF_PH1DOWN_STOP 0x0020 /* Stop when phase 1 SA gets down */ +-#define EVTF_PH1DOWN 0x0040 /* Print that phase 1 SA got down */ +-#define EVTF_ERR 0x0080 /* Print any error */ +-#define EVTF_ERR_STOP 0x0100 /* Stop on any error */ +- +-int evt_filter = EVTF_NONE; +-time_t evt_start; ++int evt_quit_event = 0; + + void dump_isakmp_sa __P((char *, int)); + void dump_internal __P((char *, int)); + char *pindex_isakmp __P((isakmp_index *)); + void print_schedule __P((caddr_t, int)); +-void print_evt __P((caddr_t, int)); +-void print_cfg __P((caddr_t, int)); +-void print_err __P((caddr_t, int)); +-void print_ph1down __P((caddr_t, int)); +-void print_ph1up __P((caddr_t, int)); +-int evt_poll __P((void)); ++void print_evt __P((struct evt_common *)); + char * fixed_addr __P((char *, char *, int)); + + static void +@@ -226,13 +207,15 @@ + printf( + "Usage:\n" + " %s reload-config\n" ++" %s show-schedule\n" + " %s [-l [-l]] show-sa [protocol]\n" + " %s flush-sa [protocol]\n" + " %s delete-sa \n" +-" %s establish-sa [-u identity] \n" ++" %s establish-sa [-u identity] [-w] \n" + " %s vpn-connect [-u identity] vpn_gateway\n" + " %s vpn-disconnect vpn_gateway\n" +-"\n" ++" %s show-event\n" ++" %s logout-user login\n""\n" + " : \"isakmp\", \"esp\" or \"ah\".\n" + " In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n" + "\n" +@@ -240,8 +223,8 @@ + " : {\"esp\",\"ah\"} \n" + " \n" + " : \"inet\" or \"inet6\"\n" +-" : \"icmp\", \"tcp\", \"udp\" or \"any\"\n", +- pname, pname, pname, pname, pname, pname, pname); ++" : \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n", ++ pname, pname, pname, pname, pname, pname, pname, pname, pname, pname); + } + + /* +@@ -312,53 +295,24 @@ + + vfree(combuf); + +- if (com_recv(&combuf) != 0) +- goto bad; +- if (handle_recv(combuf) != 0) +- goto bad; +- +- vfree(combuf); ++ do { ++ if (com_recv(&combuf) != 0) ++ goto bad; ++ if (handle_recv(combuf) != 0) ++ goto bad; ++ vfree(combuf); ++ } while (evt_quit_event != 0); + +- if (evt_filter != EVTF_NONE) +- if (evt_poll() != 0) +- goto bad; +- ++ close(so); + exit(0); + +- bad: ++bad: ++ close(so); ++ if (errno == EEXIST) ++ exit(0); + exit(1); + } + +-int +-evt_poll(void) { +- struct timeval tv; +- vchar_t *recvbuf; +- vchar_t *sendbuf; +- +- if ((sendbuf = f_getevt(0, NULL)) == NULL) +- errx(1, "Cannot make combuf"); +- +- +- while (evt_filter & (EVTF_LOOP|EVTF_PURGE)) { +- /* handle_recv closes the socket time, so open it each time */ +- com_init(); +- +- if (com_send(sendbuf) != 0) +- errx(1, "Cannot send combuf"); +- +- if (com_recv(&recvbuf) == 0) { +- handle_recv(recvbuf); +- vfree(recvbuf); +- } +- +- tv.tv_sec = 0; +- tv.tv_usec = 10; +- (void)select(0, NULL, NULL, NULL, &tv); +- } +- +- vfree(sendbuf); +- return 0; +-} + + /* %%% */ + /* +@@ -422,20 +376,8 @@ + vchar_t *buf; + struct admin_com *head; + +- /* +- * There are 3 ways of getting here +- * 1) racoonctl vc => evt_filter = (EVTF_LOOP|EVTF_CFG| ... ) +- * 2) racoonctl es => evt_filter = EVTF_NONE +- * 3) racoonctl es -l => evt_filter = EVTF_LOOP +- * Catch the second case: show-event is here to purge all +- */ +- if (evt_filter == EVTF_NONE) +- evt_filter = (EVTF_ALL|EVTF_PURGE); +- +- if ((ac >= 1) && (strcmp(av[0], "-l") == 0)) +- evt_filter |= EVTF_LOOP; +- +- if (ac >= 2) ++ evt_quit_event = -1; ++ if (ac >= 1) + errx(1, "too many arguments"); + + buf = vmalloc(sizeof(*head)); +@@ -653,6 +595,7 @@ + char *id = NULL; + char *key = NULL; + struct admin_com_psk *acp; ++ int wait = 0; + + if (ac < 1) + errx(1, "insufficient arguments"); +@@ -673,6 +616,12 @@ + ac -= 2; + } + ++ if (ac >= 1 && strcmp(av[0], "-w") == 0) { ++ wait = 1; ++ av++; ++ ac--; ++ } ++ + /* need protocol */ + if (ac < 1) + errx(1, "insufficient arguments"); +@@ -687,12 +636,16 @@ + index = get_index(ac, av); + if (index == NULL) + return NULL; ++ if (wait) ++ evt_quit_event = EVTT_PHASE1_MODE_CFG; + break; + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: + index = get_index(ac, av); + if (index == NULL) + return NULL; ++ if (wait) ++ evt_quit_event = EVTT_PHASE2_UP; + break; + default: + errno = EPROTONOSUPPORT; +@@ -749,8 +702,7 @@ + if (ac < 1) + errx(1, "insufficient arguments"); + +- evt_filter = (EVTF_LOOP|EVTF_CFG|EVTF_CFG_STOP|EVTF_ERR|EVTF_ERR_STOP); +- time(&evt_start); ++ evt_quit_event = EVTT_PHASE1_MODE_CFG; + + /* Optional -u identity */ + if (strcmp(av[0], "-u") == 0) { +@@ -814,8 +766,7 @@ + if (ac > 1) + warnx("Extra arguments"); + +- evt_filter = +- (EVTF_PH1DOWN|EVTF_PH1DOWN_STOP|EVTF_LOOP|EVTF_ERR|EVTF_ERR_STOP); ++ evt_quit_event = EVTT_PHASE1_DOWN; + + nav[nac++] = isakmp; + nav[nac++] = inet; +@@ -1337,84 +1288,32 @@ + + + void +-print_evt(buf, len) +- caddr_t buf; +- int len; ++print_evt(evtdump) ++ struct evt_common *evtdump; + { +- struct evtdump *evtdump = (struct evtdump *)buf; + int i; + char *srcstr; + char *dststr; + +- for (i = 0; evtmsg[i].msg; i++) +- if (evtmsg[i].type == evtdump->type) +- break; +- +- if (evtmsg[i].msg == NULL) +- printf("Event %d: ", evtdump->type); ++ for (i = 0; i < sizeof(evtmsg) / sizeof(evtmsg[0]); i++) ++ if (evtmsg[i].type == evtdump->ec_type) ++ break; ++ ++ if (evtmsg[i].msg == NULL) ++ printf("Event %d: ", evtdump->ec_type); + else + printf("%s : ", evtmsg[i].msg); + +- if ((srcstr = saddr2str((struct sockaddr *)&evtdump->src)) == NULL) ++ if ((srcstr = saddr2str((struct sockaddr *)&evtdump->ec_ph1src)) == NULL) + printf("unknown"); + else + printf("%s", srcstr); + printf(" -> "); +- if ((dststr = saddr2str((struct sockaddr *)&evtdump->dst)) == NULL) ++ if ((dststr = saddr2str((struct sockaddr *)&evtdump->ec_ph1dst)) == NULL) + printf("unknown"); + else + printf("%s", dststr); + printf("\n"); +- +- return; +-} +- +-void +-print_err(buf, len) +- caddr_t buf; +- int len; +-{ +- struct evtdump *evtdump = (struct evtdump *)buf; +- int i; +- +- +- for (i = 0; evtmsg[i].msg; i++) +- if (evtmsg[i].type == evtdump->type) +- break; +- +- if (evtmsg[i].level != ERROR) +- return; +- +- if (evtmsg[i].msg == NULL) +- printf("Error: Event %d\n", evtdump->type); +- else +- printf("Error: %s\n", evtmsg[i].msg); +- +- if (evt_filter & EVTF_ERR_STOP) +- evt_filter &= ~EVTF_LOOP; +- +- return; +-} +- +-/* +- * Print a message when phase 1 SA goes down +- */ +-void +-print_ph1down(buf, len) +- caddr_t buf; +- int len; +-{ +- struct evtdump *evtdump = (struct evtdump *)buf; +- +- if (evtdump->type != EVTT_PHASE1_DOWN) +- return; +- +- printf("VPN connexion terminated\n"); +- +- if (evt_filter & EVTF_PH1DOWN_STOP) +- evt_filter &= ~EVTF_LOOP; +- +- return; + } + + /* +@@ -1425,15 +1324,14 @@ + caddr_t buf; + int len; + { +- struct evtdump *evtdump = (struct evtdump *)buf; ++ struct evt_common *evtdump = (struct evt_common *)buf; + struct isakmp_data *attr; + char *banner = NULL; + struct in_addr addr4; + + memset(&addr4, 0, sizeof(addr4)); + +- if (evtdump->type != EVTT_ISAKMP_CFG_DONE && +- evtdump->type != EVTT_NO_ISAKMP_CFG) ++ if (evtdump->ec_type != EVTT_PHASE1_MODE_CFG) + return; + + len -= sizeof(*evtdump); +@@ -1487,7 +1385,7 @@ + } + } + +- if (evtdump->type == EVTT_ISAKMP_CFG_DONE) ++ if (len > 0) + printf("Bound to address %s\n", inet_ntoa(addr4)); + else + printf("VPN connexion established\n"); +@@ -1508,11 +1406,6 @@ + printf("\n"); + racoon_free(banner); + } +- +- if (evt_filter & EVTF_CFG_STOP) +- evt_filter &= ~EVTF_LOOP; +- +- return; + } + + +@@ -1563,32 +1456,28 @@ + break; + + case ADMIN_SHOW_EVT: { +- struct evtdump *evtdump; ++ struct evt_common *ec; + +- /* We got no event */ +- if (len == 0) { +- /* If we were purging the queue, it is now done */ +- if (evt_filter & EVTF_PURGE) +- evt_filter &= ~EVTF_PURGE; ++ /* We got no event? */ ++ if (len == 0) + break; +- } ++ if (len < sizeof(struct evt_common)) ++ errx(1, "Short buffer\n"); + +- if (len < sizeof(struct evtdump)) +- errx(1, "Short buffer\n"); +- +- /* Toss outdated events */ +- evtdump = (struct evtdump *)buf; +- if (evtdump->timestamp < evt_start) +- break; +- +- if (evt_filter & EVTF_ALL) +- print_evt(buf, len); +- if (evt_filter & EVTF_ERR) +- print_err(buf, len); +- if (evt_filter & EVTF_CFG) +- print_cfg(buf, len); +- if (evt_filter & EVTF_PH1DOWN) +- print_ph1down(buf, len); ++ ec = (struct evt_common *) buf; ++ if (evt_quit_event <= 0) ++ print_evt(ec); ++ else if (evt_quit_event == ec->ec_type) { ++ switch (ec->ec_type) { ++ case EVTT_PHASE1_MODE_CFG: ++ print_cfg(ec, len); ++ break; ++ default: ++ print_evt(ec); ++ break; ++ }; ++ evt_quit_event = 0; ++ } + break; + } + +@@ -1645,10 +1534,8 @@ + break; + } + +- close(so); + return 0; + +- bad: +- close(so); ++bad: + return -1; + } +Index: ipsec-tools-0.7.3/src/racoon/session.c +=================================================================== +--- ipsec-tools-0.7.3.orig/src/racoon/session.c 2007-08-01 13:52:22.000000000 +0200 ++++ ipsec-tools-0.7.3/src/racoon/session.c 2010-03-28 17:07:57.000000000 +0200 +@@ -192,6 +192,7 @@ + /* scheduling */ + timeout = schedular(); + ++ nfds = evt_get_fdmask(nfds, &rfds); + error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout); + if (error < 0) { + switch (errno) { +@@ -211,6 +212,7 @@ + (FD_ISSET(lcconf->sock_admin, &rfds))) + admin_handler(); + #endif ++ evt_handle_fdmask(&rfds); + + for (p = lcconf->myaddrs; p; p = p->next) { + if (!p->addr) +@@ -451,7 +453,7 @@ + case SIGTERM: + plog(LLV_INFO, LOCATION, NULL, + "caught signal %d\n", sig); +- EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); ++ evt_generic(EVTT_RACOON_QUIT, NULL); + pfkey_send_flush(lcconf->sock_pfkey, + SADB_SATYPE_UNSPEC); + #ifdef ENABLE_FASTQUIT -- 2.11.0