summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/sasyncd/Makefile6
-rw-r--r--usr.sbin/sasyncd/net.c110
-rw-r--r--usr.sbin/sasyncd/net.h4
-rw-r--r--usr.sbin/sasyncd/net_ctl.c25
-rw-r--r--usr.sbin/sasyncd/pfkey.c14
-rw-r--r--usr.sbin/sasyncd/timer.c6
6 files changed, 100 insertions, 65 deletions
diff --git a/usr.sbin/sasyncd/Makefile b/usr.sbin/sasyncd/Makefile
index 33feeabf7dc..3170f0f083f 100644
--- a/usr.sbin/sasyncd/Makefile
+++ b/usr.sbin/sasyncd/Makefile
@@ -1,9 +1,13 @@
-# $Id: Makefile,v 1.3 2005/05/22 20:35:48 ho Exp $
+# $Id: Makefile,v 1.4 2005/05/23 19:53:27 ho Exp $
PROG= sasyncd
SRCS= sasyncd.c carp.c conf.y log.c net.c net_ctl.c pfkey.c timer.c
MAN= sasyncd.8 sasyncd.conf.5
+.ifdef DEBUG
+CFLAGS= -O0 $(PIPE) $(DEBUG)
+.endif
+
CFLAGS+= -I${.CURDIR}
CLEANFILES= y.tab.h
diff --git a/usr.sbin/sasyncd/net.c b/usr.sbin/sasyncd/net.c
index d38eb2b379b..c8ac1f5a8ad 100644
--- a/usr.sbin/sasyncd/net.c
+++ b/usr.sbin/sasyncd/net.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: net.c,v 1.3 2005/05/23 17:35:01 ho Exp $ */
+/* $OpenBSD: net.c,v 1.4 2005/05/23 19:53:27 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -63,26 +63,41 @@ struct qmsg {
int listen_socket;
AES_KEY aes_key[2];
-#define AES_IV_LEN AES_BLOCK_SIZE
+#define AES_IV_LEN AES_BLOCK_SIZE
+
+/* We never send (or expect to receive) messages smaller/larger than this. */
+#define MSG_MINLEN 12
+#define MSG_MAXLEN 4096
/* Local prototypes. */
static u_int8_t *net_read(struct syncpeer *, u_int32_t *, u_int32_t *);
static int net_set_sa(struct sockaddr *, char *, in_port_t);
static void net_check_peers(void *);
+/* Pretty-print a buffer. */
static void
dump_buf(int lvl, u_int8_t *b, u_int32_t len, char *title)
{
- u_int32_t i, off, blen = len*2 + 3 + strlen(title);
- u_int8_t *buf = calloc(1, blen);
+ u_int32_t i, off, blen;
+ u_int8_t *buf;
+ const char def[] = "Buffer:";
- if (!buf || cfgstate.verboselevel < lvl)
+ if (cfgstate.verboselevel < lvl)
return;
- snprintf(buf, blen, "%s:\n", title);
+ blen = 2 * (len + len / 36) + 3 + (title ? strlen(title) : sizeof def);
+ if (!(buf = (u_int8_t *)calloc(1, blen)))
+ return;
+
+ snprintf(buf, blen, "%s\n ", title ? title : def);
off = strlen(buf);
- for (i = 0; i < len; i++, off+=2)
+ for (i = 0; i < len; i++, off+=2) {
snprintf(buf + off, blen - off, "%02x", b[i]);
+ if ((i+1) % 36 == 0) {
+ off += 2;
+ snprintf(buf + off, blen - off, "\n ");
+ }
+ }
log_msg(lvl, "%s", buf);
free(buf);
}
@@ -208,7 +223,7 @@ net_queue(struct syncpeer *p0, u_int32_t msgtype, u_int8_t *buf, u_int32_t len)
SHA1_Init(&ctx);
SHA1_Update(&ctx, buf, len);
SHA1_Final(hash, &ctx);
- dump_buf(5, hash, sizeof hash, "Hash");
+ dump_buf(5, hash, sizeof hash, "net_queue: computed hash");
/* Padding required? */
i = len % AES_IV_LEN;
@@ -233,13 +248,13 @@ net_queue(struct syncpeer *p0, u_int32_t msgtype, u_int8_t *buf, u_int32_t len)
v = arc4random();
memcpy(&iv[i], &v, sizeof v);
}
- dump_buf(5, iv, sizeof iv, "IV");
+ dump_buf(5, iv, sizeof iv, "net_queue: IV");
memcpy(tmp_iv, iv, sizeof tmp_iv);
/* Encrypt */
- dump_buf(5, buf, len, "Pre-enc");
+ dump_buf(5, buf, len, "net_queue: pre encrypt");
AES_cbc_encrypt(buf, buf, len, &aes_key[0], tmp_iv, AES_ENCRYPT);
- dump_buf(5, buf, len, "Post-enc");
+ dump_buf(5, buf, len, "net_queue: post encrypt");
/* Allocate send buffer */
m->len = len + sizeof iv + sizeof hash + 3 * sizeof(u_int32_t);
@@ -369,10 +384,11 @@ net_handle_messages(fd_set *fds)
/* Match! */
found++;
p->socket = newsock;
- log_msg(1, "peer \"%s\" connected", p->name);
+ log_msg(1, "net: peer \"%s\" connected",
+ p->name);
}
if (!found) {
- log_msg(1, "Found no matching peer for "
+ log_msg(1, "net: found no matching peer for "
"accepted socket, closing.");
close(newsock);
}
@@ -387,8 +403,6 @@ net_handle_messages(fd_set *fds)
if (!msg)
continue;
- /* XXX check message validity. */
-
log_msg(4, "net_handle_messages: got msg type %u len %u from "
"peer %s", msgtype, msglen, p->name);
@@ -401,8 +415,8 @@ net_handle_messages(fd_set *fds)
case MSG_PFKEYDATA:
if (p->runstate != MASTER ||
cfgstate.runstate == MASTER) {
- log_msg(0, "got PFKEY message from non-MASTER "
- "peer");
+ log_msg(1, "net: got PFKEY message from "
+ "non-MASTER peer");
free(msg);
if (cfgstate.runstate == MASTER)
net_ctl_send_state(p);
@@ -413,8 +427,8 @@ net_handle_messages(fd_set *fds)
break;
default:
- log_msg(0, "Got unknown message type %u len %u from "
- "peer %s", msgtype, msglen, p->name);
+ log_msg(0, "net: got unknown message type %u len %u "
+ "from peer %s", msgtype, msglen, p->name);
free(msg);
net_ctl_send_error(p, 0);
}
@@ -432,7 +446,6 @@ net_send_messages(fd_set *fds)
for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
if (p->socket < 0 || !FD_ISSET(p->socket, fds))
continue;
-
qm = SIMPLEQ_FIRST(&p->msgs);
if (!qm) {
/* XXX Log */
@@ -440,15 +453,17 @@ net_send_messages(fd_set *fds)
}
m = qm->msg;
- log_msg(4, "sending msg %p len %d ref %d to peer %s", m,
- m->len, m->refcnt, p->name);
+ log_msg(4, "net_send_messages: msg %p len %d ref %d "
+ "to peer %s", m, m->len, m->refcnt, p->name);
/* write message */
r = write(p->socket, m->buf, m->len);
- if (r == -1)
- log_err("net_send_messages: write()");
- else if (r < (ssize_t)m->len) {
- /* XXX retransmit? */
+ if (r == -1) {
+ net_disconnect_peer(p);
+ log_msg(0, "net_send_messages: write() failed, "
+ "peer disconnected");
+ } else if (r < (ssize_t)m->len) {
+ /* retransmit later */
continue;
}
@@ -457,7 +472,7 @@ net_send_messages(fd_set *fds)
free(qm);
if (--m->refcnt < 1) {
- log_msg(4, "freeing msg %p", m);
+ log_msg(4, "net_send_messages: freeing msg %p", m);
free(m->buf);
free(m);
}
@@ -468,8 +483,11 @@ net_send_messages(fd_set *fds)
void
net_disconnect_peer(struct syncpeer *p)
{
- if (p->socket > -1)
+ if (p->socket > -1) {
+ log_msg(1, "net_disconnect_peer: peer \"%s\" removed",
+ p->name);
close(p->socket);
+ }
p->socket = -1;
}
@@ -514,12 +532,19 @@ net_read(struct syncpeer *p, u_int32_t *msgtype, u_int32_t *msglen)
SHA_CTX ctx;
/* Read blob length */
- if (read(p->socket, &v, sizeof v) != (ssize_t)sizeof v)
+ r = read(p->socket, &v, sizeof v);
+ if (r != (ssize_t)sizeof v) {
+ if (r < 1)
+ net_disconnect_peer(p);
return NULL;
+ }
+
blob_len = ntohl(v);
if (blob_len < sizeof hash + AES_IV_LEN + 2 * sizeof(u_int32_t))
return NULL;
*msglen = blob_len - sizeof hash - AES_IV_LEN - 2 * sizeof(u_int32_t);
+ if (*msglen < MSG_MINLEN || *msglen > MSG_MAXLEN)
+ return NULL;
/* Read message blob */
blob = (u_int8_t *)malloc(blob_len);
@@ -528,7 +553,8 @@ net_read(struct syncpeer *p, u_int32_t *msgtype, u_int32_t *msglen)
return NULL;
}
r = read(p->socket, blob, blob_len);
- if (r == -1) {
+ if (r < 1) {
+ net_disconnect_peer(p);
free(blob);
return NULL;
} else if (r < (ssize_t)blob_len) {
@@ -561,21 +587,21 @@ net_read(struct syncpeer *p, u_int32_t *msgtype, u_int32_t *msglen)
}
memcpy(msg, iv + AES_IV_LEN, *msglen);
- dump_buf(5, rhash, sizeof hash, "Recv hash");
- dump_buf(5, iv, sizeof iv, "Recv IV");
- dump_buf(5, msg, *msglen, "Pre-decrypt");
+ dump_buf(5, rhash, sizeof hash, "net_read: got hash");
+ dump_buf(5, iv, AES_IV_LEN, "net_read: got IV");
+ dump_buf(5, msg, *msglen, "net_read: pre decrypt");
AES_cbc_encrypt(msg, msg, *msglen, &aes_key[1], iv, AES_DECRYPT);
- dump_buf(5, msg, *msglen, "Post-decrypt");
+ dump_buf(5, msg, *msglen, "net_read: post decrypt");
*msglen -= padlen;
SHA1_Init(&ctx);
SHA1_Update(&ctx, msg, *msglen);
SHA1_Final(hash, &ctx);
- dump_buf(5, hash, sizeof hash, "Local hash");
+ dump_buf(5, hash, sizeof hash, "net_read: computed hash");
if (memcmp(hash, rhash, sizeof hash) != 0) {
free(blob);
- log_msg(0, "net_read: bad msg hash (shared key typo?)");
+ log_msg(0, "net_read: got bad message (typo in shared key?)");
return NULL;
}
free(blob);
@@ -660,7 +686,7 @@ got_sigalrm(int s)
}
void
-net_connect_peers(void)
+net_connect(void)
{
struct sockaddr_storage sa_storage;
struct itimerval iv;
@@ -686,16 +712,18 @@ net_connect_peers(void)
continue;
}
if (connect(p->socket, sa, sa->sa_len)) {
- log_msg(1, "peer \"%s\" not ready yet", p->name);
+ log_msg(1, "net_connect: peer \"%s\" not ready yet",
+ p->name);
net_disconnect_peer(p);
continue;
}
if (net_ctl_send_state(p)) {
- log_msg(0, "peer \"%s\" failed", p->name);
+ log_msg(0, "net_connect: peer \"%s\" failed", p->name);
net_disconnect_peer(p);
continue;
}
- log_msg(1, "peer \"%s\" connected", p->name);
+ log_msg(1, "net_connect: peer \"%s\" connected, fd %d",
+ p->name, p->socket);
}
timerclear(&iv.it_value);
@@ -709,7 +737,7 @@ net_connect_peers(void)
static void
net_check_peers(void *arg)
{
- net_connect_peers();
+ net_connect();
(void)timer_add("peer recheck", 600, net_check_peers, 0);
}
diff --git a/usr.sbin/sasyncd/net.h b/usr.sbin/sasyncd/net.h
index 901ea1b35f9..b193ebd2bbc 100644
--- a/usr.sbin/sasyncd/net.h
+++ b/usr.sbin/sasyncd/net.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: net.h,v 1.2 2005/05/22 20:35:48 ho Exp $ */
+/* $OpenBSD: net.h,v 1.3 2005/05/23 19:53:27 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -48,7 +48,7 @@ enum CTLTYPE { RESERVED = 0, CTL_STATE, CTL_ERROR, CTL_ACK, CTL_UNKNOWN };
};
/* net.c */
-void net_connect_peers(void);
+void net_connect(void);
void net_disconnect_peer(struct syncpeer *);
/* net_ctl.c */
diff --git a/usr.sbin/sasyncd/net_ctl.c b/usr.sbin/sasyncd/net_ctl.c
index 4ffcf92e7b6..e03a68e7998 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.3 2005/05/22 20:35:48 ho Exp $ */
+/* $OpenBSD: net_ctl.c,v 1.4 2005/05/23 19:53:27 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -58,20 +58,20 @@ net_ctl_check_state(struct syncpeer *p, enum RUNSTATE nstate)
static char *runstate[] = CARPSTATES;
if (nstate < INIT || nstate > FAIL) {
- log_msg(0, "got bad state %d from peer \"%s\"", nstate,
- p->name);
+ log_msg(0, "net_ctl: got bad state %d from peer \"%s\"",
+ nstate, p->name);
net_ctl_send_error(p, CTL_STATE);
return -1;
}
if (cfgstate.runstate == MASTER && nstate == MASTER) {
- log_msg(0, "got bad state MASTER from peer \"%s\"",
+ log_msg(0, "net_ctl: got bad state MASTER from peer \"%s\"",
p->name);
net_ctl_send_error(p, CTL_STATE);
return -1;
}
if (p->runstate != nstate) {
p->runstate = nstate;
- log_msg(1, "peer \"%s\" state change to %s", p->name,
+ log_msg(1, "net_ctl: peer \"%s\" state change to %s", p->name,
runstate[nstate]);
}
return 0;
@@ -86,7 +86,7 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen)
static char *ct, *ctltype[] = CTLTYPES;
if (msglen < sizeof *ctl) {
- log_msg(0, "got invalid control message from peer \"%s\"",
+ log_msg(0, "net_ctl: got bad control message from peer \"%s\"",
p->name);
net_ctl_send_error(p, CTL_UNKNOWN);
return;
@@ -94,14 +94,14 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen)
switch (ntohl(ctl->type)) {
case CTL_STATE:
- log_msg(3, "got CTL_STATE from peer \"%s\"", p->name);
+ log_msg(3, "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);
break;
case CTL_ERROR:
- log_msg(1, "got ERROR from peer \"%s\"", p->name);
+ log_msg(1, "net_ctl: got ERROR from peer \"%s\"", p->name);
switch (ntohl(ctl->data)) {
case RESERVED: /* PFKEY -- nothing to do here for now */
@@ -126,7 +126,8 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen)
ct = "<unknown>";
else
ct = ctltype[ctype];
- log_msg(3, "got %s ACK from peer \"%s\"", ct, p->name);
+ log_msg(3, "net_ctl: got %s ACK from peer \"%s\"", ct,
+ p->name);
if (ctype == CTL_STATE) {
nstate = (enum RUNSTATE)ntohl(ctl->data2);
net_ctl_check_state(p, nstate);
@@ -135,7 +136,7 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen)
case CTL_UNKNOWN:
default:
- log_msg(1, "got unknown msg type %u from peer \"%s\"",
+ log_msg(1, "net_ctl: got unknown msg type %u from peer \"%s\"",
ntohl(ctl->type), p->name);
break;
}
@@ -185,12 +186,12 @@ net_ctl_update_state(void)
static char *carpstate[] = CARPSTATES;
/* We may have new peers available. */
- net_connect_peers();
+ net_connect();
for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
if (p->socket == -1)
continue;
- log_msg(2, "sending my state %s to peer \"%s\"",
+ log_msg(2, "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 e5892863297..0ed4993a99f 100644
--- a/usr.sbin/sasyncd/pfkey.c
+++ b/usr.sbin/sasyncd/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.2 2005/05/22 20:35:48 ho Exp $ */
+/* $OpenBSD: pfkey.c,v 1.3 2005/05/23 19:53:27 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -142,8 +142,9 @@ pfkey_handle_message(struct sadb_msg *m)
return 0;
}
- log_msg(3, "pfkey: got %s len %u seq %d", pfkey_print_type(msg),
- msg->sadb_msg_len * CHUNK, msg->sadb_msg_seq);
+ log_msg(3, "pfkey_handle_message: got %s len %u seq %d",
+ pfkey_print_type(msg), msg->sadb_msg_len * CHUNK,
+ msg->sadb_msg_seq);
switch (msg->sadb_msg_type) {
case SADB_X_PROMISC:
@@ -284,8 +285,9 @@ pfkey_queue_message(u_int8_t *data, u_int32_t datalen)
sadb->sadb_msg_pid = getpid();
sadb->sadb_msg_seq = seq++;
- log_msg(3, "sync: pfkey %s len %d seq %d", pfkey_print_type(sadb),
- sadb->sadb_msg_len * CHUNK, sadb->sadb_msg_seq);
+ log_msg(3, "pfkey_queue_message: pfkey %s len %d seq %d",
+ pfkey_print_type(sadb), sadb->sadb_msg_len * CHUNK,
+ sadb->sadb_msg_seq);
SIMPLEQ_INSERT_TAIL(&pfkey_msglist, pmsg, next);
return 0;
@@ -342,7 +344,7 @@ pfkey_snapshot(void *v)
while (m < (struct sadb_msg *)(buf + sz) && m->sadb_msg_len > 0) {
mlen = m->sadb_msg_len * CHUNK;
- fprintf(stderr, "snapshot: sadb_msg %p type %s len %u\n",
+ fprintf(stderr, "pfkey_snapshot: sadb_msg %p type %s len %u\n",
m, pfkey_print_type(m), mlen);
e = (struct sadb_ext *)(m + 1);
diff --git a/usr.sbin/sasyncd/timer.c b/usr.sbin/sasyncd/timer.c
index 5582d6918ce..92317a8175c 100644
--- a/usr.sbin/sasyncd/timer.c
+++ b/usr.sbin/sasyncd/timer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: timer.c,v 1.1 2005/03/30 18:44:49 ho Exp $ */
+/* $OpenBSD: timer.c,v 1.2 2005/05/23 19:53:27 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -97,7 +97,7 @@ timer_run(void)
for (e = TAILQ_FIRST(&events); e && timercmp(&now, &e->expire, >=);
e = TAILQ_FIRST(&events)) {
TAILQ_REMOVE(&events, e, next);
- log_msg(4, "timer_run: event \"%s\"",
+ log_msg(6, "timer_run: event \"%s\"",
e->name ? e->name : "<unknown>");
(*e->fun)(e->arg);
if (e->name)
@@ -128,7 +128,7 @@ timer_add(char *name, u_int32_t when, void (*function)(void *), void *arg)
gettimeofday(&now, 0);
timeradd(&now, &tmp, &new->expire);
- log_msg(4, "timer_add: new event \"%s\" (expiring in %us)",
+ log_msg(6, "timer_add: new event \"%s\" (expiring in %us)",
name ? name : "<unknown>", when);
/* Insert the new event in the queue so it's always sorted. */