2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 Daniel Borkmann.
15 #include <arpa/inet.h>
22 #include "write_or_die.h"
27 #include "crypto_verify_32.h"
28 #include "crypto_hash_sha512.h"
29 #include "crypto_box_curve25519xsalsa20poly1305.h"
31 #define crypto_box_pub_key_size crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
33 /* Config line format: username;pubkey\n */
37 unsigned char publickey
[crypto_box_pub_key_size
];
38 struct curve25519_proto proto_inf
;
39 struct user_store
*next
;
42 struct sock_map_entry
{
44 struct curve25519_proto
*proto
;
45 struct sock_map_entry
*next
;
48 struct sockaddr_map_entry
{
49 struct sockaddr_storage
*sa
;
51 struct curve25519_proto
*proto
;
52 struct sockaddr_map_entry
*next
;
55 static struct user_store
*store
= NULL
;
56 static struct rwlock store_lock
;
58 static struct hash_table sock_mapper
;
59 static struct rwlock sock_map_lock
;
61 static struct hash_table sockaddr_mapper
;
62 static struct rwlock sockaddr_map_lock
;
64 static void init_sock_mapper(void)
66 rwlock_init(&sock_map_lock
);
67 rwlock_wr_lock(&sock_map_lock
);
68 memset(&sock_mapper
, 0, sizeof(sock_mapper
));
69 init_hash(&sock_mapper
);
70 rwlock_unlock(&sock_map_lock
);
73 static void init_sockaddr_mapper(void)
75 rwlock_init(&sockaddr_map_lock
);
76 rwlock_wr_lock(&sockaddr_map_lock
);
77 memset(&sockaddr_mapper
, 0, sizeof(sockaddr_mapper
));
78 init_hash(&sockaddr_mapper
);
79 rwlock_unlock(&sockaddr_map_lock
);
82 static int cleanup_batch_sock_mapper(void *ptr
)
84 struct sock_map_entry
*next
;
85 struct sock_map_entry
*e
= ptr
;
89 while ((next
= e
->next
)) {
98 static void destroy_sock_mapper(void)
100 rwlock_wr_lock(&sock_map_lock
);
101 for_each_hash(&sock_mapper
, cleanup_batch_sock_mapper
);
102 free_hash(&sock_mapper
);
103 rwlock_unlock(&sock_map_lock
);
104 rwlock_destroy(&sock_map_lock
);
107 static int cleanup_batch_sockaddr_mapper(void *ptr
)
109 struct sockaddr_map_entry
*next
;
110 struct sockaddr_map_entry
*e
= ptr
;
114 while ((next
= e
->next
)) {
123 static void destroy_sockaddr_mapper(void)
125 rwlock_wr_lock(&sockaddr_map_lock
);
126 for_each_hash(&sockaddr_mapper
, cleanup_batch_sockaddr_mapper
);
127 free_hash(&sockaddr_mapper
);
128 rwlock_unlock(&sockaddr_map_lock
);
129 rwlock_destroy(&sockaddr_map_lock
);
132 static struct user_store
*user_store_alloc(void)
134 return xzmalloc(sizeof(struct user_store
));
137 static void user_store_free(struct user_store
*us
)
141 memset(us
, 0, sizeof(struct user_store
));
145 /* already in lock */
146 static int __check_duplicate_username(char *username
, size_t len
)
149 struct user_store
*elem
= store
;
151 if (!memcmp(elem
->username
, username
,
152 strlen(elem
->username
) + 1)) {
161 /* already in lock */
162 static int __check_duplicate_pubkey(unsigned char *pubkey
, size_t len
)
165 struct user_store
*elem
= store
;
167 if (!memcmp(elem
->publickey
, pubkey
,
168 sizeof(elem
->publickey
))) {
177 void parse_userfile_and_generate_user_store_or_die(char *homedir
)
180 char path
[512], buff
[512], *username
, *key
;
181 unsigned char pkey
[crypto_box_pub_key_size
];
183 struct user_store
*elem
;
185 memset(path
, 0, sizeof(path
));
186 snprintf(path
, sizeof(path
), "%s/%s", homedir
, FILE_CLIENTS
);
187 path
[sizeof(path
) - 1] = 0;
189 rwlock_init(&store_lock
);
190 rwlock_wr_lock(&store_lock
);
192 fp
= fopen(path
, "r");
194 panic("Cannot open client file!\n");
195 memset(buff
, 0, sizeof(buff
));
197 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
198 buff
[sizeof(buff
) - 1] = 0;
199 /* A comment. Skip this line */
200 if (buff
[0] == '#' || buff
[0] == '\n') {
201 memset(buff
, 0, sizeof(buff
));
205 username
= skips(buff
);
207 while (*key
!= ';' &&
213 panic("Parse error! No key found in l.%d!\n", line
);
217 panic("Parse error! No key found in l.%d!\n", line
);
218 key
= strtrim_right(key
, '\n');
219 memset(pkey
, 0, sizeof(pkey
));
220 if (!curve25519_pubkey_hexparse_32(pkey
, sizeof(pkey
),
222 panic("Parse error! No key found in l.%d!\n", line
);
223 if (strlen(username
) + 1 > sizeof(elem
->username
))
224 panic("Username too long in l.%d!\n", line
);
225 if (__check_duplicate_username(username
, strlen(username
) + 1))
226 panic("Duplicate username in l.%d!\n", line
);
227 if (__check_duplicate_pubkey(pkey
, sizeof(pkey
)))
228 panic("Duplicate publickey in l.%d!\n", line
);
229 if (strstr(username
, " "))
230 panic("Username consists of whitespace in l.%d!\n", line
);
231 if (strstr(username
, "\t"))
232 panic("Username consists of whitespace in l.%d!\n", line
);
233 elem
= user_store_alloc();
235 strlcpy(elem
->username
, username
, sizeof(elem
->username
));
236 memcpy(elem
->publickey
, pkey
, sizeof(elem
->publickey
));
237 ret
= curve25519_proto_init(&elem
->proto_inf
,
239 sizeof(elem
->publickey
),
242 panic("Cannot init curve25519 proto on user!\n");
245 memset(buff
, 0, sizeof(buff
));
251 panic("No registered clients found!\n");
252 rwlock_unlock(&store_lock
);
255 init_sockaddr_mapper();
258 void dump_user_store(void)
261 struct user_store
*elem
;
263 rwlock_rd_lock(&store_lock
);
266 printf("%s -> ", elem
->username
);
267 for (i
= 0; i
< sizeof(elem
->publickey
); ++i
)
268 if (i
== (sizeof(elem
->publickey
) - 1))
269 printf("%02x\n", (unsigned char)
272 printf("%02x:", (unsigned char)
276 rwlock_unlock(&store_lock
);
279 void destroy_user_store(void)
281 struct user_store
*elem
, *nelem
= NULL
;
283 rwlock_wr_lock(&store_lock
);
288 user_store_free(elem
);
291 rwlock_unlock(&store_lock
);
292 rwlock_destroy(&store_lock
);
294 destroy_sock_mapper();
295 destroy_sockaddr_mapper();
298 int username_msg(char *username
, size_t len
, char *dst
, size_t dlen
)
303 unsigned char h
[crypto_hash_sha512_BYTES
];
304 struct username_struct
*us
= (struct username_struct
*) dst
;
309 if (dlen
< sizeof(struct username_struct
))
313 uname
= xzmalloc(uname_len
);
315 fd
= open_or_die("/dev/random", O_RDONLY
);
316 ret
= read_exact(fd
, &salt
, sizeof(salt
), 0);
317 if (ret
!= sizeof(salt
))
318 panic("Cannot read from /dev/random!\n");
321 snprintf(uname
, uname_len
, "%s%u", username
, salt
);
322 uname
[uname_len
- 1] = 0;
323 crypto_hash_sha512(h
, (unsigned char *) uname
, strlen(uname
));
325 memset(&ts
, 0, sizeof(ts
));
328 us
->salt
= htonl(salt
);
329 memcpy(us
->hash
, h
, sizeof(us
->hash
));
330 taia_pack(us
->taia
, &ts
);
336 static struct taia tolerance_taia
= {
338 .nano
= 250000000ULL,
342 enum is_user_enum
username_msg_is_user(char *src
, size_t slen
, char *username
,
343 size_t len
, struct taia
*arrival_taia
)
345 int not_same
= 1, is_ts_good
= 0;
346 enum is_user_enum ret
= USERNAMES_NE
;
350 struct username_struct
*us
= (struct username_struct
*) src
;
351 struct taia ts
, sub_res
;
352 unsigned char h
[crypto_hash_sha512_BYTES
];
354 if (slen
< sizeof(struct username_struct
)) {
356 return USERNAMES_ERR
;
360 uname
= xzmalloc(uname_len
);
362 salt
= ntohl(us
->salt
);
364 snprintf(uname
, uname_len
, "%s%u", username
, salt
);
365 uname
[uname_len
- 1] = 0;
366 crypto_hash_sha512(h
, (unsigned char *) uname
, strlen(uname
));
368 if (!crypto_verify_32(&h
[0], &us
->hash
[0]) &&
369 !crypto_verify_32(&h
[32], &us
->hash
[32]))
374 taia_unpack(us
->taia
, &ts
);
375 if (taia_less(arrival_taia
, &ts
)) {
376 taia_sub(&sub_res
, &ts
, arrival_taia
);
377 if (taia_less(&sub_res
, &tolerance_taia
))
382 taia_sub(&sub_res
, arrival_taia
, &ts
);
383 if (taia_less(&sub_res
, &tolerance_taia
))
389 if (!not_same
&& is_ts_good
)
391 else if (!not_same
&& !is_ts_good
)
400 static int register_user_by_socket(int fd
, struct curve25519_proto
*proto
)
403 struct sock_map_entry
*entry
;
405 rwlock_wr_lock(&sock_map_lock
);
406 entry
= xzmalloc(sizeof(*entry
));
408 entry
->proto
= proto
;
409 pos
= insert_hash(entry
->fd
, entry
, &sock_mapper
);
411 entry
->next
= (*pos
);
414 rwlock_unlock(&sock_map_lock
);
419 static int register_user_by_sockaddr(int sock
, struct curve25519_proto
*proto
)
424 int try_register_user_by_socket(struct curve25519_struct
*c
,
425 char *src
, size_t slen
, int sock
)
428 struct user_store
*elem
;
429 enum is_user_enum err
;
430 struct taia arrival_tai
;
432 rwlock_rd_lock(&store_lock
);
434 taia_now(&arrival_tai
);
436 // clen = curve25519_decode(c, &elem->proto_inf,
437 // (unsigned char *) src,
439 // printf("clen: %d\n", clen);
442 err
= username_msg_is_user((char *) src
, slen
,
444 strlen(elem
->username
) + 1,
446 if (err
== USERNAMES_OK
) {
447 syslog(LOG_INFO
, "Found user %s for id %d!\n",
448 elem
->username
, sock
);
449 ret
= register_user_by_socket(sock
, &elem
->proto_inf
);
451 } else if (err
== USERNAMES_TS
)
455 rwlock_unlock(&store_lock
);
460 int try_register_user_by_sockaddr(struct curve25519_struct
*c
,
461 char *src
, size_t slen
,
462 struct sockaddr_storage
*sa
,
468 int get_user_by_socket(int fd
, struct curve25519_proto
**proto
)
471 struct sock_map_entry
*entry
;
474 rwlock_rd_lock(&sock_map_lock
);
475 entry
= lookup_hash(fd
, &sock_mapper
);
476 while (entry
&& fd
!= entry
->fd
)
478 if (entry
&& fd
== entry
->fd
) {
479 (*proto
) = entry
->proto
;
485 rwlock_unlock(&sock_map_lock
);
490 int get_user_by_sockaddr(struct sockaddr_storage
*sa
, size_t sa_len
,
491 struct curve25519_proto
**proto
)
496 static struct sock_map_entry
*socket_to_sock_map_entry(int fd
)
498 struct sock_map_entry
*entry
, *ret
= NULL
;
501 rwlock_rd_lock(&sock_map_lock
);
502 entry
= lookup_hash(fd
, &sock_mapper
);
503 while (entry
&& fd
!= entry
->fd
)
505 if (entry
&& fd
== entry
->fd
)
509 rwlock_unlock(&sock_map_lock
);
514 void remove_user_by_socket(int fd
)
516 struct sock_map_entry
*pos
;
517 struct sock_map_entry
*entry
= socket_to_sock_map_entry(fd
);
519 if (!entry
== 0 && errno
== ENOENT
)
521 rwlock_wr_lock(&sock_map_lock
);
522 pos
= remove_hash(entry
->fd
, entry
, entry
->next
, &sock_mapper
);
523 while (pos
&& pos
->next
&& pos
->next
!= entry
)
525 if (pos
&& pos
->next
&& pos
->next
== entry
)
526 pos
->next
= entry
->next
;
529 rwlock_unlock(&sock_map_lock
);
532 void remove_user_by_sockaddr(struct sockaddr_storage
*sa
, size_t sa_len
)