xutils: break out promisc mode functions
[netsniff-ng.git] / ct_usermgmt.c
blob26429867fda386723a731529235e6ad90d309ded
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 "ioexact.h"
22 #include "ioops.h"
23 #include "str.h"
24 #include "curvetun.h"
25 #include "xutils.h"
26 #include "curve.h"
27 #include "hash.h"
28 #include "crypto_verify_32.h"
29 #include "crypto_hash_sha512.h"
30 #include "crypto_box_curve25519xsalsa20poly1305.h"
31 #include "crypto_auth_hmacsha512256.h"
33 #define crypto_box_pub_key_size crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
35 /* Config line format: username;pubkey\n */
37 struct user_store {
38 char username[256];
39 unsigned char publickey[crypto_box_pub_key_size];
40 struct curve25519_proto proto_inf;
41 struct user_store *next;
44 struct sock_map_entry {
45 int fd;
46 struct curve25519_proto *proto;
47 struct sock_map_entry *next;
50 struct sockaddr_map_entry {
51 struct sockaddr_storage *sa;
52 size_t sa_len;
53 struct curve25519_proto *proto;
54 struct sockaddr_map_entry *next;
57 static struct user_store *store = NULL;
58 static struct rwlock store_lock;
60 static struct hash_table sock_mapper;
61 static struct rwlock sock_map_lock;
63 static struct hash_table sockaddr_mapper;
64 static struct rwlock sockaddr_map_lock;
66 static unsigned char token[crypto_auth_hmacsha512256_KEYBYTES];
68 static void init_sock_mapper(void)
70 rwlock_init(&sock_map_lock);
72 rwlock_wr_lock(&sock_map_lock);
74 memset(&sock_mapper, 0, sizeof(sock_mapper));
75 init_hash(&sock_mapper);
77 rwlock_unlock(&sock_map_lock);
80 static void init_sockaddr_mapper(void)
82 rwlock_init(&sockaddr_map_lock);
83 rwlock_wr_lock(&sockaddr_map_lock);
85 memset(&sockaddr_mapper, 0, sizeof(sockaddr_mapper));
86 init_hash(&sockaddr_mapper);
88 rwlock_unlock(&sockaddr_map_lock);
91 static int cleanup_batch_sock_mapper(void *ptr)
93 struct sock_map_entry *next;
94 struct sock_map_entry *e = ptr;
96 if (!e)
97 return 0;
99 while ((next = e->next)) {
100 e->next = NULL;
101 xfree(e);
102 e = next;
105 xfree(e);
107 return 0;
110 static void destroy_sock_mapper(void)
112 rwlock_wr_lock(&sock_map_lock);
113 for_each_hash(&sock_mapper, cleanup_batch_sock_mapper);
114 free_hash(&sock_mapper);
115 rwlock_unlock(&sock_map_lock);
117 rwlock_destroy(&sock_map_lock);
120 static int cleanup_batch_sockaddr_mapper(void *ptr)
122 struct sockaddr_map_entry *next;
123 struct sockaddr_map_entry *e = ptr;
125 if (!e)
126 return 0;
128 while ((next = e->next)) {
129 e->next = NULL;
130 xfree(e);
131 e = next;
134 xfree(e);
135 return 0;
138 static void destroy_sockaddr_mapper(void)
140 rwlock_wr_lock(&sockaddr_map_lock);
141 for_each_hash(&sockaddr_mapper, cleanup_batch_sockaddr_mapper);
142 free_hash(&sockaddr_mapper);
143 rwlock_unlock(&sockaddr_map_lock);
145 rwlock_destroy(&sockaddr_map_lock);
148 static struct user_store *user_store_alloc(void)
150 return xzmalloc(sizeof(struct user_store));
153 static void user_store_free(struct user_store *us)
155 if (!us)
156 return;
157 memset(us, 0, sizeof(struct user_store));
158 xfree(us);
161 /* already in lock */
162 static int __check_duplicate_username(char *username, size_t len)
164 int duplicate = 0;
165 struct user_store *elem = store;
167 while (elem) {
168 if (!memcmp(elem->username, username,
169 strlen(elem->username) + 1)) {
170 duplicate = 1;
171 break;
173 elem = elem->next;
176 return duplicate;
179 /* already in lock */
180 static int __check_duplicate_pubkey(unsigned char *pubkey, size_t len)
182 int duplicate = 0;
183 struct user_store *elem = store;
185 while (elem) {
186 if (!memcmp(elem->publickey, pubkey,
187 sizeof(elem->publickey))) {
188 duplicate = 1;
189 break;
191 elem = elem->next;
194 return duplicate;
197 enum parse_states {
198 PARSE_USERNAME,
199 PARSE_PUBKEY,
200 PARSE_DONE,
203 static int parse_line(char *line, char *homedir)
205 int ret;
206 char *str;
207 enum parse_states s = PARSE_USERNAME;
208 struct user_store *elem;
209 unsigned char pkey[crypto_box_pub_key_size];
211 elem = user_store_alloc();
212 elem->next = store;
214 str = strtok(line, ";");
215 for (; str != NULL;) {
216 switch (s) {
217 case PARSE_USERNAME:
218 if (__check_duplicate_username(str, strlen(str) + 1))
219 return -EINVAL;
220 strlcpy(elem->username, str, sizeof(elem->username));
221 s = PARSE_PUBKEY;
222 break;
223 case PARSE_PUBKEY:
224 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
225 str, strlen(str)))
226 return -EINVAL;
227 if (__check_duplicate_pubkey(pkey, sizeof(pkey)))
228 return -EINVAL;
229 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
230 ret = curve25519_proto_init(&elem->proto_inf,
231 elem->publickey,
232 sizeof(elem->publickey),
233 homedir, 1);
234 if (ret)
235 return -EIO;
236 s = PARSE_DONE;
237 break;
238 case PARSE_DONE:
239 break;
240 default:
241 return -EIO;
244 str = strtok(NULL, ";");
247 store = elem;
248 return s == PARSE_DONE ? 0 : -EIO;
251 void parse_userfile_and_generate_user_store_or_die(char *homedir)
253 FILE *fp;
254 char path[PATH_MAX], buff[512];
255 int line = 1, ret, fd;
257 memset(path, 0, sizeof(path));
258 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_CLIENTS);
260 rwlock_init(&store_lock);
261 rwlock_wr_lock(&store_lock);
263 fp = fopen(path, "r");
264 if (!fp)
265 panic("Cannot open client file!\n");
267 memset(buff, 0, sizeof(buff));
268 while (fgets(buff, sizeof(buff), fp) != NULL) {
269 buff[sizeof(buff) - 1] = 0;
270 /* A comment. Skip this line */
271 if (buff[0] == '#' || buff[0] == '\n') {
272 memset(buff, 0, sizeof(buff));
273 line++;
274 continue;
277 ret = parse_line(buff, homedir);
278 if (ret < 0)
279 panic("Cannot parse line %d from clients!\n", line);
280 line++;
281 memset(buff, 0, sizeof(buff));
284 fclose(fp);
286 if (store == NULL)
287 panic("No registered clients found!\n");
289 rwlock_unlock(&store_lock);
291 init_sock_mapper();
292 init_sockaddr_mapper();
295 * Pubkey is also used as a hmac of the initial packet to check
296 * the integrity of the packet, so that we know if it's just random
297 * garbage or a 'valid' packet. Again, just for the integrity!
300 memset(path, 0, sizeof(path));
301 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_PUBKEY);
303 fd = open_or_die(path, O_RDONLY);
304 ret = read(fd, token, sizeof(token));
305 if (ret != crypto_auth_hmacsha512256_KEYBYTES)
306 panic("Cannot read public key!\n");
307 close(fd);
310 void dump_user_store(void)
312 int i;
313 struct user_store *elem;
315 rwlock_rd_lock(&store_lock);
317 elem = store;
318 while (elem) {
319 printf("%s -> ", elem->username);
320 for (i = 0; i < sizeof(elem->publickey); ++i)
321 if (i == (sizeof(elem->publickey) - 1))
322 printf("%02x\n", (unsigned char)
323 elem->publickey[i]);
324 else
325 printf("%02x:", (unsigned char)
326 elem->publickey[i]);
327 elem = elem->next;
330 rwlock_unlock(&store_lock);
333 void destroy_user_store(void)
335 struct user_store *elem, *nelem = NULL;
337 rwlock_wr_lock(&store_lock);
339 elem = store;
340 while (elem) {
341 nelem = elem->next;
342 elem->next = NULL;
343 user_store_free(elem);
344 elem = nelem;
346 rwlock_unlock(&store_lock);
348 rwlock_destroy(&store_lock);
350 destroy_sock_mapper();
351 destroy_sockaddr_mapper();
354 int username_msg(char *username, size_t len, char *dst, size_t dlen)
356 int fd;
357 ssize_t ret;
358 uint32_t salt;
359 unsigned char h[crypto_hash_sha512_BYTES];
360 struct username_struct *us = (struct username_struct *) dst;
361 char *uname;
362 size_t uname_len;
364 if (dlen < sizeof(struct username_struct))
365 return -ENOMEM;
367 uname_len = 512;
368 uname = xzmalloc(uname_len);
370 fd = open_or_die("/dev/random", O_RDONLY);
371 ret = read_exact(fd, &salt, sizeof(salt), 0);
372 if (ret != sizeof(salt))
373 panic("Cannot read from /dev/random!\n");
374 close(fd);
376 slprintf(uname, uname_len, "%s%u", username, salt);
377 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
379 us->salt = htonl(salt);
380 memcpy(us->hash, h, sizeof(us->hash));
382 xfree(uname);
383 return 0;
386 enum is_user_enum username_msg_is_user(char *src, size_t slen, char *username,
387 size_t len)
389 char *uname;
390 size_t uname_len;
391 uint32_t salt;
392 struct username_struct *us = (struct username_struct *) src;
393 unsigned char h[crypto_hash_sha512_BYTES];
395 if (slen < sizeof(struct username_struct)) {
396 errno = ENOMEM;
397 return USERNAMES_ERR;
400 uname_len = 512;
401 uname = xzmalloc(uname_len);
403 salt = ntohl(us->salt);
405 slprintf(uname, uname_len, "%s%u", username, salt);
406 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
407 xfree(uname);
409 if (!crypto_verify_32(&h[0], &us->hash[0]) &&
410 !crypto_verify_32(&h[32], &us->hash[32]))
411 return USERNAMES_OK;
412 else
413 return USERNAMES_NE;
416 static int register_user_by_socket(int fd, struct curve25519_proto *proto)
418 void **pos;
419 struct sock_map_entry *entry;
421 rwlock_wr_lock(&sock_map_lock);
423 entry = xzmalloc(sizeof(*entry));
424 entry->fd = fd;
425 entry->proto = proto;
427 pos = insert_hash(entry->fd, entry, &sock_mapper);
428 if (pos) {
429 entry->next = (*pos);
430 (*pos) = entry;
433 rwlock_unlock(&sock_map_lock);
435 return 0;
438 static int register_user_by_sockaddr(struct sockaddr_storage *sa,
439 size_t sa_len,
440 struct curve25519_proto *proto)
442 void **pos;
443 struct sockaddr_map_entry *entry;
444 unsigned int hash = hash_name((char *) sa, sa_len);
446 rwlock_wr_lock(&sockaddr_map_lock);
448 entry = xzmalloc(sizeof(*entry));
449 entry->sa = xmemdupz(sa, sa_len);
450 entry->sa_len = sa_len;
451 entry->proto = proto;
453 pos = insert_hash(hash, entry, &sockaddr_mapper);
454 if (pos) {
455 entry->next = (*pos);
456 (*pos) = entry;
459 rwlock_unlock(&sockaddr_map_lock);
461 return 0;
464 int try_register_user_by_socket(struct curve25519_struct *c,
465 char *src, size_t slen, int sock, int log)
467 int ret = -1;
468 char *cbuff = NULL;
469 size_t real_len = 132;
470 ssize_t clen;
471 struct user_store *elem;
472 enum is_user_enum err;
473 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
474 struct taia arrival_taia;
476 /* assert(132 == clen + sizeof(auth)); */
478 * Check hmac first, if malicious, drop immediately before we
479 * investigate more efforts.
481 if (slen < real_len)
482 return -1;
484 taia_now(&arrival_taia);
486 memcpy(auth, src, sizeof(auth));
488 src += sizeof(auth);
489 real_len -= sizeof(auth);
491 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
492 real_len, token)) {
493 syslog(LOG_ERR, "Bad packet hmac for id %d! Dropping!\n", sock);
494 return -1;
495 } else {
496 if (log)
497 syslog(LOG_INFO, "Good packet hmac for id %d!\n", sock);
500 rwlock_rd_lock(&store_lock);
502 elem = store;
503 while (elem) {
504 clen = curve25519_decode(c, &elem->proto_inf,
505 (unsigned char *) src, real_len,
506 (unsigned char **) &cbuff,
507 &arrival_taia);
508 if (clen <= 0) {
509 elem = elem->next;
510 continue;
513 cbuff += crypto_box_zerobytes;
514 clen -= crypto_box_zerobytes;
516 if (log)
517 syslog(LOG_INFO, "Packet decoded successfully for id %d!\n", sock);
519 err = username_msg_is_user(cbuff, clen, elem->username,
520 strlen(elem->username) + 1);
521 if (err == USERNAMES_OK) {
522 if (log)
523 syslog(LOG_INFO, "Found user %s for id %d! Registering ...\n",
524 elem->username, sock);
525 ret = register_user_by_socket(sock, &elem->proto_inf);
526 break;
529 elem = elem->next;
532 rwlock_unlock(&store_lock);
534 if (ret == -1)
535 syslog(LOG_ERR, "User not found! Dropping connection!\n");
537 return ret;
540 int try_register_user_by_sockaddr(struct curve25519_struct *c,
541 char *src, size_t slen,
542 struct sockaddr_storage *sa,
543 size_t sa_len, int log)
545 int ret = -1;
546 char *cbuff = NULL;
547 struct user_store *elem;
548 ssize_t clen;
549 size_t real_len = 132;
550 enum is_user_enum err;
551 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
552 struct taia arrival_taia;
554 /* assert(132 == clen + sizeof(auth)); */
556 * Check hmac first, if malicious, drop immediately before we
557 * investigate more efforts.
559 if (slen < real_len)
560 return -1;
562 taia_now(&arrival_taia);
564 memcpy(auth, src, sizeof(auth));
566 src += sizeof(auth);
567 real_len -= sizeof(auth);
569 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
570 real_len, token)) {
571 syslog(LOG_ERR, "Got bad packet hmac! Dropping!\n");
572 return -1;
573 } else {
574 if (log)
575 syslog(LOG_INFO, "Got good packet hmac!\n");
578 rwlock_rd_lock(&store_lock);
580 elem = store;
581 while (elem) {
582 clen = curve25519_decode(c, &elem->proto_inf,
583 (unsigned char *) src, real_len,
584 (unsigned char **) &cbuff,
585 &arrival_taia);
586 if (clen <= 0) {
587 elem = elem->next;
588 continue;
591 cbuff += crypto_box_zerobytes;
592 clen -= crypto_box_zerobytes;
594 if (log)
595 syslog(LOG_INFO, "Packet decoded successfully!\n");
597 err = username_msg_is_user(cbuff, clen, elem->username,
598 strlen(elem->username) + 1);
599 if (err == USERNAMES_OK) {
600 if (log)
601 syslog(LOG_INFO, "Found user %s! Registering ...\n",
602 elem->username);
603 ret = register_user_by_sockaddr(sa, sa_len,
604 &elem->proto_inf);
605 break;
608 elem = elem->next;
611 rwlock_unlock(&store_lock);
613 if (ret == -1)
614 syslog(LOG_ERR, "User not found! Dropping connection!\n");
616 return ret;
619 int get_user_by_socket(int fd, struct curve25519_proto **proto)
621 int ret = -1;
622 struct sock_map_entry *entry;
624 errno = 0;
626 rwlock_rd_lock(&sock_map_lock);
628 entry = lookup_hash(fd, &sock_mapper);
629 while (entry && fd != entry->fd)
630 entry = entry->next;
631 if (entry && fd == entry->fd) {
632 (*proto) = entry->proto;
633 ret = 0;
634 } else {
635 (*proto) = NULL;
636 errno = ENOENT;
639 rwlock_unlock(&sock_map_lock);
641 return ret;
644 int get_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len,
645 struct curve25519_proto **proto)
647 int ret = -1;
648 struct sockaddr_map_entry *entry;
649 unsigned int hash = hash_name((char *) sa, sa_len);
651 errno = 0;
653 rwlock_rd_lock(&sockaddr_map_lock);
655 entry = lookup_hash(hash, &sockaddr_mapper);
656 while (entry && entry->sa_len == sa_len &&
657 memcmp(sa, entry->sa, entry->sa_len))
658 entry = entry->next;
659 if (entry && entry->sa_len == sa_len &&
660 !memcmp(sa, entry->sa, entry->sa_len)) {
661 (*proto) = entry->proto;
662 ret = 0;
663 } else {
664 (*proto) = NULL;
665 errno = ENOENT;
668 rwlock_unlock(&sockaddr_map_lock);
670 return ret;
673 static struct sock_map_entry *socket_to_sock_map_entry(int fd)
675 struct sock_map_entry *entry, *ret = NULL;
677 errno = 0;
679 rwlock_rd_lock(&sock_map_lock);
681 entry = lookup_hash(fd, &sock_mapper);
682 while (entry && fd != entry->fd)
683 entry = entry->next;
684 if (entry && fd == entry->fd)
685 ret = entry;
686 else
687 errno = ENOENT;
689 rwlock_unlock(&sock_map_lock);
691 return ret;
694 void remove_user_by_socket(int fd)
696 struct sock_map_entry *pos;
697 struct sock_map_entry *entry = socket_to_sock_map_entry(fd);
699 if (!entry)
700 return;
702 rwlock_wr_lock(&sock_map_lock);
704 pos = remove_hash(entry->fd, entry, entry->next, &sock_mapper);
705 while (pos && pos->next && pos->next != entry)
706 pos = pos->next;
707 if (pos && pos->next && pos->next == entry)
708 pos->next = entry->next;
710 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
711 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
713 entry->proto = NULL;
714 entry->next = NULL;
716 xfree(entry);
718 rwlock_unlock(&sock_map_lock);
721 static struct sockaddr_map_entry *
722 sockaddr_to_sockaddr_map_entry(struct sockaddr_storage *sa, size_t sa_len)
724 struct sockaddr_map_entry *entry, *ret = NULL;
725 unsigned int hash = hash_name((char *) sa, sa_len);
727 errno = 0;
729 rwlock_rd_lock(&sockaddr_map_lock);
731 entry = lookup_hash(hash, &sockaddr_mapper);
732 while (entry && entry->sa_len == sa_len &&
733 memcmp(sa, entry->sa, entry->sa_len))
734 entry = entry->next;
735 if (entry && entry->sa_len == sa_len &&
736 !memcmp(sa, entry->sa, entry->sa_len))
737 ret = entry;
738 else
739 errno = ENOENT;
741 rwlock_unlock(&sockaddr_map_lock);
743 return ret;
746 void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len)
748 struct sockaddr_map_entry *pos;
749 struct sockaddr_map_entry *entry;
750 unsigned int hash = hash_name((char *) sa, sa_len);
752 entry = sockaddr_to_sockaddr_map_entry(sa, sa_len);
753 if (!entry)
754 return;
756 rwlock_wr_lock(&sockaddr_map_lock);
758 pos = remove_hash(hash, entry, entry->next, &sockaddr_mapper);
759 while (pos && pos->next && pos->next != entry)
760 pos = pos->next;
761 if (pos && pos->next && pos->next == entry)
762 pos->next = entry->next;
764 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
765 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
767 entry->proto = NULL;
768 entry->next = NULL;
770 xfree(entry->sa);
771 xfree(entry);
773 rwlock_unlock(&sockaddr_map_lock);