man: improvements to language for flowtop.8
[netsniff-ng.git] / ct_servmgmt.c
blob38eb9c5331851de02c8662712e79e75e8d51d2d7
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 "curve.h"
21 #include "crypto.h"
22 #include "ct_servmgmt.h"
24 struct server_store {
25 int udp;
26 char alias[256];
27 char host[256];
28 char port[6]; /* 5 + \0 */
29 unsigned char publickey[crypto_box_pub_key_size];
30 struct curve25519_proto proto_inf;
31 unsigned char auth_token[crypto_auth_hmacsha512256_KEYBYTES];
32 struct server_store *next;
35 static struct server_store *store = NULL;
36 static struct server_store *selected = NULL;
37 static struct rwlock store_lock;
39 static struct server_store *server_store_alloc(void)
41 return xzmalloc(sizeof(struct server_store));
44 static void server_store_free(struct server_store *ss)
46 if (!ss)
47 return;
48 memset(ss, 0, sizeof(struct server_store));
49 xfree(ss);
52 enum parse_states {
53 PARSE_ALIAS,
54 PARSE_SERVER,
55 PARSE_PORT,
56 PARSE_CARRIER,
57 PARSE_PUBKEY,
58 PARSE_DONE,
61 static int parse_line(char *line, char *homedir)
63 int ret;
64 char *str;
65 enum parse_states s = PARSE_ALIAS;
66 struct server_store *elem;
67 unsigned char pkey[crypto_box_pub_key_size];
69 elem = server_store_alloc();
70 elem->next = store;
72 str = strtok(line, ";");
73 for (; str != NULL;) {
74 switch (s) {
75 case PARSE_ALIAS:
76 strlcpy(elem->alias, str, sizeof(elem->alias));
77 s = PARSE_SERVER;
78 break;
79 case PARSE_SERVER:
80 strlcpy(elem->host, str, sizeof(elem->host));
81 s = PARSE_PORT;
82 break;
83 case PARSE_PORT:
84 strlcpy(elem->port, str, sizeof(elem->port));
85 s = PARSE_CARRIER;
86 break;
87 case PARSE_CARRIER:
88 if (!strncmp("udp", str, strlen("udp")))
89 elem->udp = 1;
90 else if (!strncmp("tcp", str, strlen("tcp")))
91 elem->udp = 0;
92 else {
93 syslog(LOG_ERR, "Incorrect carrier type !(udp|tcp) in server spec.\n");
94 return -EIO;
96 s = PARSE_PUBKEY;
97 break;
98 case PARSE_PUBKEY:
99 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
100 str, strlen(str)))
101 return -EINVAL;
102 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
103 memcpy(elem->auth_token, pkey, sizeof(elem->auth_token));
104 ret = curve25519_proto_init(&elem->proto_inf,
105 elem->publickey,
106 sizeof(elem->publickey),
107 homedir, 1);
108 if (ret)
109 return -EIO;
110 s = PARSE_DONE;
111 break;
112 case PARSE_DONE:
113 break;
114 default:
115 return -EIO;
118 str = strtok(NULL, ";");
121 store = elem;
122 return s == PARSE_DONE ? 0 : -EIO;
125 void parse_userfile_and_generate_serv_store_or_die(char *homedir)
127 FILE *fp;
128 char path[PATH_MAX], buff[1024];
129 int line = 1, ret;
131 memset(path, 0, sizeof(path));
132 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS);
134 rwlock_init(&store_lock);
135 rwlock_wr_lock(&store_lock);
137 fp = fopen(path, "r");
138 if (!fp)
139 panic("Cannot open server file!\n");
141 memset(buff, 0, sizeof(buff));
142 while (fgets(buff, sizeof(buff), fp) != NULL) {
143 buff[sizeof(buff) - 1] = 0;
144 /* A comment. Skip this line */
145 if (buff[0] == '#' || buff[0] == '\n') {
146 memset(buff, 0, sizeof(buff));
147 line++;
148 continue;
151 ret = parse_line(buff, homedir);
152 if (ret < 0)
153 panic("Cannot parse line %d from clients!\n", line);
154 line++;
155 memset(buff, 0, sizeof(buff));
158 fclose(fp);
160 if (store == NULL)
161 panic("No registered servers found!\n");
163 rwlock_unlock(&store_lock);
166 void dump_serv_store(void)
168 int i;
169 struct server_store *elem;
171 rwlock_rd_lock(&store_lock);
172 elem = store;
173 while (elem) {
174 printf("[%s] -> %s:%s via %s -> ", elem->alias,
175 elem->host, elem->port,
176 elem->udp ? "udp" : "tcp");
177 for (i = 0; i < sizeof(elem->publickey); ++i)
178 if (i == (sizeof(elem->publickey) - 1))
179 printf("%02x\n", (unsigned char)
180 elem->publickey[i]);
181 else
182 printf("%02x:", (unsigned char)
183 elem->publickey[i]);
184 elem = elem->next;
186 rwlock_unlock(&store_lock);
189 void destroy_serv_store(void)
191 struct server_store *elem, *nelem = NULL;
193 rwlock_wr_lock(&store_lock);
194 selected = NULL;
195 elem = store;
196 while (elem) {
197 nelem = elem->next;
198 elem->next = NULL;
199 server_store_free(elem);
200 elem = nelem;
202 rwlock_unlock(&store_lock);
203 rwlock_destroy(&store_lock);
206 void get_serv_store_entry_by_alias(char *alias, size_t len,
207 char **host, char **port, int *udp)
209 struct server_store *elem;
211 rwlock_rd_lock(&store_lock);
212 elem = store;
213 if (!alias) {
214 while (elem && elem->next)
215 elem = elem->next;
216 if (elem) {
217 (*host) = elem->host;
218 (*port) = elem->port;
219 (*udp) = elem->udp;
220 selected = elem;
221 } else {
222 rwlock_unlock(&store_lock);
223 goto nothing;
225 } else {
226 while (elem) {
227 if (!strncmp(elem->alias, alias,
228 min(len, strlen(elem->alias) + 1)))
229 break;
230 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;
242 rwlock_unlock(&store_lock);
244 return;
245 nothing:
246 (*host) = NULL;
247 (*port) = NULL;
248 (*udp) = -1;
251 struct curve25519_proto *get_serv_store_entry_proto_inf(void)
253 struct curve25519_proto *ret = NULL;
255 rwlock_rd_lock(&store_lock);
256 if (selected)
257 ret = &selected->proto_inf;
258 rwlock_unlock(&store_lock);
260 return ret;
263 unsigned char *get_serv_store_entry_auth_token(void)
265 unsigned char *ret = NULL;
267 rwlock_rd_lock(&store_lock);
268 if (selected)
269 ret = selected->auth_token;
270 rwlock_unlock(&store_lock);
272 return ret;