unet-cli: strip initial newline in usage message
[project/unetd.git] / pex-msg.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
4 */
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <sys/un.h>
8 #include <arpa/inet.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <libubox/list.h>
12 #include <libubox/uloop.h>
13 #include <libubox/usock.h>
14 #include "pex-msg.h"
15 #include "chacha20.h"
16 #include "auth-data.h"
17
18 static char pex_tx_buf[PEX_BUF_SIZE];
19 static FILE *pex_urandom;
20 static struct uloop_fd pex_fd, pex_unix_fd;
21 static LIST_HEAD(requests);
22 static struct uloop_timeout gc_timer;
23 static int pex_raw_v4_fd = -1, pex_raw_v6_fd = -1;
24
25 static pex_recv_cb_t pex_recv_cb;
26 static pex_recv_control_cb_t pex_control_cb;
27 static int pex_unix_tx_fd = -1;
28
29 int pex_socket(void)
30 {
31 return pex_fd.fd;
32 }
33
34 int pex_raw_socket(int family)
35 {
36 return family == AF_INET ? pex_raw_v4_fd : pex_raw_v6_fd;
37 }
38
39 static const void *
40 get_mapped_sockaddr(const void *addr)
41 {
42 static struct sockaddr_in6 sin6;
43 const struct sockaddr_in *sin = addr;
44
45 if (!sin || sin->sin_family != AF_INET)
46 return addr;
47
48 memset(&sin6, 0, sizeof(sin6));
49 sin6.sin6_family = AF_INET6;
50 sin6.sin6_addr.s6_addr[10] = 0xff;
51 sin6.sin6_addr.s6_addr[11] = 0xff;
52 memcpy(&sin6.sin6_addr.s6_addr[12], &sin->sin_addr, sizeof(struct in_addr));
53 sin6.sin6_port = sin->sin_port;
54
55 return &sin6;
56 }
57
58 struct pex_msg_update_recv_ctx {
59 struct list_head list;
60
61 union network_endpoint addr;
62
63 uint8_t priv_key[CURVE25519_KEY_SIZE];
64 uint8_t auth_key[CURVE25519_KEY_SIZE];
65 uint8_t e_key[CURVE25519_KEY_SIZE];
66
67 uint64_t req_id;
68
69 void *data;
70 int data_len;
71 int data_ofs;
72
73 int idle;
74 };
75
76 uint64_t pex_network_hash(const uint8_t *auth_key, uint64_t req_id)
77 {
78 siphash_key_t key = {
79 .key = {
80 be64_to_cpu(req_id),
81 be64_to_cpu(req_id)
82 }
83 };
84 uint64_t hash;
85
86 siphash_to_be64(&hash, auth_key, CURVE25519_KEY_SIZE, &key);
87
88 return hash;
89 }
90
91
92 struct pex_hdr *__pex_msg_init(const uint8_t *pubkey, uint8_t opcode)
93 {
94 struct pex_hdr *hdr = (struct pex_hdr *)pex_tx_buf;
95
96 hdr->version = 0;
97 hdr->opcode = opcode;
98 hdr->len = 0;
99 memcpy(hdr->id, pubkey, sizeof(hdr->id));
100
101 return hdr;
102 }
103
104 struct pex_hdr *__pex_msg_init_ext(const uint8_t *pubkey, const uint8_t *auth_key,
105 uint8_t opcode, bool ext)
106 {
107 struct pex_hdr *hdr = __pex_msg_init(pubkey, opcode);
108 struct pex_ext_hdr *ehdr = (struct pex_ext_hdr *)(hdr + 1);
109 uint64_t hash;
110
111 if (!ext)
112 return hdr;
113
114 hdr->len = sizeof(*ehdr);
115
116 if (fread(&ehdr->nonce, sizeof(ehdr->nonce), 1, pex_urandom) != 1)
117 return NULL;
118
119 hash = pex_network_hash(auth_key, ehdr->nonce);
120 *(uint64_t *)hdr->id ^= hash;
121 memcpy(ehdr->auth_id, auth_key, sizeof(ehdr->auth_id));
122
123 return hdr;
124 }
125
126 void *pex_msg_append(size_t len)
127 {
128 struct pex_hdr *hdr = (struct pex_hdr *)pex_tx_buf;
129 int ofs = hdr->len + sizeof(struct pex_hdr);
130 void *buf = &pex_tx_buf[ofs];
131
132 if (sizeof(pex_tx_buf) - ofs < len)
133 return NULL;
134
135 hdr->len += len;
136 memset(buf, 0, len);
137
138 return buf;
139 }
140
141 static void
142 pex_fd_cb(struct uloop_fd *fd, unsigned int events)
143 {
144 static struct sockaddr_in6 sin6;
145 static char buf[PEX_RX_BUF_SIZE];
146 ssize_t len;
147
148 while (1) {
149 static struct iovec iov[2] = {
150 { .iov_base = &sin6 },
151 { .iov_base = buf },
152 };
153 static struct msghdr msg = {
154 .msg_iov = iov,
155 .msg_iovlen = ARRAY_SIZE(iov),
156 };
157 socklen_t slen = sizeof(sin6);
158
159 len = recvfrom(fd->fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6, &slen);
160 if (len < 0) {
161 if (errno == EINTR)
162 continue;
163
164 if (errno == EAGAIN)
165 break;
166
167 pex_close();
168 return;
169 }
170
171 if (!len)
172 continue;
173
174 if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
175 struct sockaddr_in *sin = (struct sockaddr_in *)&sin6;
176 struct in_addr in = *(struct in_addr *)&sin6.sin6_addr.s6_addr[12];
177 int port = sin6.sin6_port;
178
179 memset(&sin6, 0, sizeof(sin6));
180 sin->sin_port = port;
181 sin->sin_family = AF_INET;
182 sin->sin_addr = in;
183 slen = sizeof(*sin);
184 }
185
186 retry:
187 if (pex_unix_tx_fd >= 0) {
188 iov[0].iov_len = slen;
189 iov[1].iov_len = len;
190 if (sendmsg(pex_unix_tx_fd, &msg, 0) < 0) {
191 switch (errno) {
192 case EINTR:
193 goto retry;
194 case EMSGSIZE:
195 case ENOBUFS:
196 case EAGAIN:
197 continue;
198 default:
199 perror("sendmsg");
200 close(pex_unix_tx_fd);
201 pex_unix_tx_fd = -1;
202 break;
203 }
204 }
205 }
206
207 pex_recv_cb(buf, len, &sin6);
208 }
209 }
210
211 static void
212 pex_unix_cb(struct uloop_fd *fd, unsigned int events)
213 {
214 static char buf[PEX_RX_BUF_SIZE];
215 static struct iovec iov = {
216 .iov_base = buf,
217 .iov_len = sizeof(buf),
218 };
219 ssize_t len;
220
221 while (1) {
222 const struct sockaddr *sa = (struct sockaddr *)buf;
223 uint8_t fd_buf[CMSG_SPACE(sizeof(int))] = { 0 };
224 struct msghdr msg = {
225 .msg_iov = &iov,
226 .msg_iovlen = 1,
227 .msg_control = fd_buf,
228 .msg_controllen = CMSG_LEN(sizeof(int)),
229 };
230 struct cmsghdr *cmsg;
231 socklen_t slen;
232 int *pfd;
233
234 cmsg = CMSG_FIRSTHDR(&msg);
235 cmsg->cmsg_type = SCM_RIGHTS;
236 cmsg->cmsg_level = SOL_SOCKET;
237 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
238
239 pfd = (int *)CMSG_DATA(cmsg);
240 *pfd = -1;
241
242 len = recvmsg(fd->fd, &msg, 0);
243 if (len < 0) {
244 if (errno == EINTR)
245 continue;
246
247 if (errno == EAGAIN)
248 break;
249
250 pex_close();
251 return;
252 }
253
254 if (*pfd >= 0) {
255 if (pex_unix_tx_fd >= 0)
256 close(pex_unix_tx_fd);
257
258 pex_unix_tx_fd = *pfd;
259 }
260
261 if (!len)
262 continue;
263
264 if (len < sizeof(*sa))
265 continue;
266
267 if (sa->sa_family == AF_LOCAL) {
268 slen = sizeof(struct sockaddr);
269 len -= slen;
270 if (len < sizeof(struct pex_msg_local_control))
271 continue;
272
273 if (pex_control_cb)
274 pex_control_cb((struct pex_msg_local_control *)&buf[slen], len);
275
276 continue;
277 }
278
279 if (sa->sa_family == AF_INET)
280 slen = sizeof(struct sockaddr_in);
281 else if (sa->sa_family == AF_INET6)
282 slen = sizeof(struct sockaddr_in6);
283 else
284 continue;
285
286 sa = get_mapped_sockaddr(sa);
287 sendto(pex_fd.fd, buf + slen, len - slen, 0, sa, sizeof(struct sockaddr_in6));
288 }
289 }
290
291
292 int __pex_msg_send(int fd, const void *addr, void *ip_hdr, size_t ip_hdrlen)
293 {
294 struct pex_hdr *hdr = (struct pex_hdr *)pex_tx_buf;
295 const struct sockaddr *sa = addr;
296 size_t tx_len = sizeof(*hdr) + hdr->len;
297 uint16_t orig_len = hdr->len;
298 int ret;
299
300 if (fd < 0) {
301 hdr->len -= sizeof(struct pex_ext_hdr);
302 if (ip_hdrlen)
303 fd = pex_raw_socket(sa->sa_family);
304 else {
305 fd = pex_fd.fd;
306 sa = addr = get_mapped_sockaddr(addr);
307 }
308
309 if (fd < 0)
310 return -1;
311 }
312
313 hdr->len = htons(hdr->len);
314 if (ip_hdr) {
315 ret = sendto_rawudp(fd, addr, ip_hdr, ip_hdrlen, pex_tx_buf, tx_len);
316 } else if (addr) {
317 socklen_t addr_len;
318
319 if (sa->sa_family == AF_INET6)
320 addr_len = sizeof(struct sockaddr_in6);
321 else
322 addr_len = sizeof(struct sockaddr_in);
323
324 ret = sendto(fd, pex_tx_buf, tx_len, 0, addr, addr_len);
325 } else {
326 ret = send(fd, pex_tx_buf, tx_len, 0);
327 }
328 hdr->len = orig_len;
329
330 return ret;
331 }
332
333 static void
334 pex_msg_update_response_fill(struct pex_msg_update_send_ctx *ctx)
335 {
336 struct pex_hdr *hdr = (struct pex_hdr *)pex_tx_buf;
337 int ofs = hdr->len + sizeof(struct pex_hdr);
338 int cur_len = ctx->rem;
339
340 if (cur_len > PEX_BUF_SIZE - ofs)
341 cur_len = PEX_BUF_SIZE - ofs;
342
343 memcpy(pex_msg_append(cur_len), ctx->cur, cur_len);
344 ctx->cur += cur_len;
345 ctx->rem -= cur_len;
346 }
347
348 void pex_msg_update_response_init(struct pex_msg_update_send_ctx *ctx,
349 const uint8_t *pubkey, const uint8_t *auth_key,
350 const uint8_t *peer_key, bool ext,
351 struct pex_update_request *req,
352 const void *data, int len)
353 {
354 uint8_t e_key_priv[CURVE25519_KEY_SIZE];
355 uint8_t enc_key[CURVE25519_KEY_SIZE];
356 struct pex_update_response *res;
357
358 ctx->pubkey = pubkey;
359 ctx->auth_key = auth_key;
360 ctx->ext = ext;
361 ctx->req_id = req->req_id;
362
363 if (!__pex_msg_init_ext(pubkey, auth_key, PEX_MSG_UPDATE_RESPONSE, ext))
364 return;
365
366 res = pex_msg_append(sizeof(*res));
367 res->req_id = req->req_id;
368 res->data_len = cpu_to_be32(len);
369
370 if (!fread(e_key_priv, sizeof(e_key_priv), 1, pex_urandom))
371 return;
372
373 curve25519_clamp_secret(e_key_priv);
374 curve25519_generate_public(res->e_key, e_key_priv);
375 curve25519(enc_key, e_key_priv, peer_key);
376
377 ctx->data = ctx->cur = malloc(len);
378 ctx->rem = len;
379
380 memcpy(ctx->data, data, len);
381 chacha20_encrypt_msg(ctx->data, len, &req->req_id, enc_key);
382
383 pex_msg_update_response_fill(ctx);
384 }
385
386 bool pex_msg_update_response_continue(struct pex_msg_update_send_ctx *ctx)
387 {
388 struct pex_update_response_data *res_ext;
389
390 if (ctx->rem <= 0) {
391 free(ctx->data);
392 ctx->data = NULL;
393
394 return false;
395 }
396
397 if (!__pex_msg_init_ext(ctx->pubkey, ctx->auth_key,
398 PEX_MSG_UPDATE_RESPONSE_DATA, ctx->ext))
399 return false;
400
401 res_ext = pex_msg_append(sizeof(*res_ext));
402 res_ext->req_id = ctx->req_id;
403 res_ext->offset = cpu_to_be32(ctx->cur - ctx->data);
404 pex_msg_update_response_fill(ctx);
405
406 return true;
407 }
408
409
410 struct pex_update_request *
411 pex_msg_update_request_init(const uint8_t *pubkey, const uint8_t *priv_key,
412 const uint8_t *auth_key, union network_endpoint *addr,
413 uint64_t cur_version, bool ext)
414 {
415 struct pex_update_request *req;
416 struct pex_msg_update_recv_ctx *ctx;
417
418 list_for_each_entry(ctx, &requests, list) {
419 if (!memcmp(&ctx->addr, addr, sizeof(ctx->addr)))
420 return NULL;
421 }
422
423 ctx = calloc(1, sizeof(*ctx));
424 memcpy(&ctx->addr, addr, sizeof(ctx->addr));
425 memcpy(ctx->auth_key, auth_key, sizeof(ctx->auth_key));
426 memcpy(ctx->priv_key, priv_key, sizeof(ctx->priv_key));
427 if (!fread(&ctx->req_id, sizeof(ctx->req_id), 1, pex_urandom)) {
428 free(ctx);
429 return NULL;
430 }
431 list_add_tail(&ctx->list, &requests);
432 if (!gc_timer.pending)
433 uloop_timeout_set(&gc_timer, 1000);
434
435 if (!__pex_msg_init_ext(pubkey, auth_key, PEX_MSG_UPDATE_REQUEST, ext)) {
436 free(ctx);
437 return NULL;
438 }
439
440 req = pex_msg_append(sizeof(*req));
441 req->cur_version = cpu_to_be64(cur_version);
442 req->req_id = ctx->req_id;
443
444 return req;
445 }
446
447 static struct pex_msg_update_recv_ctx *
448 pex_msg_update_recv_ctx_get(uint64_t req_id)
449 {
450 struct pex_msg_update_recv_ctx *ctx;
451
452 list_for_each_entry(ctx, &requests, list) {
453 if (ctx->req_id == req_id) {
454 ctx->idle = 0;
455 return ctx;
456 }
457 }
458
459 return NULL;
460 }
461
462 static void pex_msg_update_ctx_free(struct pex_msg_update_recv_ctx *ctx)
463 {
464 list_del(&ctx->list);
465 free(ctx->data);
466 free(ctx);
467 }
468
469 void *pex_msg_update_response_recv(const void *data, int len, enum pex_opcode op,
470 int *data_len, uint64_t *timestamp)
471 {
472 struct pex_msg_update_recv_ctx *ctx;
473 uint8_t enc_key[CURVE25519_KEY_SIZE];
474 void *ret;
475
476 *data_len = 0;
477 if (op == PEX_MSG_UPDATE_RESPONSE) {
478 const struct pex_update_response *res = data;
479
480 if (len < sizeof(*res))
481 return NULL;
482
483 ctx = pex_msg_update_recv_ctx_get(res->req_id);
484 if (!ctx || ctx->data_len || !res->data_len ||
485 be32_to_cpu(res->data_len) > UNETD_NET_DATA_SIZE_MAX)
486 return NULL;
487
488 data += sizeof(*res);
489 len -= sizeof(*res);
490
491 ctx->data_len = be32_to_cpu(res->data_len);
492 memcpy(ctx->e_key, res->e_key, sizeof(ctx->e_key));
493 ctx->data = malloc(ctx->data_len);
494 } else if (op == PEX_MSG_UPDATE_RESPONSE_DATA) {
495 const struct pex_update_response_data *res = data;
496
497 if (len <= sizeof(*res))
498 return NULL;
499
500 ctx = pex_msg_update_recv_ctx_get(res->req_id);
501 if (!ctx || ctx->data_ofs != be32_to_cpu(res->offset))
502 return NULL;
503
504 data += sizeof(*res);
505 len -= sizeof(*res);
506 } else if (op == PEX_MSG_UPDATE_RESPONSE_NO_DATA) {
507 const struct pex_update_response_no_data *res = data;
508
509 if (len < sizeof(*res))
510 return NULL;
511
512 ctx = pex_msg_update_recv_ctx_get(res->req_id);
513 if (!ctx)
514 return NULL;
515
516 goto error;
517 } else {
518 return NULL;
519 }
520
521 if (ctx->data_ofs + len > ctx->data_len)
522 goto error;
523
524 memcpy(ctx->data + ctx->data_ofs, data, len);
525 ctx->data_ofs += len;
526 if (ctx->data_ofs < ctx->data_len)
527 return NULL;
528
529 curve25519(enc_key, ctx->priv_key, ctx->e_key);
530 chacha20_encrypt_msg(ctx->data, ctx->data_len, &ctx->req_id, enc_key);
531 if (unet_auth_data_validate(ctx->auth_key, ctx->data, ctx->data_len, timestamp, NULL))
532 goto error;
533
534 *data_len = ctx->data_len;
535 ret = ctx->data;
536 ctx->data = NULL;
537 pex_msg_update_ctx_free(ctx);
538
539 return ret;
540
541 error:
542 pex_msg_update_ctx_free(ctx);
543 *data_len = -1;
544 return NULL;
545 }
546
547 struct pex_hdr *pex_rx_accept(void *data, size_t len, bool ext)
548 {
549 struct pex_hdr *hdr = data;
550 uint16_t hdr_len;
551 size_t min_size;
552
553 min_size = sizeof(*hdr);
554 if (ext)
555 min_size += sizeof(struct pex_ext_hdr);
556
557 if (len < min_size)
558 return NULL;
559
560 hdr_len = ntohs(hdr->len);
561 if (len < min_size + hdr_len)
562 return NULL;
563
564 hdr->len = hdr_len;
565
566 return hdr;
567 }
568
569 static void
570 pex_gc_cb(struct uloop_timeout *t)
571 {
572 struct pex_msg_update_recv_ctx *ctx, *tmp;
573
574 list_for_each_entry_safe(ctx, tmp, &requests, list) {
575 if (++ctx->idle <= 3)
576 continue;
577
578 pex_msg_update_ctx_free(ctx);
579 }
580
581 if (!list_empty(&requests))
582 uloop_timeout_set(t, 1000);
583 }
584
585 int pex_open(void *addr, size_t addr_len, pex_recv_cb_t cb, bool server)
586 {
587 struct sockaddr *sa = addr;
588 int yes = 1, no = 0;
589 int fd;
590
591 pex_recv_cb = cb;
592
593 if (server) {
594 pex_raw_v4_fd = fd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
595 if (fd < 0)
596 return -1;
597
598 setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
599 setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &yes, sizeof(yes));
600
601 #ifdef linux
602 pex_raw_v6_fd = fd = socket(PF_INET6, SOCK_RAW, IPPROTO_UDP);
603 if (fd < 0)
604 goto close_raw;
605
606 setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
607 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &no, sizeof(no));
608 setsockopt(fd, IPPROTO_IPV6, IPV6_HDRINCL, &yes, sizeof(yes));
609 #endif
610 }
611
612 pex_urandom = fopen("/dev/urandom", "r");
613 if (!pex_urandom)
614 goto close_raw;
615
616 fd = socket(sa->sa_family == AF_INET ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
617 if (fd < 0)
618 goto close_urandom;
619
620 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
621 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
622
623 if (server) {
624 if (bind(fd, addr, addr_len) < 0) {
625 perror("bind");
626 goto close_socket;
627 }
628
629 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
630 setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes));
631 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &no, sizeof(no));
632 } else {
633 if (connect(fd, addr, addr_len) < 0) {
634 perror("connect");
635 goto close_socket;
636 }
637 }
638
639 pex_fd.fd = fd;
640 pex_fd.cb = pex_fd_cb;
641 uloop_fd_add(&pex_fd, ULOOP_READ);
642
643 gc_timer.cb = pex_gc_cb;
644
645 return 0;
646
647 close_socket:
648 close(fd);
649 close_urandom:
650 fclose(pex_urandom);
651 close_raw:
652 if (pex_raw_v4_fd >= 0)
653 close(pex_raw_v4_fd);
654 if (pex_raw_v6_fd >= 0)
655 close(pex_raw_v6_fd);
656 pex_raw_v4_fd = -1;
657 pex_raw_v6_fd = -1;
658 return -1;
659 }
660
661 int pex_unix_open(const char *path, pex_recv_control_cb_t cb)
662 {
663 mode_t prev_mask;
664 int fd;
665
666 pex_control_cb = cb;
667 unlink(path);
668
669 prev_mask = umask(0177);
670 fd = usock(USOCK_UDP | USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, path, NULL);
671 umask(prev_mask);
672 if (fd < 0)
673 return -1;
674
675 pex_unix_fd.cb = pex_unix_cb;
676 pex_unix_fd.fd = fd;
677 uloop_fd_add(&pex_unix_fd, ULOOP_READ);
678
679 return 0;
680 }
681
682 void pex_close(void)
683 {
684 if (pex_raw_v4_fd >= 0)
685 close(pex_raw_v4_fd);
686 if (pex_raw_v6_fd >= 0)
687 close(pex_raw_v6_fd);
688 pex_raw_v4_fd = -1;
689 pex_raw_v6_fd = -1;
690
691 if (pex_urandom)
692 fclose(pex_urandom);
693
694 if (pex_fd.cb) {
695 uloop_fd_delete(&pex_fd);
696 close(pex_fd.fd);
697 }
698
699 if (pex_unix_fd.cb) {
700 uloop_fd_delete(&pex_unix_fd);
701 close(pex_unix_fd.fd);
702 }
703
704 pex_fd.cb = NULL;
705 pex_unix_fd.cb = NULL;
706 pex_urandom = NULL;
707 }