Refactor admin socket event protocol to be less error prone. Backwards compatibility is provided. Submitted by Timo Teras.

This commit is contained in:
mgrooms 2008-03-06 00:34:11 +00:00
parent 089a95fdcd
commit 3fd729ad89
17 changed files with 604 additions and 464 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: admin.c,v 1.18 2007/07/18 12:07:51 vanhu Exp $ */
/* $NetBSD: admin.c,v 1.19 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */
@ -93,7 +93,7 @@ mode_t adminsock_mode = 0600;
static struct sockaddr_un sunaddr;
static int admin_process __P((int, char *));
static int admin_reply __P((int, struct admin_com *, vchar_t *));
static int admin_reply __P((int, struct admin_com *, int, vchar_t *));
int
admin_handler()
@ -147,16 +147,16 @@ admin_handler()
goto end;
}
if (com.ac_cmd == ADMIN_RELOAD_CONF) {
/* reload does not work at all! */
signal_handler(SIGHUP);
goto end;
}
error = admin_process(so2, combuf);
end:
(void)close(so2);
end:
if (error == -2) {
plog(LLV_DEBUG, LOCATION, NULL,
"[%d] admin connection established\n", so2);
} else {
(void)close(so2);
}
if (combuf)
racoon_free(combuf);
@ -176,99 +176,100 @@ admin_process(so2, combuf)
vchar_t *id = NULL;
vchar_t *key = NULL;
int idtype = 0;
int error = -1;
int error = 0, ac_errno = 0;
struct evt_listener_list *event_list = NULL;
com->ac_errno = 0;
if (com->ac_cmd & ADMIN_FLAG_VERSION)
com->ac_cmd &= ~ADMIN_FLAG_VERSION;
else
com->ac_version = 0;
switch (com->ac_cmd) {
case ADMIN_RELOAD_CONF:
/* don't entered because of proccessing it in other place. */
plog(LLV_ERROR, LOCATION, NULL, "should never reach here\n");
goto out;
signal_handler(SIGHUP);
break;
case ADMIN_SHOW_SCHED:
{
case ADMIN_SHOW_SCHED: {
caddr_t p = NULL;
int len;
com->ac_errno = -1;
if (sched_dump(&p, &len) == -1)
goto out2;
if ((buf = vmalloc(len)) == NULL)
goto out2;
memcpy(buf->v, p, len);
com->ac_errno = 0;
out2:
racoon_free(p);
if (sched_dump(&p, &len) != -1) {
buf = vmalloc(len);
if (buf != NULL)
memcpy(buf->v, p, len);
else
ac_errno = ENOMEM;
racoon_free(p);
} else
ac_errno = ENOMEM;
break;
}
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;
if (com->ac_version == 0) {
buf = evt_dump();
ac_errno = 0;
}
break;
case ADMIN_SHOW_SA:
case ADMIN_FLUSH_SA:
{
switch (com->ac_proto) {
case ADMIN_PROTO_ISAKMP:
switch (com->ac_cmd) {
case ADMIN_SHOW_SA:
buf = dumpph1();
if (buf == NULL)
com->ac_errno = -1;
ac_errno = ENOMEM;
break;
case ADMIN_FLUSH_SA:
flushph1();
break;
default:
ac_errno = ENOTSUP;
break;
}
break;
case ADMIN_PROTO_IPSEC:
case ADMIN_PROTO_AH:
case ADMIN_PROTO_ESP:
switch (com->ac_cmd) {
case ADMIN_SHOW_SA:
{
case ADMIN_SHOW_SA: {
u_int p;
p = admin2pfkey_proto(com->ac_proto);
if (p == -1)
goto out;
buf = pfkey_dump_sadb(p);
if (buf == NULL)
com->ac_errno = -1;
}
if (p != -1) {
buf = pfkey_dump_sadb(p);
if (buf == NULL)
ac_errno = ENOMEM;
} else
ac_errno = EINVAL;
break;
}
case ADMIN_FLUSH_SA:
pfkey_flush_sadb(com->ac_proto);
break;
default:
ac_errno = ENOTSUP;
break;
}
break;
case ADMIN_PROTO_INTERNAL:
switch (com->ac_cmd) {
case ADMIN_SHOW_SA:
buf = NULL; /*XXX dumpph2(&error);*/
if (buf == NULL)
com->ac_errno = error;
ac_errno = ENOTSUP;
break;
case ADMIN_FLUSH_SA:
/*XXX flushph2();*/
com->ac_errno = 0;
break;
default:
ac_errno = ENOTSUP;
break;
}
break;
default:
/* ignore */
com->ac_errno = -1;
ac_errno = ENOTSUP;
}
}
break;
case ADMIN_DELETE_SA: {
@ -300,7 +301,6 @@ out2:
racoon_free(loc);
racoon_free(rem);
break;
}
@ -352,7 +352,6 @@ out2:
}
racoon_free(rem);
break;
}
@ -360,8 +359,6 @@ out2:
struct admin_com_psk *acp;
char *data;
com->ac_cmd = ADMIN_ESTABLISH_SA;
acp = (struct admin_com_psk *)
((char *)com + sizeof(*com) +
sizeof(struct admin_com_indexes));
@ -389,8 +386,7 @@ out2:
memcpy(key->v, data, key->l);
}
/* FALLTHROUGH */
case ADMIN_ESTABLISH_SA:
{
case ADMIN_ESTABLISH_SA: {
struct sockaddr *dst;
struct sockaddr *src;
src = (struct sockaddr *)
@ -402,12 +398,24 @@ out2:
switch (com->ac_proto) {
case ADMIN_PROTO_ISAKMP: {
struct ph1handle *ph1;
struct remoteconf *rmconf;
struct sockaddr *remote = NULL;
struct sockaddr *local = NULL;
u_int16_t port;
com->ac_errno = -1;
ac_errno = -1;
/* connected already? */
ph1 = getph1byaddrwop(src, dst);
if (ph1 != NULL) {
event_list = &ph1->evt_listeners;
if (ph1->status == PHASE1ST_ESTABLISHED)
ac_errno = EEXIST;
else
ac_errno = 0;
break;
}
/* search appropreate configuration */
rmconf = getrmconf(dst);
@ -459,10 +467,12 @@ out2:
"%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;
com->ac_errno = 0;
event_list = &ph1->evt_listeners;
ac_errno = 0;
out1:
if (local != NULL)
racoon_free(local);
@ -472,24 +482,29 @@ out1:
}
case ADMIN_PROTO_AH:
case ADMIN_PROTO_ESP:
ac_errno = ENOTSUP;
break;
default:
/* ignore */
com->ac_errno = -1;
ac_errno = ENOTSUP;
}
}
break;
}
default:
plog(LLV_ERROR, LOCATION, NULL,
"invalid command: %d\n", com->ac_cmd);
com->ac_errno = -1;
ac_errno = ENOTSUP;
}
if ((error = admin_reply(so2, com, buf)) != 0)
if ((error = admin_reply(so2, com, ac_errno, buf)) != 0)
goto out;
error = 0;
/* start pushing events if so requested */
if ((ac_errno == 0) &&
(com->ac_version >= 1) &&
(com->ac_cmd == ADMIN_SHOW_EVT || event_list != NULL))
error = evt_subscribe(event_list, so2);
out:
if (buf != NULL)
vfree(buf);
@ -498,12 +513,13 @@ out:
}
static int
admin_reply(so, combuf, buf)
int so;
struct admin_com *combuf;
admin_reply(so, req, ac_errno, buf)
int so, ac_errno;
struct admin_com *req;
vchar_t *buf;
{
int tlen;
struct admin_com *combuf;
char *retbuf = NULL;
if (buf != NULL)
@ -518,8 +534,11 @@ admin_reply(so, combuf, buf)
return -1;
}
memcpy(retbuf, combuf, sizeof(*combuf));
((struct admin_com *)retbuf)->ac_len = tlen;
combuf = (struct admin_com *) retbuf;
combuf->ac_len = tlen;
combuf->ac_cmd = req->ac_cmd & ~ADMIN_FLAG_VERSION;
combuf->ac_errno = ac_errno;
combuf->ac_proto = req->ac_proto;
if (buf != NULL)
memcpy(retbuf + sizeof(*combuf), buf->v, buf->l);

View File

@ -1,4 +1,4 @@
/* $NetBSD: admin.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */
/* $NetBSD: admin.h,v 1.5 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: admin.h,v 1.11 2005/06/19 22:37:47 manubsd Exp */
@ -46,10 +46,18 @@ extern mode_t adminsock_mode;
struct admin_com {
u_int16_t ac_len; /* total packet length including data */
u_int16_t ac_cmd;
int16_t ac_errno;
union {
int16_t ac_errno;
uint16_t ac_version;
};
u_int16_t ac_proto;
};
/*
* Version field in request is valid.
*/
#define ADMIN_FLAG_VERSION 0x8000
/*
* No data follows as the data.
* These don't use proto field.

View File

@ -1,9 +1,10 @@
/* $NetBSD: evt.c,v 1.5 2006/09/09 16:22:09 manu Exp $ */
/* $NetBSD: evt.c,v 1.6 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */
/*
* Copyright (C) 2004 Emmanuel Dreyfus
* Copyright (C) 2008 Timo Teras
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -46,14 +47,54 @@
#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;
void
static EVT_LISTENER_LIST(evt_listeners);
static EVT_LISTENER_LIST(evt_fds);
struct evt_message {
struct admin_com adm;
struct evt_async evt;
};
struct evt {
struct evtdump *dump;
TAILQ_ENTRY(evt) next;
};
TAILQ_HEAD(evtlist, evt);
#define EVTLIST_MAX 32
static struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
static int evtlist_len = 0;
static int evtlist_inuse = 0;
static struct {
int newtype, oldtype;
} evttype_map[] = {
{ EVT_RACOON_QUIT, EVTT_RACOON_QUIT },
{ EVT_PHASE1_UP, EVTT_PHASE1_UP },
{ EVT_PHASE1_DOWN, EVTT_PHASE1_DOWN },
{ EVT_PHASE1_NO_RESPONSE, EVTT_PEER_NO_RESPONSE },
{ EVT_PHASE1_NO_PROPOSAL, EVTT_PEERPH1_NOPROP },
{ EVT_PHASE1_AUTH_FAILED, EVTT_PEERPH1AUTH_FAILED },
{ EVT_PHASE1_DPD_TIMEOUT, EVTT_DPD_TIMEOUT },
{ EVT_PHASE1_PEER_DELETED, EVTT_PEER_DELETE },
{ EVT_PHASE1_MODE_CFG, EVTT_ISAKMP_CFG_DONE },
{ EVT_PHASE1_XAUTH_SUCCESS, EVTT_XAUTH_SUCCESS },
{ EVT_PHASE1_XAUTH_FAILED, EVTT_XAUTH_FAILED },
{ EVT_PHASE2_NO_PHASE1, -1 },
{ EVT_PHASE2_UP, EVTT_PHASE2_UP },
{ EVT_PHASE2_DOWN, EVTT_PHASE2_DOWN },
{ EVT_PHASE2_NO_RESPONSE, EVTT_PEER_NO_RESPONSE },
};
static void
evt_push(src, dst, type, optdata)
struct sockaddr *src;
struct sockaddr *dst;
@ -63,9 +104,21 @@ evt_push(src, dst, type, optdata)
struct evtdump *evtdump;
struct evt *evt;
size_t len;
int i;
/* If admin socket is disabled, silently discard anything */
if (adminsock_path == NULL)
if (adminsock_path == NULL || !evtlist_inuse)
return;
/* Map the event type to old */
for (i = 0; i < sizeof(evttype_map) / sizeof(evttype_map[0]); i++)
if (evttype_map[i].newtype == type)
break;
if (i >= sizeof(evttype_map) / sizeof(evttype_map[0]))
return;
type = evttype_map[i].oldtype;
if (type < 0)
return;
/* If we are above the limit, don't record anything */
@ -121,7 +174,7 @@ evt_push(src, dst, type, optdata)
return;
}
struct evtdump *
static struct evtdump *
evt_pop(void) {
struct evtdump *evtdump;
struct evt *evt;
@ -142,6 +195,12 @@ evt_dump(void) {
struct evtdump *evtdump;
vchar_t *buf = NULL;
if (!evtlist_inuse) {
evtlist_inuse = 1;
plog(LLV_ERROR, LOCATION, NULL,
"evt_dump: deprecated event polling used\n");
}
if ((evtdump = evt_pop()) != NULL) {
if ((buf = vmalloc(evtdump->len)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
@ -155,4 +214,208 @@ evt_dump(void) {
return buf;
}
static struct evt_message *
evtmsg_create(type, optdata)
int type;
vchar_t *optdata;
{
struct evt_message *e;
size_t len;
len = sizeof(struct evt_message);
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 evt_message));
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
evtmsg_broadcast(ll, e)
const struct evt_listener_list *ll;
struct evt_message *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 evt_message *e;
if ((e = evtmsg_create(type, optdata)) == NULL)
return;
evtmsg_broadcast(&evt_listeners, e);
evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
racoon_free(e);
}
void
evt_phase1(ph1, type, optdata)
const struct ph1handle *ph1;
int type;
vchar_t *optdata;
{
struct evt_message *e;
if ((e = evtmsg_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));
evtmsg_broadcast(&ph1->evt_listeners, e);
evtmsg_broadcast(&evt_listeners, e);
evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
racoon_free(e);
}
void
evt_phase2(ph2, type, optdata)
const struct ph2handle *ph2;
int type;
vchar_t *optdata;
{
struct evt_message *e;
struct ph1handle *ph1 = ph2->ph1;
if ((e = evtmsg_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;
evtmsg_broadcast(&ph2->evt_listeners, e);
if (ph1)
evtmsg_broadcast(&ph1->evt_listeners, e);
evtmsg_broadcast(&evt_listeners, e);
evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
racoon_free(e);
}
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 (list == NULL)
list = &evt_listeners;
LIST_INSERT_HEAD(list, l, ll_chain);
LIST_INSERT_HEAD(&evt_fds, l, fd_chain);
l->fd = fd;
plog(LLV_DEBUG, LOCATION, NULL,
"[%d] admin connection is polling events\n", fd);
return -2;
}
void
evt_list_init(list)
struct evt_listener_list *list;
{
LIST_INIT(list);
}
void
evt_list_cleanup(list)
struct evt_listener_list *list;
{
while (!LIST_EMPTY(list))
evt_unsubscribe(LIST_FIRST(list));
}
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;
}
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 */

View File

@ -1,9 +1,10 @@
/* $NetBSD: evt.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */
/* $NetBSD: evt.h,v 1.5 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: evt.h,v 1.5 2006/01/19 10:24:09 fredsen Exp */
/*
* Copyright (C) 2004 Emmanuel Dreyfus
* Copyright (C) 2008 Timo Teras
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,6 +35,10 @@
#ifndef _EVT_H
#define _EVT_H
/*
* Old style (deprecated) events which are polled.
*/
struct evtdump {
size_t len;
struct sockaddr_storage src;
@ -64,25 +69,81 @@ struct evtdump {
#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;
/*
* New style, asynchronous events.
*/
struct evt_async {
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
*/
};
TAILQ_HEAD(evtlist, evt);
/* type */
#define EVT_RACOON_QUIT 0x0001
#define EVTLIST_MAX 32
#define EVT_PHASE1_UP 0x0100
#define EVT_PHASE1_DOWN 0x0101
#define EVT_PHASE1_NO_RESPONSE 0x0102
#define EVT_PHASE1_NO_PROPOSAL 0x0103
#define EVT_PHASE1_AUTH_FAILED 0x0104
#define EVT_PHASE1_DPD_TIMEOUT 0x0105
#define EVT_PHASE1_PEER_DELETED 0x0106
#define EVT_PHASE1_MODE_CFG 0x0107
#define EVT_PHASE1_XAUTH_SUCCESS 0x0108
#define EVT_PHASE1_XAUTH_FAILED 0x0109
#define EVT_PHASE2_NO_PHASE1 0x0200
#define EVT_PHASE2_UP 0x0201
#define EVT_PHASE2_DOWN 0x0202
#define EVT_PHASE2_NO_RESPONSE 0x0203
#ifdef ENABLE_ADMINPORT
struct evtdump *evt_pop(void);
vchar_t *evt_dump(void);
void evt_push(struct sockaddr *, struct sockaddr *, int, vchar_t *);
#endif
#ifdef ENABLE_ADMINPORT
#define EVT_PUSH(src, dst, type, optdata) evt_push(src, dst, type, optdata);
struct ph1handle;
struct ph2handle;
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;
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));
vchar_t *evt_dump __P((void));
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
#define EVT_PUSH(src, dst, type, optdata) ;
#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) ;
#endif /* ENABLE_ADMINPORT */
#endif /* _EVT_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: handler.c,v 1.18 2008/01/11 14:06:56 vanhu Exp $ */
/* $NetBSD: handler.c,v 1.19 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
@ -273,6 +273,7 @@ newph1()
iph1->dpd_fails = 0;
iph1->dpd_r_u = NULL;
#endif
evt_list_init(&iph1->evt_listeners);
return iph1;
}
@ -289,8 +290,7 @@ delph1(iph1)
/* 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)
@ -495,8 +495,8 @@ getph2byid(src, dst, spid)
LIST_FOREACH(p, &ph2tree, chain) {
if (spid == p->spid &&
CMPSADDR(src, p->src) == 0 &&
CMPSADDR(dst, p->dst) == 0){
cmpsaddrwild(src, p->src) == 0 &&
cmpsaddrwild(dst, p->dst) == 0){
/* Sanity check to detect zombie handlers
* XXX Sould be done "somewhere" more interesting,
* because we have lots of getph2byxxxx(), but this one
@ -582,6 +582,7 @@ newph2()
return NULL;
iph2->status = PHASE1ST_SPAWN;
evt_list_init(&iph2->evt_listeners);
return iph2;
}
@ -595,6 +596,8 @@ void
initph2(iph2)
struct ph2handle *iph2;
{
evt_list_cleanup(&iph2->evt_listeners);
sched_scrub_param(iph2);
iph2->sce = NULL;
iph2->scr = NULL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: handler.h,v 1.11 2008/01/11 14:06:56 vanhu Exp $ */
/* $NetBSD: handler.h,v 1.12 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */
@ -41,6 +41,7 @@
#include "isakmp_var.h"
#include "oakley.h"
#include "evt.h"
/* Phase 1 handler */
/*
@ -211,7 +212,7 @@ struct ph1handle {
#ifdef ENABLE_HYBRID
struct isakmp_cfg_state *mode_cfg; /* ISAKMP mode config state */
#endif
EVT_LISTENER_LIST(evt_listeners);
};
/* Phase 2 handler */
@ -324,6 +325,7 @@ struct ph2handle {
LIST_ENTRY(ph2handle) chain;
LIST_ENTRY(ph2handle) ph1bind; /* chain to ph1handle */
EVT_LISTENER_LIST(evt_listeners);
};
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp.c,v 1.30 2008/02/22 18:50:03 manu Exp $ */
/* $NetBSD: isakmp.c,v 1.31 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
@ -1026,7 +1026,7 @@ quick_main(iph2, msg)
}
/* new negotiation of phase 1 for initiator */
int
struct ph1handle *
isakmp_ph1begin_i(rmconf, remote, local)
struct remoteconf *rmconf;
struct sockaddr *remote, *local;
@ -1039,7 +1039,7 @@ isakmp_ph1begin_i(rmconf, remote, local)
/* get new entry to isakmp status table. */
iph1 = newph1();
if (iph1 == NULL)
return -1;
return NULL;
iph1->status = PHASE1ST_START;
iph1->rmconf = rmconf;
@ -1055,7 +1055,7 @@ isakmp_ph1begin_i(rmconf, remote, local)
if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
remph1(iph1);
delph1(iph1);
return -1;
return NULL;
}
#endif
#ifdef ENABLE_FRAG
@ -1072,7 +1072,7 @@ isakmp_ph1begin_i(rmconf, remote, local)
if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
remph1(iph1);
delph1(iph1);
return -1;
return NULL;
}
(void)insph1(iph1);
@ -1108,7 +1108,7 @@ isakmp_ph1begin_i(rmconf, remote, local)
remph1(iph1);
delph1(iph1);
return -1;
return NULL;
}
#ifdef ENABLE_STATS
@ -1119,7 +1119,7 @@ isakmp_ph1begin_i(rmconf, remote, local)
timedelta(&start, &end));
#endif
return 0;
return iph1;
}
/* new negotiation of phase 1 for responder */
@ -1943,8 +1943,7 @@ isakmp_ph1resend(iph1)
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, EVT_PHASE1_NO_RESPONSE, NULL);
return -1;
}
@ -1953,8 +1952,7 @@ isakmp_ph1resend(iph1)
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, EVT_PHASE1_NO_RESPONSE, NULL);
return -1;
}
@ -2003,7 +2001,7 @@ isakmp_ph2resend(iph2)
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, EVT_PHASE2_NO_RESPONSE, NULL);
unbindph12(iph2);
return -1;
}
@ -2012,8 +2010,7 @@ isakmp_ph2resend(iph2)
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, EVT_PHASE2_NO_RESPONSE, NULL);
return -1;
}
@ -2104,7 +2101,7 @@ isakmp_ph1delete(iph1)
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, EVT_PHASE1_DOWN, NULL);
racoon_free(src);
racoon_free(dst);
@ -2251,7 +2248,7 @@ isakmp_post_acquire(iph2)
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;
}
@ -3035,9 +3032,9 @@ log_ph1established(iph1)
src, dst,
isakmp_pindex(&iph1->index, 0));
EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL);
evt_phase1(iph1, EVT_PHASE1_UP, NULL);
if(!iph1->rmconf->mode_cfg)
EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL);
evt_phase1(iph1, EVT_PHASE1_MODE_CFG, NULL);
racoon_free(src);
racoon_free(dst);

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_agg.c,v 1.9 2006/09/30 21:49:37 manu Exp $ */
/* $NetBSD: isakmp_agg.c,v 1.10 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */
@ -587,8 +587,7 @@ agg_i2recv(iph1, msg)
/* message printed inner oakley_validate_auth() */
goto end;
}
EVT_PUSH(iph1->local, iph1->remote,
EVTT_PEERPH1AUTH_FAILED, NULL);
evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
isakmp_info_send_n1(iph1, ptype, NULL);
goto end;
}
@ -1486,8 +1485,7 @@ agg_r2recv(iph1, msg0)
/* message printed inner oakley_validate_auth() */
goto end;
}
EVT_PUSH(iph1->local, iph1->remote,
EVTT_PEERPH1AUTH_FAILED, NULL);
evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
isakmp_info_send_n1(iph1, ptype, NULL);
goto end;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_base.c,v 1.7 2006/10/02 21:51:33 manu Exp $ */
/* $NetBSD: isakmp_base.c,v 1.8 2008/03/06 00:34:11 mgrooms Exp $ */
/* $KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane Exp $ */
@ -716,8 +716,7 @@ base_i3recv(iph1, msg)
/* message printed inner oakley_validate_auth() */
goto end;
}
EVT_PUSH(iph1->local, iph1->remote,
EVTT_PEERPH1AUTH_FAILED, NULL);
evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
isakmp_info_send_n1(iph1, ptype, NULL);
goto end;
}
@ -1242,8 +1241,7 @@ base_r2recv(iph1, msg)
/* message printed inner oakley_validate_auth() */
goto end;
}
EVT_PUSH(iph1->local, iph1->remote,
EVTT_PEERPH1AUTH_FAILED, NULL);
evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
isakmp_info_send_n1(iph1, ptype, NULL);
goto end;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_cfg.c,v 1.14 2007/10/19 03:37:19 manu Exp $ */
/* $NetBSD: isakmp_cfg.c,v 1.15 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
@ -473,8 +473,7 @@ isakmp_cfg_reply(iph1, attrpl)
"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, EVT_PHASE1_MODE_CFG, buf);
vfree(buf);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_ident.c,v 1.6 2006/10/02 21:41:59 manu Exp $ */
/* $NetBSD: isakmp_ident.c,v 1.7 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: isakmp_ident.c,v 1.21 2006/04/06 16:46:08 manubsd Exp */
@ -788,8 +788,7 @@ ident_i4recv(iph1, msg0)
/* msg printed inner oakley_validate_auth() */
goto end;
}
EVT_PUSH(iph1->local, iph1->remote,
EVTT_PEERPH1AUTH_FAILED, NULL);
evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
isakmp_info_send_n1(iph1, type, NULL);
goto end;
}
@ -1537,8 +1536,7 @@ ident_r3recv(iph1, msg0)
/* msg printed inner oakley_validate_auth() */
goto end;
}
EVT_PUSH(iph1->local, iph1->remote,
EVTT_PEERPH1AUTH_FAILED, NULL);
evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
isakmp_info_send_n1(iph1, type, NULL);
goto end;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_inf.c,v 1.24 2008/01/11 14:27:34 vanhu Exp $ */
/* $NetBSD: isakmp_inf.c,v 1.25 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
@ -515,8 +515,7 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted)
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, EVT_PHASE1_PEER_DELETED, NULL);
SCHED_KILL(del_ph1->scr);
/*
@ -536,8 +535,6 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted)
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;
@ -1621,7 +1618,7 @@ isakmp_info_send_r_u(arg)
"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, EVT_PHASE1_DPD_TIMEOUT, NULL);
purge_remote(iph1);
/* Do not reschedule here: phase1 is deleted,

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_var.h,v 1.7 2007/02/20 09:11:14 vanhu Exp $ */
/* $NetBSD: isakmp_var.h,v 1.8 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: isakmp_var.h,v 1.12 2005/05/07 14:45:31 manubsd Exp */
@ -62,8 +62,8 @@ struct isakmp_pl_ke; /* XXX */
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 *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_xauth.c,v 1.13 2007/08/07 04:35:01 manu Exp $ */
/* $NetBSD: isakmp_xauth.c,v 1.14 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
@ -1577,13 +1577,11 @@ isakmp_xauth_set(iph1, attr)
plog(LLV_ERROR, LOCATION, NULL,
"Xauth authentication failed\n");
EVT_PUSH(iph1->local, iph1->remote,
EVTT_XAUTH_FAILED, NULL);
evt_phase1(iph1, EVT_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, EVT_PHASE1_XAUTH_SUCCESS, NULL);
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: racoonctl.8,v 1.14 2007/12/31 01:42:07 mgrooms Exp $
.\" $NetBSD: racoonctl.8,v 1.15 2008/03/06 00:34:11 mgrooms Exp $
.\"
.\" Id: racoonctl.8,v 1.6 2006/05/07 21:32:59 manubsd Exp
.\"
@ -65,7 +65,6 @@ vpn-disconnect
.Ar vpn_gateway
.Nm
show-event
.Op Fl l
.Nm
logout-user
.Ar login
@ -135,16 +134,9 @@ Delete an SA, either an ISAKMP SA, IPsec ESP SA, or IPsec AH SA.
This is a particular case of the previous command.
It will kill all SAs associated with
.Ar vpn_gateway .
.It show-event Op Fl l
Dump all events reported by
.Xr racoon 8 ,
then quit.
The
.Fl l
flag causes
.Nm
to not stop once all the events have been read, but rather to loop
awaiting and reporting new events.
.It show-event
Listen for all events reported by
.Xr racoon 8 .
.It logout-user Ar login
Delete all SA established on behalf of the Xauth user
.Ar login .

View File

@ -1,9 +1,10 @@
/* $NetBSD: racoonctl.c,v 1.8 2007/12/31 01:42:07 mgrooms Exp $ */
/* $NetBSD: racoonctl.c,v 1.9 2008/03/06 00:34:11 mgrooms Exp $ */
/* Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* Copyright (C) 2008 Timo Teras.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -135,26 +136,24 @@ struct cmd_tag {
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 },
{ EVT_RACOON_QUIT, "Racoon terminated" },
{ EVT_PHASE1_UP, "Phase 1 established" },
{ EVT_PHASE1_DOWN, "Phase 1 deleted" },
{ EVT_PHASE1_NO_RESPONSE, "Phase 1 error: peer not responding" },
{ EVT_PHASE1_NO_PROPOSAL, "Phase 1 error: no proposal chosen" },
{ EVT_PHASE1_AUTH_FAILED,
"Phase 1 error: authentication failed (bad certificate?)" },
{ EVT_PHASE1_DPD_TIMEOUT, "Phase 1 error: dead peer detected" },
{ EVT_PHASE1_MODE_CFG, "Phase 1 mode configuration done" },
{ EVT_PHASE1_XAUTH_SUCCESS, "Phase 1 Xauth succeeded" },
{ EVT_PHASE1_XAUTH_FAILED, "Phase 1 Xauth failed" },
{ EVT_PHASE2_NO_PHASE1, "Phase 2 error: no suitable phase 1" },
{ EVT_PHASE2_UP, "Phase 2 established" },
{ EVT_PHASE2_DOWN, "Phase 2 deleted" },
{ EVT_PHASE2_NO_RESPONSE, "Phase 2 error: no response" },
};
static int get_proto __P((char *));
@ -194,31 +193,13 @@ static char _addr1_[NI_MAXHOST], _addr2_[NI_MAXHOST];
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_async *));
char * fixed_addr __P((char *, char *, int));
static void
@ -313,54 +294,24 @@ main(ac, av)
vfree(combuf);
if (com_recv(&combuf) != 0)
goto bad;
if (handle_recv(combuf) != 0)
goto bad;
do {
if (com_recv(&combuf) != 0)
goto bad;
if (handle_recv(combuf) != 0)
goto bad;
vfree(combuf);
} while (evt_quit_event != 0);
vfree(combuf);
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;
}
/* %%% */
/*
* return command buffer.
@ -395,61 +346,42 @@ get_combuf(ac, av)
}
static vchar_t *
f_reload(ac, av)
int ac;
char **av;
make_request(u_int16_t cmd, u_int16_t proto, size_t len)
{
vchar_t *buf;
struct admin_com *head;
buf = vmalloc(sizeof(*head));
buf = vmalloc(sizeof(struct admin_com) + len);
if (buf == NULL)
errx(1, "not enough core");
head = (struct admin_com *)buf->v;
head = (struct admin_com *) buf->v;
head->ac_len = buf->l;
head->ac_cmd = ADMIN_RELOAD_CONF;
head->ac_errno = 0;
head->ac_proto = 0;
head->ac_cmd = ADMIN_FLAG_VERSION | cmd;
head->ac_version = 1;
head->ac_proto = proto;
return buf;
}
static vchar_t *
f_reload(ac, av)
int ac;
char **av;
{
return make_request(ADMIN_RELOAD_CONF, 0, 0);
}
static vchar_t *
f_getevt(ac, av)
int ac;
char **av;
{
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));
if (buf == NULL)
errx(1, "not enough core");
head = (struct admin_com *)buf->v;
head->ac_len = buf->l;
head->ac_cmd = ADMIN_SHOW_EVT;
head->ac_errno = 0;
head->ac_proto = 0;
return buf;
return make_request(ADMIN_SHOW_EVT, 0, 0);
}
static vchar_t *
@ -457,20 +389,7 @@ f_getsched(ac, av)
int ac;
char **av;
{
vchar_t *buf;
struct admin_com *head;
buf = vmalloc(sizeof(*head));
if (buf == NULL)
errx(1, "not enough core");
head = (struct admin_com *)buf->v;
head->ac_len = buf->l;
head->ac_cmd = ADMIN_SHOW_SCHED;
head->ac_errno = 0;
head->ac_proto = 0;
return buf;
return make_request(ADMIN_SHOW_SCHED, 0, 0);
}
static vchar_t *
@ -478,8 +397,6 @@ f_getsa(ac, av)
int ac;
char **av;
{
vchar_t *buf;
struct admin_com *head;
int proto;
/* need protocol */
@ -489,17 +406,7 @@ f_getsa(ac, av)
if (proto == -1)
errx(1, "unknown protocol %s", *av);
buf = vmalloc(sizeof(*head));
if (buf == NULL)
errx(1, "not enough core");
head = (struct admin_com *)buf->v;
head->ac_len = buf->l;
head->ac_cmd = ADMIN_SHOW_SA;
head->ac_errno = 0;
head->ac_proto = proto;
return buf;
return make_request(ADMIN_SHOW_SA, proto, 0);
}
static vchar_t *
@ -518,17 +425,7 @@ f_flushsa(ac, av)
if (proto == -1)
errx(1, "unknown protocol %s", *av);
buf = vmalloc(sizeof(*head));
if (buf == NULL)
errx(1, "not enough core");
head = (struct admin_com *)buf->v;
head->ac_len = buf->l;
head->ac_cmd = ADMIN_FLUSH_SA;
head->ac_errno = 0;
head->ac_proto = proto;
return buf;
return make_request(ADMIN_FLUSH_SA, proto, 0);
}
static vchar_t *
@ -537,7 +434,6 @@ f_deletesa(ac, av)
char **av;
{
vchar_t *buf, *index;
struct admin_com *head;
int proto;
/* need protocol */
@ -567,17 +463,11 @@ f_deletesa(ac, av)
return NULL;
}
buf = vmalloc(sizeof(*head) + index->l);
buf = make_request(ADMIN_DELETE_SA, proto, index->l);
if (buf == NULL)
goto out;
head = (struct admin_com *)buf->v;
head->ac_len = buf->l + index->l;
head->ac_cmd = ADMIN_DELETE_SA;
head->ac_errno = 0;
head->ac_proto = proto;
memcpy(buf->v+sizeof(*head), index->v, index->l);
memcpy(buf->v + sizeof(struct admin_com), index->v, index->l);
out:
if (index != NULL)
@ -592,7 +482,6 @@ f_deleteallsadst(ac, av)
char **av;
{
vchar_t *buf, *index;
struct admin_com *head;
int proto;
/* need protocol */
@ -622,17 +511,11 @@ f_deleteallsadst(ac, av)
return NULL;
}
buf = vmalloc(sizeof(*head) + index->l);
buf = make_request(ADMIN_DELETE_ALL_SA_DST, proto, index->l);
if (buf == NULL)
goto out;
head = (struct admin_com *)buf->v;
head->ac_len = buf->l + index->l;
head->ac_cmd = ADMIN_DELETE_ALL_SA_DST;
head->ac_errno = 0;
head->ac_proto = proto;
memcpy(buf->v+sizeof(*head), index->v, index->l);
memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
out:
if (index != NULL)
@ -647,7 +530,6 @@ f_exchangesa(ac, av)
char **av;
{
vchar_t *buf, *index;
struct admin_com *head;
int proto;
int cmd = ADMIN_ESTABLISH_SA;
size_t com_len = 0;
@ -700,22 +582,17 @@ f_exchangesa(ac, av)
return NULL;
}
com_len += sizeof(*head) + index->l;
if ((buf = vmalloc(com_len)) == NULL)
com_len += index->l;
buf = make_request(cmd, proto, com_len);
if (buf == NULL)
errx(1, "Cannot allocate buffer");
head = (struct admin_com *)buf->v;
head->ac_len = buf->l;
head->ac_cmd = cmd;
head->ac_errno = 0;
head->ac_proto = proto;
memcpy(buf->v+sizeof(*head), index->v, index->l);
memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
if (id && key) {
char *data;
acp = (struct admin_com_psk *)
(buf->v + sizeof(*head) + index->l);
(buf->v + sizeof(struct admin_com) + index->l);
acp->id_type = IDTYPE_USERFQDN;
acp->id_len = strlen(id) + 1;
@ -750,8 +627,7 @@ f_vpnc(ac, av)
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 = EVT_PHASE1_MODE_CFG;
/* Optional -u identity */
if (strcmp(av[0], "-u") == 0) {
@ -815,8 +691,7 @@ f_vpnd(ac, av)
if (ac > 1)
warnx("Extra arguments");
evt_filter =
(EVTF_PH1DOWN|EVTF_PH1DOWN_STOP|EVTF_LOOP|EVTF_ERR|EVTF_ERR_STOP);
evt_quit_event = EVT_PHASE1_DOWN;
nav[nac++] = isakmp;
nav[nac++] = inet;
@ -833,7 +708,6 @@ f_logoutusr(ac, av)
char **av;
{
vchar_t *buf;
struct admin_com *head;
char *user;
/* need username */
@ -843,17 +717,11 @@ f_logoutusr(ac, av)
if ((user == NULL) || (strlen(user) > LOGINLEN))
errx(1, "bad login (too long?)");
buf = vmalloc(sizeof(*head) + strlen(user) + 1);
buf = make_request(ADMIN_LOGOUT_USER, 0, 0);
if (buf == NULL)
return NULL;
head = (struct admin_com *)buf->v;
head->ac_len = buf->l;
head->ac_cmd = ADMIN_LOGOUT_USER;
head->ac_errno = 0;
head->ac_proto = 0;
strncpy((char *)(head + 1), user, LOGINLEN);
strncpy(buf->v + sizeof(struct admin_com), user, LOGINLEN);
return buf;
}
@ -1336,84 +1204,32 @@ print_schedule(buf, len)
void
print_evt(buf, len)
caddr_t buf;
int len;
print_evt(evtdump)
struct evt_async *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
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
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;
}
/*
@ -1424,15 +1240,14 @@ print_cfg(buf, len)
caddr_t buf;
int len;
{
struct evtdump *evtdump = (struct evtdump *)buf;
struct evt_async *evtdump = (struct evt_async *)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 != EVT_PHASE1_MODE_CFG)
return;
len -= sizeof(*evtdump);
@ -1485,12 +1300,12 @@ print_cfg(buf, len)
(n + sizeof(*attr) + ntohs(attr->lorv));
}
}
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");
if (banner) {
struct winsize win;
int col = 0;
@ -1507,13 +1322,8 @@ print_cfg(buf, len)
printf("\n");
racoon_free(banner);
}
if (evt_filter & EVTF_CFG_STOP)
evt_filter &= ~EVTF_LOOP;
return;
}
char *
fixed_addr(addr, port, len)
@ -1548,7 +1358,7 @@ static int
handle_recv(combuf)
vchar_t *combuf;
{
struct admin_com h, *com;
struct admin_com *com;
caddr_t buf;
int len;
@ -1562,32 +1372,29 @@ handle_recv(combuf)
break;
case ADMIN_SHOW_EVT: {
struct evtdump *evtdump;
struct evt_async *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_async))
errx(1, "Short buffer\n");
ec = (struct evt_async *) buf;
if (evt_quit_event <= 0)
print_evt(ec);
else if (evt_quit_event == ec->ec_type) {
switch (ec->ec_type) {
case EVT_PHASE1_MODE_CFG:
print_cfg(ec, len);
break;
default:
print_evt(ec);
break;
}
evt_quit_event = 0;
}
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);
break;
}
@ -1644,10 +1451,8 @@ handle_recv(combuf)
break;
}
close(so);
return 0;
bad:
close(so);
bad:
return -1;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: session.c,v 1.10 2008/03/05 22:09:44 mgrooms Exp $ */
/* $NetBSD: session.c,v 1.11 2008/03/06 00:34:11 mgrooms Exp $ */
/* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */
@ -192,6 +192,7 @@ session(void)
/* 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 @@ session(void)
(FD_ISSET(lcconf->sock_admin, &rfds)))
admin_handler();
#endif
evt_handle_fdmask(&rfds);
for (p = lcconf->myaddrs; p; p = p->next) {
if (!p->addr)
@ -449,7 +451,7 @@ check_sigreq()
case SIGTERM:
plog(LLV_INFO, LOCATION, NULL,
"caught signal %d\n", sig);
EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL);
evt_generic(EVT_RACOON_QUIT, NULL);
pfkey_send_flush(lcconf->sock_pfkey,
SADB_SATYPE_UNSPEC);
#ifdef ENABLE_FASTQUIT