Corrected spinning loop potential in getrandombytes
[netsniff-ng-old.git] / ct_usermgmt.c
blob0c80dc7a6b29a7b6c15172a928c9ea0ea52be51a
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 "ct_usermgmt.h"
19 #include "locking.h"
20 #include "xmalloc.h"
21 #include "xio.h"
22 #include "curvetun.h"
23 #include "xutils.h"
24 #include "curve.h"
25 #include "hash.h"
26 #include "crypto_verify_32.h"
27 #include "crypto_hash_sha512.h"
28 #include "crypto_box_curve25519xsalsa20poly1305.h"
29 #include "crypto_auth_hmacsha512256.h"
31 #define crypto_box_pub_key_size crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
33 /* Config line format: username;pubkey\n */
35 struct user_store {
36 char username[256];
37 unsigned char publickey[crypto_box_pub_key_size];
38 struct curve25519_proto proto_inf;
39 struct user_store *next;
42 struct sock_map_entry {
43 int fd;
44 struct curve25519_proto *proto;
45 struct sock_map_entry *next;
48 struct sockaddr_map_entry {
49 struct sockaddr_storage *sa;
50 size_t sa_len;
51 struct curve25519_proto *proto;
52 struct sockaddr_map_entry *next;
55 static struct user_store *store = NULL;
56 static struct rwlock store_lock;
58 static struct hash_table sock_mapper;
59 static struct rwlock sock_map_lock;
61 static struct hash_table sockaddr_mapper;
62 static struct rwlock sockaddr_map_lock;
64 static unsigned char token[crypto_auth_hmacsha512256_KEYBYTES];
66 static void init_sock_mapper(void)
68 rwlock_init(&sock_map_lock);
70 rwlock_wr_lock(&sock_map_lock);
72 memset(&sock_mapper, 0, sizeof(sock_mapper));
73 init_hash(&sock_mapper);
75 rwlock_unlock(&sock_map_lock);
78 static void init_sockaddr_mapper(void)
80 rwlock_init(&sockaddr_map_lock);
81 rwlock_wr_lock(&sockaddr_map_lock);
83 memset(&sockaddr_mapper, 0, sizeof(sockaddr_mapper));
84 init_hash(&sockaddr_mapper);
86 rwlock_unlock(&sockaddr_map_lock);
89 static int cleanup_batch_sock_mapper(void *ptr)
91 struct sock_map_entry *next;
92 struct sock_map_entry *e = ptr;
94 if (!e)
95 return 0;
97 while ((next = e->next)) {
98 e->next = NULL;
99 xfree(e);
100 e = next;
103 xfree(e);
105 return 0;
108 static void destroy_sock_mapper(void)
110 rwlock_wr_lock(&sock_map_lock);
111 for_each_hash(&sock_mapper, cleanup_batch_sock_mapper);
112 free_hash(&sock_mapper);
113 rwlock_unlock(&sock_map_lock);
115 rwlock_destroy(&sock_map_lock);
118 static int cleanup_batch_sockaddr_mapper(void *ptr)
120 struct sockaddr_map_entry *next;
121 struct sockaddr_map_entry *e = ptr;
123 if (!e)
124 return 0;
126 while ((next = e->next)) {
127 e->next = NULL;
128 xfree(e);
129 e = next;
132 xfree(e);
133 return 0;
136 static void destroy_sockaddr_mapper(void)
138 rwlock_wr_lock(&sockaddr_map_lock);
139 for_each_hash(&sockaddr_mapper, cleanup_batch_sockaddr_mapper);
140 free_hash(&sockaddr_mapper);
141 rwlock_unlock(&sockaddr_map_lock);
143 rwlock_destroy(&sockaddr_map_lock);
146 static struct user_store *user_store_alloc(void)
148 return xzmalloc(sizeof(struct user_store));
151 static void user_store_free(struct user_store *us)
153 if (!us)
154 return;
155 memset(us, 0, sizeof(struct user_store));
156 xfree(us);
159 /* already in lock */
160 static int __check_duplicate_username(char *username, size_t len)
162 int duplicate = 0;
163 struct user_store *elem = store;
165 while (elem) {
166 if (!memcmp(elem->username, username,
167 strlen(elem->username) + 1)) {
168 duplicate = 1;
169 break;
171 elem = elem->next;
174 return duplicate;
177 /* already in lock */
178 static int __check_duplicate_pubkey(unsigned char *pubkey, size_t len)
180 int duplicate = 0;
181 struct user_store *elem = store;
183 while (elem) {
184 if (!memcmp(elem->publickey, pubkey,
185 sizeof(elem->publickey))) {
186 duplicate = 1;
187 break;
189 elem = elem->next;
192 return duplicate;
195 enum parse_states {
196 PARSE_USERNAME,
197 PARSE_PUBKEY,
198 PARSE_DONE,
201 static int parse_line(char *line, char *homedir)
203 int ret;
204 char *str;
205 enum parse_states s = PARSE_USERNAME;
206 struct user_store *elem;
207 unsigned char pkey[crypto_box_pub_key_size];
209 elem = user_store_alloc();
210 elem->next = store;
212 str = strtok(line, ";");
213 for (; str != NULL;) {
214 switch (s) {
215 case PARSE_USERNAME:
216 if (__check_duplicate_username(str, strlen(str) + 1))
217 return -EINVAL;
218 strlcpy(elem->username, str, sizeof(elem->username));
219 s = PARSE_PUBKEY;
220 break;
221 case PARSE_PUBKEY:
222 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
223 str, strlen(str)))
224 return -EINVAL;
225 if (__check_duplicate_pubkey(pkey, sizeof(pkey)))
226 return -EINVAL;
227 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
228 ret = curve25519_proto_init(&elem->proto_inf,
229 elem->publickey,
230 sizeof(elem->publickey),
231 homedir, 1);
232 if (ret)
233 return -EIO;
234 s = PARSE_DONE;
235 break;
236 case PARSE_DONE:
237 break;
238 default:
239 return -EIO;
242 str = strtok(NULL, ";");
245 store = elem;
246 return s == PARSE_DONE ? 0 : -EIO;
249 void parse_userfile_and_generate_user_store_or_die(char *homedir)
251 FILE *fp;
252 char path[PATH_MAX], buff[512];
253 int line = 1, ret, fd;
255 memset(path, 0, sizeof(path));
256 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_CLIENTS);
258 rwlock_init(&store_lock);
259 rwlock_wr_lock(&store_lock);
261 fp = fopen(path, "r");
262 if (!fp)
263 panic("Cannot open client file!\n");
265 memset(buff, 0, sizeof(buff));
266 while (fgets(buff, sizeof(buff), fp) != NULL) {
267 buff[sizeof(buff) - 1] = 0;
268 /* A comment. Skip this line */
269 if (buff[0] == '#' || buff[0] == '\n') {
270 memset(buff, 0, sizeof(buff));
271 line++;
272 continue;
275 ret = parse_line(buff, homedir);
276 if (ret < 0)
277 panic("Cannot parse line %d from clients!\n", line);
278 line++;
279 memset(buff, 0, sizeof(buff));
282 fclose(fp);
284 if (store == NULL)
285 panic("No registered clients found!\n");
287 rwlock_unlock(&store_lock);
289 init_sock_mapper();
290 init_sockaddr_mapper();
293 * Pubkey is also used as a hmac of the initial packet to check
294 * the integrity of the packet, so that we know if it's just random
295 * garbage or a 'valid' packet. Again, just for the integrity!
298 memset(path, 0, sizeof(path));
299 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_PUBKEY);
301 fd = open_or_die(path, O_RDONLY);
302 ret = read(fd, token, sizeof(token));
303 if (ret != crypto_auth_hmacsha512256_KEYBYTES)
304 panic("Cannot read public key!\n");
305 close(fd);
308 void dump_user_store(void)
310 int i;
311 struct user_store *elem;
313 rwlock_rd_lock(&store_lock);
315 elem = store;
316 while (elem) {
317 printf("%s -> ", elem->username);
318 for (i = 0; i < sizeof(elem->publickey); ++i)
319 if (i == (sizeof(elem->publickey) - 1))
320 printf("%02x\n", (unsigned char)
321 elem->publickey[i]);
322 else
323 printf("%02x:", (unsigned char)
324 elem->publickey[i]);
325 elem = elem->next;
328 rwlock_unlock(&store_lock);
331 void destroy_user_store(void)
333 struct user_store *elem, *nelem = NULL;
335 rwlock_wr_lock(&store_lock);
337 elem = store;
338 while (elem) {
339 nelem = elem->next;
340 elem->next = NULL;
341 user_store_free(elem);
342 elem = nelem;
344 rwlock_unlock(&store_lock);
346 rwlock_destroy(&store_lock);
348 destroy_sock_mapper();
349 destroy_sockaddr_mapper();
352 int username_msg(char *username, size_t len, char *dst, size_t dlen)
354 int fd;
355 ssize_t ret;
356 uint32_t salt;
357 unsigned char h[crypto_hash_sha512_BYTES];
358 struct username_struct *us = (struct username_struct *) dst;
359 char *uname;
360 size_t uname_len;
362 if (dlen < sizeof(struct username_struct))
363 return -ENOMEM;
365 uname_len = 512;
366 uname = xzmalloc(uname_len);
368 fd = open_or_die("/dev/random", O_RDONLY);
369 ret = read_exact(fd, &salt, sizeof(salt), 0);
370 if (ret != sizeof(salt))
371 panic("Cannot read from /dev/random!\n");
372 close(fd);
374 slprintf(uname, uname_len, "%s%u", username, salt);
375 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
377 us->salt = htonl(salt);
378 memcpy(us->hash, h, sizeof(us->hash));
380 xfree(uname);
381 return 0;
384 enum is_user_enum username_msg_is_user(char *src, size_t slen, char *username,
385 size_t len)
387 char *uname;
388 size_t uname_len;
389 uint32_t salt;
390 struct username_struct *us = (struct username_struct *) src;
391 unsigned char h[crypto_hash_sha512_BYTES];
393 if (slen < sizeof(struct username_struct)) {
394 errno = ENOMEM;
395 return USERNAMES_ERR;
398 uname_len = 512;
399 uname = xzmalloc(uname_len);
401 salt = ntohl(us->salt);
403 slprintf(uname, uname_len, "%s%u", username, salt);
404 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
405 xfree(uname);
407 if (!crypto_verify_32(&h[0], &us->hash[0]) &&
408 !crypto_verify_32(&h[32], &us->hash[32]))
409 return USERNAMES_OK;
410 else
411 return USERNAMES_NE;
414 static int register_user_by_socket(int fd, struct curve25519_proto *proto)
416 void **pos;
417 struct sock_map_entry *entry;
419 rwlock_wr_lock(&sock_map_lock);
421 entry = xzmalloc(sizeof(*entry));
422 entry->fd = fd;
423 entry->proto = proto;
425 pos = insert_hash(entry->fd, entry, &sock_mapper);
426 if (pos) {
427 entry->next = (*pos);
428 (*pos) = entry;
431 rwlock_unlock(&sock_map_lock);
433 return 0;
436 static int register_user_by_sockaddr(struct sockaddr_storage *sa,
437 size_t sa_len,
438 struct curve25519_proto *proto)
440 void **pos;
441 struct sockaddr_map_entry *entry;
442 unsigned int hash = hash_name((char *) sa, sa_len);
444 rwlock_wr_lock(&sockaddr_map_lock);
446 entry = xzmalloc(sizeof(*entry));
447 entry->sa = xmemdupz(sa, sa_len);
448 entry->sa_len = sa_len;
449 entry->proto = proto;
451 pos = insert_hash(hash, entry, &sockaddr_mapper);
452 if (pos) {
453 entry->next = (*pos);
454 (*pos) = entry;
457 rwlock_unlock(&sockaddr_map_lock);
459 return 0;
462 int try_register_user_by_socket(struct curve25519_struct *c,
463 char *src, size_t slen, int sock, int log)
465 int ret = -1;
466 char *cbuff = NULL;
467 size_t real_len = 132;
468 ssize_t clen;
469 struct user_store *elem;
470 enum is_user_enum err;
471 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
472 struct taia arrival_taia;
474 /* assert(132 == clen + sizeof(auth)); */
476 * Check hmac first, if malicious, drop immediately before we
477 * investigate more efforts.
479 if (slen < real_len)
480 return -1;
482 taia_now(&arrival_taia);
484 memcpy(auth, src, sizeof(auth));
486 src += sizeof(auth);
487 real_len -= sizeof(auth);
489 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
490 real_len, token)) {
491 syslog(LOG_ERR, "Bad packet hmac for id %d! Dropping!\n", sock);
492 return -1;
493 } else {
494 if (log)
495 syslog(LOG_INFO, "Good packet hmac for id %d!\n", sock);
498 rwlock_rd_lock(&store_lock);
500 elem = store;
501 while (elem) {
502 clen = curve25519_decode(c, &elem->proto_inf,
503 (unsigned char *) src, real_len,
504 (unsigned char **) &cbuff,
505 &arrival_taia);
506 if (clen <= 0) {
507 elem = elem->next;
508 continue;
511 cbuff += crypto_box_zerobytes;
512 clen -= crypto_box_zerobytes;
514 if (log)
515 syslog(LOG_INFO, "Packet decoded sucessfully for id %d!\n", sock);
517 err = username_msg_is_user(cbuff, clen, elem->username,
518 strlen(elem->username) + 1);
519 if (err == USERNAMES_OK) {
520 if (log)
521 syslog(LOG_INFO, "Found user %s for id %d! Registering ...\n",
522 elem->username, sock);
523 ret = register_user_by_socket(sock, &elem->proto_inf);
524 break;
527 elem = elem->next;
530 rwlock_unlock(&store_lock);
532 if (ret == -1)
533 syslog(LOG_ERR, "User not found! Dropping connection!\n");
535 return ret;
538 int try_register_user_by_sockaddr(struct curve25519_struct *c,
539 char *src, size_t slen,
540 struct sockaddr_storage *sa,
541 size_t sa_len, int log)
543 int ret = -1;
544 char *cbuff = NULL;
545 struct user_store *elem;
546 ssize_t clen;
547 size_t real_len = 132;
548 enum is_user_enum err;
549 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
550 struct taia arrival_taia;
552 /* assert(132 == clen + sizeof(auth)); */
554 * Check hmac first, if malicious, drop immediately before we
555 * investigate more efforts.
557 if (slen < real_len)
558 return -1;
560 taia_now(&arrival_taia);
562 memcpy(auth, src, sizeof(auth));
564 src += sizeof(auth);
565 real_len -= sizeof(auth);
567 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
568 real_len, token)) {
569 syslog(LOG_ERR, "Got bad packet hmac! Dropping!\n");
570 return -1;
571 } else {
572 if (log)
573 syslog(LOG_INFO, "Got good packet hmac!\n");
576 rwlock_rd_lock(&store_lock);
578 elem = store;
579 while (elem) {
580 clen = curve25519_decode(c, &elem->proto_inf,
581 (unsigned char *) src, real_len,
582 (unsigned char **) &cbuff,
583 &arrival_taia);
584 if (clen <= 0) {
585 elem = elem->next;
586 continue;
589 cbuff += crypto_box_zerobytes;
590 clen -= crypto_box_zerobytes;
592 if (log)
593 syslog(LOG_INFO, "Packet decoded sucessfully!\n");
595 err = username_msg_is_user(cbuff, clen, elem->username,
596 strlen(elem->username) + 1);
597 if (err == USERNAMES_OK) {
598 if (log)
599 syslog(LOG_INFO, "Found user %s! Registering ...\n",
600 elem->username);
601 ret = register_user_by_sockaddr(sa, sa_len,
602 &elem->proto_inf);
603 break;
606 elem = elem->next;
609 rwlock_unlock(&store_lock);
611 if (ret == -1)
612 syslog(LOG_ERR, "User not found! Dropping connection!\n");
614 return ret;
617 int get_user_by_socket(int fd, struct curve25519_proto **proto)
619 int ret = -1;
620 struct sock_map_entry *entry;
622 errno = 0;
624 rwlock_rd_lock(&sock_map_lock);
626 entry = lookup_hash(fd, &sock_mapper);
627 while (entry && fd != entry->fd)
628 entry = entry->next;
629 if (entry && fd == entry->fd) {
630 (*proto) = entry->proto;
631 ret = 0;
632 } else {
633 (*proto) = NULL;
634 errno = ENOENT;
637 rwlock_unlock(&sock_map_lock);
639 return ret;
642 int get_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len,
643 struct curve25519_proto **proto)
645 int ret = -1;
646 struct sockaddr_map_entry *entry;
647 unsigned int hash = hash_name((char *) sa, sa_len);
649 errno = 0;
651 rwlock_rd_lock(&sockaddr_map_lock);
653 entry = lookup_hash(hash, &sockaddr_mapper);
654 while (entry && entry->sa_len == sa_len &&
655 memcmp(sa, entry->sa, entry->sa_len))
656 entry = entry->next;
657 if (entry && entry->sa_len == sa_len &&
658 !memcmp(sa, entry->sa, entry->sa_len)) {
659 (*proto) = entry->proto;
660 ret = 0;
661 } else {
662 (*proto) = NULL;
663 errno = ENOENT;
666 rwlock_unlock(&sockaddr_map_lock);
668 return ret;
671 static struct sock_map_entry *socket_to_sock_map_entry(int fd)
673 struct sock_map_entry *entry, *ret = NULL;
675 errno = 0;
677 rwlock_rd_lock(&sock_map_lock);
679 entry = lookup_hash(fd, &sock_mapper);
680 while (entry && fd != entry->fd)
681 entry = entry->next;
682 if (entry && fd == entry->fd)
683 ret = entry;
684 else
685 errno = ENOENT;
687 rwlock_unlock(&sock_map_lock);
689 return ret;
692 void remove_user_by_socket(int fd)
694 struct sock_map_entry *pos;
695 struct sock_map_entry *entry = socket_to_sock_map_entry(fd);
697 if (!entry)
698 return;
700 rwlock_wr_lock(&sock_map_lock);
702 pos = remove_hash(entry->fd, entry, entry->next, &sock_mapper);
703 while (pos && pos->next && pos->next != entry)
704 pos = pos->next;
705 if (pos && pos->next && pos->next == entry)
706 pos->next = entry->next;
708 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
709 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
711 entry->proto = NULL;
712 entry->next = NULL;
714 xfree(entry);
716 rwlock_unlock(&sock_map_lock);
719 static struct sockaddr_map_entry *
720 sockaddr_to_sockaddr_map_entry(struct sockaddr_storage *sa, size_t sa_len)
722 struct sockaddr_map_entry *entry, *ret = NULL;
723 unsigned int hash = hash_name((char *) sa, sa_len);
725 errno = 0;
727 rwlock_rd_lock(&sockaddr_map_lock);
729 entry = lookup_hash(hash, &sockaddr_mapper);
730 while (entry && entry->sa_len == sa_len &&
731 memcmp(sa, entry->sa, entry->sa_len))
732 entry = entry->next;
733 if (entry && entry->sa_len == sa_len &&
734 !memcmp(sa, entry->sa, entry->sa_len))
735 ret = entry;
736 else
737 errno = ENOENT;
739 rwlock_unlock(&sockaddr_map_lock);
741 return ret;
744 void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len)
746 struct sockaddr_map_entry *pos;
747 struct sockaddr_map_entry *entry;
748 unsigned int hash = hash_name((char *) sa, sa_len);
750 entry = sockaddr_to_sockaddr_map_entry(sa, sa_len);
751 if (!entry)
752 return;
754 rwlock_wr_lock(&sockaddr_map_lock);
756 pos = remove_hash(hash, entry, entry->next, &sockaddr_mapper);
757 while (pos && pos->next && pos->next != entry)
758 pos = pos->next;
759 if (pos && pos->next && pos->next == entry)
760 pos->next = entry->next;
762 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
763 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
765 entry->proto = NULL;
766 entry->next = NULL;
768 xfree(entry->sa);
769 xfree(entry);
771 rwlock_unlock(&sockaddr_map_lock);