docs: minor: fix headline of mz
[netsniff-ng.git] / src / ct_servmgmt.c
bloba0e33ec32b49f127fe63ab415b99ef8064d8b73a
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 "built_in.h"
16 #include "locking.h"
17 #include "xmalloc.h"
18 #include "curvetun.h"
19 #include "xutils.h"
20 #include "curve.h"
21 #include "ct_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 int udp;
31 char alias[256];
32 char host[256];
33 char port[6]; /* 5 + \0 */
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;
41 static struct server_store *selected = NULL;
42 static struct rwlock store_lock;
44 static struct server_store *server_store_alloc(void)
46 return xzmalloc(sizeof(struct server_store));
49 static void server_store_free(struct server_store *ss)
51 if (!ss)
52 return;
53 memset(ss, 0, sizeof(struct server_store));
54 xfree(ss);
57 enum parse_states {
58 PARSE_ALIAS,
59 PARSE_SERVER,
60 PARSE_PORT,
61 PARSE_CARRIER,
62 PARSE_PUBKEY,
63 PARSE_DONE,
66 static int parse_line(char *line, char *homedir)
68 int ret;
69 char *str;
70 enum parse_states s = PARSE_ALIAS;
71 struct server_store *elem;
72 unsigned char pkey[crypto_box_pub_key_size];
74 elem = server_store_alloc();
75 elem->next = store;
77 str = strtok(line, ";");
78 for (; str != NULL;) {
79 switch (s) {
80 case PARSE_ALIAS:
81 strlcpy(elem->alias, str, sizeof(elem->alias));
82 s = PARSE_SERVER;
83 break;
84 case PARSE_SERVER:
85 strlcpy(elem->host, str, sizeof(elem->host));
86 s = PARSE_PORT;
87 break;
88 case PARSE_PORT:
89 strlcpy(elem->port, str, sizeof(elem->port));
90 s = PARSE_CARRIER;
91 break;
92 case PARSE_CARRIER:
93 if (!strncmp("udp", str, strlen("udp")))
94 elem->udp = 1;
95 else
96 elem->udp = 0;
97 s = PARSE_PUBKEY;
98 break;
99 case PARSE_PUBKEY:
100 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
101 str, strlen(str)))
102 return -EINVAL;
103 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
104 memcpy(elem->auth_token, pkey, sizeof(elem->auth_token));
105 ret = curve25519_proto_init(&elem->proto_inf,
106 elem->publickey,
107 sizeof(elem->publickey),
108 homedir, 1);
109 if (ret)
110 return -EIO;
111 s = PARSE_DONE;
112 break;
113 case PARSE_DONE:
114 break;
115 default:
116 return -EIO;
119 str = strtok(NULL, ";");
122 store = elem;
123 return s == PARSE_DONE ? 0 : -EIO;
126 void parse_userfile_and_generate_serv_store_or_die(char *homedir)
128 FILE *fp;
129 char path[PATH_MAX], buff[1024];
130 int line = 1, ret;
132 memset(path, 0, sizeof(path));
133 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS);
135 rwlock_init(&store_lock);
136 rwlock_wr_lock(&store_lock);
138 fp = fopen(path, "r");
139 if (!fp)
140 panic("Cannot open server file!\n");
142 memset(buff, 0, sizeof(buff));
143 while (fgets(buff, sizeof(buff), fp) != NULL) {
144 buff[sizeof(buff) - 1] = 0;
145 /* A comment. Skip this line */
146 if (buff[0] == '#' || buff[0] == '\n') {
147 memset(buff, 0, sizeof(buff));
148 line++;
149 continue;
152 ret = parse_line(buff, homedir);
153 if (ret < 0)
154 panic("Cannot parse line %d from clients!\n", line);
155 line++;
156 memset(buff, 0, sizeof(buff));
159 fclose(fp);
161 if (store == NULL)
162 panic("No registered servers found!\n");
164 rwlock_unlock(&store_lock);
167 void dump_serv_store(void)
169 int i;
170 struct server_store *elem;
172 rwlock_rd_lock(&store_lock);
173 elem = store;
174 while (elem) {
175 printf("[%s] -> %s:%s via %s -> ", elem->alias,
176 elem->host, elem->port,
177 elem->udp ? "udp" : "tcp");
178 for (i = 0; i < sizeof(elem->publickey); ++i)
179 if (i == (sizeof(elem->publickey) - 1))
180 printf("%02x\n", (unsigned char)
181 elem->publickey[i]);
182 else
183 printf("%02x:", (unsigned char)
184 elem->publickey[i]);
185 elem = elem->next;
187 rwlock_unlock(&store_lock);
190 void destroy_serv_store(void)
192 struct server_store *elem, *nelem = NULL;
194 rwlock_wr_lock(&store_lock);
195 selected = NULL;
196 elem = store;
197 while (elem) {
198 nelem = elem->next;
199 elem->next = NULL;
200 server_store_free(elem);
201 elem = nelem;
203 rwlock_unlock(&store_lock);
204 rwlock_destroy(&store_lock);
207 void get_serv_store_entry_by_alias(char *alias, size_t len,
208 char **host, char **port, int *udp)
210 struct server_store *elem;
212 rwlock_rd_lock(&store_lock);
213 elem = store;
214 if (!alias) {
215 while (elem && elem->next)
216 elem = elem->next;
217 if (elem) {
218 (*host) = elem->host;
219 (*port) = elem->port;
220 (*udp) = elem->udp;
221 selected = elem;
222 } else {
223 rwlock_unlock(&store_lock);
224 goto nothing;
226 } else {
227 while (elem) {
228 if (!strncmp(elem->alias, alias,
229 min(len, strlen(elem->alias) + 1)))
230 break;
231 elem = elem->next;
233 if (elem) {
234 (*host) = elem->host;
235 (*port) = elem->port;
236 (*udp) = elem->udp;
237 selected = elem;
238 } else {
239 rwlock_unlock(&store_lock);
240 goto nothing;
243 rwlock_unlock(&store_lock);
245 return;
246 nothing:
247 (*host) = NULL;
248 (*port) = NULL;
249 (*udp) = -1;
252 struct curve25519_proto *get_serv_store_entry_proto_inf(void)
254 struct curve25519_proto *ret = NULL;
256 rwlock_rd_lock(&store_lock);
257 if (selected)
258 ret = &selected->proto_inf;
259 rwlock_unlock(&store_lock);
261 return ret;
264 unsigned char *get_serv_store_entry_auth_token(void)
266 unsigned char *ret = NULL;
268 rwlock_rd_lock(&store_lock);
269 if (selected)
270 ret = selected->auth_token;
271 rwlock_unlock(&store_lock);
273 return ret;