curvetun: Fix issues detected by the Coverity scanner
[netsniff-ng.git] / curvetun_mgmt_users.c
blob52b20d87ad1ab35228c936ddc3eb0e7c67c456c6
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <string.h>
13 #include <syslog.h>
14 #include <limits.h>
15 #include <arpa/inet.h>
17 #include "die.h"
18 #include "locking.h"
19 #include "xmalloc.h"
20 #include "ioexact.h"
21 #include "ioops.h"
22 #include "str.h"
23 #include "curvetun.h"
24 #include "curve.h"
25 #include "crypto.h"
26 #include "curvetun_mgmt_users.h"
27 #include "hash.h"
29 struct user_store {
30 char username[256];
31 unsigned char publickey[crypto_box_pub_key_size];
32 struct curve25519_proto proto_inf;
33 struct user_store *next;
36 struct sock_map_entry {
37 int fd;
38 struct curve25519_proto *proto;
39 struct sock_map_entry *next;
42 struct sockaddr_map_entry {
43 struct sockaddr_storage *sa;
44 size_t sa_len;
45 struct curve25519_proto *proto;
46 struct sockaddr_map_entry *next;
49 static struct user_store *store = NULL;
50 static struct rwlock store_lock;
52 static struct hash_table sock_mapper;
53 static struct rwlock sock_map_lock;
55 static struct hash_table sockaddr_mapper;
56 static struct rwlock sockaddr_map_lock;
58 static unsigned char token[crypto_auth_hmacsha512256_KEYBYTES];
60 static void init_sock_mapper(void)
62 rwlock_init(&sock_map_lock);
64 rwlock_wr_lock(&sock_map_lock);
66 memset(&sock_mapper, 0, sizeof(sock_mapper));
67 init_hash(&sock_mapper);
69 rwlock_unlock(&sock_map_lock);
72 static void init_sockaddr_mapper(void)
74 rwlock_init(&sockaddr_map_lock);
75 rwlock_wr_lock(&sockaddr_map_lock);
77 memset(&sockaddr_mapper, 0, sizeof(sockaddr_mapper));
78 init_hash(&sockaddr_mapper);
80 rwlock_unlock(&sockaddr_map_lock);
83 static int cleanup_batch_sock_mapper(void *ptr)
85 struct sock_map_entry *next;
86 struct sock_map_entry *e = ptr;
88 if (!e)
89 return 0;
91 while ((next = e->next)) {
92 e->next = NULL;
93 xfree(e);
94 e = next;
97 xfree(e);
99 return 0;
102 static void destroy_sock_mapper(void)
104 rwlock_wr_lock(&sock_map_lock);
105 for_each_hash(&sock_mapper, cleanup_batch_sock_mapper);
106 free_hash(&sock_mapper);
107 rwlock_unlock(&sock_map_lock);
109 rwlock_destroy(&sock_map_lock);
112 static int cleanup_batch_sockaddr_mapper(void *ptr)
114 struct sockaddr_map_entry *next;
115 struct sockaddr_map_entry *e = ptr;
117 if (!e)
118 return 0;
120 while ((next = e->next)) {
121 e->next = NULL;
122 xfree(e);
123 e = next;
126 xfree(e);
127 return 0;
130 static void destroy_sockaddr_mapper(void)
132 rwlock_wr_lock(&sockaddr_map_lock);
133 for_each_hash(&sockaddr_mapper, cleanup_batch_sockaddr_mapper);
134 free_hash(&sockaddr_mapper);
135 rwlock_unlock(&sockaddr_map_lock);
137 rwlock_destroy(&sockaddr_map_lock);
140 static struct user_store *user_store_alloc(void)
142 return xzmalloc(sizeof(struct user_store));
145 static void user_store_free(struct user_store *us)
147 if (!us)
148 return;
149 memset(us, 0, sizeof(struct user_store));
150 xfree(us);
153 /* already in lock */
154 static int __check_duplicate_username(char *username, size_t len)
156 int duplicate = 0;
157 struct user_store *elem = store;
159 while (elem) {
160 if (!memcmp(elem->username, username,
161 strlen(elem->username) + 1)) {
162 duplicate = 1;
163 break;
165 elem = elem->next;
168 return duplicate;
171 /* already in lock */
172 static int __check_duplicate_pubkey(unsigned char *pubkey, size_t len)
174 int duplicate = 0;
175 struct user_store *elem = store;
177 while (elem) {
178 if (!memcmp(elem->publickey, pubkey,
179 sizeof(elem->publickey))) {
180 duplicate = 1;
181 break;
183 elem = elem->next;
186 return duplicate;
189 enum parse_states {
190 PARSE_USERNAME,
191 PARSE_PUBKEY,
192 PARSE_DONE,
195 static int parse_line(char *line, char *homedir)
197 char *str;
198 enum parse_states s = PARSE_USERNAME;
199 struct user_store *elem;
200 unsigned char pkey[crypto_box_pub_key_size];
202 elem = user_store_alloc();
203 elem->next = store;
205 str = strtok(line, ";");
206 for (; str != NULL;) {
207 switch (s) {
208 case PARSE_USERNAME:
209 if (__check_duplicate_username(str, strlen(str) + 1)) {
210 user_store_free(elem);
211 return -EINVAL;
213 strlcpy(elem->username, str, sizeof(elem->username));
214 s = PARSE_PUBKEY;
215 break;
216 case PARSE_PUBKEY:
217 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
218 str, strlen(str))) {
219 user_store_free(elem);
220 return -EINVAL;
222 if (__check_duplicate_pubkey(pkey, sizeof(pkey))) {
223 user_store_free(elem);
224 return -EINVAL;
226 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
227 curve25519_proto_init(&elem->proto_inf, elem->publickey, sizeof(elem->publickey));
228 s = PARSE_DONE;
229 break;
230 case PARSE_DONE:
231 break;
232 default:
233 user_store_free(elem);
234 return -EIO;
237 str = strtok(NULL, ";");
240 store = elem;
241 return s == PARSE_DONE ? 0 : -EIO;
244 void parse_userfile_and_generate_user_store_or_die(char *homedir)
246 FILE *fp;
247 char path[PATH_MAX], buff[512];
248 int line = 1, ret, fd;
250 memset(path, 0, sizeof(path));
251 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_CLIENTS);
253 rwlock_init(&store_lock);
254 rwlock_wr_lock(&store_lock);
256 fp = fopen(path, "r");
257 if (!fp)
258 panic("Cannot open client file!\n");
260 memset(buff, 0, sizeof(buff));
261 while (fgets(buff, sizeof(buff), fp) != NULL) {
262 buff[sizeof(buff) - 1] = 0;
263 /* A comment. Skip this line */
264 if (buff[0] == '#' || buff[0] == '\n') {
265 memset(buff, 0, sizeof(buff));
266 line++;
267 continue;
270 ret = parse_line(buff, homedir);
271 if (ret < 0)
272 panic("Cannot parse line %d from clients!\n", line);
273 line++;
274 memset(buff, 0, sizeof(buff));
277 fclose(fp);
279 if (store == NULL)
280 panic("No registered clients found!\n");
282 rwlock_unlock(&store_lock);
284 init_sock_mapper();
285 init_sockaddr_mapper();
288 * Pubkey is also used as a hmac of the initial packet to check
289 * the integrity of the packet, so that we know if it's just random
290 * garbage or a 'valid' packet. Again, just for the integrity!
293 memset(path, 0, sizeof(path));
294 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_PUBKEY);
296 fd = open_or_die(path, O_RDONLY);
297 ret = read(fd, token, sizeof(token));
298 if (ret != crypto_auth_hmacsha512256_KEYBYTES)
299 panic("Cannot read public key!\n");
300 close(fd);
303 void dump_user_store(void)
305 int i;
306 struct user_store *elem;
308 rwlock_rd_lock(&store_lock);
310 elem = store;
311 while (elem) {
312 printf("%s -> ", elem->username);
313 for (i = 0; i < sizeof(elem->publickey); ++i)
314 if (i == (sizeof(elem->publickey) - 1))
315 printf("%02x\n", (unsigned char)
316 elem->publickey[i]);
317 else
318 printf("%02x:", (unsigned char)
319 elem->publickey[i]);
320 elem = elem->next;
323 rwlock_unlock(&store_lock);
326 void destroy_user_store(void)
328 struct user_store *elem, *nelem = NULL;
330 rwlock_wr_lock(&store_lock);
332 elem = store;
333 while (elem) {
334 nelem = elem->next;
335 elem->next = NULL;
336 user_store_free(elem);
337 elem = nelem;
339 rwlock_unlock(&store_lock);
341 rwlock_destroy(&store_lock);
343 destroy_sock_mapper();
344 destroy_sockaddr_mapper();
347 int username_msg(char *username, size_t len, char *dst, size_t dlen)
349 int fd;
350 ssize_t ret;
351 uint32_t salt;
352 unsigned char h[crypto_hash_sha512_BYTES];
353 struct username_struct *us = (struct username_struct *) dst;
354 char *uname;
355 size_t uname_len;
357 if (dlen < sizeof(struct username_struct))
358 return -ENOMEM;
360 uname_len = 512;
361 uname = xzmalloc(uname_len);
363 fd = open_or_die("/dev/random", O_RDONLY);
364 ret = read_exact(fd, &salt, sizeof(salt), 0);
365 if (ret != sizeof(salt))
366 panic("Cannot read from /dev/random!\n");
367 close(fd);
369 slprintf(uname, uname_len, "%s%u", username, salt);
370 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
372 us->salt = htonl(salt);
373 memcpy(us->hash, h, sizeof(us->hash));
375 xfree(uname);
376 return 0;
379 enum is_user_enum username_msg_is_user(char *src, size_t slen, char *username,
380 size_t len)
382 char *uname;
383 size_t uname_len;
384 uint32_t salt;
385 struct username_struct *us = (struct username_struct *) src;
386 unsigned char h[crypto_hash_sha512_BYTES];
388 if (slen < sizeof(struct username_struct)) {
389 errno = ENOMEM;
390 return USERNAMES_ERR;
393 uname_len = 512;
394 uname = xzmalloc(uname_len);
396 salt = ntohl(us->salt);
398 slprintf(uname, uname_len, "%s%u", username, salt);
399 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
400 xfree(uname);
402 if (!crypto_verify_32(&h[0], &us->hash[0]) &&
403 !crypto_verify_32(&h[32], &us->hash[32]))
404 return USERNAMES_OK;
405 else
406 return USERNAMES_NE;
409 static int register_user_by_socket(int fd, struct curve25519_proto *proto)
411 void **pos;
412 struct sock_map_entry *entry;
414 rwlock_wr_lock(&sock_map_lock);
416 entry = xzmalloc(sizeof(*entry));
417 entry->fd = fd;
418 entry->proto = proto;
420 pos = insert_hash(entry->fd, entry, &sock_mapper);
421 if (pos) {
422 entry->next = (*pos);
423 (*pos) = entry;
426 rwlock_unlock(&sock_map_lock);
428 return 0;
431 static int register_user_by_sockaddr(struct sockaddr_storage *sa,
432 size_t sa_len,
433 struct curve25519_proto *proto)
435 void **pos;
436 struct sockaddr_map_entry *entry;
437 unsigned int hash = hash_name((char *) sa, sa_len);
439 rwlock_wr_lock(&sockaddr_map_lock);
441 entry = xzmalloc(sizeof(*entry));
442 entry->sa = xmemdupz(sa, sa_len);
443 entry->sa_len = sa_len;
444 entry->proto = proto;
446 pos = insert_hash(hash, entry, &sockaddr_mapper);
447 if (pos) {
448 entry->next = (*pos);
449 (*pos) = entry;
452 rwlock_unlock(&sockaddr_map_lock);
454 return 0;
457 int try_register_user_by_socket(struct curve25519_struct *c,
458 char *src, size_t slen, int sock, int log)
460 int ret = -1;
461 char *cbuff = NULL;
462 size_t real_len = 132;
463 ssize_t clen;
464 struct user_store *elem;
465 enum is_user_enum err;
466 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
467 struct taia arrival_taia;
469 /* assert(132 == clen + sizeof(auth)); */
471 * Check hmac first, if malicious, drop immediately before we
472 * investigate more efforts.
474 if (slen < real_len)
475 return -1;
477 taia_now(&arrival_taia);
479 memcpy(auth, src, sizeof(auth));
481 src += sizeof(auth);
482 real_len -= sizeof(auth);
484 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
485 real_len, token)) {
486 syslog(LOG_ERR, "Bad packet hmac for id %d! Dropping!\n", sock);
487 return -1;
488 } else {
489 if (log)
490 syslog(LOG_INFO, "Good packet hmac for id %d!\n", sock);
493 rwlock_rd_lock(&store_lock);
495 elem = store;
496 while (elem) {
497 clen = curve25519_decode(c, &elem->proto_inf,
498 (unsigned char *) src, real_len,
499 (unsigned char **) &cbuff,
500 &arrival_taia);
501 if (clen <= 0) {
502 elem = elem->next;
503 continue;
506 cbuff += crypto_box_zerobytes;
507 clen -= crypto_box_zerobytes;
509 if (log)
510 syslog(LOG_INFO, "Packet decoded successfully for id %d!\n", sock);
512 err = username_msg_is_user(cbuff, clen, elem->username,
513 strlen(elem->username) + 1);
514 if (err == USERNAMES_OK) {
515 if (log)
516 syslog(LOG_INFO, "Found user %s for id %d! Registering ...\n",
517 elem->username, sock);
518 ret = register_user_by_socket(sock, &elem->proto_inf);
519 break;
522 elem = elem->next;
525 rwlock_unlock(&store_lock);
527 if (ret == -1)
528 syslog(LOG_ERR, "User not found! Dropping connection!\n");
530 return ret;
533 int try_register_user_by_sockaddr(struct curve25519_struct *c,
534 char *src, size_t slen,
535 struct sockaddr_storage *sa,
536 size_t sa_len, int log)
538 int ret = -1;
539 char *cbuff = NULL;
540 struct user_store *elem;
541 ssize_t clen;
542 size_t real_len = 132;
543 enum is_user_enum err;
544 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
545 struct taia arrival_taia;
547 /* assert(132 == clen + sizeof(auth)); */
549 * Check hmac first, if malicious, drop immediately before we
550 * investigate more efforts.
552 if (slen < real_len)
553 return -1;
555 taia_now(&arrival_taia);
557 memcpy(auth, src, sizeof(auth));
559 src += sizeof(auth);
560 real_len -= sizeof(auth);
562 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
563 real_len, token)) {
564 syslog(LOG_ERR, "Got bad packet hmac! Dropping!\n");
565 return -1;
566 } else {
567 if (log)
568 syslog(LOG_INFO, "Got good packet hmac!\n");
571 rwlock_rd_lock(&store_lock);
573 elem = store;
574 while (elem) {
575 clen = curve25519_decode(c, &elem->proto_inf,
576 (unsigned char *) src, real_len,
577 (unsigned char **) &cbuff,
578 &arrival_taia);
579 if (clen <= 0) {
580 elem = elem->next;
581 continue;
584 cbuff += crypto_box_zerobytes;
585 clen -= crypto_box_zerobytes;
587 if (log)
588 syslog(LOG_INFO, "Packet decoded successfully!\n");
590 err = username_msg_is_user(cbuff, clen, elem->username,
591 strlen(elem->username) + 1);
592 if (err == USERNAMES_OK) {
593 if (log)
594 syslog(LOG_INFO, "Found user %s! Registering ...\n",
595 elem->username);
596 ret = register_user_by_sockaddr(sa, sa_len,
597 &elem->proto_inf);
598 break;
601 elem = elem->next;
604 rwlock_unlock(&store_lock);
606 if (ret == -1)
607 syslog(LOG_ERR, "User not found! Dropping connection!\n");
609 return ret;
612 int get_user_by_socket(int fd, struct curve25519_proto **proto)
614 int ret = -1;
615 struct sock_map_entry *entry;
617 errno = 0;
619 rwlock_rd_lock(&sock_map_lock);
621 entry = lookup_hash(fd, &sock_mapper);
622 while (entry && fd != entry->fd)
623 entry = entry->next;
624 if (entry && fd == entry->fd) {
625 (*proto) = entry->proto;
626 ret = 0;
627 } else {
628 (*proto) = NULL;
629 errno = ENOENT;
632 rwlock_unlock(&sock_map_lock);
634 return ret;
637 int get_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len,
638 struct curve25519_proto **proto)
640 int ret = -1;
641 struct sockaddr_map_entry *entry;
642 unsigned int hash = hash_name((char *) sa, sa_len);
644 errno = 0;
646 rwlock_rd_lock(&sockaddr_map_lock);
648 entry = lookup_hash(hash, &sockaddr_mapper);
649 while (entry && entry->sa_len == sa_len &&
650 memcmp(sa, entry->sa, entry->sa_len))
651 entry = entry->next;
652 if (entry && entry->sa_len == sa_len &&
653 !memcmp(sa, entry->sa, entry->sa_len)) {
654 (*proto) = entry->proto;
655 ret = 0;
656 } else {
657 (*proto) = NULL;
658 errno = ENOENT;
661 rwlock_unlock(&sockaddr_map_lock);
663 return ret;
666 static struct sock_map_entry *socket_to_sock_map_entry(int fd)
668 struct sock_map_entry *entry, *ret = NULL;
670 errno = 0;
672 rwlock_rd_lock(&sock_map_lock);
674 entry = lookup_hash(fd, &sock_mapper);
675 while (entry && fd != entry->fd)
676 entry = entry->next;
677 if (entry && fd == entry->fd)
678 ret = entry;
679 else
680 errno = ENOENT;
682 rwlock_unlock(&sock_map_lock);
684 return ret;
687 void remove_user_by_socket(int fd)
689 struct sock_map_entry *pos;
690 struct sock_map_entry *entry = socket_to_sock_map_entry(fd);
692 if (!entry)
693 return;
695 rwlock_wr_lock(&sock_map_lock);
697 pos = remove_hash(entry->fd, entry, entry->next, &sock_mapper);
698 while (pos && pos->next && pos->next != entry)
699 pos = pos->next;
700 if (pos && pos->next && pos->next == entry)
701 pos->next = entry->next;
703 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
704 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
706 entry->proto = NULL;
707 entry->next = NULL;
709 xfree(entry);
711 rwlock_unlock(&sock_map_lock);
714 static struct sockaddr_map_entry *
715 sockaddr_to_sockaddr_map_entry(struct sockaddr_storage *sa, size_t sa_len)
717 struct sockaddr_map_entry *entry, *ret = NULL;
718 unsigned int hash = hash_name((char *) sa, sa_len);
720 errno = 0;
722 rwlock_rd_lock(&sockaddr_map_lock);
724 entry = lookup_hash(hash, &sockaddr_mapper);
725 while (entry && entry->sa_len == sa_len &&
726 memcmp(sa, entry->sa, entry->sa_len))
727 entry = entry->next;
728 if (entry && entry->sa_len == sa_len &&
729 !memcmp(sa, entry->sa, entry->sa_len))
730 ret = entry;
731 else
732 errno = ENOENT;
734 rwlock_unlock(&sockaddr_map_lock);
736 return ret;
739 void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len)
741 struct sockaddr_map_entry *pos;
742 struct sockaddr_map_entry *entry;
743 unsigned int hash = hash_name((char *) sa, sa_len);
745 entry = sockaddr_to_sockaddr_map_entry(sa, sa_len);
746 if (!entry)
747 return;
749 rwlock_wr_lock(&sockaddr_map_lock);
751 pos = remove_hash(hash, entry, entry->next, &sockaddr_mapper);
752 while (pos && pos->next && pos->next != entry)
753 pos = pos->next;
754 if (pos && pos->next && pos->next == entry)
755 pos->next = entry->next;
757 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
758 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
760 entry->proto = NULL;
761 entry->next = NULL;
763 xfree(entry->sa);
764 xfree(entry);
766 rwlock_unlock(&sockaddr_map_lock);