net.c revision 1.7
1/*	$OpenBSD: net.c,v 1.7 2005/05/26 19:19:51 ho Exp $	*/
2
3/*
4 * Copyright (c) 2005 H�kan Olsson.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * This code was written under funding by Multicom Security AB.
30 */
31
32#include <sys/types.h>
33#include <sys/socket.h>
34#include <sys/time.h>
35#include <netinet/in.h>
36#include <arpa/inet.h>
37#include <ifaddrs.h>
38#include <netdb.h>
39
40#include <openssl/aes.h>
41#include <openssl/sha.h>
42
43#include <errno.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <unistd.h>
48
49#include "sasyncd.h"
50#include "net.h"
51
52struct msg {
53	u_int8_t	*buf;
54	u_int32_t	 len;
55	int		 refcnt;
56};
57
58struct qmsg {
59	SIMPLEQ_ENTRY(qmsg)	next;
60	struct msg	*msg;
61};
62
63int	*listeners;
64AES_KEY	aes_key[2];
65#define AES_IV_LEN	AES_BLOCK_SIZE
66
67/* We never send (or expect to receive) messages smaller/larger than this. */
68#define MSG_MINLEN	12
69#define MSG_MAXLEN	4096
70
71/* Local prototypes. */
72static u_int8_t *net_read(struct syncpeer *, u_int32_t *, u_int32_t *);
73static int	 net_set_sa(struct sockaddr *, char *, in_port_t);
74static void	 net_check_peers(void *);
75
76/* Pretty-print a buffer. */
77void
78dump_buf(int lvl, u_int8_t *b, u_int32_t len, char *title)
79{
80	u_int32_t	i, off, blen;
81	u_int8_t	*buf;
82	const char	def[] = "Buffer:";
83
84	if (cfgstate.verboselevel < lvl)
85		return;
86
87	blen = 2 * (len + len / 36) + 3 + (title ? strlen(title) : sizeof def);
88	if (!(buf = (u_int8_t *)calloc(1, blen)))
89		return;
90
91	snprintf(buf, blen, "%s\n ", title ? title : def);
92	off = strlen(buf);
93	for (i = 0; i < len; i++, off+=2) {
94		snprintf(buf + off, blen - off, "%02x", b[i]);
95		if ((i+1) % 36 == 0) {
96			off += 2;
97			snprintf(buf + off, blen - off, "\n ");
98		}
99	}
100	log_msg(lvl, "%s", buf);
101	free(buf);
102}
103
104/* Add a listening socket. */
105static int
106net_add_listener(struct sockaddr *sa)
107{
108	char	host[NI_MAXHOST], port[NI_MAXSERV];
109	int	r, s;
110
111	s = socket(sa->sa_family, SOCK_STREAM, 0);
112	if (s < 0) {
113		perror("net_add_listener: socket()");
114		close(s);
115		return -1;
116	}
117
118	r = 1;
119	if (setsockopt(s, SOL_SOCKET,
120		cfgstate.listen_on ? SO_REUSEADDR : SO_REUSEPORT, (void *)&r,
121		sizeof r)) {
122		perror("net_add_listener: setsockopt()");
123		close(s);
124		return -1;
125	}
126
127	if (bind(s, sa, sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) :
128		sizeof (struct sockaddr_in6))) {
129		perror("net_add_listener: bind()");
130		close(s);
131		return -1;
132	}
133
134	if (listen(s, 3)) {
135		perror("net_add_listener: listen()");
136		close(s);
137		return -1;
138	}
139
140	if (getnameinfo(sa, sa->sa_len, host, sizeof host, port, sizeof port,
141		NI_NUMERICHOST | NI_NUMERICSERV))
142		log_msg(3, "listening on port %u fd %d", cfgstate.listen_port,
143		    s);
144	else
145		log_msg(3, "listening on %s port %s fd %d", host, port, s);
146
147	return s;
148}
149
150/* Allocate and fill in listeners array. */
151static int
152net_setup_listeners(void)
153{
154	struct sockaddr_storage	 sa_storage;
155	struct sockaddr		*sa = (struct sockaddr *)&sa_storage;
156	struct sockaddr_in	*sin = (struct sockaddr_in *)sa;
157	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)sa;
158	struct ifaddrs		*ifap = 0, *ifa;
159	int			 i, count;
160
161	/* Setup listening sockets.  */
162	memset(&sa_storage, 0, sizeof sa_storage);
163	if (net_set_sa(sa, cfgstate.listen_on, cfgstate.listen_port) == 0) {
164		listeners = (int *)calloc(2, sizeof(int));
165		if (!listeners) {
166			perror("net_setup_listeners: calloc()");
167			return -1;
168		}
169		listeners[1] = -1;
170		listeners[0] = net_add_listener(sa);
171		if (listeners[0] == -1) {
172			log_msg(0, "net_setup_listeners: could not find "
173			    "listen address (%s)", cfgstate.listen_on);
174			goto errout;
175		}
176		return 0;
177	}
178
179	/*
180	 * If net_set_sa() failed, cfgstate.listen_on is probably an
181	 * interface name, so we should listen on all it's addresses.
182	 */
183
184	if (getifaddrs(&ifap) != 0) {
185		perror("net_setup_listeners: getifaddrs()");
186		return -1;
187	}
188
189	/* How many addresses matches? */
190	for (count = 0, ifa = ifap; ifa; ifa = ifa->ifa_next) {
191		if (!ifa->ifa_name || !ifa->ifa_addr ||
192		    (ifa->ifa_addr->sa_family != AF_INET &&
193			ifa->ifa_addr->sa_family != AF_INET6))
194			continue;
195		if (cfgstate.listen_family &&
196		    cfgstate.listen_family != ifa->ifa_addr->sa_family)
197			continue;
198		if (strcmp(ifa->ifa_name, cfgstate.listen_on) != 0)
199			continue;
200		count++;
201	}
202
203	if (!count) {
204		log_msg(0, "net_setup_listeners: no listeners found for %s",
205		    cfgstate.listen_on);
206		return -1;
207	}
208
209	/* Allocate one extra slot and set to -1, marking end of array. */
210	listeners = (int *)calloc(count + 1, sizeof(int));
211	if (!listeners) {
212		perror("net_setup_listeners: calloc()");
213		return -1;
214	}
215	for (i = 0; i <= count; i++)
216		listeners[i] = -1;
217
218	/* Create listening sockets */
219	for (count = 0, ifa = ifap; ifa; ifa = ifa->ifa_next) {
220		if (!ifa->ifa_name || !ifa->ifa_addr ||
221		    (ifa->ifa_addr->sa_family != AF_INET &&
222			ifa->ifa_addr->sa_family != AF_INET6))
223			continue;
224		if (cfgstate.listen_family &&
225		    cfgstate.listen_family != ifa->ifa_addr->sa_family)
226			continue;
227		if (strcmp(ifa->ifa_name, cfgstate.listen_on) != 0)
228			continue;
229
230		memset(&sa_storage, 0, sizeof sa_storage);
231		sa->sa_family = ifa->ifa_addr->sa_family;
232		switch (sa->sa_family) {
233		case AF_INET:
234			sin->sin_port = htons(cfgstate.listen_port);
235			sin->sin_len = sizeof *sin;
236			memcpy(&sin->sin_addr,
237			    &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
238			    sizeof sin->sin_addr);
239			break;
240		case AF_INET6:
241			sin6->sin6_port = htons(cfgstate.listen_port);
242			sin6->sin6_len = sizeof *sin6;
243			memcpy(&sin6->sin6_addr,
244			    &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
245			    sizeof sin6->sin6_addr);
246			break;
247		}
248
249		listeners[count] = net_add_listener(sa);
250		if (listeners[count] == -1) {
251			log_msg(4, "net_setup_listeners(setup): failed to "
252			    "add listener, count = %d", count);
253			goto errout;
254		}
255		count++;
256	}
257	freeifaddrs(ifap);
258	return 0;
259
260  errout:
261	if (ifap)
262		freeifaddrs(ifap);
263	for (i = 0; listeners[i] != -1; i++)
264		close(listeners[i]);
265	free(listeners);
266	return -1;
267}
268
269int
270net_init(void)
271{
272	struct syncpeer *p;
273	int		 r;
274
275	/* The shared key needs to be 128, 192 or 256 bits */
276	r = strlen(cfgstate.sharedkey) << 3;
277	if (r != 128 && r != 192 && r != 256) {
278		fprintf(stderr, "Bad shared key length (%d bits), "
279		    "should be 128, 192 or 256\n", r);
280		return -1;
281	}
282
283	if (AES_set_encrypt_key(cfgstate.sharedkey, r, &aes_key[0]) ||
284	    AES_set_decrypt_key(cfgstate.sharedkey, r, &aes_key[1])) {
285		fprintf(stderr, "Bad AES shared key\n");
286		return -1;
287	}
288
289	if (net_setup_listeners())
290		return -1;
291
292	for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
293		p->socket = -1;
294		SIMPLEQ_INIT(&p->msgs);
295	}
296
297	net_check_peers(0);
298	return 0;
299}
300
301static void
302net_enqueue(struct syncpeer *p, struct msg *m)
303{
304	struct qmsg	*qm;
305
306	if (p->socket < 0)
307		return;
308
309	qm = (struct qmsg *)malloc(sizeof *qm);
310	if (!qm) {
311		log_err("net_enqueue: malloc()");
312		return;
313	}
314
315	memset(qm, 0, sizeof *qm);
316	qm->msg = m;
317	m->refcnt++;
318
319	SIMPLEQ_INSERT_TAIL(&p->msgs, qm, next);
320	return;
321}
322
323/*
324 * Queue a message for transmission to a particular peer,
325 * or to all peers if no peer is specified.
326 */
327int
328net_queue(struct syncpeer *p0, u_int32_t msgtype, u_int8_t *buf, u_int32_t len)
329{
330	struct syncpeer *p = p0;
331	struct msg	*m;
332	SHA_CTX		 ctx;
333	u_int8_t	 hash[SHA_DIGEST_LENGTH];
334	u_int8_t	 iv[AES_IV_LEN], tmp_iv[AES_IV_LEN];
335	u_int32_t	 v, padlen = 0;
336	int		 i, offset;
337
338	m = (struct msg *)calloc(1, sizeof *m);
339	if (!m) {
340		log_err("net_queue: calloc()");
341		free(buf);
342		return -1;
343	}
344
345	/* Generate hash */
346	SHA1_Init(&ctx);
347	SHA1_Update(&ctx, buf, len);
348	SHA1_Final(hash, &ctx);
349	dump_buf(5, hash, sizeof hash, "net_queue: computed hash");
350
351	/* Padding required? */
352	i = len % AES_IV_LEN;
353	if (i) {
354		u_int8_t *pbuf;
355		i = AES_IV_LEN - i;
356		pbuf = realloc(buf, len + i);
357		if (!pbuf) {
358			log_err("net_queue: realloc()");
359			free(buf);
360			free(m);
361			return -1;
362		}
363		padlen = i;
364		while (i > 0)
365			pbuf[len++] = (u_int8_t)i--;
366		buf = pbuf;
367	}
368
369	/* Get random IV */
370	for (i = 0; i <= sizeof iv - sizeof v; i += sizeof v) {
371		v = arc4random();
372		memcpy(&iv[i], &v, sizeof v);
373	}
374	dump_buf(5, iv, sizeof iv, "net_queue: IV");
375	memcpy(tmp_iv, iv, sizeof tmp_iv);
376
377	/* Encrypt */
378	dump_buf(5, buf, len, "net_queue: pre encrypt");
379	AES_cbc_encrypt(buf, buf, len, &aes_key[0], tmp_iv, AES_ENCRYPT);
380	dump_buf(5, buf, len, "net_queue: post encrypt");
381
382	/* Allocate send buffer */
383	m->len = len + sizeof iv + sizeof hash + 3 * sizeof(u_int32_t);
384	m->buf = (u_int8_t *)malloc(m->len);
385	if (!m->buf) {
386		free(m);
387		free(buf);
388		log_err("net_queue: calloc()");
389		return -1;
390	}
391	offset = 0;
392
393	/* Fill it (order must match parsing code in net_read()) */
394	v = htonl(m->len - sizeof(u_int32_t));
395	memcpy(m->buf + offset, &v, sizeof v);
396	offset += sizeof v;
397	v = htonl(msgtype);
398	memcpy(m->buf + offset, &v, sizeof v);
399	offset += sizeof v;
400	v = htonl(padlen);
401	memcpy(m->buf + offset, &v, sizeof v);
402	offset += sizeof v;
403	memcpy(m->buf + offset, hash, sizeof hash);
404	offset += sizeof hash;
405	memcpy(m->buf + offset, iv, sizeof iv);
406	offset += sizeof iv;
407	memcpy(m->buf + offset, buf, len);
408	free(buf);
409
410	if (p)
411		net_enqueue(p, m);
412	else
413		for (p = LIST_FIRST(&cfgstate.peerlist); p;
414		     p = LIST_NEXT(p, link))
415			net_enqueue(p, m);
416
417	if (!m->refcnt) {
418		free(m->buf);
419		free(m);
420	}
421
422	return 0;
423}
424
425/* Set all write pending filedescriptors. */
426int
427net_set_pending_wfds(fd_set *fds)
428{
429	struct syncpeer *p;
430	int		max_fd = -1;
431
432	for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link))
433		if (p->socket > -1 && SIMPLEQ_FIRST(&p->msgs)) {
434			FD_SET(p->socket, fds);
435			if (p->socket > max_fd)
436				max_fd = p->socket;
437		}
438	return max_fd + 1;
439}
440
441/*
442 * Set readable filedescriptors. They are basically the same as for write,
443 * plus the listening socket.
444 */
445int
446net_set_rfds(fd_set *fds)
447{
448	struct syncpeer *p;
449	int		i, max_fd = -1;
450
451	for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
452		if (p->socket > -1)
453			FD_SET(p->socket, fds);
454		if (p->socket > max_fd)
455			max_fd = p->socket;
456	}
457	for (i = 0; listeners[i] != -1; i++) {
458		FD_SET(listeners[i], fds);
459		if (listeners[i] > max_fd)
460			max_fd = listeners[i];
461	}
462	return max_fd + 1;
463}
464
465static void
466net_accept(int accept_socket)
467{
468	struct sockaddr_storage	 sa_storage, sa_storage2;
469	struct sockaddr		*sa = (struct sockaddr *)&sa_storage;
470	struct sockaddr		*sa2 = (struct sockaddr *)&sa_storage2;
471	struct sockaddr_in	*sin, *sin2;
472	struct sockaddr_in6	*sin6, *sin62;
473	struct syncpeer		*p;
474	socklen_t		 socklen;
475	int			 s, found;
476
477	/* Accept a new incoming connection */
478	socklen = sizeof sa_storage;
479	memset(&sa_storage, 0, socklen);
480	memset(&sa_storage2, 0, socklen);
481	s = accept(accept_socket, sa, &socklen);
482	if (s > -1) {
483		/* Setup the syncpeer structure */
484		found = 0;
485		for (p = LIST_FIRST(&cfgstate.peerlist); p && !found;
486		     p = LIST_NEXT(p, link)) {
487
488			/* Match? */
489			if (net_set_sa(sa2, p->name, 0))
490				continue;
491			if (sa->sa_family != sa2->sa_family)
492				continue;
493			if (sa->sa_family == AF_INET) {
494				sin = (struct sockaddr_in *)sa;
495				sin2 = (struct sockaddr_in *)sa2;
496				if (memcmp(&sin->sin_addr, &sin2->sin_addr,
497					sizeof(struct in_addr)))
498					continue;
499			} else {
500				sin6 = (struct sockaddr_in6 *)sa;
501				sin62 = (struct sockaddr_in6 *)sa2;
502				if (memcmp(&sin6->sin6_addr, &sin62->sin6_addr,
503					sizeof(struct in6_addr)))
504					continue;
505			}
506			/* Match! */
507			found++;
508			p->socket = s;
509			log_msg(1, "net: peer \"%s\" connected", p->name);
510			if (cfgstate.runstate == MASTER)
511				timer_add("pfkey_snap", 2, pfkey_snapshot, p);
512		}
513		if (!found) {
514			log_msg(1, "net: found no matching peer for accepted "
515			    "socket, closing.");
516			close(s);
517		}
518	} else
519		log_err("net: accept()");
520}
521
522void
523net_handle_messages(fd_set *fds)
524{
525	struct syncpeer *p;
526	u_int8_t	*msg;
527	u_int32_t	 msgtype, msglen;
528	int		 i;
529
530	for (i = 0; listeners[i] != -1; i++)
531		if (FD_ISSET(listeners[i], fds))
532			net_accept(listeners[i]);
533
534	for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
535		if (p->socket < 0 || !FD_ISSET(p->socket, fds))
536			continue;
537		msg = net_read(p, &msgtype, &msglen);
538		if (!msg)
539			continue;
540
541		log_msg(5, "net_handle_messages: got msg type %u len %u from "
542		    "peer %s", msgtype, msglen, p->name);
543
544		switch (msgtype) {
545		case MSG_SYNCCTL:
546			net_ctl_handle_msg(p, msg, msglen);
547			free(msg);
548			break;
549
550		case MSG_PFKEYDATA:
551			if (p->runstate != MASTER ||
552			    cfgstate.runstate == MASTER) {
553				log_msg(1, "net: got PFKEY message from "
554				    "non-MASTER peer");
555				free(msg);
556				if (cfgstate.runstate == MASTER)
557					net_ctl_send_state(p);
558				else
559					net_ctl_send_error(p, 0);
560			} else if (pfkey_queue_message(msg, msglen))
561				free(msg);
562			break;
563
564		default:
565			log_msg(0, "net: got unknown message type %u len %u "
566			    "from peer %s", msgtype, msglen, p->name);
567			free(msg);
568			net_ctl_send_error(p, 0);
569		}
570	}
571}
572
573void
574net_send_messages(fd_set *fds)
575{
576	struct syncpeer *p;
577	struct qmsg	*qm;
578	struct msg	*m;
579	ssize_t		 r;
580
581	for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
582		if (p->socket < 0 || !FD_ISSET(p->socket, fds))
583			continue;
584		qm = SIMPLEQ_FIRST(&p->msgs);
585		if (!qm) {
586			/* XXX Log */
587			continue;
588		}
589		m = qm->msg;
590
591		log_msg(5, "net_send_messages: msg %p len %d ref %d "
592		    "to peer %s", m, m->len, m->refcnt, p->name);
593
594		/* write message */
595		r = write(p->socket, m->buf, m->len);
596		if (r == -1) {
597			net_disconnect_peer(p);
598			log_msg(0, "net_send_messages: write() failed, "
599			    "peer disconnected");
600		} else if (r < (ssize_t)m->len) {
601			/* retransmit later */
602			continue;
603		}
604
605		/* cleanup */
606		SIMPLEQ_REMOVE_HEAD(&p->msgs, next);
607		free(qm);
608
609		if (--m->refcnt < 1) {
610			log_msg(5, "net_send_messages: freeing msg %p", m);
611			free(m->buf);
612			free(m);
613		}
614	}
615	return;
616}
617
618void
619net_disconnect_peer(struct syncpeer *p)
620{
621	if (p->socket > -1) {
622		log_msg(1, "net_disconnect_peer: peer \"%s\" removed",
623		    p->name);
624		close(p->socket);
625	}
626	p->socket = -1;
627}
628
629void
630net_shutdown(void)
631{
632	struct syncpeer *p;
633	struct qmsg	*qm;
634	struct msg	*m;
635	int		 i;
636
637	while ((p = LIST_FIRST(&cfgstate.peerlist))) {
638		while ((qm = SIMPLEQ_FIRST(&p->msgs))) {
639			SIMPLEQ_REMOVE_HEAD(&p->msgs, next);
640			m = qm->msg;
641			if (--m->refcnt < 1) {
642				free(m->buf);
643				free(m);
644			}
645			free(qm);
646		}
647		net_disconnect_peer(p);
648		if (p->name)
649			free(p->name);
650		LIST_REMOVE(p, link);
651		free(p);
652	}
653
654	if (listeners) {
655		for (i = 0; listeners[i] != -1; i++)
656			close(listeners[i]);
657		free(listeners);
658		listeners = 0;
659	}
660}
661
662/*
663 * Helper functions (local) below here.
664 */
665
666static u_int8_t *
667net_read(struct syncpeer *p, u_int32_t *msgtype, u_int32_t *msglen)
668{
669	u_int8_t	*msg, *blob, *rhash, *iv, hash[SHA_DIGEST_LENGTH];
670	u_int32_t	 v, blob_len;
671	int		 padlen = 0, offset = 0, r;
672	SHA_CTX		 ctx;
673
674	/* Read blob length */
675	r = read(p->socket, &v, sizeof v);
676	if (r != (ssize_t)sizeof v) {
677		if (r < 1)
678			net_disconnect_peer(p);
679		return NULL;
680	}
681
682	blob_len = ntohl(v);
683	if (blob_len < sizeof hash + AES_IV_LEN + 2 * sizeof(u_int32_t))
684		return NULL;
685	*msglen = blob_len - sizeof hash - AES_IV_LEN - 2 * sizeof(u_int32_t);
686	if (*msglen < MSG_MINLEN || *msglen > MSG_MAXLEN)
687		return NULL;
688
689	/* Read message blob */
690	blob = (u_int8_t *)malloc(blob_len);
691	if (!blob) {
692		log_err("net_read: malloc()");
693		return NULL;
694	}
695	r = read(p->socket, blob, blob_len);
696	if (r < 1) {
697		net_disconnect_peer(p);
698		free(blob);
699		return NULL;
700	} else if (r < (ssize_t)blob_len) {
701		/* XXX wait and read more? */
702		fprintf(stderr, "net_read: wanted %d, got %d\n", blob_len, r);
703		free(blob);
704		return NULL;
705	}
706
707	offset = 0;
708	memcpy(&v, blob + offset, sizeof v);
709	*msgtype = ntohl(v);
710	offset += sizeof v;
711
712	if (*msgtype > MSG_MAXTYPE) {
713		free(blob);
714		return NULL;
715	}
716
717	memcpy(&v, blob + offset, sizeof v);
718	padlen = ntohl(v);
719	offset += sizeof v;
720
721	rhash = blob + offset;
722	iv    = rhash + sizeof hash;
723	msg = (u_int8_t *)malloc(*msglen);
724	if (!msg) {
725		free(blob);
726		return NULL;
727	}
728	memcpy(msg, iv + AES_IV_LEN, *msglen);
729
730	dump_buf(5, rhash, sizeof hash, "net_read: got hash");
731	dump_buf(5, iv, AES_IV_LEN, "net_read: got IV");
732	dump_buf(5, msg, *msglen, "net_read: pre decrypt");
733	AES_cbc_encrypt(msg, msg, *msglen, &aes_key[1], iv, AES_DECRYPT);
734	dump_buf(5, msg, *msglen, "net_read: post decrypt");
735	*msglen -= padlen;
736
737	SHA1_Init(&ctx);
738	SHA1_Update(&ctx, msg, *msglen);
739	SHA1_Final(hash, &ctx);
740	dump_buf(5, hash, sizeof hash, "net_read: computed hash");
741
742	if (memcmp(hash, rhash, sizeof hash) != 0) {
743		free(blob);
744		log_msg(0, "net_read: got bad message (typo in shared key?)");
745		return NULL;
746	}
747	free(blob);
748	return msg;
749}
750
751static int
752net_set_sa(struct sockaddr *sa, char *name, in_port_t port)
753{
754	struct sockaddr_in	*sin = (struct sockaddr_in *)sa;
755	struct sockaddr_in6	*sin6 = (struct sockaddr_in6 *)sa;
756
757	if (!name) {
758		/* XXX Assume IPv4 */
759		sa->sa_family = AF_INET;
760		sin->sin_port = htons(port);
761		sin->sin_len = sizeof *sin;
762		return 0;
763	}
764
765	if (inet_pton(AF_INET, name, &sin->sin_addr) == 1) {
766		sa->sa_family = AF_INET;
767		sin->sin_port = htons(port);
768		sin->sin_len = sizeof *sin;
769		return 0;
770	}
771
772	if (inet_pton(AF_INET6, name, &sin6->sin6_addr) == 1) {
773		sa->sa_family = AF_INET6;
774		sin6->sin6_port = htons(port);
775		sin6->sin6_len = sizeof *sin6;
776		return 0;
777	}
778
779	return -1;
780}
781
782static void
783got_sigalrm(int s)
784{
785	return;
786}
787
788void
789net_connect(void)
790{
791	struct sockaddr_storage sa_storage;
792	struct itimerval	iv;
793	struct sockaddr	*sa = (struct sockaddr *)&sa_storage;
794	struct syncpeer	*p;
795
796	signal(SIGALRM, got_sigalrm);
797	memset(&iv, 0, sizeof iv);
798	iv.it_value.tv_sec = 5;
799	iv.it_interval.tv_sec = 5;
800	setitimer(ITIMER_REAL, &iv, NULL);
801
802	for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
803		if (p->socket > -1)
804			continue;
805
806		memset(sa, 0, sizeof sa_storage);
807		if (net_set_sa(sa, p->name, cfgstate.listen_port))
808			continue;
809		p->socket = socket(sa->sa_family, SOCK_STREAM, 0);
810		if (p->socket < 0) {
811			log_err("peer \"%s\": socket()", p->name);
812			continue;
813		}
814		if (connect(p->socket, sa, sa->sa_len)) {
815			log_msg(1, "net_connect: peer \"%s\" not ready yet",
816			    p->name);
817			net_disconnect_peer(p);
818			continue;
819		}
820		if (net_ctl_send_state(p)) {
821			log_msg(0, "net_connect: peer \"%s\" failed", p->name);
822			net_disconnect_peer(p);
823			continue;
824		}
825		log_msg(1, "net_connect: peer \"%s\" connected, fd %d",
826		    p->name, p->socket);
827
828		/* Schedule a pfkey sync to the newly connected peer. */
829		if (cfgstate.runstate == MASTER)
830			timer_add("pfkey_snapshot", 2, pfkey_snapshot, p);
831	}
832
833	timerclear(&iv.it_value);
834	timerclear(&iv.it_interval);
835	setitimer(ITIMER_REAL, &iv, NULL);
836	signal(SIGALRM, SIG_IGN);
837
838	return;
839}
840
841static void
842net_check_peers(void *arg)
843{
844	net_connect();
845	(void)timer_add("peer recheck", 600, net_check_peers, 0);
846}
847