ifpps: Remove unused 'forks' member from struct ifstat
[netsniff-ng.git] / ct_usermgmt.c
blob201c0c787fd3c86fd644f374f3a1cf621ff7b303
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 "curve.h"
26 #include "crypto.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 int ret;
198 char *str;
199 enum parse_states s = PARSE_USERNAME;
200 struct user_store *elem;
201 unsigned char pkey[crypto_box_pub_key_size];
203 elem = user_store_alloc();
204 elem->next = store;
206 str = strtok(line, ";");
207 for (; str != NULL;) {
208 switch (s) {
209 case PARSE_USERNAME:
210 if (__check_duplicate_username(str, strlen(str) + 1))
211 return -EINVAL;
212 strlcpy(elem->username, str, sizeof(elem->username));
213 s = PARSE_PUBKEY;
214 break;
215 case PARSE_PUBKEY:
216 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
217 str, strlen(str)))
218 return -EINVAL;
219 if (__check_duplicate_pubkey(pkey, sizeof(pkey)))
220 return -EINVAL;
221 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
222 ret = curve25519_proto_init(&elem->proto_inf,
223 elem->publickey,
224 sizeof(elem->publickey),
225 homedir, 1);
226 if (ret)
227 return -EIO;
228 s = PARSE_DONE;
229 break;
230 case PARSE_DONE:
231 break;
232 default:
233 return -EIO;
236 str = strtok(NULL, ";");
239 store = elem;
240 return s == PARSE_DONE ? 0 : -EIO;
243 void parse_userfile_and_generate_user_store_or_die(char *homedir)
245 FILE *fp;
246 char path[PATH_MAX], buff[512];
247 int line = 1, ret, fd;
249 memset(path, 0, sizeof(path));
250 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_CLIENTS);
252 rwlock_init(&store_lock);
253 rwlock_wr_lock(&store_lock);
255 fp = fopen(path, "r");
256 if (!fp)
257 panic("Cannot open client file!\n");
259 memset(buff, 0, sizeof(buff));
260 while (fgets(buff, sizeof(buff), fp) != NULL) {
261 buff[sizeof(buff) - 1] = 0;
262 /* A comment. Skip this line */
263 if (buff[0] == '#' || buff[0] == '\n') {
264 memset(buff, 0, sizeof(buff));
265 line++;
266 continue;
269 ret = parse_line(buff, homedir);
270 if (ret < 0)
271 panic("Cannot parse line %d from clients!\n", line);
272 line++;
273 memset(buff, 0, sizeof(buff));
276 fclose(fp);
278 if (store == NULL)
279 panic("No registered clients found!\n");
281 rwlock_unlock(&store_lock);
283 init_sock_mapper();
284 init_sockaddr_mapper();
287 * Pubkey is also used as a hmac of the initial packet to check
288 * the integrity of the packet, so that we know if it's just random
289 * garbage or a 'valid' packet. Again, just for the integrity!
292 memset(path, 0, sizeof(path));
293 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_PUBKEY);
295 fd = open_or_die(path, O_RDONLY);
296 ret = read(fd, token, sizeof(token));
297 if (ret != crypto_auth_hmacsha512256_KEYBYTES)
298 panic("Cannot read public key!\n");
299 close(fd);
302 void dump_user_store(void)
304 int i;
305 struct user_store *elem;
307 rwlock_rd_lock(&store_lock);
309 elem = store;
310 while (elem) {
311 printf("%s -> ", elem->username);
312 for (i = 0; i < sizeof(elem->publickey); ++i)
313 if (i == (sizeof(elem->publickey) - 1))
314 printf("%02x\n", (unsigned char)
315 elem->publickey[i]);
316 else
317 printf("%02x:", (unsigned char)
318 elem->publickey[i]);
319 elem = elem->next;
322 rwlock_unlock(&store_lock);
325 void destroy_user_store(void)
327 struct user_store *elem, *nelem = NULL;
329 rwlock_wr_lock(&store_lock);
331 elem = store;
332 while (elem) {
333 nelem = elem->next;
334 elem->next = NULL;
335 user_store_free(elem);
336 elem = nelem;
338 rwlock_unlock(&store_lock);
340 rwlock_destroy(&store_lock);
342 destroy_sock_mapper();
343 destroy_sockaddr_mapper();
346 int username_msg(char *username, size_t len, char *dst, size_t dlen)
348 int fd;
349 ssize_t ret;
350 uint32_t salt;
351 unsigned char h[crypto_hash_sha512_BYTES];
352 struct username_struct *us = (struct username_struct *) dst;
353 char *uname;
354 size_t uname_len;
356 if (dlen < sizeof(struct username_struct))
357 return -ENOMEM;
359 uname_len = 512;
360 uname = xzmalloc(uname_len);
362 fd = open_or_die("/dev/random", O_RDONLY);
363 ret = read_exact(fd, &salt, sizeof(salt), 0);
364 if (ret != sizeof(salt))
365 panic("Cannot read from /dev/random!\n");
366 close(fd);
368 slprintf(uname, uname_len, "%s%u", username, salt);
369 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
371 us->salt = htonl(salt);
372 memcpy(us->hash, h, sizeof(us->hash));
374 xfree(uname);
375 return 0;
378 enum is_user_enum username_msg_is_user(char *src, size_t slen, char *username,
379 size_t len)
381 char *uname;
382 size_t uname_len;
383 uint32_t salt;
384 struct username_struct *us = (struct username_struct *) src;
385 unsigned char h[crypto_hash_sha512_BYTES];
387 if (slen < sizeof(struct username_struct)) {
388 errno = ENOMEM;
389 return USERNAMES_ERR;
392 uname_len = 512;
393 uname = xzmalloc(uname_len);
395 salt = ntohl(us->salt);
397 slprintf(uname, uname_len, "%s%u", username, salt);
398 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
399 xfree(uname);
401 if (!crypto_verify_32(&h[0], &us->hash[0]) &&
402 !crypto_verify_32(&h[32], &us->hash[32]))
403 return USERNAMES_OK;
404 else
405 return USERNAMES_NE;
408 static int register_user_by_socket(int fd, struct curve25519_proto *proto)
410 void **pos;
411 struct sock_map_entry *entry;
413 rwlock_wr_lock(&sock_map_lock);
415 entry = xzmalloc(sizeof(*entry));
416 entry->fd = fd;
417 entry->proto = proto;
419 pos = insert_hash(entry->fd, entry, &sock_mapper);
420 if (pos) {
421 entry->next = (*pos);
422 (*pos) = entry;
425 rwlock_unlock(&sock_map_lock);
427 return 0;
430 static int register_user_by_sockaddr(struct sockaddr_storage *sa,
431 size_t sa_len,
432 struct curve25519_proto *proto)
434 void **pos;
435 struct sockaddr_map_entry *entry;
436 unsigned int hash = hash_name((char *) sa, sa_len);
438 rwlock_wr_lock(&sockaddr_map_lock);
440 entry = xzmalloc(sizeof(*entry));
441 entry->sa = xmemdupz(sa, sa_len);
442 entry->sa_len = sa_len;
443 entry->proto = proto;
445 pos = insert_hash(hash, entry, &sockaddr_mapper);
446 if (pos) {
447 entry->next = (*pos);
448 (*pos) = entry;
451 rwlock_unlock(&sockaddr_map_lock);
453 return 0;
456 int try_register_user_by_socket(struct curve25519_struct *c,
457 char *src, size_t slen, int sock, int log)
459 int ret = -1;
460 char *cbuff = NULL;
461 size_t real_len = 132;
462 ssize_t clen;
463 struct user_store *elem;
464 enum is_user_enum err;
465 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
466 struct taia arrival_taia;
468 /* assert(132 == clen + sizeof(auth)); */
470 * Check hmac first, if malicious, drop immediately before we
471 * investigate more efforts.
473 if (slen < real_len)
474 return -1;
476 taia_now(&arrival_taia);
478 memcpy(auth, src, sizeof(auth));
480 src += sizeof(auth);
481 real_len -= sizeof(auth);
483 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
484 real_len, token)) {
485 syslog(LOG_ERR, "Bad packet hmac for id %d! Dropping!\n", sock);
486 return -1;
487 } else {
488 if (log)
489 syslog(LOG_INFO, "Good packet hmac for id %d!\n", sock);
492 rwlock_rd_lock(&store_lock);
494 elem = store;
495 while (elem) {
496 clen = curve25519_decode(c, &elem->proto_inf,
497 (unsigned char *) src, real_len,
498 (unsigned char **) &cbuff,
499 &arrival_taia);
500 if (clen <= 0) {
501 elem = elem->next;
502 continue;
505 cbuff += crypto_box_zerobytes;
506 clen -= crypto_box_zerobytes;
508 if (log)
509 syslog(LOG_INFO, "Packet decoded successfully for id %d!\n", sock);
511 err = username_msg_is_user(cbuff, clen, elem->username,
512 strlen(elem->username) + 1);
513 if (err == USERNAMES_OK) {
514 if (log)
515 syslog(LOG_INFO, "Found user %s for id %d! Registering ...\n",
516 elem->username, sock);
517 ret = register_user_by_socket(sock, &elem->proto_inf);
518 break;
521 elem = elem->next;
524 rwlock_unlock(&store_lock);
526 if (ret == -1)
527 syslog(LOG_ERR, "User not found! Dropping connection!\n");
529 return ret;
532 int try_register_user_by_sockaddr(struct curve25519_struct *c,
533 char *src, size_t slen,
534 struct sockaddr_storage *sa,
535 size_t sa_len, int log)
537 int ret = -1;
538 char *cbuff = NULL;
539 struct user_store *elem;
540 ssize_t clen;
541 size_t real_len = 132;
542 enum is_user_enum err;
543 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
544 struct taia arrival_taia;
546 /* assert(132 == clen + sizeof(auth)); */
548 * Check hmac first, if malicious, drop immediately before we
549 * investigate more efforts.
551 if (slen < real_len)
552 return -1;
554 taia_now(&arrival_taia);
556 memcpy(auth, src, sizeof(auth));
558 src += sizeof(auth);
559 real_len -= sizeof(auth);
561 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
562 real_len, token)) {
563 syslog(LOG_ERR, "Got bad packet hmac! Dropping!\n");
564 return -1;
565 } else {
566 if (log)
567 syslog(LOG_INFO, "Got good packet hmac!\n");
570 rwlock_rd_lock(&store_lock);
572 elem = store;
573 while (elem) {
574 clen = curve25519_decode(c, &elem->proto_inf,
575 (unsigned char *) src, real_len,
576 (unsigned char **) &cbuff,
577 &arrival_taia);
578 if (clen <= 0) {
579 elem = elem->next;
580 continue;
583 cbuff += crypto_box_zerobytes;
584 clen -= crypto_box_zerobytes;
586 if (log)
587 syslog(LOG_INFO, "Packet decoded successfully!\n");
589 err = username_msg_is_user(cbuff, clen, elem->username,
590 strlen(elem->username) + 1);
591 if (err == USERNAMES_OK) {
592 if (log)
593 syslog(LOG_INFO, "Found user %s! Registering ...\n",
594 elem->username);
595 ret = register_user_by_sockaddr(sa, sa_len,
596 &elem->proto_inf);
597 break;
600 elem = elem->next;
603 rwlock_unlock(&store_lock);
605 if (ret == -1)
606 syslog(LOG_ERR, "User not found! Dropping connection!\n");
608 return ret;
611 int get_user_by_socket(int fd, struct curve25519_proto **proto)
613 int ret = -1;
614 struct sock_map_entry *entry;
616 errno = 0;
618 rwlock_rd_lock(&sock_map_lock);
620 entry = lookup_hash(fd, &sock_mapper);
621 while (entry && fd != entry->fd)
622 entry = entry->next;
623 if (entry && fd == entry->fd) {
624 (*proto) = entry->proto;
625 ret = 0;
626 } else {
627 (*proto) = NULL;
628 errno = ENOENT;
631 rwlock_unlock(&sock_map_lock);
633 return ret;
636 int get_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len,
637 struct curve25519_proto **proto)
639 int ret = -1;
640 struct sockaddr_map_entry *entry;
641 unsigned int hash = hash_name((char *) sa, sa_len);
643 errno = 0;
645 rwlock_rd_lock(&sockaddr_map_lock);
647 entry = lookup_hash(hash, &sockaddr_mapper);
648 while (entry && entry->sa_len == sa_len &&
649 memcmp(sa, entry->sa, entry->sa_len))
650 entry = entry->next;
651 if (entry && entry->sa_len == sa_len &&
652 !memcmp(sa, entry->sa, entry->sa_len)) {
653 (*proto) = entry->proto;
654 ret = 0;
655 } else {
656 (*proto) = NULL;
657 errno = ENOENT;
660 rwlock_unlock(&sockaddr_map_lock);
662 return ret;
665 static struct sock_map_entry *socket_to_sock_map_entry(int fd)
667 struct sock_map_entry *entry, *ret = NULL;
669 errno = 0;
671 rwlock_rd_lock(&sock_map_lock);
673 entry = lookup_hash(fd, &sock_mapper);
674 while (entry && fd != entry->fd)
675 entry = entry->next;
676 if (entry && fd == entry->fd)
677 ret = entry;
678 else
679 errno = ENOENT;
681 rwlock_unlock(&sock_map_lock);
683 return ret;
686 void remove_user_by_socket(int fd)
688 struct sock_map_entry *pos;
689 struct sock_map_entry *entry = socket_to_sock_map_entry(fd);
691 if (!entry)
692 return;
694 rwlock_wr_lock(&sock_map_lock);
696 pos = remove_hash(entry->fd, entry, entry->next, &sock_mapper);
697 while (pos && pos->next && pos->next != entry)
698 pos = pos->next;
699 if (pos && pos->next && pos->next == entry)
700 pos->next = entry->next;
702 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
703 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
705 entry->proto = NULL;
706 entry->next = NULL;
708 xfree(entry);
710 rwlock_unlock(&sock_map_lock);
713 static struct sockaddr_map_entry *
714 sockaddr_to_sockaddr_map_entry(struct sockaddr_storage *sa, size_t sa_len)
716 struct sockaddr_map_entry *entry, *ret = NULL;
717 unsigned int hash = hash_name((char *) sa, sa_len);
719 errno = 0;
721 rwlock_rd_lock(&sockaddr_map_lock);
723 entry = lookup_hash(hash, &sockaddr_mapper);
724 while (entry && entry->sa_len == sa_len &&
725 memcmp(sa, entry->sa, entry->sa_len))
726 entry = entry->next;
727 if (entry && entry->sa_len == sa_len &&
728 !memcmp(sa, entry->sa, entry->sa_len))
729 ret = entry;
730 else
731 errno = ENOENT;
733 rwlock_unlock(&sockaddr_map_lock);
735 return ret;
738 void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len)
740 struct sockaddr_map_entry *pos;
741 struct sockaddr_map_entry *entry;
742 unsigned int hash = hash_name((char *) sa, sa_len);
744 entry = sockaddr_to_sockaddr_map_entry(sa, sa_len);
745 if (!entry)
746 return;
748 rwlock_wr_lock(&sockaddr_map_lock);
750 pos = remove_hash(hash, entry, entry->next, &sockaddr_mapper);
751 while (pos && pos->next && pos->next != entry)
752 pos = pos->next;
753 if (pos && pos->next && pos->next == entry)
754 pos->next = entry->next;
756 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
757 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
759 entry->proto = NULL;
760 entry->next = NULL;
762 xfree(entry->sa);
763 xfree(entry);
765 rwlock_unlock(&sockaddr_map_lock);