Added BPF attach/detach support check.
[netsniff-ng.git] / src / servmgmt.c
blob04d419cf6aa0c52f27687080c7a2253e68f8a52d
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 "parser.h"
17 #include "locking.h"
18 #include "xmalloc.h"
19 #include "curvetun.h"
20 #include "strlcpy.h"
21 #include "curve.h"
22 #include "servmgmt.h"
23 #include "crypto_box_curve25519xsalsa20poly1305.h"
24 #include "crypto_auth_hmacsha512256.h"
26 #define crypto_box_pub_key_size crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
28 /* Config line format: alias;serverip|servername;port;udp|tcp;pubkey\n */
30 struct server_store {
31 char alias[256];
32 char host[256];
33 char port[6]; /* 5 + \0 */
34 int udp;
35 unsigned char publickey[crypto_box_pub_key_size];
36 struct curve25519_proto proto_inf;
37 unsigned char auth_token[crypto_auth_hmacsha512256_KEYBYTES];
38 struct server_store *next;
41 static struct server_store *store = NULL;
43 static struct server_store *selected = NULL;
45 static struct rwlock store_lock;
47 static struct server_store *server_store_alloc(void)
49 return xzmalloc(sizeof(struct server_store));
52 static void server_store_free(struct server_store *ss)
54 if (!ss)
55 return;
56 memset(ss, 0, sizeof(struct server_store));
57 xfree(ss);
60 void parse_userfile_and_generate_serv_store_or_die(char *homedir)
62 FILE *fp;
63 char path[PATH_MAX], buff[1024], *alias, *host, *port, *udp, *key;
64 unsigned char pkey[crypto_box_pub_key_size];
65 int line = 1, __udp = 0, ret;
66 struct server_store *elem;
68 memset(path, 0, sizeof(path));
69 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS);
71 rwlock_init(&store_lock);
72 rwlock_wr_lock(&store_lock);
74 fp = fopen(path, "r");
75 if (!fp)
76 panic("Cannot open server file!\n");
77 memset(buff, 0, sizeof(buff));
79 /* TODO: this is huge crap. needs to be rewritten! */
80 while (fgets(buff, sizeof(buff), fp) != NULL) {
81 buff[sizeof(buff) - 1] = 0;
82 /* A comment. Skip this line */
83 if (buff[0] == '#' || buff[0] == '\n') {
84 memset(buff, 0, sizeof(buff));
85 line++;
86 continue;
88 alias = skips(buff);
89 host = alias;
90 while (*host != ';' &&
91 *host != '\0' &&
92 *host != ' ' &&
93 *host != '\t')
94 host++;
95 if (*host != ';')
96 panic("Parse error! No alias found in l.%d!\n", line);
97 *host = '\0';
98 host++;
99 if (*host == '\n')
100 panic("Parse error! No host found in l.%d!\n", line);
101 port = host;
102 while (*port != ';' &&
103 *port != '\0' &&
104 *port != ' ' &&
105 *port != '\t')
106 port++;
107 if (*port != ';')
108 panic("Parse error! No host found in l.%d!\n", line);
109 *port = '\0';
110 port++;
111 if (*port == '\n')
112 panic("Parse error! No port found in l.%d!\n", line);
113 udp = port;
114 while (*udp != ';' &&
115 *udp != '\0' &&
116 *udp != ' ' &&
117 *udp != '\t')
118 udp++;
119 if (*udp != ';')
120 panic("Parse error! No port found in l.%d!\n", line);
121 *udp = '\0';
122 udp++;
123 if (*udp == '\n')
124 panic("Parse error! No udp|tcp found in l.%d!\n", line);
125 if (udp[0] == 'u' && udp[1] == 'd' && udp[2] == 'p')
126 __udp = 1;
127 else if (udp[0] == 't' && udp[1] == 'c' && udp[2] == 'p')
128 __udp = 0;
129 else
130 panic("Parse error! No udp|tcp found in l.%d!\n", line);
131 udp += 3;
132 if (*udp != ';')
133 panic("Parse error! No key found in l.%d!\n", line);
134 *udp = '\0';
135 udp++;
136 if (*udp == '\n')
137 panic("Parse error! No key found in l.%d!\n", line);
138 key = udp;
139 key[strlen(key) - 1] = 0;
140 memset(pkey, 0, sizeof(pkey));
141 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
142 key, strlen(key)))
143 panic("Parse error! No key found in l.%d!\n", line);
145 if (strlen(alias) + 1 > sizeof(elem->alias))
146 panic("Alias too long in l.%d!\n", line);
147 if (strlen(host) + 1 > sizeof(elem->host))
148 panic("Host too long in l.%d!\n", line);
149 if (strlen(port) + 1 > sizeof(elem->port))
150 panic("Port too long in l.%d!\n", line);
151 if (strstr(alias, " ") || strstr(alias, "\t"))
152 panic("Alias consists of whitespace in l.%d!\n", line);
153 if (strstr(host, " ") || strstr(host, "\t"))
154 panic("Host consists of whitespace in l.%d!\n", line);
155 if (strstr(port, " ") || strstr(port, "\t"))
156 panic("Port consists of whitespace in l.%d!\n", line);
158 elem = server_store_alloc();
159 elem->next = store;
160 elem->udp = __udp;
161 strlcpy(elem->alias, alias, sizeof(elem->alias));
162 strlcpy(elem->host, host, sizeof(elem->host));
163 strlcpy(elem->port, port, sizeof(elem->port));
164 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
165 memcpy(elem->auth_token, elem->publickey, sizeof(elem->auth_token));
166 ret = curve25519_proto_init(&elem->proto_inf,
167 elem->publickey,
168 sizeof(elem->publickey),
169 homedir, 0);
170 if (ret)
171 panic("Cannot init curve25519 proto on server!\n");
172 store = elem;
173 smp_wmb();
174 memset(buff, 0, sizeof(buff));
175 line++;
178 fclose(fp);
179 if (store == NULL)
180 panic("No registered servers found!\n");
181 rwlock_unlock(&store_lock);
184 void dump_serv_store(void)
186 int i;
187 struct server_store *elem;
189 rwlock_rd_lock(&store_lock);
190 elem = store;
191 while (elem) {
192 printf("[%s] -> %s:%s via %s -> ", elem->alias,
193 elem->host, elem->port,
194 elem->udp ? "udp" : "tcp");
195 for (i = 0; i < sizeof(elem->publickey); ++i)
196 if (i == (sizeof(elem->publickey) - 1))
197 printf("%02x\n", (unsigned char)
198 elem->publickey[i]);
199 else
200 printf("%02x:", (unsigned char)
201 elem->publickey[i]);
202 elem = elem->next;
204 rwlock_unlock(&store_lock);
207 void destroy_serv_store(void)
209 struct server_store *elem, *nelem = NULL;
211 rwlock_wr_lock(&store_lock);
212 selected = NULL;
213 elem = store;
214 while (elem) {
215 nelem = elem->next;
216 elem->next = NULL;
217 server_store_free(elem);
218 elem = nelem;
220 rwlock_unlock(&store_lock);
221 rwlock_destroy(&store_lock);
224 void get_serv_store_entry_by_alias(char *alias, size_t len,
225 char **host, char **port, int *udp)
227 struct server_store *elem;
229 rwlock_rd_lock(&store_lock);
230 elem = store;
231 if (!alias) {
232 while (elem && elem->next)
233 elem = elem->next;
234 if (elem) {
235 (*host) = elem->host;
236 (*port) = elem->port;
237 (*udp) = elem->udp;
238 selected = elem;
239 } else {
240 rwlock_unlock(&store_lock);
241 goto nothing;
243 } else {
244 while (elem) {
245 if (!strncmp(elem->alias, alias,
246 min(len, strlen(elem->alias) + 1)))
247 break;
248 elem = elem->next;
250 if (elem) {
251 (*host) = elem->host;
252 (*port) = elem->port;
253 (*udp) = elem->udp;
254 selected = elem;
255 } else {
256 rwlock_unlock(&store_lock);
257 goto nothing;
260 rwlock_unlock(&store_lock);
261 return;
262 nothing:
263 (*host) = NULL;
264 (*port) = NULL;
265 (*udp) = -1;
268 struct curve25519_proto *get_serv_store_entry_proto_inf(void)
270 struct curve25519_proto *ret = NULL;
271 rwlock_rd_lock(&store_lock);
272 if (selected)
273 ret = &selected->proto_inf;
274 rwlock_unlock(&store_lock);
275 return ret;
278 unsigned char *get_serv_store_entry_auth_token(void)
280 unsigned char *ret = NULL;
281 rwlock_rd_lock(&store_lock);
282 if (selected)
283 ret = selected->auth_token;
284 rwlock_unlock(&store_lock);
285 return ret;