ioops: Constify `name' parameter to tun_open_or_die()
[netsniff-ng.git] / curvetun_mgmt_servers.c
blobee6d7326a3863e55f62c17fcfd09aa0c1e7ddd15
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 "curvetun_mgmt_servers.h"
22 #include "crypto.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 char *str;
64 enum parse_states s = PARSE_ALIAS;
65 struct server_store *elem;
66 unsigned char pkey[crypto_box_pub_key_size];
68 elem = server_store_alloc();
69 elem->next = store;
71 str = strtok(line, ";");
72 for (; str != NULL;) {
73 switch (s) {
74 case PARSE_ALIAS:
75 strlcpy(elem->alias, str, sizeof(elem->alias));
76 s = PARSE_SERVER;
77 break;
78 case PARSE_SERVER:
79 strlcpy(elem->host, str, sizeof(elem->host));
80 s = PARSE_PORT;
81 break;
82 case PARSE_PORT:
83 strlcpy(elem->port, str, sizeof(elem->port));
84 s = PARSE_CARRIER;
85 break;
86 case PARSE_CARRIER:
87 if (!strncmp("udp", str, strlen("udp")))
88 elem->udp = 1;
89 else if (!strncmp("tcp", str, strlen("tcp")))
90 elem->udp = 0;
91 else {
92 syslog(LOG_ERR, "Incorrect carrier type !(udp|tcp) in server spec.\n");
93 return -EIO;
95 s = PARSE_PUBKEY;
96 break;
97 case PARSE_PUBKEY:
98 if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey),
99 str, strlen(str)))
100 return -EINVAL;
101 memcpy(elem->publickey, pkey, sizeof(elem->publickey));
102 memcpy(elem->auth_token, pkey, sizeof(elem->auth_token));
103 curve25519_proto_init(&elem->proto_inf, elem->publickey, sizeof(elem->publickey));
104 s = PARSE_DONE;
105 break;
106 case PARSE_DONE:
107 break;
108 default:
109 return -EIO;
112 str = strtok(NULL, ";");
115 store = elem;
116 return s == PARSE_DONE ? 0 : -EIO;
119 void parse_userfile_and_generate_serv_store_or_die(char *homedir)
121 FILE *fp;
122 char path[PATH_MAX], buff[1024];
123 int line = 1, ret;
125 memset(path, 0, sizeof(path));
126 slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS);
128 rwlock_init(&store_lock);
129 rwlock_wr_lock(&store_lock);
131 fp = fopen(path, "r");
132 if (!fp)
133 panic("Cannot open server file!\n");
135 memset(buff, 0, sizeof(buff));
136 while (fgets(buff, sizeof(buff), fp) != NULL) {
137 buff[sizeof(buff) - 1] = 0;
138 /* A comment. Skip this line */
139 if (buff[0] == '#' || buff[0] == '\n') {
140 memset(buff, 0, sizeof(buff));
141 line++;
142 continue;
145 ret = parse_line(buff, homedir);
146 if (ret < 0)
147 panic("Cannot parse line %d from clients!\n", line);
148 line++;
149 memset(buff, 0, sizeof(buff));
152 fclose(fp);
154 if (store == NULL)
155 panic("No registered servers found!\n");
157 rwlock_unlock(&store_lock);
160 void dump_serv_store(void)
162 int i;
163 struct server_store *elem;
165 rwlock_rd_lock(&store_lock);
166 elem = store;
167 while (elem) {
168 printf("[%s] -> %s:%s via %s -> ", elem->alias,
169 elem->host, elem->port,
170 elem->udp ? "udp" : "tcp");
171 for (i = 0; i < sizeof(elem->publickey); ++i)
172 if (i == (sizeof(elem->publickey) - 1))
173 printf("%02x\n", (unsigned char)
174 elem->publickey[i]);
175 else
176 printf("%02x:", (unsigned char)
177 elem->publickey[i]);
178 elem = elem->next;
180 rwlock_unlock(&store_lock);
183 void destroy_serv_store(void)
185 struct server_store *elem, *nelem = NULL;
187 rwlock_wr_lock(&store_lock);
188 selected = NULL;
189 elem = store;
190 while (elem) {
191 nelem = elem->next;
192 elem->next = NULL;
193 server_store_free(elem);
194 elem = nelem;
196 rwlock_unlock(&store_lock);
197 rwlock_destroy(&store_lock);
200 void get_serv_store_entry_by_alias(char *alias, size_t len,
201 char **host, char **port, int *udp)
203 struct server_store *elem;
205 rwlock_rd_lock(&store_lock);
206 elem = store;
207 if (!alias) {
208 while (elem && elem->next)
209 elem = elem->next;
210 if (elem) {
211 (*host) = elem->host;
212 (*port) = elem->port;
213 (*udp) = elem->udp;
214 selected = elem;
215 } else {
216 rwlock_unlock(&store_lock);
217 goto nothing;
219 } else {
220 while (elem) {
221 if (!strncmp(elem->alias, alias,
222 min(len, strlen(elem->alias) + 1)))
223 break;
224 elem = elem->next;
226 if (elem) {
227 (*host) = elem->host;
228 (*port) = elem->port;
229 (*udp) = elem->udp;
230 selected = elem;
231 } else {
232 rwlock_unlock(&store_lock);
233 goto nothing;
236 rwlock_unlock(&store_lock);
238 return;
239 nothing:
240 (*host) = NULL;
241 (*port) = NULL;
242 (*udp) = -1;
245 struct curve25519_proto *get_serv_store_entry_proto_inf(void)
247 struct curve25519_proto *ret = NULL;
249 rwlock_rd_lock(&store_lock);
250 if (selected)
251 ret = &selected->proto_inf;
252 rwlock_unlock(&store_lock);
254 return ret;
257 unsigned char *get_serv_store_entry_auth_token(void)
259 unsigned char *ret = NULL;
261 rwlock_rd_lock(&store_lock);
262 if (selected)
263 ret = selected->auth_token;
264 rwlock_unlock(&store_lock);
266 return ret;