2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 Daniel Borkmann.
4 * Subject to the GPL, version 2.
15 #include <arpa/inet.h>
18 #include "ct_usermgmt.h"
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
{
38 struct curve25519_proto
*proto
;
39 struct sock_map_entry
*next
;
42 struct sockaddr_map_entry
{
43 struct sockaddr_storage
*sa
;
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
;
91 while ((next
= e
->next
)) {
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
;
120 while ((next
= e
->next
)) {
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
)
149 memset(us
, 0, sizeof(struct user_store
));
153 /* already in lock */
154 static int __check_duplicate_username(char *username
, size_t len
)
157 struct user_store
*elem
= store
;
160 if (!memcmp(elem
->username
, username
,
161 strlen(elem
->username
) + 1)) {
171 /* already in lock */
172 static int __check_duplicate_pubkey(unsigned char *pubkey
, size_t len
)
175 struct user_store
*elem
= store
;
178 if (!memcmp(elem
->publickey
, pubkey
,
179 sizeof(elem
->publickey
))) {
195 static int parse_line(char *line
, char *homedir
)
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();
206 str
= strtok(line
, ";");
207 for (; str
!= NULL
;) {
210 if (__check_duplicate_username(str
, strlen(str
) + 1))
212 strlcpy(elem
->username
, str
, sizeof(elem
->username
));
216 if (!curve25519_pubkey_hexparse_32(pkey
, sizeof(pkey
),
219 if (__check_duplicate_pubkey(pkey
, sizeof(pkey
)))
221 memcpy(elem
->publickey
, pkey
, sizeof(elem
->publickey
));
222 ret
= curve25519_proto_init(&elem
->proto_inf
,
224 sizeof(elem
->publickey
),
236 str
= strtok(NULL
, ";");
240 return s
== PARSE_DONE
? 0 : -EIO
;
243 void parse_userfile_and_generate_user_store_or_die(char *homedir
)
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");
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
));
269 ret
= parse_line(buff
, homedir
);
271 panic("Cannot parse line %d from clients!\n", line
);
273 memset(buff
, 0, sizeof(buff
));
279 panic("No registered clients found!\n");
281 rwlock_unlock(&store_lock
);
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");
302 void dump_user_store(void)
305 struct user_store
*elem
;
307 rwlock_rd_lock(&store_lock
);
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)
317 printf("%02x:", (unsigned char)
322 rwlock_unlock(&store_lock
);
325 void destroy_user_store(void)
327 struct user_store
*elem
, *nelem
= NULL
;
329 rwlock_wr_lock(&store_lock
);
335 user_store_free(elem
);
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
)
351 unsigned char h
[crypto_hash_sha512_BYTES
];
352 struct username_struct
*us
= (struct username_struct
*) dst
;
356 if (dlen
< sizeof(struct username_struct
))
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");
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
));
378 enum is_user_enum
username_msg_is_user(char *src
, size_t slen
, char *username
,
384 struct username_struct
*us
= (struct username_struct
*) src
;
385 unsigned char h
[crypto_hash_sha512_BYTES
];
387 if (slen
< sizeof(struct username_struct
)) {
389 return USERNAMES_ERR
;
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
));
401 if (!crypto_verify_32(&h
[0], &us
->hash
[0]) &&
402 !crypto_verify_32(&h
[32], &us
->hash
[32]))
408 static int register_user_by_socket(int fd
, struct curve25519_proto
*proto
)
411 struct sock_map_entry
*entry
;
413 rwlock_wr_lock(&sock_map_lock
);
415 entry
= xzmalloc(sizeof(*entry
));
417 entry
->proto
= proto
;
419 pos
= insert_hash(entry
->fd
, entry
, &sock_mapper
);
421 entry
->next
= (*pos
);
425 rwlock_unlock(&sock_map_lock
);
430 static int register_user_by_sockaddr(struct sockaddr_storage
*sa
,
432 struct curve25519_proto
*proto
)
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
);
447 entry
->next
= (*pos
);
451 rwlock_unlock(&sockaddr_map_lock
);
456 int try_register_user_by_socket(struct curve25519_struct
*c
,
457 char *src
, size_t slen
, int sock
, int log
)
461 size_t real_len
= 132;
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.
476 taia_now(&arrival_taia
);
478 memcpy(auth
, src
, sizeof(auth
));
481 real_len
-= sizeof(auth
);
483 if (crypto_auth_hmacsha512256_verify(auth
, (unsigned char *) src
,
485 syslog(LOG_ERR
, "Bad packet hmac for id %d! Dropping!\n", sock
);
489 syslog(LOG_INFO
, "Good packet hmac for id %d!\n", sock
);
492 rwlock_rd_lock(&store_lock
);
496 clen
= curve25519_decode(c
, &elem
->proto_inf
,
497 (unsigned char *) src
, real_len
,
498 (unsigned char **) &cbuff
,
505 cbuff
+= crypto_box_zerobytes
;
506 clen
-= crypto_box_zerobytes
;
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
) {
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
);
524 rwlock_unlock(&store_lock
);
527 syslog(LOG_ERR
, "User not found! Dropping connection!\n");
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
)
539 struct user_store
*elem
;
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.
554 taia_now(&arrival_taia
);
556 memcpy(auth
, src
, sizeof(auth
));
559 real_len
-= sizeof(auth
);
561 if (crypto_auth_hmacsha512256_verify(auth
, (unsigned char *) src
,
563 syslog(LOG_ERR
, "Got bad packet hmac! Dropping!\n");
567 syslog(LOG_INFO
, "Got good packet hmac!\n");
570 rwlock_rd_lock(&store_lock
);
574 clen
= curve25519_decode(c
, &elem
->proto_inf
,
575 (unsigned char *) src
, real_len
,
576 (unsigned char **) &cbuff
,
583 cbuff
+= crypto_box_zerobytes
;
584 clen
-= crypto_box_zerobytes
;
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
) {
593 syslog(LOG_INFO
, "Found user %s! Registering ...\n",
595 ret
= register_user_by_sockaddr(sa
, sa_len
,
603 rwlock_unlock(&store_lock
);
606 syslog(LOG_ERR
, "User not found! Dropping connection!\n");
611 int get_user_by_socket(int fd
, struct curve25519_proto
**proto
)
614 struct sock_map_entry
*entry
;
618 rwlock_rd_lock(&sock_map_lock
);
620 entry
= lookup_hash(fd
, &sock_mapper
);
621 while (entry
&& fd
!= entry
->fd
)
623 if (entry
&& fd
== entry
->fd
) {
624 (*proto
) = entry
->proto
;
631 rwlock_unlock(&sock_map_lock
);
636 int get_user_by_sockaddr(struct sockaddr_storage
*sa
, size_t sa_len
,
637 struct curve25519_proto
**proto
)
640 struct sockaddr_map_entry
*entry
;
641 unsigned int hash
= hash_name((char *) sa
, sa_len
);
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
))
651 if (entry
&& entry
->sa_len
== sa_len
&&
652 !memcmp(sa
, entry
->sa
, entry
->sa_len
)) {
653 (*proto
) = entry
->proto
;
660 rwlock_unlock(&sockaddr_map_lock
);
665 static struct sock_map_entry
*socket_to_sock_map_entry(int fd
)
667 struct sock_map_entry
*entry
, *ret
= NULL
;
671 rwlock_rd_lock(&sock_map_lock
);
673 entry
= lookup_hash(fd
, &sock_mapper
);
674 while (entry
&& fd
!= entry
->fd
)
676 if (entry
&& fd
== entry
->fd
)
681 rwlock_unlock(&sock_map_lock
);
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
);
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
)
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
));
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
);
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
))
727 if (entry
&& entry
->sa_len
== sa_len
&&
728 !memcmp(sa
, entry
->sa
, entry
->sa_len
))
733 rwlock_unlock(&sockaddr_map_lock
);
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
);
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
)
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
));
765 rwlock_unlock(&sockaddr_map_lock
);