Merge pull request #58 from electronjoe/a1cf780cccc4819eb360cda1e0e94e17935cb8c7
[netsniff-ng-old.git] / ct_servmgmt.c
bloba63eb5749271c9a5538a2a044a3ddac24a245075
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <limits.h>
12 #include <syslog.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 if (!strncmp("tcp", str, strlen("tcp")))
96 elem->udp = 0;
97 else {
98 syslog(LOG_ERR, "Incorrect carrier type !(udp|tcp) in server spec.\n");
99 return -EIO;
101 s = PARSE_PUBKEY;
102 break;
103 case PARSE_PUBKEY:
104 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
105 str, strlen(str)))
106 return -EINVAL;
107 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
108 memcpy(elem->auth_token, pkey, sizeof(elem->auth_token));
109 ret = curve25519_proto_init(&elem->proto_inf,
110 elem->publickey,
111 sizeof(elem->publickey),
112 homedir, 1);
113 if (ret)
114 return -EIO;
115 s = PARSE_DONE;
116 break;
117 case PARSE_DONE:
118 break;
119 default:
120 return -EIO;
123 str = strtok(NULL, ";");
126 store = elem;
127 return s == PARSE_DONE ? 0 : -EIO;
130 void parse_userfile_and_generate_serv_store_or_die(char *homedir)
132 FILE *fp;
133 char path[PATH_MAX], buff[1024];
134 int line = 1, ret;
136 memset(path, 0, sizeof(path));
137 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS);
139 rwlock_init(&store_lock);
140 rwlock_wr_lock(&store_lock);
142 fp = fopen(path, "r");
143 if (!fp)
144 panic("Cannot open server file!\n");
146 memset(buff, 0, sizeof(buff));
147 while (fgets(buff, sizeof(buff), fp) != NULL) {
148 buff[sizeof(buff) - 1] = 0;
149 /* A comment. Skip this line */
150 if (buff[0] == '#' || buff[0] == '\n') {
151 memset(buff, 0, sizeof(buff));
152 line++;
153 continue;
156 ret = parse_line(buff, homedir);
157 if (ret < 0)
158 panic("Cannot parse line %d from clients!\n", line);
159 line++;
160 memset(buff, 0, sizeof(buff));
163 fclose(fp);
165 if (store == NULL)
166 panic("No registered servers found!\n");
168 rwlock_unlock(&store_lock);
171 void dump_serv_store(void)
173 int i;
174 struct server_store *elem;
176 rwlock_rd_lock(&store_lock);
177 elem = store;
178 while (elem) {
179 printf("[%s] -> %s:%s via %s -> ", elem->alias,
180 elem->host, elem->port,
181 elem->udp ? "udp" : "tcp");
182 for (i = 0; i < sizeof(elem->publickey); ++i)
183 if (i == (sizeof(elem->publickey) - 1))
184 printf("%02x\n", (unsigned char)
185 elem->publickey[i]);
186 else
187 printf("%02x:", (unsigned char)
188 elem->publickey[i]);
189 elem = elem->next;
191 rwlock_unlock(&store_lock);
194 void destroy_serv_store(void)
196 struct server_store *elem, *nelem = NULL;
198 rwlock_wr_lock(&store_lock);
199 selected = NULL;
200 elem = store;
201 while (elem) {
202 nelem = elem->next;
203 elem->next = NULL;
204 server_store_free(elem);
205 elem = nelem;
207 rwlock_unlock(&store_lock);
208 rwlock_destroy(&store_lock);
211 void get_serv_store_entry_by_alias(char *alias, size_t len,
212 char **host, char **port, int *udp)
214 struct server_store *elem;
216 rwlock_rd_lock(&store_lock);
217 elem = store;
218 if (!alias) {
219 while (elem && elem->next)
220 elem = elem->next;
221 if (elem) {
222 (*host) = elem->host;
223 (*port) = elem->port;
224 (*udp) = elem->udp;
225 selected = elem;
226 } else {
227 rwlock_unlock(&store_lock);
228 goto nothing;
230 } else {
231 while (elem) {
232 if (!strncmp(elem->alias, alias,
233 min(len, strlen(elem->alias) + 1)))
234 break;
235 elem = elem->next;
237 if (elem) {
238 (*host) = elem->host;
239 (*port) = elem->port;
240 (*udp) = elem->udp;
241 selected = elem;
242 } else {
243 rwlock_unlock(&store_lock);
244 goto nothing;
247 rwlock_unlock(&store_lock);
249 return;
250 nothing:
251 (*host) = NULL;
252 (*port) = NULL;
253 (*udp) = -1;
256 struct curve25519_proto *get_serv_store_entry_proto_inf(void)
258 struct curve25519_proto *ret = NULL;
260 rwlock_rd_lock(&store_lock);
261 if (selected)
262 ret = &selected->proto_inf;
263 rwlock_unlock(&store_lock);
265 return ret;
268 unsigned char *get_serv_store_entry_auth_token(void)
270 unsigned char *ret = NULL;
272 rwlock_rd_lock(&store_lock);
273 if (selected)
274 ret = selected->auth_token;
275 rwlock_unlock(&store_lock);
277 return ret;