trafgen: inherit netsniff-ng's -H -Q options
[netsniff-ng.git] / curvetun_mgmt_users.c
blob665ceb3536c6d19c969761946b14942aa131d750
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 return -EINVAL;
211 strlcpy(elem->username, str, sizeof(elem->username));
212 s = PARSE_PUBKEY;
213 break;
214 case PARSE_PUBKEY:
215 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
216 str, strlen(str)))
217 return -EINVAL;
218 if (__check_duplicate_pubkey(pkey, sizeof(pkey)))
219 return -EINVAL;
220 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
221 curve25519_proto_init(&elem->proto_inf, elem->publickey, sizeof(elem->publickey));
222 s = PARSE_DONE;
223 break;
224 case PARSE_DONE:
225 break;
226 default:
227 return -EIO;
230 str = strtok(NULL, ";");
233 store = elem;
234 return s == PARSE_DONE ? 0 : -EIO;
237 void parse_userfile_and_generate_user_store_or_die(char *homedir)
239 FILE *fp;
240 char path[PATH_MAX], buff[512];
241 int line = 1, ret, fd;
243 memset(path, 0, sizeof(path));
244 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_CLIENTS);
246 rwlock_init(&store_lock);
247 rwlock_wr_lock(&store_lock);
249 fp = fopen(path, "r");
250 if (!fp)
251 panic("Cannot open client file!\n");
253 memset(buff, 0, sizeof(buff));
254 while (fgets(buff, sizeof(buff), fp) != NULL) {
255 buff[sizeof(buff) - 1] = 0;
256 /* A comment. Skip this line */
257 if (buff[0] == '#' || buff[0] == '\n') {
258 memset(buff, 0, sizeof(buff));
259 line++;
260 continue;
263 ret = parse_line(buff, homedir);
264 if (ret < 0)
265 panic("Cannot parse line %d from clients!\n", line);
266 line++;
267 memset(buff, 0, sizeof(buff));
270 fclose(fp);
272 if (store == NULL)
273 panic("No registered clients found!\n");
275 rwlock_unlock(&store_lock);
277 init_sock_mapper();
278 init_sockaddr_mapper();
281 * Pubkey is also used as a hmac of the initial packet to check
282 * the integrity of the packet, so that we know if it's just random
283 * garbage or a 'valid' packet. Again, just for the integrity!
286 memset(path, 0, sizeof(path));
287 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_PUBKEY);
289 fd = open_or_die(path, O_RDONLY);
290 ret = read(fd, token, sizeof(token));
291 if (ret != crypto_auth_hmacsha512256_KEYBYTES)
292 panic("Cannot read public key!\n");
293 close(fd);
296 void dump_user_store(void)
298 int i;
299 struct user_store *elem;
301 rwlock_rd_lock(&store_lock);
303 elem = store;
304 while (elem) {
305 printf("%s -> ", elem->username);
306 for (i = 0; i < sizeof(elem->publickey); ++i)
307 if (i == (sizeof(elem->publickey) - 1))
308 printf("%02x\n", (unsigned char)
309 elem->publickey[i]);
310 else
311 printf("%02x:", (unsigned char)
312 elem->publickey[i]);
313 elem = elem->next;
316 rwlock_unlock(&store_lock);
319 void destroy_user_store(void)
321 struct user_store *elem, *nelem = NULL;
323 rwlock_wr_lock(&store_lock);
325 elem = store;
326 while (elem) {
327 nelem = elem->next;
328 elem->next = NULL;
329 user_store_free(elem);
330 elem = nelem;
332 rwlock_unlock(&store_lock);
334 rwlock_destroy(&store_lock);
336 destroy_sock_mapper();
337 destroy_sockaddr_mapper();
340 int username_msg(char *username, size_t len, char *dst, size_t dlen)
342 int fd;
343 ssize_t ret;
344 uint32_t salt;
345 unsigned char h[crypto_hash_sha512_BYTES];
346 struct username_struct *us = (struct username_struct *) dst;
347 char *uname;
348 size_t uname_len;
350 if (dlen < sizeof(struct username_struct))
351 return -ENOMEM;
353 uname_len = 512;
354 uname = xzmalloc(uname_len);
356 fd = open_or_die("/dev/random", O_RDONLY);
357 ret = read_exact(fd, &salt, sizeof(salt), 0);
358 if (ret != sizeof(salt))
359 panic("Cannot read from /dev/random!\n");
360 close(fd);
362 slprintf(uname, uname_len, "%s%u", username, salt);
363 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
365 us->salt = htonl(salt);
366 memcpy(us->hash, h, sizeof(us->hash));
368 xfree(uname);
369 return 0;
372 enum is_user_enum username_msg_is_user(char *src, size_t slen, char *username,
373 size_t len)
375 char *uname;
376 size_t uname_len;
377 uint32_t salt;
378 struct username_struct *us = (struct username_struct *) src;
379 unsigned char h[crypto_hash_sha512_BYTES];
381 if (slen < sizeof(struct username_struct)) {
382 errno = ENOMEM;
383 return USERNAMES_ERR;
386 uname_len = 512;
387 uname = xzmalloc(uname_len);
389 salt = ntohl(us->salt);
391 slprintf(uname, uname_len, "%s%u", username, salt);
392 crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname));
393 xfree(uname);
395 if (!crypto_verify_32(&h[0], &us->hash[0]) &&
396 !crypto_verify_32(&h[32], &us->hash[32]))
397 return USERNAMES_OK;
398 else
399 return USERNAMES_NE;
402 static int register_user_by_socket(int fd, struct curve25519_proto *proto)
404 void **pos;
405 struct sock_map_entry *entry;
407 rwlock_wr_lock(&sock_map_lock);
409 entry = xzmalloc(sizeof(*entry));
410 entry->fd = fd;
411 entry->proto = proto;
413 pos = insert_hash(entry->fd, entry, &sock_mapper);
414 if (pos) {
415 entry->next = (*pos);
416 (*pos) = entry;
419 rwlock_unlock(&sock_map_lock);
421 return 0;
424 static int register_user_by_sockaddr(struct sockaddr_storage *sa,
425 size_t sa_len,
426 struct curve25519_proto *proto)
428 void **pos;
429 struct sockaddr_map_entry *entry;
430 unsigned int hash = hash_name((char *) sa, sa_len);
432 rwlock_wr_lock(&sockaddr_map_lock);
434 entry = xzmalloc(sizeof(*entry));
435 entry->sa = xmemdupz(sa, sa_len);
436 entry->sa_len = sa_len;
437 entry->proto = proto;
439 pos = insert_hash(hash, entry, &sockaddr_mapper);
440 if (pos) {
441 entry->next = (*pos);
442 (*pos) = entry;
445 rwlock_unlock(&sockaddr_map_lock);
447 return 0;
450 int try_register_user_by_socket(struct curve25519_struct *c,
451 char *src, size_t slen, int sock, int log)
453 int ret = -1;
454 char *cbuff = NULL;
455 size_t real_len = 132;
456 ssize_t clen;
457 struct user_store *elem;
458 enum is_user_enum err;
459 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
460 struct taia arrival_taia;
462 /* assert(132 == clen + sizeof(auth)); */
464 * Check hmac first, if malicious, drop immediately before we
465 * investigate more efforts.
467 if (slen < real_len)
468 return -1;
470 taia_now(&arrival_taia);
472 memcpy(auth, src, sizeof(auth));
474 src += sizeof(auth);
475 real_len -= sizeof(auth);
477 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
478 real_len, token)) {
479 syslog(LOG_ERR, "Bad packet hmac for id %d! Dropping!\n", sock);
480 return -1;
481 } else {
482 if (log)
483 syslog(LOG_INFO, "Good packet hmac for id %d!\n", sock);
486 rwlock_rd_lock(&store_lock);
488 elem = store;
489 while (elem) {
490 clen = curve25519_decode(c, &elem->proto_inf,
491 (unsigned char *) src, real_len,
492 (unsigned char **) &cbuff,
493 &arrival_taia);
494 if (clen <= 0) {
495 elem = elem->next;
496 continue;
499 cbuff += crypto_box_zerobytes;
500 clen -= crypto_box_zerobytes;
502 if (log)
503 syslog(LOG_INFO, "Packet decoded successfully for id %d!\n", sock);
505 err = username_msg_is_user(cbuff, clen, elem->username,
506 strlen(elem->username) + 1);
507 if (err == USERNAMES_OK) {
508 if (log)
509 syslog(LOG_INFO, "Found user %s for id %d! Registering ...\n",
510 elem->username, sock);
511 ret = register_user_by_socket(sock, &elem->proto_inf);
512 break;
515 elem = elem->next;
518 rwlock_unlock(&store_lock);
520 if (ret == -1)
521 syslog(LOG_ERR, "User not found! Dropping connection!\n");
523 return ret;
526 int try_register_user_by_sockaddr(struct curve25519_struct *c,
527 char *src, size_t slen,
528 struct sockaddr_storage *sa,
529 size_t sa_len, int log)
531 int ret = -1;
532 char *cbuff = NULL;
533 struct user_store *elem;
534 ssize_t clen;
535 size_t real_len = 132;
536 enum is_user_enum err;
537 unsigned char auth[crypto_auth_hmacsha512256_BYTES];
538 struct taia arrival_taia;
540 /* assert(132 == clen + sizeof(auth)); */
542 * Check hmac first, if malicious, drop immediately before we
543 * investigate more efforts.
545 if (slen < real_len)
546 return -1;
548 taia_now(&arrival_taia);
550 memcpy(auth, src, sizeof(auth));
552 src += sizeof(auth);
553 real_len -= sizeof(auth);
555 if (crypto_auth_hmacsha512256_verify(auth, (unsigned char *) src,
556 real_len, token)) {
557 syslog(LOG_ERR, "Got bad packet hmac! Dropping!\n");
558 return -1;
559 } else {
560 if (log)
561 syslog(LOG_INFO, "Got good packet hmac!\n");
564 rwlock_rd_lock(&store_lock);
566 elem = store;
567 while (elem) {
568 clen = curve25519_decode(c, &elem->proto_inf,
569 (unsigned char *) src, real_len,
570 (unsigned char **) &cbuff,
571 &arrival_taia);
572 if (clen <= 0) {
573 elem = elem->next;
574 continue;
577 cbuff += crypto_box_zerobytes;
578 clen -= crypto_box_zerobytes;
580 if (log)
581 syslog(LOG_INFO, "Packet decoded successfully!\n");
583 err = username_msg_is_user(cbuff, clen, elem->username,
584 strlen(elem->username) + 1);
585 if (err == USERNAMES_OK) {
586 if (log)
587 syslog(LOG_INFO, "Found user %s! Registering ...\n",
588 elem->username);
589 ret = register_user_by_sockaddr(sa, sa_len,
590 &elem->proto_inf);
591 break;
594 elem = elem->next;
597 rwlock_unlock(&store_lock);
599 if (ret == -1)
600 syslog(LOG_ERR, "User not found! Dropping connection!\n");
602 return ret;
605 int get_user_by_socket(int fd, struct curve25519_proto **proto)
607 int ret = -1;
608 struct sock_map_entry *entry;
610 errno = 0;
612 rwlock_rd_lock(&sock_map_lock);
614 entry = lookup_hash(fd, &sock_mapper);
615 while (entry && fd != entry->fd)
616 entry = entry->next;
617 if (entry && fd == entry->fd) {
618 (*proto) = entry->proto;
619 ret = 0;
620 } else {
621 (*proto) = NULL;
622 errno = ENOENT;
625 rwlock_unlock(&sock_map_lock);
627 return ret;
630 int get_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len,
631 struct curve25519_proto **proto)
633 int ret = -1;
634 struct sockaddr_map_entry *entry;
635 unsigned int hash = hash_name((char *) sa, sa_len);
637 errno = 0;
639 rwlock_rd_lock(&sockaddr_map_lock);
641 entry = lookup_hash(hash, &sockaddr_mapper);
642 while (entry && entry->sa_len == sa_len &&
643 memcmp(sa, entry->sa, entry->sa_len))
644 entry = entry->next;
645 if (entry && entry->sa_len == sa_len &&
646 !memcmp(sa, entry->sa, entry->sa_len)) {
647 (*proto) = entry->proto;
648 ret = 0;
649 } else {
650 (*proto) = NULL;
651 errno = ENOENT;
654 rwlock_unlock(&sockaddr_map_lock);
656 return ret;
659 static struct sock_map_entry *socket_to_sock_map_entry(int fd)
661 struct sock_map_entry *entry, *ret = NULL;
663 errno = 0;
665 rwlock_rd_lock(&sock_map_lock);
667 entry = lookup_hash(fd, &sock_mapper);
668 while (entry && fd != entry->fd)
669 entry = entry->next;
670 if (entry && fd == entry->fd)
671 ret = entry;
672 else
673 errno = ENOENT;
675 rwlock_unlock(&sock_map_lock);
677 return ret;
680 void remove_user_by_socket(int fd)
682 struct sock_map_entry *pos;
683 struct sock_map_entry *entry = socket_to_sock_map_entry(fd);
685 if (!entry)
686 return;
688 rwlock_wr_lock(&sock_map_lock);
690 pos = remove_hash(entry->fd, entry, entry->next, &sock_mapper);
691 while (pos && pos->next && pos->next != entry)
692 pos = pos->next;
693 if (pos && pos->next && pos->next == entry)
694 pos->next = entry->next;
696 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
697 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
699 entry->proto = NULL;
700 entry->next = NULL;
702 xfree(entry);
704 rwlock_unlock(&sock_map_lock);
707 static struct sockaddr_map_entry *
708 sockaddr_to_sockaddr_map_entry(struct sockaddr_storage *sa, size_t sa_len)
710 struct sockaddr_map_entry *entry, *ret = NULL;
711 unsigned int hash = hash_name((char *) sa, sa_len);
713 errno = 0;
715 rwlock_rd_lock(&sockaddr_map_lock);
717 entry = lookup_hash(hash, &sockaddr_mapper);
718 while (entry && entry->sa_len == sa_len &&
719 memcmp(sa, entry->sa, entry->sa_len))
720 entry = entry->next;
721 if (entry && entry->sa_len == sa_len &&
722 !memcmp(sa, entry->sa, entry->sa_len))
723 ret = entry;
724 else
725 errno = ENOENT;
727 rwlock_unlock(&sockaddr_map_lock);
729 return ret;
732 void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len)
734 struct sockaddr_map_entry *pos;
735 struct sockaddr_map_entry *entry;
736 unsigned int hash = hash_name((char *) sa, sa_len);
738 entry = sockaddr_to_sockaddr_map_entry(sa, sa_len);
739 if (!entry)
740 return;
742 rwlock_wr_lock(&sockaddr_map_lock);
744 pos = remove_hash(hash, entry, entry->next, &sockaddr_mapper);
745 while (pos && pos->next && pos->next != entry)
746 pos = pos->next;
747 if (pos && pos->next && pos->next == entry)
748 pos->next = entry->next;
750 memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce));
751 memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce));
753 entry->proto = NULL;
754 entry->next = NULL;
756 xfree(entry->sa);
757 xfree(entry);
759 rwlock_unlock(&sockaddr_map_lock);