GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/sasyncd/net.c Lines: 0 418 0.0 %
Date: 2017-11-07 Branches: 0 257 0.0 %

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