xio: refactor fopencookie related functions
[netsniff-ng.git] / ct_servmgmt.c
blob0d7da78434431ab64a6de3a33600c43a1006b625
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 "str.h"
16 #include "built_in.h"
17 #include "locking.h"
18 #include "xmalloc.h"
19 #include "curvetun.h"
20 #include "xutils.h"
21 #include "curve.h"
22 #include "ct_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 int udp;
32 char alias[256];
33 char host[256];
34 char port[6]; /* 5 + \0 */
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;
42 static struct server_store *selected = NULL;
43 static struct rwlock store_lock;
45 static struct server_store *server_store_alloc(void)
47 return xzmalloc(sizeof(struct server_store));
50 static void server_store_free(struct server_store *ss)
52 if (!ss)
53 return;
54 memset(ss, 0, sizeof(struct server_store));
55 xfree(ss);
58 enum parse_states {
59 PARSE_ALIAS,
60 PARSE_SERVER,
61 PARSE_PORT,
62 PARSE_CARRIER,
63 PARSE_PUBKEY,
64 PARSE_DONE,
67 static int parse_line(char *line, char *homedir)
69 int ret;
70 char *str;
71 enum parse_states s = PARSE_ALIAS;
72 struct server_store *elem;
73 unsigned char pkey[crypto_box_pub_key_size];
75 elem = server_store_alloc();
76 elem->next = store;
78 str = strtok(line, ";");
79 for (; str != NULL;) {
80 switch (s) {
81 case PARSE_ALIAS:
82 strlcpy(elem->alias, str, sizeof(elem->alias));
83 s = PARSE_SERVER;
84 break;
85 case PARSE_SERVER:
86 strlcpy(elem->host, str, sizeof(elem->host));
87 s = PARSE_PORT;
88 break;
89 case PARSE_PORT:
90 strlcpy(elem->port, str, sizeof(elem->port));
91 s = PARSE_CARRIER;
92 break;
93 case PARSE_CARRIER:
94 if (!strncmp("udp", str, strlen("udp")))
95 elem->udp = 1;
96 else if (!strncmp("tcp", str, strlen("tcp")))
97 elem->udp = 0;
98 else {
99 syslog(LOG_ERR, "Incorrect carrier type !(udp|tcp) in server spec.\n");
100 return -EIO;
102 s = PARSE_PUBKEY;
103 break;
104 case PARSE_PUBKEY:
105 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
106 str, strlen(str)))
107 return -EINVAL;
108 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
109 memcpy(elem->auth_token, pkey, sizeof(elem->auth_token));
110 ret = curve25519_proto_init(&elem->proto_inf,
111 elem->publickey,
112 sizeof(elem->publickey),
113 homedir, 1);
114 if (ret)
115 return -EIO;
116 s = PARSE_DONE;
117 break;
118 case PARSE_DONE:
119 break;
120 default:
121 return -EIO;
124 str = strtok(NULL, ";");
127 store = elem;
128 return s == PARSE_DONE ? 0 : -EIO;
131 void parse_userfile_and_generate_serv_store_or_die(char *homedir)
133 FILE *fp;
134 char path[PATH_MAX], buff[1024];
135 int line = 1, ret;
137 memset(path, 0, sizeof(path));
138 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS);
140 rwlock_init(&store_lock);
141 rwlock_wr_lock(&store_lock);
143 fp = fopen(path, "r");
144 if (!fp)
145 panic("Cannot open server file!\n");
147 memset(buff, 0, sizeof(buff));
148 while (fgets(buff, sizeof(buff), fp) != NULL) {
149 buff[sizeof(buff) - 1] = 0;
150 /* A comment. Skip this line */
151 if (buff[0] == '#' || buff[0] == '\n') {
152 memset(buff, 0, sizeof(buff));
153 line++;
154 continue;
157 ret = parse_line(buff, homedir);
158 if (ret < 0)
159 panic("Cannot parse line %d from clients!\n", line);
160 line++;
161 memset(buff, 0, sizeof(buff));
164 fclose(fp);
166 if (store == NULL)
167 panic("No registered servers found!\n");
169 rwlock_unlock(&store_lock);
172 void dump_serv_store(void)
174 int i;
175 struct server_store *elem;
177 rwlock_rd_lock(&store_lock);
178 elem = store;
179 while (elem) {
180 printf("[%s] -> %s:%s via %s -> ", elem->alias,
181 elem->host, elem->port,
182 elem->udp ? "udp" : "tcp");
183 for (i = 0; i < sizeof(elem->publickey); ++i)
184 if (i == (sizeof(elem->publickey) - 1))
185 printf("%02x\n", (unsigned char)
186 elem->publickey[i]);
187 else
188 printf("%02x:", (unsigned char)
189 elem->publickey[i]);
190 elem = elem->next;
192 rwlock_unlock(&store_lock);
195 void destroy_serv_store(void)
197 struct server_store *elem, *nelem = NULL;
199 rwlock_wr_lock(&store_lock);
200 selected = NULL;
201 elem = store;
202 while (elem) {
203 nelem = elem->next;
204 elem->next = NULL;
205 server_store_free(elem);
206 elem = nelem;
208 rwlock_unlock(&store_lock);
209 rwlock_destroy(&store_lock);
212 void get_serv_store_entry_by_alias(char *alias, size_t len,
213 char **host, char **port, int *udp)
215 struct server_store *elem;
217 rwlock_rd_lock(&store_lock);
218 elem = store;
219 if (!alias) {
220 while (elem && elem->next)
221 elem = elem->next;
222 if (elem) {
223 (*host) = elem->host;
224 (*port) = elem->port;
225 (*udp) = elem->udp;
226 selected = elem;
227 } else {
228 rwlock_unlock(&store_lock);
229 goto nothing;
231 } else {
232 while (elem) {
233 if (!strncmp(elem->alias, alias,
234 min(len, strlen(elem->alias) + 1)))
235 break;
236 elem = elem->next;
238 if (elem) {
239 (*host) = elem->host;
240 (*port) = elem->port;
241 (*udp) = elem->udp;
242 selected = elem;
243 } else {
244 rwlock_unlock(&store_lock);
245 goto nothing;
248 rwlock_unlock(&store_lock);
250 return;
251 nothing:
252 (*host) = NULL;
253 (*port) = NULL;
254 (*udp) = -1;
257 struct curve25519_proto *get_serv_store_entry_proto_inf(void)
259 struct curve25519_proto *ret = NULL;
261 rwlock_rd_lock(&store_lock);
262 if (selected)
263 ret = &selected->proto_inf;
264 rwlock_unlock(&store_lock);
266 return ret;
269 unsigned char *get_serv_store_entry_auth_token(void)
271 unsigned char *ret = NULL;
273 rwlock_rd_lock(&store_lock);
274 if (selected)
275 ret = selected->auth_token;
276 rwlock_unlock(&store_lock);
278 return ret;