added socket to proto mapper for tcp
[netsniff-ng.git] / src / usermgmt.c
blob2e0cacf990208eab99934729aecf685d63dc4b1d
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.
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 <arpa/inet.h>
17 #include "die.h"
18 #include "usermgmt.h"
19 #include "parser.h"
20 #include "locking.h"
21 #include "xmalloc.h"
22 #include "write_or_die.h"
23 #include "curvetun.h"
24 #include "strlcpy.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"
31 #define crypto_box_pub_key_size crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
33 /* Config line format: username;pubkey\n */
35 struct user_store {
36 char username[256];
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 {
43 int fd;
44 struct curve25519_proto *proto;
45 struct sock_map_entry *next;
48 struct sockaddr_map_entry {
49 struct sockaddr_storage *sa;
50 size_t sa_len;
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;
87 if (!e)
88 return 0;
89 while ((next = e->next)) {
90 e->next = NULL;
91 xfree(e);
92 e = next;
94 xfree(e);
95 return 0;
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;
112 if (!e)
113 return 0;
114 while ((next = e->next)) {
115 e->next = NULL;
116 xfree(e);
117 e = next;
119 xfree(e);
120 return 0;
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)
139 if (!us)
140 return;
141 memset(us, 0, sizeof(struct user_store));
142 xfree(us);
145 /* already in lock */
146 static int __check_duplicate_username(char *username, size_t len)
148 int duplicate = 0;
149 struct user_store *elem = store;
150 while (elem) {
151 if (!memcmp(elem->username, username,
152 strlen(elem->username) + 1)) {
153 duplicate = 1;
154 break;
156 elem = elem->next;
158 return duplicate;
161 /* already in lock */
162 static int __check_duplicate_pubkey(unsigned char *pubkey, size_t len)
164 int duplicate = 0;
165 struct user_store *elem = store;
166 while (elem) {
167 if (!memcmp(elem->publickey, pubkey,
168 sizeof(elem->publickey))) {
169 duplicate = 1;
170 break;
172 elem = elem->next;
174 return duplicate;
177 void parse_userfile_and_generate_user_store_or_die(char *homedir)
179 FILE *fp;
180 char path[512], buff[512], *username, *key;
181 unsigned char pkey[crypto_box_pub_key_size];
182 int line = 1, ret;
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");
193 if (!fp)
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));
202 line++;
203 continue;
205 username = skips(buff);
206 key = username;
207 while (*key != ';' &&
208 *key != '\0' &&
209 *key != ' ' &&
210 *key != '\t')
211 key++;
212 if (*key != ';')
213 panic("Parse error! No key found in l.%d!\n", line);
214 *key = '\0';
215 key++;
216 if (*key == '\n')
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),
221 key, strlen(key)))
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();
234 elem->next = store;
235 strlcpy(elem->username, username, sizeof(elem->username));
236 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
237 ret = curve25519_proto_init(&elem->proto_inf,
238 elem->publickey,
239 sizeof(elem->publickey),
240 homedir, 1);
241 if (ret)
242 panic("Cannot init curve25519 proto on user!\n");
243 store = elem;
244 smp_wmb();
245 memset(buff, 0, sizeof(buff));
246 line++;
249 fclose(fp);
250 if (store == NULL)
251 panic("No registered clients found!\n");
252 rwlock_unlock(&store_lock);
254 init_sock_mapper();
255 init_sockaddr_mapper();
258 void dump_user_store(void)
260 int i;
261 struct user_store *elem;
263 rwlock_rd_lock(&store_lock);
264 elem = store;
265 while (elem) {
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)
270 elem->publickey[i]);
271 else
272 printf("%02x:", (unsigned char)
273 elem->publickey[i]);
274 elem = elem->next;
276 rwlock_unlock(&store_lock);
279 void destroy_user_store(void)
281 struct user_store *elem, *nelem = NULL;
283 rwlock_wr_lock(&store_lock);
284 elem = store;
285 while (elem) {
286 nelem = elem->next;
287 elem->next = NULL;
288 user_store_free(elem);
289 elem = nelem;
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)
300 int fd;
301 ssize_t ret;
302 uint32_t salt;
303 unsigned char h[crypto_hash_sha512_BYTES];
304 struct username_struct *us = (struct username_struct *) dst;
305 struct taia ts;
306 char *uname;
307 size_t uname_len;
309 if (dlen < sizeof(struct username_struct))
310 return -ENOMEM;
312 uname_len = 512;
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");
319 close(fd);
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));
326 taia_now(&ts);
328 us->salt = htonl(salt);
329 memcpy(us->hash, h, sizeof(us->hash));
330 taia_pack(us->taia, &ts);
332 xfree(uname);
333 return 0;
336 static struct taia tolerance_taia = {
337 .sec.x = 0,
338 .nano = 250000000ULL,
339 .atto = 0,
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;
347 char *uname;
348 size_t uname_len;
349 uint32_t salt;
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)) {
355 errno = ENOMEM;
356 return USERNAMES_ERR;
359 uname_len = 512;
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]))
370 not_same = 0;
371 else
372 not_same = 1;
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))
378 is_ts_good = 1;
379 else
380 is_ts_good = 0;
381 } else {
382 taia_sub(&sub_res, arrival_taia, &ts);
383 if (taia_less(&sub_res, &tolerance_taia))
384 is_ts_good = 1;
385 else
386 is_ts_good = 0;
389 if (!not_same && is_ts_good)
390 ret = USERNAMES_OK;
391 else if (!not_same && !is_ts_good)
392 ret = USERNAMES_TS;
393 else
394 ret = USERNAMES_NE;
396 xfree(uname);
397 return ret;
400 static int register_user_by_socket(int fd, struct curve25519_proto *proto)
402 void **pos;
403 struct sock_map_entry *entry;
405 rwlock_wr_lock(&sock_map_lock);
406 entry = xzmalloc(sizeof(*entry));
407 entry->fd = fd;
408 entry->proto = proto;
409 pos = insert_hash(entry->fd, entry, &sock_mapper);
410 if (pos) {
411 entry->next = (*pos);
412 (*pos) = entry;
414 rwlock_unlock(&sock_map_lock);
416 return 0;
419 static int register_user_by_sockaddr(int sock, struct curve25519_proto *proto)
421 return 0;
424 int try_register_user_by_socket(struct curve25519_struct *c,
425 char *src, size_t slen, int sock)
427 int ret = -1;
428 struct user_store *elem;
429 enum is_user_enum err;
430 struct taia arrival_tai;
432 rwlock_rd_lock(&store_lock);
433 elem = store;
434 taia_now(&arrival_tai);
435 while (elem) {
436 // clen = curve25519_decode(c, &elem->proto_inf,
437 // (unsigned char *) src,
438 // slen, &cbuff);
439 // printf("clen: %d\n", clen);
440 // if (clen <= 0)
441 // goto next;
442 err = username_msg_is_user((char *) src, slen,
443 elem->username,
444 strlen(elem->username) + 1,
445 &arrival_tai);
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);
450 break;
451 } else if (err == USERNAMES_TS)
452 break;
453 elem = elem->next;
455 rwlock_unlock(&store_lock);
457 return ret;
460 int try_register_user_by_sockaddr(struct curve25519_struct *c,
461 char *src, size_t slen,
462 struct sockaddr_storage *sa,
463 size_t sa_len)
465 return -1;
468 int get_user_by_socket(int fd, struct curve25519_proto **proto)
470 int ret = -1;
471 struct sock_map_entry *entry;
473 errno = 0;
474 rwlock_rd_lock(&sock_map_lock);
475 entry = lookup_hash(fd, &sock_mapper);
476 while (entry && fd != entry->fd)
477 entry = entry->next;
478 if (entry && fd == entry->fd) {
479 (*proto) = entry->proto;
480 ret = 0;
481 } else {
482 (*proto) = NULL;
483 errno = ENOENT;
485 rwlock_unlock(&sock_map_lock);
487 return ret;
490 int get_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len,
491 struct curve25519_proto **proto)
493 return -1;
496 static struct sock_map_entry *socket_to_sock_map_entry(int fd)
498 struct sock_map_entry *entry, *ret = NULL;
500 errno = 0;
501 rwlock_rd_lock(&sock_map_lock);
502 entry = lookup_hash(fd, &sock_mapper);
503 while (entry && fd != entry->fd)
504 entry = entry->next;
505 if (entry && fd == entry->fd)
506 ret = entry;
507 else
508 errno = ENOENT;
509 rwlock_unlock(&sock_map_lock);
511 return ret;
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)
520 return;
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)
524 pos = pos->next;
525 if (pos && pos->next && pos->next == entry)
526 pos->next = entry->next;
527 entry->next = NULL;
528 xfree(entry);
529 rwlock_unlock(&sock_map_lock);
532 void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len)