From 7588b01c4f647fa7013a9ca3fc70a4cf7ca56f3c Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Wed, 16 Jun 2010 17:39:06 +0000 Subject: Add support to use sasyncd(8) with iked(8) instead of isakmpd(8). The new config option "control isakmpd|iked|all|none" in sasyncd.conf(5) is used to set the mode; the default is to control isakmpd like before. When controlling iked, sasyncd connects to the daemon using the imsg socket and sends imsgs - this is easy because the imsg framework has been imported into libutil. iked(8) already includes the important bits to work with sasyncd(8) (the active/passive mode option in ikectl). manpage bits ok jsg@ ok jsg@ --- usr.sbin/sasyncd/Makefile | 6 +- usr.sbin/sasyncd/carp.c | 16 ++--- usr.sbin/sasyncd/conf.y | 33 ++++++++- usr.sbin/sasyncd/monitor.c | 144 +++++++++++++++++++++++++++++++++------- usr.sbin/sasyncd/monitor.h | 10 +-- usr.sbin/sasyncd/sasyncd.8 | 7 +- usr.sbin/sasyncd/sasyncd.c | 5 +- usr.sbin/sasyncd/sasyncd.conf.5 | 15 ++++- usr.sbin/sasyncd/sasyncd.h | 11 ++- 9 files changed, 196 insertions(+), 51 deletions(-) diff --git a/usr.sbin/sasyncd/Makefile b/usr.sbin/sasyncd/Makefile index 33965457f1c..03c364e4f6e 100644 --- a/usr.sbin/sasyncd/Makefile +++ b/usr.sbin/sasyncd/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.5 2005/05/24 02:35:39 ho Exp $ +# $Id: Makefile,v 1.6 2010/06/16 17:39:05 reyk Exp $ PROG= sasyncd SRCS= sasyncd.c carp.c conf.y log.c monitor.c net.c net_ctl.c pfkey.c timer.c @@ -8,7 +8,7 @@ MAN= sasyncd.8 sasyncd.conf.5 CFLAGS= -O0 $(PIPE) $(DEBUG) .endif -CFLAGS+= -I${.CURDIR} +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../sbin/iked CLEANFILES= y.tab.h # ElectricFence @@ -20,6 +20,6 @@ CLEANFILES= y.tab.h CFLAGS+= -Wall -Wstrict-prototypes -Wmissing-prototypes \ -Wmissing-declarations -LDADD+= -lcrypto +LDADD+= -lcrypto -lutil .include diff --git a/usr.sbin/sasyncd/carp.c b/usr.sbin/sasyncd/carp.c index 3fe52854912..85bed1bab0a 100644 --- a/usr.sbin/sasyncd/carp.c +++ b/usr.sbin/sasyncd/carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: carp.c,v 1.10 2009/06/26 13:25:23 deraadt Exp $ */ +/* $OpenBSD: carp.c,v 1.11 2010/06/16 17:39:05 reyk Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -173,7 +173,7 @@ carp_update_state(enum RUNSTATE current_state) cfgstate.runstate = current_state; if (current_state == MASTER) pfkey_set_promisc(); - isakmpd_setrun(); + control_setrun(); net_ctl_update_state(); } } @@ -269,15 +269,15 @@ carp_init(void) return 0; } -/* Enable or disable isakmpd connection checker. */ +/* Enable or disable isakmpd/iked connection checker. */ void -isakmpd_setrun(void) +control_setrun(void) { if (cfgstate.runstate == MASTER) { - if (monitor_isakmpd_active(1)) - log_msg(0, "failed to activate isakmpd"); + if (monitor_control_active(1)) + log_msg(0, "failed to activate controlled daemon"); } else { - if (monitor_isakmpd_active(0)) - log_msg(0, "failed to passivate isakmpd"); + if (monitor_control_active(0)) + log_msg(0, "failed to passivate controlled daemon"); } } diff --git a/usr.sbin/sasyncd/conf.y b/usr.sbin/sasyncd/conf.y index 338de98236b..947bb6891c5 100644 --- a/usr.sbin/sasyncd/conf.y +++ b/usr.sbin/sasyncd/conf.y @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.y,v 1.14 2007/05/17 11:01:36 moritz Exp $ */ +/* $OpenBSD: conf.y,v 1.15 2010/06/16 17:39:05 reyk Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -64,11 +64,11 @@ unsigned char x2i(unsigned char *); %token MODE INTERFACE INTERVAL LISTEN ON PORT PEER SHAREDKEY %token Y_SLAVE Y_MASTER INET INET6 FLUSHMODE STARTUP NEVER SYNC -%token GROUP SKIPSLAVE +%token GROUP SKIPSLAVE CONTROL %token STRING %token HEX %token VALUE -%type af port mode flushmode +%type af port mode flushmode ctlmode %% /* Rules */ @@ -125,6 +125,27 @@ key : STRING log_msg(2, "config: %d byte shared hex key", $1.len); } +ctlmode : STRING + { + /* Compare strings to avoid keywords for daemons */ + if (strcmp("isakmpd", $1) == 0) + $$ = CTL_ISAKMPD; + else if (strcmp("iked", $1) == 0) + $$ = CTL_IKED; + else if (strcmp("all", $1) == 0) + $$ = CTL_MASK; + else if (strcmp("none", $1) == 0) + $$ = CTL_NONE; + else { + log_err("config: invalid control mode"); + free($1); + YYERROR; + } + log_msg(2, "config: control mode set to %s", $1); + free($1); + } + ; + setting : INTERFACE STRING { if (cfgstate.carp_ifname) @@ -210,6 +231,11 @@ setting : INTERFACE STRING } log_msg(2, "config: shared key set"); } + | CONTROL ctlmode + { + cfgstate.flags &= ~CTL_MASK; + cfgstate.flags |= $2; + } ; %% @@ -231,6 +257,7 @@ match(char *token) { /* Sorted */ static const struct keyword keywords[] = { + { "control", CONTROL }, { "flushmode", FLUSHMODE }, { "group", GROUP }, { "inet", INET }, diff --git a/usr.sbin/sasyncd/monitor.c b/usr.sbin/sasyncd/monitor.c index 45072e7463e..613af4d60d6 100644 --- a/usr.sbin/sasyncd/monitor.c +++ b/usr.sbin/sasyncd/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.12 2006/12/25 08:17:17 deraadt Exp $ */ +/* $OpenBSD: monitor.c,v 1.13 2010/06/16 17:39:05 reyk Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,9 @@ #include #include #include +#include + +#include "types.h" /* iked imsg types */ #include "monitor.h" #include "sasyncd.h" @@ -55,8 +59,8 @@ volatile sig_atomic_t sigchld = 0; static void got_sigchld(int); static void sig_to_child(int); static void m_priv_pfkey_snap(int); -static void m_priv_isakmpd_activate(void); -static void m_priv_isakmpd_passivate(void); +static int m_priv_control_activate(void); +static int m_priv_control_passivate(void); static ssize_t m_write(int, void *, size_t); static ssize_t m_read(int, void *, size_t); @@ -146,10 +150,20 @@ monitor_drain_input(void) void monitor_loop(void) { - u_int32_t v; - ssize_t r; + u_int32_t v, vn; + ssize_t r; + fd_set rfds; + int ret; + struct timeval *tvp, tv; + + FD_ZERO(&rfds); + tvp = NULL; + vn = 0; for (;;) { + ret = 0; + v = 0; + if (sigchld) { pid_t pid; int status; @@ -162,13 +176,30 @@ monitor_loop(void) break; } - /* Wait for next task */ - if ((r = m_read(m_state.s, &v, sizeof v)) < 1) { - if (r == -1) - log_err(0, "monitor_loop: read() "); + FD_SET(m_state.s, &rfds); + if (select(m_state.s + 1, &rfds, NULL, NULL, tvp) == -1) { + if (errno == EINTR || errno == EAGAIN) + continue; + log_err(0, "monitor_loop: select() "); break; } + /* Wait for next task */ + if (FD_ISSET(m_state.s, &rfds)) { + if ((r = m_read(m_state.s, &v, sizeof v)) < 1) { + if (r == -1) + log_err(0, "monitor_loop: read() "); + break; + } + } + + /* Retry after timeout */ + if (v == 0 && tvp != NULL) { + v = vn; + tvp = NULL; + vn = 0; + } + switch (v) { case MONITOR_GETSNAP: /* Get the data. */ @@ -180,13 +211,21 @@ monitor_loop(void) case MONITOR_CARPDEC: carp_demote(CARP_DEC, 1); break; - case MONITOR_ISAKMPD_ACTIVATE: - m_priv_isakmpd_activate(); + case MONITOR_CONTROL_ACTIVATE: + ret = m_priv_control_activate(); break; - case MONITOR_ISAKMPD_PASSIVATE: - m_priv_isakmpd_passivate(); + case MONITOR_CONTROL_PASSIVATE: + ret = m_priv_control_passivate(); break; } + + if (ret == -1) { + /* Trigger retry after timeout */ + tv.tv_sec = MONITOR_RETRY_TIMEOUT; + tv.tv_usec = 0; + tvp = &tv; + vn = v; + } } monitor_carpundemote(NULL); @@ -288,10 +327,10 @@ monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd, } int -monitor_isakmpd_active(int active) +monitor_control_active(int active) { u_int32_t cmd = - active ? MONITOR_ISAKMPD_ACTIVATE : MONITOR_ISAKMPD_PASSIVATE; + active ? MONITOR_CONTROL_ACTIVATE : MONITOR_CONTROL_PASSIVATE; if (write(m_state.s, &cmd, sizeof cmd) < 1) return -1; return 0; @@ -386,11 +425,11 @@ m_priv_pfkey_snap(int s) return; } -static void +static int m_priv_isakmpd_fifocmd(const char *cmd) { struct stat sb; - int fd = -1; + int fd = -1, ret = -1; if ((fd = open(ISAKMPD_FIFO, O_WRONLY)) == -1) { log_err("m_priv_isakmpd_fifocmd: open(%s)", ISAKMPD_FIFO); @@ -409,23 +448,78 @@ m_priv_isakmpd_fifocmd(const char *cmd) log_err("m_priv_isakmpd_fifocmd write"); goto out; } + + ret = 0; out: if (fd != -1) close(fd); - /* No values returned. */ - return; + + return (ret); } -static void -m_priv_isakmpd_activate(void) +static int +m_priv_iked_imsg(u_int cmd) { - m_priv_isakmpd_fifocmd("M active\n"); + struct sockaddr_un sun; + int fd = -1, ret = -1; + struct imsgbuf ibuf; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + log_err("m_priv_iked_imsg: socket"); + goto out; + } + + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_UNIX; + strlcpy(sun.sun_path, IKED_SOCKET, sizeof(sun.sun_path)); + + if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { + log_err("m_priv_iked_imsg: connect"); + goto out; + } + + imsg_init(&ibuf, fd); + if (imsg_compose(&ibuf, cmd, 0, 0, -1, NULL, 0) == -1) { + log_err("m_priv_iked_imsg: compose"); + goto err; + } + if (imsg_flush(&ibuf) == -1) { + log_err("m_priv_iked_imsg: flush"); + goto err; + } + + ret = 0; + err: + imsg_clear(&ibuf); + out: + if (fd != -1) + close(fd); + + return (ret); } -static void -m_priv_isakmpd_passivate(void) +static int +m_priv_control_activate(void) +{ + if (cfgstate.flags & CTL_ISAKMPD) + if (m_priv_isakmpd_fifocmd("M active\n") == -1) + return (-1); + if (cfgstate.flags & CTL_IKED) + if (m_priv_iked_imsg(IMSG_CTL_ACTIVE) == -1) + return (-1); + return (0); +} + +static int +m_priv_control_passivate(void) { - m_priv_isakmpd_fifocmd("M passive\n"); + if (cfgstate.flags & CTL_ISAKMPD) + if (m_priv_isakmpd_fifocmd("M passive\n") == -1) + return (-1); + if (cfgstate.flags & CTL_IKED) + if (m_priv_iked_imsg(IMSG_CTL_PASSIVE) == -1) + return (-1); + return (0); } ssize_t diff --git a/usr.sbin/sasyncd/monitor.h b/usr.sbin/sasyncd/monitor.h index 10cf767e307..3548729708b 100644 --- a/usr.sbin/sasyncd/monitor.h +++ b/usr.sbin/sasyncd/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.1 2006/09/01 01:13:25 mpf Exp $ */ +/* $OpenBSD: monitor.h,v 1.2 2010/06/16 17:39:05 reyk Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -28,8 +28,10 @@ #define MONITOR_GETSNAP 1 #define MONITOR_CARPINC 2 #define MONITOR_CARPDEC 3 -#define MONITOR_ISAKMPD_ACTIVATE 4 -#define MONITOR_ISAKMPD_PASSIVATE 5 +#define MONITOR_CONTROL_ACTIVATE 4 +#define MONITOR_CONTROL_PASSIVATE 5 + +#define MONITOR_RETRY_TIMEOUT 4 #define ISAKMPD_FIFO "/var/run/isakmpd.fifo" @@ -38,4 +40,4 @@ void monitor_loop(void); int monitor_get_pfkey_snap(u_int8_t **, u_int32_t *, u_int8_t **, u_int32_t *); -int monitor_isakmpd_active(int); +int monitor_control_active(int); diff --git a/usr.sbin/sasyncd/sasyncd.8 b/usr.sbin/sasyncd/sasyncd.8 index 9e4970a9b50..89ce15ca158 100644 --- a/usr.sbin/sasyncd/sasyncd.8 +++ b/usr.sbin/sasyncd/sasyncd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sasyncd.8,v 1.10 2008/04/04 06:21:27 otto Exp $ +.\" $OpenBSD: sasyncd.8,v 1.11 2010/06/16 17:39:05 reyk Exp $ .\" .\" Copyright (c) 2005 Håkan Olsson. All rights reserved. .\" @@ -27,7 +27,7 @@ .\" .\" Manual page for sasyncd .\" -.Dd $Mdocdate: April 4 2008 $ +.Dd $Mdocdate: June 16 2010 $ .Dt SASYNCD 8 .Os .Sh NAME @@ -46,6 +46,8 @@ The most typical scenario is to run .Nm on hosts also running .Xr isakmpd 8 +or +.Xr iked 8 and sharing a common IP address using .Xr carp 4 . .Pp @@ -136,6 +138,7 @@ configuration file. .Xr ipsec 4 , .Xr pfsync 4 , .Xr sasyncd.conf 5 , +.Xr iked 8 , .Xr isakmpd 8 .Sh HISTORY The diff --git a/usr.sbin/sasyncd/sasyncd.c b/usr.sbin/sasyncd/sasyncd.c index 4a53424fa71..46a14c401ab 100644 --- a/usr.sbin/sasyncd/sasyncd.c +++ b/usr.sbin/sasyncd/sasyncd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sasyncd.c,v 1.19 2009/11/11 23:05:40 deraadt Exp $ */ +/* $OpenBSD: sasyncd.c,v 1.20 2010/06/16 17:39:05 reyk Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -76,7 +76,7 @@ sasyncd_run(pid_t ppid) return -1; } - isakmpd_setrun(); + control_setrun(); signal(SIGINT, sasyncd_stop); signal(SIGTERM, sasyncd_stop); @@ -185,6 +185,7 @@ main(int argc, char **argv) LIST_INIT(&cfgstate.peerlist); cfgstate.listen_port = SASYNCD_DEFAULT_PORT; + cfgstate.flags |= CTL_DEFAULT; if (!cfgfile) cfgfile = SASYNCD_CFGFILE; diff --git a/usr.sbin/sasyncd/sasyncd.conf.5 b/usr.sbin/sasyncd/sasyncd.conf.5 index 6fa24dab74e..26b3a00ade7 100644 --- a/usr.sbin/sasyncd/sasyncd.conf.5 +++ b/usr.sbin/sasyncd/sasyncd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sasyncd.conf.5,v 1.15 2007/05/31 19:20:29 jmc Exp $ +.\" $OpenBSD: sasyncd.conf.5,v 1.16 2010/06/16 17:39:05 reyk Exp $ .\" .\" Copyright (c) 2005 Håkan Olsson. All rights reserved. .\" @@ -27,7 +27,7 @@ .\" .\" Manual page for sasyncd.conf .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: June 16 2010 $ .Dt SASYNCD.CONF 5 .Os .Sh NAME @@ -157,6 +157,17 @@ The shared AES key used to encrypt messages between hosts. This configuration setting is required and must be either 16, 24 or 32 bytes long (corresponding to AES using a 128, 192 or 256 bit key). +.It Ic control isakmpd | iked | all | none +By default, +.Xr sasyncd 8 +tracks its local master/slave mode and toggles the passive mode of +.Xr isakmpd 8 +accordingly. +This option can be changed to control +.Xr iked 8 +instead, +to control all supported daemons at the same time, +or to turn it off to synchronize SAs only. .El .Sh SEE ALSO .Xr chmod 1 , diff --git a/usr.sbin/sasyncd/sasyncd.h b/usr.sbin/sasyncd/sasyncd.h index 92939f3a6c5..d518087b207 100644 --- a/usr.sbin/sasyncd/sasyncd.h +++ b/usr.sbin/sasyncd/sasyncd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sasyncd.h,v 1.14 2007/01/08 15:31:01 markus Exp $ */ +/* $OpenBSD: sasyncd.h,v 1.15 2010/06/16 17:39:05 reyk Exp $ */ /* * Copyright (c) 2005 Håkan Olsson. All rights reserved. @@ -73,6 +73,13 @@ struct cfgstate { /* Do not sync SAs to/from our peers. */ #define SKIP_LOCAL_SAS 0x0004 +/* Control isakmpd or iked */ +#define CTL_NONE 0x0000 +#define CTL_ISAKMPD 0x0008 +#define CTL_IKED 0x0010 +#define CTL_DEFAULT CTL_ISAKMPD +#define CTL_MASK 0x0018 + extern struct cfgstate cfgstate; extern int carp_demoted; @@ -113,7 +120,7 @@ void carp_update_state(enum RUNSTATE); void carp_set_rfd(fd_set *); void carp_read_message(fd_set *); const char* carp_state_name(enum RUNSTATE); -void isakmpd_setrun(void); +void control_setrun(void); /* log.c */ -- cgit v1.2.3