pcap_mm: simplify code by using raw
[netsniff-ng.git] / ct_usermgmt.c
blob86eaefaf6f8378ddd2462550b1f60175f7f07d0a
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 Daniel Borkmann.
5 * Subject to the GPL, version 2.
6 */
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <fcntl.h>
13 #include <string.h>
14 #include <syslog.h>
15 #include <limits.h>
16 #include <arpa/inet.h>
18 #include "die.h"
19 #include "ct_usermgmt.h"
20 #include "locking.h"
21 #include "xmalloc.h"
22 #include "xio.h"
23 #include "curvetun.h"
24 #include "xutils.h"
25 #include "curve.h"
26 #include "hash.h"
27 #include "crypto_verify_32.h"
28 #include "crypto_hash_sha512.h"
29 #include "crypto_box_curve25519xsalsa20poly1305.h"
30 #include "crypto_auth_hmacsha512256.h"
32 #define crypto_box_pub_key_size crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
34 /* Config line format: username;pubkey\n */
36 struct user_store {
37 char username[256];
38 unsigned char publickey[crypto_box_pub_key_size];
39 struct curve25519_proto proto_inf;
40 struct user_store *next;
43 struct sock_map_entry {
44 int fd;
45 struct curve25519_proto *proto;
46 struct sock_map_entry *next;
49 struct sockaddr_map_entry {
50 struct sockaddr_storage *sa;
51 size_t sa_len;
52 struct curve25519_proto *proto;
53 struct sockaddr_map_entry *next;
56 static struct user_store *store = NULL;
57 static struct rwlock store_lock;
59 static struct hash_table sock_mapper;
60 static struct rwlock sock_map_lock;
62 static struct hash_table sockaddr_mapper;
63 static struct rwlock sockaddr_map_lock;
65 static unsigned char token[crypto_auth_hmacsha512256_KEYBYTES];
67 static void init_sock_mapper(void)
69 rwlock_init(&sock_map_lock);
71 rwlock_wr_lock(&sock_map_lock);
73 memset(&sock_mapper, 0, sizeof(sock_mapper));
74 init_hash(&sock_mapper);
76 rwlock_unlock(&sock_map_lock);
79 static void init_sockaddr_mapper(void)
81 rwlock_init(&sockaddr_map_lock);
82 rwlock_wr_lock(&sockaddr_map_lock);
84 memset(&sockaddr_mapper, 0, sizeof(sockaddr_mapper));
85 init_hash(&sockaddr_mapper);
87 rwlock_unlock(&sockaddr_map_lock);
90 static int cleanup_batch_sock_mapper(void *ptr)
92 struct sock_map_entry *next;
93 struct sock_map_entry *e = ptr;
95 if (!e)
96 return 0;
98 while ((next = e->next)) {
99 e->next = NULL;
100 xfree(e);
101 e = next;
104 xfree(e);
106 return 0;
109 static void destroy_sock_mapper(void)
111 rwlock_wr_lock(&sock_map_lock);
112 for_each_hash(&sock_mapper, cleanup_batch_sock_mapper);
113 free_hash(&sock_mapper);
114 rwlock_unlock(&sock_map_lock);
116 rwlock_destroy(&sock_map_lock);
119 static int cleanup_batch_sockaddr_mapper(void *ptr)
121 struct sockaddr_map_entry *next;
122 struct sockaddr_map_entry *e = ptr;
124 if (!e)
125 return 0;
127 while ((next = e->next)) {
128 e->next = NULL;
129 xfree(e);
130 e = next;
133 xfree(e);
134 return 0;
137 static void destroy_sockaddr_mapper(void)
139 rwlock_wr_lock(&sockaddr_map_lock);
140 for_each_hash(&sockaddr_mapper, cleanup_batch_sockaddr_mapper);
141 free_hash(&sockaddr_mapper);
142 rwlock_unlock(&sockaddr_map_lock);
144 rwlock_destroy(&sockaddr_map_lock);
147 static struct user_store *user_store_alloc(void)
149 return xzmalloc(sizeof(struct user_store));
152 static void user_store_free(struct user_store *us)
154 if (!us)
155 return;
156 memset(us, 0, sizeof(struct user_store));
157 xfree(us);
160 /* already in lock */
161 static int __check_duplicate_username(char *username, size_t len)
163 int duplicate = 0;
164 struct user_store *elem = store;
166 while (elem) {
167 if (!memcmp(elem->username, username,
168 strlen(elem->username) + 1)) {
169 duplicate = 1;
170 break;
172 elem = elem->next;
175 return duplicate;
178 /* already in lock */
179 static int __check_duplicate_pubkey(unsigned char *pubkey, size_t len)
181 int duplicate = 0;
182 struct user_store *elem = store;
184 while (elem) {
185 if (!memcmp(elem->publickey, pubkey,
186 sizeof(elem->publickey))) {
187 duplicate = 1;
188 break;
190 elem = elem->next;
193 return duplicate;
196 enum parse_states {
197 PARSE_USERNAME,
198 PARSE_PUBKEY,
199 PARSE_DONE,
202 static int parse_line(char *line, char *homedir)
204 int ret;
205 char *str;
206 enum parse_states s = PARSE_USERNAME;
207 struct user_store *elem;
208 unsigned char pkey[crypto_box_pub_key_size];
210 elem = user_store_alloc();
211 elem->next = store;
213 str = strtok(line, ";");
214 for (; str != NULL;) {
215 switch (s) {
216 case PARSE_USERNAME:
217 if (__check_duplicate_username(str, strlen(str) + 1))
218 return -EINVAL;
219 strlcpy(elem->username, str, sizeof(elem->username));
220 s = PARSE_PUBKEY;
221 break;
222 case PARSE_PUBKEY:
223 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
224 str, strlen(str)))
225 return -EINVAL;
226 if (__check_duplicate_pubkey(pkey, sizeof(pkey)))
227 return -EINVAL;
228 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
229 ret = curve25519_proto_init(&elem->proto_inf,
230 elem->publickey,
231 sizeof(elem->publickey),
232 homedir, 1);
233 if (ret)
234 return -EIO;
235 s = PARSE_DONE;
236 break;
237 case PARSE_DONE:
238 break;
239 default:
240 return -EIO;
243 str = strtok(NULL, ";");
246 store = elem;
247 return s == PARSE_DONE ? 0 : -EIO;
250 void parse_userfile_and_generate_user_store_or_die(char *homedir)
252 FILE *fp;
253 char path[PATH_MAX], buff[512];
254 int line = 1, ret, fd;
256 memset(path, 0, sizeof(path));
257 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_CLIENTS);
259 rwlock_init(&store_lock);
260 rwlock_wr_lock(&store_lock);
262 fp = fopen(path, "r");
263 if (!fp)
264 panic("Cannot open client file!\n");
266 memset(buff, 0, sizeof(buff));
267 while (fgets(buff, sizeof(buff), fp) != NULL) {
268 buff[sizeof(buff) - 1] = 0;
269 /* A comment. Skip this line */
270 if (buff[0] == '#' || buff[0] == '\n') {
271 memset(buff, 0, sizeof(buff));
272 line++;
273 continue;
276 ret = parse_line(buff, homedir);
277 if (ret < 0)
278 panic("Cannot parse line %d from clients!\n", line);
279 line++;
280 memset(buff, 0, sizeof(buff));
283 fclose(fp);
285 if (store == NULL)
286 panic("No registered clients found!\n");
288 rwlock_unlock(&store_lock);
290 init_sock_mapper();
291 init_sockaddr_mapper();
294 * Pubkey is also used as a hmac of the initial packet to check
295 * the integrity of the packet, so that we know if it's just random
296 * garbage or a 'valid' packet. Again, just for the integrity!
299 memset(path, 0, sizeof(path));
300 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_PUBKEY);
302 fd = open_or_die(path, O_RDONLY);
303 ret = read(fd, token, sizeof(token));
304 if (ret != crypto_auth_hmacsha512256_KEYBYTES)
305 panic("Cannot read public key!\n");
306 close(fd);
309 void dump_user_store(void)
311 int i;
312 struct user_store *elem;
314 rwlock_rd_lock(&store_lock);
316 elem = store;
317 while (elem) {
318 printf("%s -> ", elem->username);
319 for (i = 0; i < sizeof(elem->publickey); ++i)
320 if (i == (sizeof(elem->publickey) - 1))
321 printf("%02x\n", (unsigned char)
322 elem->publickey[i]);
323 else
324 printf("%02x:", (unsigned char)
325 elem->publickey[i]);
326 elem = elem->next;
329 rwlock_unlock(&store_lock);
332 void destroy_user_store(void)
334 struct user_store *elem, *nelem = NULL;
336 rwlock_wr_lock(&store_lock);
338 elem = store;
339 while (elem) {
340 nelem = elem->next;
341 elem->next = NULL;
342 user_store_free(elem);
343 elem = nelem;
345 rwlock_unlock(&store_lock);
347 rwlock_destroy(&store_lock);
349 destroy_sock_mapper();
350 destroy_sockaddr_mapper();
353 int username_msg(char *username, size_t len, char *dst, size_t dlen)
355 int fd;
356 ssize_t ret;
357 uint32_t salt;
358 unsigned char h[crypto_hash_sha512_BYTES];
359 struct username_struct *us = (struct username_struct *) dst;
360 char *uname;
361 size_t uname_len;
363 if (dlen < sizeof(struct username_struct))
364 return -ENOMEM;
366 uname_len = 512;
367 uname = xzmalloc(uname_len);
369 fd = open_or_die("/dev/random", O_RDONLY);
370 ret = read_exact(fd, &salt, sizeof(salt), 0);
371 if (ret != sizeof(salt))
372 panic("Cannot read from /dev/random!\n");
373 close(fd);
375 slprintf(uname, uname_len, "%s%u", username, salt);
376 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
378 us->salt = htonl(salt);
379 memcpy(us->hash, h, sizeof(us->hash));
381 xfree(uname);
382 return 0;
385 enum is_user_enum username_msg_is_user(char *src, size_t slen, char *username,
386 size_t len)
388 char *uname;
389 size_t uname_len;
390 uint32_t salt;
391 struct username_struct *us = (struct username_struct *) src;
392 unsigned char h[crypto_hash_sha512_BYTES];
394 if (slen < sizeof(struct username_struct)) {
395 errno = ENOMEM;
396 return USERNAMES_ERR;
399 uname_len = 512;
400 uname = xzmalloc(uname_len);
402 salt = ntohl(us->salt);
404 slprintf(uname, uname_len, "%s%u", username, salt);
405 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
406 xfree(uname);
408 if (!crypto_verify_32(&h[0], &us->hash[0]) &&
409 !crypto_verify_32(&h[32], &us->hash[32]))
410 return USERNAMES_OK;
411 else
412 return USERNAMES_NE;
415 static int register_user_by_socket(int fd, struct curve25519_proto *proto)
417 void **pos;
418 struct sock_map_entry *entry;
420 rwlock_wr_lock(&sock_map_lock);
422 entry = xzmalloc(sizeof(*entry));
423 entry->fd = fd;
424 entry->proto = proto;
426 pos = insert_hash(entry->fd, entry, &sock_mapper);
427 if (pos) {
428 entry->next = (*pos);
429 (*pos) = entry;
432 rwlock_unlock(&sock_map_lock);
434 return 0;
437 static int register_user_by_sockaddr(struct sockaddr_storage *sa,
438 size_t sa_len,
439 struct curve25519_proto *proto)
441 void **pos;
442 struct sockaddr_map_entry *entry;
443 unsigned int hash = hash_name((char *) sa, sa_len);
445 rwlock_wr_lock(&sockaddr_map_lock);
447 entry = xzmalloc(sizeof(*entry));
448 entry->sa = xmemdupz(sa, sa_len);
449 entry->sa_len = sa_len;
450 entry->proto = proto;
452 pos = insert_hash(hash, entry, &sockaddr_mapper);
453 if (pos) {
454 entry->next = (*pos);
455 (*pos) = entry;
458 rwlock_unlock(&sockaddr_map_lock);
460 return 0;
463 int try_register_user_by_socket(struct curve25519_struct *c,
464 char *src, size_t slen, int sock, int log)
466 int ret = -1;
467 char *cbuff = NULL;
468 size_t real_len = 132;
469 ssize_t clen;
470 struct user_store *elem;
471 enum is_user_enum err;
472 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
473 struct taia arrival_taia;
475 /* assert(132 == clen + sizeof(auth)); */
477 * Check hmac first, if malicious, drop immediately before we
478 * investigate more efforts.
480 if (slen < real_len)
481 return -1;
483 taia_now(&arrival_taia);
485 memcpy(auth, src, sizeof(auth));
487 src += sizeof(auth);
488 real_len -= sizeof(auth);
490 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
491 real_len, token)) {
492 syslog(LOG_ERR, "Bad packet hmac for id %d! Dropping!\n", sock);
493 return -1;
494 } else {
495 if (log)
496 syslog(LOG_INFO, "Good packet hmac for id %d!\n", sock);
499 rwlock_rd_lock(&store_lock);
501 elem = store;
502 while (elem) {
503 clen = curve25519_decode(c, &elem->proto_inf,
504 (unsigned char *) src, real_len,
505 (unsigned char **) &cbuff,
506 &arrival_taia);
507 if (clen <= 0) {
508 elem = elem->next;
509 continue;
512 cbuff += crypto_box_zerobytes;
513 clen -= crypto_box_zerobytes;
515 if (log)
516 syslog(LOG_INFO, "Packet decoded sucessfully for id %d!\n", sock);
518 err = username_msg_is_user(cbuff, clen, elem->username,
519 strlen(elem->username) + 1);
520 if (err == USERNAMES_OK) {
521 if (log)
522 syslog(LOG_INFO, "Found user %s for id %d! Registering ...\n",
523 elem->username, sock);
524 ret = register_user_by_socket(sock, &elem->proto_inf);
525 break;
528 elem = elem->next;
531 rwlock_unlock(&store_lock);
533 if (ret == -1)
534 syslog(LOG_ERR, "User not found! Dropping connection!\n");
536 return ret;
539 int try_register_user_by_sockaddr(struct curve25519_struct *c,
540 char *src, size_t slen,
541 struct sockaddr_storage *sa,
542 size_t sa_len, int log)
544 int ret = -1;
545 char *cbuff = NULL;
546 struct user_store *elem;
547 ssize_t clen;
548 size_t real_len = 132;
549 enum is_user_enum err;
550 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
551 struct taia arrival_taia;
553 /* assert(132 == clen + sizeof(auth)); */
555 * Check hmac first, if malicious, drop immediately before we
556 * investigate more efforts.
558 if (slen < real_len)
559 return -1;
561 taia_now(&arrival_taia);
563 memcpy(auth, src, sizeof(auth));
565 src += sizeof(auth);
566 real_len -= sizeof(auth);
568 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
569 real_len, token)) {
570 syslog(LOG_ERR, "Got bad packet hmac! Dropping!\n");
571 return -1;
572 } else {
573 if (log)
574 syslog(LOG_INFO, "Got good packet hmac!\n");
577 rwlock_rd_lock(&store_lock);
579 elem = store;
580 while (elem) {
581 clen = curve25519_decode(c, &elem->proto_inf,
582 (unsigned char *) src, real_len,
583 (unsigned char **) &cbuff,
584 &arrival_taia);
585 if (clen <= 0) {
586 elem = elem->next;
587 continue;
590 cbuff += crypto_box_zerobytes;
591 clen -= crypto_box_zerobytes;
593 if (log)
594 syslog(LOG_INFO, "Packet decoded sucessfully!\n");
596 err = username_msg_is_user(cbuff, clen, elem->username,
597 strlen(elem->username) + 1);
598 if (err == USERNAMES_OK) {
599 if (log)
600 syslog(LOG_INFO, "Found user %s! Registering ...\n",
601 elem->username);
602 ret = register_user_by_sockaddr(sa, sa_len,
603 &elem->proto_inf);
604 break;
607 elem = elem->next;
610 rwlock_unlock(&store_lock);
612 if (ret == -1)
613 syslog(LOG_ERR, "User not found! Dropping connection!\n");
615 return ret;
618 int get_user_by_socket(int fd, struct curve25519_proto **proto)
620 int ret = -1;
621 struct sock_map_entry *entry;
623 errno = 0;
625 rwlock_rd_lock(&sock_map_lock);
627 entry = lookup_hash(fd, &sock_mapper);
628 while (entry && fd != entry->fd)
629 entry = entry->next;
630 if (entry && fd == entry->fd) {
631 (*proto) = entry->proto;
632 ret = 0;
633 } else {
634 (*proto) = NULL;
635 errno = ENOENT;
638 rwlock_unlock(&sock_map_lock);
640 return ret;
643 int get_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len,
644 struct curve25519_proto **proto)
646 int ret = -1;
647 struct sockaddr_map_entry *entry;
648 unsigned int hash = hash_name((char *) sa, sa_len);
650 errno = 0;
652 rwlock_rd_lock(&sockaddr_map_lock);
654 entry = lookup_hash(hash, &sockaddr_mapper);
655 while (entry && entry->sa_len == sa_len &&
656 memcmp(sa, entry->sa, entry->sa_len))
657 entry = entry->next;
658 if (entry && entry->sa_len == sa_len &&
659 !memcmp(sa, entry->sa, entry->sa_len)) {
660 (*proto) = entry->proto;
661 ret = 0;
662 } else {
663 (*proto) = NULL;
664 errno = ENOENT;
667 rwlock_unlock(&sockaddr_map_lock);
669 return ret;
672 static struct sock_map_entry *socket_to_sock_map_entry(int fd)
674 struct sock_map_entry *entry, *ret = NULL;
676 errno = 0;
678 rwlock_rd_lock(&sock_map_lock);
680 entry = lookup_hash(fd, &sock_mapper);
681 while (entry && fd != entry->fd)
682 entry = entry->next;
683 if (entry && fd == entry->fd)
684 ret = entry;
685 else
686 errno = ENOENT;
688 rwlock_unlock(&sock_map_lock);
690 return ret;
693 void remove_user_by_socket(int fd)
695 struct sock_map_entry *pos;
696 struct sock_map_entry *entry = socket_to_sock_map_entry(fd);
698 if (!entry)
699 return;
701 rwlock_wr_lock(&sock_map_lock);
703 pos = remove_hash(entry->fd, entry, entry->next, &sock_mapper);
704 while (pos && pos->next && pos->next != entry)
705 pos = pos->next;
706 if (pos && pos->next && pos->next == entry)
707 pos->next = entry->next;
709 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
710 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
712 entry->proto = NULL;
713 entry->next = NULL;
715 xfree(entry);
717 rwlock_unlock(&sock_map_lock);
720 static struct sockaddr_map_entry *
721 sockaddr_to_sockaddr_map_entry(struct sockaddr_storage *sa, size_t sa_len)
723 struct sockaddr_map_entry *entry, *ret = NULL;
724 unsigned int hash = hash_name((char *) sa, sa_len);
726 errno = 0;
728 rwlock_rd_lock(&sockaddr_map_lock);
730 entry = lookup_hash(hash, &sockaddr_mapper);
731 while (entry && entry->sa_len == sa_len &&
732 memcmp(sa, entry->sa, entry->sa_len))
733 entry = entry->next;
734 if (entry && entry->sa_len == sa_len &&
735 !memcmp(sa, entry->sa, entry->sa_len))
736 ret = entry;
737 else
738 errno = ENOENT;
740 rwlock_unlock(&sockaddr_map_lock);
742 return ret;
745 void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len)
747 struct sockaddr_map_entry *pos;
748 struct sockaddr_map_entry *entry;
749 unsigned int hash = hash_name((char *) sa, sa_len);
751 entry = sockaddr_to_sockaddr_map_entry(sa, sa_len);
752 if (!entry)
753 return;
755 rwlock_wr_lock(&sockaddr_map_lock);
757 pos = remove_hash(hash, entry, entry->next, &sockaddr_mapper);
758 while (pos && pos->next && pos->next != entry)
759 pos = pos->next;
760 if (pos && pos->next && pos->next == entry)
761 pos->next = entry->next;
763 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
764 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
766 entry->proto = NULL;
767 entry->next = NULL;
769 xfree(entry->sa);
770 xfree(entry);
772 rwlock_unlock(&sockaddr_map_lock);