docs: Added note to curvetun doc
[netsniff-ng.git] / src / servmgmt.c
blob152d406a31470081e4ceaba0a31cad6e6d5c5354
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, version 2.
6 */
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <limits.h>
14 #include "die.h"
15 #include "compiler.h"
16 #include "locking.h"
17 #include "xmalloc.h"
18 #include "curvetun.h"
19 #include "xstring.h"
20 #include "curve.h"
21 #include "servmgmt.h"
22 #include "crypto_box_curve25519xsalsa20poly1305.h"
23 #include "crypto_auth_hmacsha512256.h"
25 #define crypto_box_pub_key_size crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
27 /* Config line format: alias;serverip|servername;port;udp|tcp;pubkey\n */
29 struct server_store {
30 char alias[256];
31 char host[256];
32 char port[6]; /* 5 + \0 */
33 int udp;
34 unsigned char publickey[crypto_box_pub_key_size];
35 struct curve25519_proto proto_inf;
36 unsigned char auth_token[crypto_auth_hmacsha512256_KEYBYTES];
37 struct server_store *next;
40 static struct server_store *store = NULL;
42 static struct server_store *selected = NULL;
44 static struct rwlock store_lock;
46 static struct server_store *server_store_alloc(void)
48 return xzmalloc(sizeof(struct server_store));
51 static void server_store_free(struct server_store *ss)
53 if (!ss)
54 return;
55 memset(ss, 0, sizeof(struct server_store));
56 xfree(ss);
59 void parse_userfile_and_generate_serv_store_or_die(char *homedir)
61 FILE *fp;
62 char path[PATH_MAX], buff[1024], *alias, *host, *port, *udp, *key;
63 unsigned char pkey[crypto_box_pub_key_size];
64 int line = 1, __udp = 0, ret;
65 struct server_store *elem;
67 memset(path, 0, sizeof(path));
68 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS);
70 rwlock_init(&store_lock);
71 rwlock_wr_lock(&store_lock);
73 fp = fopen(path, "r");
74 if (!fp)
75 panic("Cannot open server file!\n");
76 memset(buff, 0, sizeof(buff));
78 /* TODO: this is huge crap. needs to be rewritten! */
79 while (fgets(buff, sizeof(buff), fp) != NULL) {
80 buff[sizeof(buff) - 1] = 0;
81 /* A comment. Skip this line */
82 if (buff[0] == '#' || buff[0] == '\n') {
83 memset(buff, 0, sizeof(buff));
84 line++;
85 continue;
87 alias = skips(buff);
88 host = alias;
89 while (*host != ';' &&
90 *host != '\0' &&
91 *host != ' ' &&
92 *host != '\t')
93 host++;
94 if (*host != ';')
95 panic("Parse error! No alias found in l.%d!\n", line);
96 *host = '\0';
97 host++;
98 if (*host == '\n')
99 panic("Parse error! No host found in l.%d!\n", line);
100 port = host;
101 while (*port != ';' &&
102 *port != '\0' &&
103 *port != ' ' &&
104 *port != '\t')
105 port++;
106 if (*port != ';')
107 panic("Parse error! No host found in l.%d!\n", line);
108 *port = '\0';
109 port++;
110 if (*port == '\n')
111 panic("Parse error! No port found in l.%d!\n", line);
112 udp = port;
113 while (*udp != ';' &&
114 *udp != '\0' &&
115 *udp != ' ' &&
116 *udp != '\t')
117 udp++;
118 if (*udp != ';')
119 panic("Parse error! No port found in l.%d!\n", line);
120 *udp = '\0';
121 udp++;
122 if (*udp == '\n')
123 panic("Parse error! No udp|tcp found in l.%d!\n", line);
124 if (udp[0] == 'u' && udp[1] == 'd' && udp[2] == 'p')
125 __udp = 1;
126 else if (udp[0] == 't' && udp[1] == 'c' && udp[2] == 'p')
127 __udp = 0;
128 else
129 panic("Parse error! No udp|tcp found in l.%d!\n", line);
130 udp += 3;
131 if (*udp != ';')
132 panic("Parse error! No key found in l.%d!\n", line);
133 *udp = '\0';
134 udp++;
135 if (*udp == '\n')
136 panic("Parse error! No key found in l.%d!\n", line);
137 key = udp;
138 key[strlen(key) - 1] = 0;
139 memset(pkey, 0, sizeof(pkey));
140 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
141 key, strlen(key)))
142 panic("Parse error! No key found in l.%d!\n", line);
144 if (strlen(alias) + 1 > sizeof(elem->alias))
145 panic("Alias too long in l.%d!\n", line);
146 if (strlen(host) + 1 > sizeof(elem->host))
147 panic("Host too long in l.%d!\n", line);
148 if (strlen(port) + 1 > sizeof(elem->port))
149 panic("Port too long in l.%d!\n", line);
150 if (strstr(alias, " ") || strstr(alias, "\t"))
151 panic("Alias consists of whitespace in l.%d!\n", line);
152 if (strstr(host, " ") || strstr(host, "\t"))
153 panic("Host consists of whitespace in l.%d!\n", line);
154 if (strstr(port, " ") || strstr(port, "\t"))
155 panic("Port consists of whitespace in l.%d!\n", line);
157 elem = server_store_alloc();
158 elem->next = store;
159 elem->udp = __udp;
160 strlcpy(elem->alias, alias, sizeof(elem->alias));
161 strlcpy(elem->host, host, sizeof(elem->host));
162 strlcpy(elem->port, port, sizeof(elem->port));
163 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
164 memcpy(elem->auth_token, elem->publickey, sizeof(elem->auth_token));
165 ret = curve25519_proto_init(&elem->proto_inf,
166 elem->publickey,
167 sizeof(elem->publickey),
168 homedir, 0);
169 if (ret)
170 panic("Cannot init curve25519 proto on server!\n");
171 store = elem;
172 memset(buff, 0, sizeof(buff));
173 line++;
176 fclose(fp);
177 if (store == NULL)
178 panic("No registered servers found!\n");
179 rwlock_unlock(&store_lock);
182 void dump_serv_store(void)
184 int i;
185 struct server_store *elem;
187 rwlock_rd_lock(&store_lock);
188 elem = store;
189 while (elem) {
190 printf("[%s] -> %s:%s via %s -> ", elem->alias,
191 elem->host, elem->port,
192 elem->udp ? "udp" : "tcp");
193 for (i = 0; i < sizeof(elem->publickey); ++i)
194 if (i == (sizeof(elem->publickey) - 1))
195 printf("%02x\n", (unsigned char)
196 elem->publickey[i]);
197 else
198 printf("%02x:", (unsigned char)
199 elem->publickey[i]);
200 elem = elem->next;
202 rwlock_unlock(&store_lock);
205 void destroy_serv_store(void)
207 struct server_store *elem, *nelem = NULL;
209 rwlock_wr_lock(&store_lock);
210 selected = NULL;
211 elem = store;
212 while (elem) {
213 nelem = elem->next;
214 elem->next = NULL;
215 server_store_free(elem);
216 elem = nelem;
218 rwlock_unlock(&store_lock);
219 rwlock_destroy(&store_lock);
222 void get_serv_store_entry_by_alias(char *alias, size_t len,
223 char **host, char **port, int *udp)
225 struct server_store *elem;
227 rwlock_rd_lock(&store_lock);
228 elem = store;
229 if (!alias) {
230 while (elem && elem->next)
231 elem = elem->next;
232 if (elem) {
233 (*host) = elem->host;
234 (*port) = elem->port;
235 (*udp) = elem->udp;
236 selected = elem;
237 } else {
238 rwlock_unlock(&store_lock);
239 goto nothing;
241 } else {
242 while (elem) {
243 if (!strncmp(elem->alias, alias,
244 min(len, strlen(elem->alias) + 1)))
245 break;
246 elem = elem->next;
248 if (elem) {
249 (*host) = elem->host;
250 (*port) = elem->port;
251 (*udp) = elem->udp;
252 selected = elem;
253 } else {
254 rwlock_unlock(&store_lock);
255 goto nothing;
258 rwlock_unlock(&store_lock);
259 return;
260 nothing:
261 (*host) = NULL;
262 (*port) = NULL;
263 (*udp) = -1;
266 struct curve25519_proto *get_serv_store_entry_proto_inf(void)
268 struct curve25519_proto *ret = NULL;
269 rwlock_rd_lock(&store_lock);
270 if (selected)
271 ret = &selected->proto_inf;
272 rwlock_unlock(&store_lock);
273 return ret;
276 unsigned char *get_serv_store_entry_auth_token(void)
278 unsigned char *ret = NULL;
279 rwlock_rd_lock(&store_lock);
280 if (selected)
281 ret = selected->auth_token;
282 rwlock_unlock(&store_lock);
283 return ret;