diff options
-rw-r--r-- | usr.sbin/sasyncd/conf.y | 25 | ||||
-rw-r--r-- | usr.sbin/sasyncd/log.c | 3 | ||||
-rw-r--r-- | usr.sbin/sasyncd/monitor.c | 53 | ||||
-rw-r--r-- | usr.sbin/sasyncd/net.c | 12 | ||||
-rw-r--r-- | usr.sbin/sasyncd/net_ctl.c | 8 | ||||
-rw-r--r-- | usr.sbin/sasyncd/pfkey.c | 47 | ||||
-rw-r--r-- | usr.sbin/sasyncd/sasyncd.h | 16 |
7 files changed, 116 insertions, 48 deletions
diff --git a/usr.sbin/sasyncd/conf.y b/usr.sbin/sasyncd/conf.y index 1ae00cf5879..f824ecdb894 100644 --- a/usr.sbin/sasyncd/conf.y +++ b/usr.sbin/sasyncd/conf.y @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.y,v 1.3 2005/05/24 19:18:10 ho Exp $ */ +/* $OpenBSD: conf.y,v 1.4 2005/05/26 19:19:51 ho Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -58,10 +58,10 @@ void yyerror(const char *); } %token MODE CARP INTERFACE INTERVAL LISTEN ON PORT PEER SHAREDKEY -%token Y_SLAVE Y_MASTER INET INET6 +%token Y_SLAVE Y_MASTER INET INET6 FLUSHMODE STARTUP NEVER SYNC %token <string> STRING %token <val> VALUE -%type <val> af port interval mode +%type <val> af port interval mode flushmode %% /* Rules */ @@ -87,6 +87,11 @@ interval : /* empty */ { $$ = CARP_DEFAULT_INTERVAL; } | INTERVAL VALUE { $$ = $2; } ; +flushmode : STARTUP { $$ = FM_STARTUP; } + | NEVER { $$ = FM_NEVER; } + | SYNC { $$ = FM_SYNC; } + ; + setting : CARP INTERFACE STRING interval { if (cfgstate.carp_ifname) @@ -96,6 +101,12 @@ setting : CARP INTERFACE STRING interval log_msg(2, "config: carp interface %s interval %d", $3, $4); } + | FLUSHMODE flushmode + { + const char *fm[] = FLUSHMODES; + cfgstate.flushmode = $2; + log_msg(2, "config: flush mode set to %s", fm[$2]); + } | PEER STRING { struct syncpeer *peer; @@ -146,9 +157,9 @@ setting : CARP INTERFACE STRING interval } | mode { + const char *m[] = CARPSTATES; cfgstate.lockedstate = $1; - log_msg(2, "config: mode set to %s", - $1 == MASTER ? "MASTER" : "SLAVE"); + log_msg(2, "config: mode set to %s", m[$1]); } | SHAREDKEY STRING { @@ -179,6 +190,7 @@ match(char *token) /* Sorted */ static const struct keyword keywords[] = { { "carp", CARP }, + { "flushmode", FLUSHMODE }, { "inet", INET }, { "inet6", INET6 }, { "interface", INTERFACE }, @@ -186,11 +198,14 @@ match(char *token) { "listen", LISTEN }, { "master", Y_MASTER }, { "mode", MODE }, + { "never", NEVER }, { "on", ON }, { "peer", PEER }, { "port", PORT }, { "sharedkey", SHAREDKEY }, { "slave", Y_SLAVE }, + { "startup", STARTUP }, + { "sync", SYNC }, }; const struct keyword *k; diff --git a/usr.sbin/sasyncd/log.c b/usr.sbin/sasyncd/log.c index e7e7aa9fd4b..70003eb89b9 100644 --- a/usr.sbin/sasyncd/log.c +++ b/usr.sbin/sasyncd/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.3 2005/05/22 12:14:16 ho Exp $ */ +/* $OpenBSD: log.c,v 1.4 2005/05/26 19:19:51 ho Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -29,7 +29,6 @@ * This code was written under funding by Multicom Security AB. */ - #include <sys/types.h> #include <stdio.h> #include <string.h> diff --git a/usr.sbin/sasyncd/monitor.c b/usr.sbin/sasyncd/monitor.c index e3abbe34e24..496f3b9668c 100644 --- a/usr.sbin/sasyncd/monitor.c +++ b/usr.sbin/sasyncd/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.3 2005/05/26 05:33:48 ho Exp $ */ +/* $OpenBSD: monitor.c,v 1.4 2005/05/26 19:19:51 ho Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -123,36 +123,51 @@ sig_to_child(int s) kill(m_state.pid, s); } +static void +monitor_drain_input(void) +{ + int one = 1; + u_int8_t tmp; + + ioctl(m_state.s, FIONBIO, &one); + while (read(m_state.s, &tmp, 1) > 0) + ; + ioctl(m_state.s, FIONBIO, 0); +} + /* We only use privsep to get in-kernel SADB and SPD snapshots via sysctl */ void monitor_loop(void) { - extern volatile sig_atomic_t daemon_shutdown; - pid_t pid; - int status; u_int32_t v; + ssize_t r; - while (!daemon_shutdown) { + for (;;) { if (sigchld) { + pid_t pid; + int status; do { pid = waitpid(m_state.pid, &status, WNOHANG); } while (pid == -1 && errno == EINTR); if (pid == m_state.pid && - (WIFEXITED(status) || WIFSIGNALED(status))) { - daemon_shutdown++; + (WIFEXITED(status) || WIFSIGNALED(status))) break; - } } /* Wait for next snapshot task. Disregard read data. */ - if (read(m_state.s, &v, sizeof v) != (ssize_t)sizeof v) + if ((r = read(m_state.s, &v, sizeof v)) != sizeof v) { + if (r == -1) + log_err(0, "monitor_loop: read() "); break; + } /* Get the data. */ m_priv_pfkey_snap(m_state.s); } - + + if (!sigchld) + log_msg(0, "monitor_loop: priv process exiting abnormally"); exit(0); } @@ -160,13 +175,11 @@ int monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd, u_int32_t *spdsize) { - int one = 1; - u_int8_t tmp; u_int32_t rbytes; /* We write a (any) value to the monitor socket to start a snapshot. */ - *sadbsize = 0; - if (write(m_state.s, sadbsize, sizeof *sadbsize) < 1) + rbytes = 0; + if (write(m_state.s, &rbytes, sizeof rbytes) < 1) return -1; /* Read SADB data. */ @@ -178,10 +191,7 @@ monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd, *sadb = (u_int8_t *)malloc(*sadbsize); if (!*sadb) { log_err("monitor_get_pfkey_snap: malloc()"); - /* Drain input */ - ioctl(m_state.s, FIONBIO, &one); - while (read(m_state.s, &tmp, 1) > 0); - ioctl(m_state.s, FIONBIO, 0); + monitor_drain_input(); return -1; } rbytes = read(m_state.s, *sadb, *sadbsize); @@ -205,10 +215,7 @@ monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd, *spd = (u_int8_t *)malloc(*spdsize); if (!*spd) { log_err("monitor_get_pfkey_snap: malloc()"); - /* Drain input */ - ioctl(m_state.s, FIONBIO, &one); - while (read(m_state.s, &tmp, 1) > 0); - ioctl(m_state.s, FIONBIO, 0); + monitor_drain_input(); if (*sadbsize) { memset(*sadb, 0, *sadbsize); free(*sadb); @@ -228,7 +235,7 @@ monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd, } } - log_msg(5, "monitor_get_pfkey_snap: got %d bytes SADB, %d bytes SPD", + log_msg(3, "monitor_get_pfkey_snap: got %d bytes SADB, %d bytes SPD", *sadbsize, *spdsize); return 0; } diff --git a/usr.sbin/sasyncd/net.c b/usr.sbin/sasyncd/net.c index 63b6b938038..6e4d4104327 100644 --- a/usr.sbin/sasyncd/net.c +++ b/usr.sbin/sasyncd/net.c @@ -1,4 +1,4 @@ -/* $OpenBSD: net.c,v 1.6 2005/05/24 19:18:11 ho Exp $ */ +/* $OpenBSD: net.c,v 1.7 2005/05/26 19:19:51 ho Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -139,10 +139,10 @@ net_add_listener(struct sockaddr *sa) if (getnameinfo(sa, sa->sa_len, host, sizeof host, port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV)) - log_msg(2, "listening on port %u fd %d", cfgstate.listen_port, + log_msg(3, "listening on port %u fd %d", cfgstate.listen_port, s); else - log_msg(2, "listening on %s port %s fd %d", host, port, s); + log_msg(3, "listening on %s port %s fd %d", host, port, s); return s; } @@ -538,7 +538,7 @@ net_handle_messages(fd_set *fds) if (!msg) continue; - log_msg(4, "net_handle_messages: got msg type %u len %u from " + log_msg(5, "net_handle_messages: got msg type %u len %u from " "peer %s", msgtype, msglen, p->name); switch (msgtype) { @@ -588,7 +588,7 @@ net_send_messages(fd_set *fds) } m = qm->msg; - log_msg(4, "net_send_messages: msg %p len %d ref %d " + log_msg(5, "net_send_messages: msg %p len %d ref %d " "to peer %s", m, m->len, m->refcnt, p->name); /* write message */ @@ -607,7 +607,7 @@ net_send_messages(fd_set *fds) free(qm); if (--m->refcnt < 1) { - log_msg(4, "net_send_messages: freeing msg %p", m); + log_msg(5, "net_send_messages: freeing msg %p", m); free(m->buf); free(m); } diff --git a/usr.sbin/sasyncd/net_ctl.c b/usr.sbin/sasyncd/net_ctl.c index 17d169506f3..820551b4cad 100644 --- a/usr.sbin/sasyncd/net_ctl.c +++ b/usr.sbin/sasyncd/net_ctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: net_ctl.c,v 1.5 2005/05/24 19:17:07 ho Exp $ */ +/* $OpenBSD: net_ctl.c,v 1.6 2005/05/26 19:19:51 ho Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -92,7 +92,7 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen) switch (ntohl(ctl->type)) { case CTL_STATE: - log_msg(5, "net_ctl: got CTL_STATE from peer \"%s\"", p->name); + log_msg(4, "net_ctl: got CTL_STATE from peer \"%s\"", p->name); nstate = (enum RUNSTATE)ntohl(ctl->data); if (net_ctl_check_state(p, nstate) == 0) net_ctl_send_ack(p, CTL_STATE, cfgstate.runstate); @@ -124,7 +124,7 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen) ct = "<unknown>"; else ct = ctltype[ctype]; - log_msg(5, "net_ctl: got %s ACK from peer \"%s\"", ct, + log_msg(4, "net_ctl: got %s ACK from peer \"%s\"", ct, p->name); if (ctype == CTL_STATE) { nstate = (enum RUNSTATE)ntohl(ctl->data2); @@ -189,7 +189,7 @@ net_ctl_update_state(void) for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) { if (p->socket == -1) continue; - log_msg(3, "net_ctl: sending my state %s to peer \"%s\"", + log_msg(4, "net_ctl: sending my state %s to peer \"%s\"", carpstate[cfgstate.runstate], p->name); net_ctl_send_state(p); } diff --git a/usr.sbin/sasyncd/pfkey.c b/usr.sbin/sasyncd/pfkey.c index f1955a436ae..4e29c4ee8c6 100644 --- a/usr.sbin/sasyncd/pfkey.c +++ b/usr.sbin/sasyncd/pfkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkey.c,v 1.8 2005/05/26 05:34:17 ho Exp $ */ +/* $OpenBSD: pfkey.c,v 1.9 2005/05/26 19:19:51 ho Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -46,6 +46,7 @@ #include <unistd.h> #include "sasyncd.h" +#include "net.h" struct pfkey_msg { @@ -101,6 +102,28 @@ pfkey_set_promisc(void) return pfkey_write((u_int8_t *)&msg, sizeof msg); } +/* Send a SADB_FLUSH PFKEY message to peer 'p' */ +static void +pfkey_send_flush(struct syncpeer *p) +{ + struct sadb_msg *m = (struct sadb_msg *)calloc(1, sizeof *m); + static u_int32_t seq = 1; + + if (m) { + memset(m, 0, sizeof *m); + m->sadb_msg_version = PF_KEY_V2; + m->sadb_msg_seq = seq++; + m->sadb_msg_type = SADB_FLUSH; + m->sadb_msg_satype = SADB_SATYPE_UNSPEC; + m->sadb_msg_pid = getpid(); + m->sadb_msg_len = sizeof *m / CHUNK; + + log_msg(3, "pfkey_send_flush: sending FLUSH to peer %s", + p->name); + net_queue(p, MSG_PFKEYDATA, (u_int8_t *)m, sizeof *m); + } +} + static const char * pfkey_print_type(struct sadb_msg *msg) { @@ -148,6 +171,12 @@ pfkey_handle_message(struct sadb_msg *m) return 0; } + if (msg->sadb_msg_type == SADB_FLUSH && + cfgstate.flushmode == FM_NEVER) { + free(m); + return 0; + } + switch (msg->sadb_msg_type) { case SADB_X_PROMISC: case SADB_DUMP: @@ -329,9 +358,13 @@ pfkey_snapshot(void *v) return; } + /* XXX needs moving if snapshot is called more than once per peer */ + if (cfgstate.flushmode == FM_STARTUP) + pfkey_send_flush(p); + /* Parse SADB data */ if (sadbsz && sadb) { - dump_buf(5, sadb, sadbsz, "pfkey_snapshot: SADB data"); + dump_buf(3, sadb, sadbsz, "pfkey_snapshot: SADB data"); max = sadb + sadbsz; for (next = sadb; next < max; next += m->sadb_msg_len * CHUNK) { @@ -342,25 +375,25 @@ pfkey_snapshot(void *v) /* Tweak and send this SA to the peer. */ m->sadb_msg_type = SADB_ADD; - /* XXX Locate lifetime_cur ext and zero bytes */ - /* Allocate msgbuffer, net_queue() will free it. */ sendbuf = (u_int8_t *)malloc(m->sadb_msg_len * CHUNK); if (sendbuf) { memcpy(sendbuf, m, m->sadb_msg_len * CHUNK); net_queue(p, MSG_PFKEYDATA, sendbuf, m->sadb_msg_len * CHUNK); + log_msg(3, "pfkey_snapshot: sync SA %p to" + "peer %s", m, p->name); } } memset(sadb, 0, sadbsz); free(sadb); } -#ifdef notyet /* Parse SPD data */ if (spdsz && spd) { +#ifdef notyet struct ipsec_policy *ip; - dump_buf(5, spd, spdsz, "pfkey_snapshot: SPD data"); + dump_buf(3, spd, spdsz, "pfkey_snapshot: SPD data"); max = spd + spdsz; for (next = spd; next < max; @@ -370,11 +403,11 @@ pfkey_snapshot(void *v) continue; /* XXX incomplete */ } +#endif /* Cleanup. */ memset(spd, 0, spdsz); free(spd); } -#endif return; } diff --git a/usr.sbin/sasyncd/sasyncd.h b/usr.sbin/sasyncd/sasyncd.h index 7409cfff715..f99384a9346 100644 --- a/usr.sbin/sasyncd/sasyncd.h +++ b/usr.sbin/sasyncd/sasyncd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sasyncd.h,v 1.6 2005/05/24 19:18:11 ho Exp $ */ +/* $OpenBSD: sasyncd.h,v 1.7 2005/05/26 19:19:51 ho Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -35,6 +35,9 @@ enum RUNSTATE { INIT = 0, SLAVE, MASTER, FAIL }; #define CARPSTATES { "INIT", "SLAVE", "MASTER", "FAIL" } +enum FLUSHMODE { FM_STARTUP = 0, FM_NEVER, FM_SYNC }; +#define FLUSHMODES { "STARTUP", "NEVER", "SYNC" }; + struct syncpeer; struct timeval; @@ -43,6 +46,7 @@ struct cfgstate { enum RUNSTATE lockedstate; int debug; int verboselevel; + enum FLUSHMODE flushmode; char *carp_ifname; int carp_check_interval; @@ -88,6 +92,16 @@ void carp_check_state(void); int carp_init(void); /* log.c */ +/* + * Log levels for log_msg(level, ...) roughly means: + * 0 = errors and other important messages + * 1 = state changes, ctl message errors and dis-/connecting peers + * 2 = configuration and initialization messages + * 3 = PF_KEY logging + * 4 = misc network + * 5 = crypto + * 6 = timers + */ void log_init(char *); void log_msg(int, const char *, ...); void log_err(const char *, ...); |