ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
(Generate patch)

Comparing gvpe/src/conf.C (file contents):
Revision 1.16 by pcg, Tue Oct 14 03:22:09 2003 UTC vs.
Revision 1.42 by pcg, Mon Dec 5 12:58:08 2005 UTC

1/* 1/*
2 conf.c -- configuration code 2 conf.c -- configuration code
3 Copyright (C) 1998 Robert van der Meulen 3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de>
4 1998-2002 Ivo Timmermans <ivo@o2w.nl>
5 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
6 2000 Cris van Pelt <tribbel@arise.dhs.org>
7 2003 Marc Lehmann <pcg@goof.com>
8 4
5 This file is part of GVPE.
6
9 This program is free software; you can redistribute it and/or modify 7 GVPE is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or 9 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version. 10 (at your option) any later version.
13 11
14 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details. 15 GNU General Public License for more details.
18 16
19 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software 18 along with gvpe; if not, write to the Free Software
21 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22*/ 20*/
23 21
24#include "config.h" 22#include "config.h"
25 23
26#include <cstdio> 24#include <cstdio>
31#include <netdb.h> 29#include <netdb.h>
32#include <sys/stat.h> 30#include <sys/stat.h>
33#include <sys/types.h> 31#include <sys/types.h>
34#include <unistd.h> 32#include <unistd.h>
35 33
36#include <netinet/in.h> 34#include "netcompat.h"
37#include <arpa/inet.h>
38#ifdef ENABLE_ICMP
39# ifdef HAVE_NETINET_IN_SYSTM_H
40# include <netinet/in_systm.h>
41# endif
42# ifdef HAVE_NETINET_IP_H
43# include <netinet/ip.h>
44# endif
45# include <netinet/ip_icmp.h>
46#endif
47 35
48#include <openssl/err.h> 36#include <openssl/err.h>
49#include <openssl/pem.h> 37#include <openssl/pem.h>
50#include <openssl/rsa.h> 38#include <openssl/rsa.h>
51#include <openssl/rand.h> 39#include <openssl/rand.h>
52 40#include <openssl/bn.h>
53#include "gettext.h"
54 41
55#include "conf.h" 42#include "conf.h"
56#include "slog.h" 43#include "slog.h"
57#include "util.h" 44#include "util.h"
58 45
59char *confbase; 46char *confbase;
60char *thisnode; 47char *thisnode;
61char *identname; 48char *identname;
62char *pidfilename;
63 49
64struct configuration conf; 50struct configuration conf;
65 51
66u8 best_protocol (u8 protset) 52u8 best_protocol (u8 protset)
67{ 53{
68 if (protset & PROT_IPv4 ) return PROT_IPv4; 54 if (protset & PROT_IPv4 ) return PROT_IPv4;
69 if (protset & PROT_ICMPv4) return PROT_ICMPv4; 55 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
70 if (protset & PROT_UDPv4 ) return PROT_UDPv4; 56 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
71 if (protset & PROT_TCPv4 ) return PROT_TCPv4; 57 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
58 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
72 59
73 return 0; 60 return 0;
74} 61}
75 62
76const char *strprotocol (u8 protocol) 63const char *strprotocol (u8 protocol)
77{ 64{
78 if (protocol & PROT_IPv4 ) return "rawip"; 65 if (protocol & PROT_IPv4 ) return "rawip";
79 if (protocol & PROT_ICMPv4) return "icmp"; 66 if (protocol & PROT_ICMPv4) return "icmp";
80 if (protocol & PROT_UDPv4 ) return "udp"; 67 if (protocol & PROT_UDPv4 ) return "udp";
81 if (protocol & PROT_TCPv4 ) return "tcp"; 68 if (protocol & PROT_TCPv4 ) return "tcp";
69 if (protocol & PROT_DNSv4 ) return "dns";
82 70
83 return "<unknown>"; 71 return "<unknown>";
72}
73
74static bool
75match_list (const vector<const char *> &list, const char *str)
76{
77 for (vector<const char *>::const_iterator i = list.end (); i-- > list.begin (); )
78 if ((*i)[0] == '*' && !(*i)[1])
79 return true;
80 else if (!strcmp (*i, str))
81 return true;
82
83 return false;
84}
85
86bool
87conf_node::can_direct (struct conf_node *other)
88{
89 if (match_list (allow_direct, other->nodename))
90 return true;
91
92 if (match_list (deny_direct, other->nodename))
93 return false;
94
95 return true;
84} 96}
85 97
86void 98void
87conf_node::print () 99conf_node::print ()
88{ 100{
100 ); 112 );
101} 113}
102 114
103conf_node::~conf_node () 115conf_node::~conf_node ()
104{ 116{
117#if 0
118 // does not work, because string pointers etc. are shared
119 // is not called, however
105 if (rsa_key) 120 if (rsa_key)
106 RSA_free (rsa_key); 121 RSA_free (rsa_key);
107 122
108 free (nodename); 123 free (nodename);
109 free (hostname); 124 free (hostname);
125 free (if_up_data);
126#if ENABLE_DNS
127 free (domain);
128 free (dns_hostname);
129#endif
130#endif
110} 131}
111 132
112void configuration::init () 133void configuration::init ()
113{ 134{
114 memset (this, 0, sizeof (*this)); 135 memset (this, 0, sizeof (*this));
115 136
137 mtu = DEFAULT_MTU;
116 rekey = DEFAULT_REKEY; 138 rekey = DEFAULT_REKEY;
117 keepalive = DEFAULT_KEEPALIVE; 139 keepalive = DEFAULT_KEEPALIVE;
118 llevel = L_INFO; 140 llevel = L_INFO;
119 ip_proto = IPPROTO_GRE; 141 ip_proto = IPPROTO_GRE;
120#if ENABLE_ICMP 142#if ENABLE_ICMP
121 icmp_type = ICMP_ECHOREPLY; 143 icmp_type = ICMP_ECHOREPLY;
122#endif 144#endif
123 145
124 default_node.udp_port = DEFAULT_UDPPORT; 146 default_node.udp_port = DEFAULT_UDPPORT;
125 default_node.tcp_port = DEFAULT_UDPPORT; 147 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm
126 default_node.connectmode = conf_node::C_ALWAYS; 148 default_node.connectmode = conf_node::C_ALWAYS;
127 default_node.compress = true; 149 default_node.compress = true;
128 default_node.protocols = PROT_UDPv4; 150 default_node.protocols = 0;
151 default_node.max_retry = DEFAULT_MAX_RETRY;
152 default_node.if_up_data = strdup ("");
153
154#if ENABLE_DNS
155 default_node.dns_port = 0; // default is 0 == client
156
157 dns_forw_host = strdup ("127.0.0.1");
158 dns_forw_port = 53;
159 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
160 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
161 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
162 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING;
163#endif
164
165 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
129} 166}
130 167
131void configuration::cleanup() 168void configuration::cleanup()
132{ 169{
133 if (rsa_key) 170 if (rsa_key)
134 RSA_free (rsa_key); 171 RSA_free (rsa_key);
135 172
136 rsa_key = 0; 173 rsa_key = 0;
137 174
175 free (pidfilename); pidfilename = 0;
138 free (ifname); ifname = 0; 176 free (ifname); ifname = 0;
139#if ENABLE_HTTP_PROXY 177#if ENABLE_HTTP_PROXY
140 free (proxy_host); proxy_host = 0; 178 free (proxy_host); proxy_host = 0;
141 free (proxy_auth); proxy_auth = 0; 179 free (proxy_auth); proxy_auth = 0;
180#endif
181#if ENABLE_DNS
182 free (dns_forw_host); dns_forw_host = 0;
142#endif 183#endif
143} 184}
144 185
145void 186void
146configuration::clear_config () 187configuration::clear ()
147{ 188{
148 for (configuration::node_vector::iterator i = nodes.begin(); i != nodes.end(); ++i) 189 for (configuration::node_vector::iterator i = nodes.begin(); i != nodes.end(); ++i)
149 delete *i; 190 delete *i;
150 191
151 nodes.clear (); 192 nodes.clear ();
152 193
153 cleanup (); 194 cleanup ();
154 init (); 195 init ();
155} 196}
156 197
157#define parse_bool(target,name,trueval,falseval) \ 198#define parse_bool(target,name,trueval,falseval) do { \
158 if (!strcmp (val, "yes")) target = trueval; \ 199 if (!strcmp (val, "yes")) target = trueval; \
159 else if (!strcmp (val, "no")) target = falseval; \ 200 else if (!strcmp (val, "no")) target = falseval; \
160 else if (!strcmp (val, "true")) target = trueval; \ 201 else if (!strcmp (val, "true")) target = trueval; \
161 else if (!strcmp (val, "false")) target = falseval; \ 202 else if (!strcmp (val, "false")) target = falseval; \
162 else if (!strcmp (val, "on")) target = trueval; \ 203 else if (!strcmp (val, "on")) target = trueval; \
163 else if (!strcmp (val, "off")) target = falseval; \ 204 else if (!strcmp (val, "off")) target = falseval; \
164 else \ 205 else \
165 slog (L_WARN, \ 206 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \
166 _("illegal value for '%s', only 'yes|true|on' or 'no|false|off' allowed, at '%s' line %d"), \ 207} while (0)
167 name, var, fname, lineno);
168 208
169void configuration::read_config (bool need_keys) 209const char *
210configuration_parser::parse_line (char *line)
211{
212 {
213 char *end = line + strlen (line);
214
215 while (*end < ' ' && end >= line)
216 end--;
217
218 *++end = 0;
219 }
220
221 char *tok = line;
222 const char *var = strtok (tok, "\t =");
223 tok = 0;
224
225 if (!var || !var[0])
226 return 0; /* no tokens on this line */
227
228 if (var[0] == '#')
229 return 0; /* comment: ignore */
230
231 char *val = strtok (NULL, "\t\n\r =");
232
233 if (!val || val[0] == '#')
234 return _("no value given for variable. (ignored)");
235
236 if (!strcmp (var, "on"))
237 {
238 if (!::thisnode
239 || (val[0] == '!' && strcmp (val + 1, ::thisnode))
240 || !strcmp (val, ::thisnode))
241 return parse_line (strtok (NULL, "\n\r"));
242 else
243 return 0;
244 }
245
246 // truly global
247 if (!strcmp (var, "loglevel"))
248 {
249 loglevel l = string_to_loglevel (val);
250
251 if (l == L_NONE)
252 return _("unknown loglevel. (skipping)");
253 }
254 else if (!strcmp (var, "ip-proto"))
255 conf.ip_proto = atoi (val);
256 else if (!strcmp (var, "icmp-type"))
257 {
258#if ENABLE_ICMP
259 conf.icmp_type = atoi (val);
260#endif
261 }
262
263 // per config
264 else if (!strcmp (var, "node"))
265 {
266 parse_argv ();
267
268 conf.default_node.id++;
269 node = new conf_node (conf.default_node);
270 conf.nodes.push_back (node);
271 node->nodename = strdup (val);
272
273 {
274 char *fname;
275 FILE *f;
276
277 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
278
279 f = fopen (fname, "r");
280 if (f)
281 {
282 node->rsa_key = RSA_new ();
283
284 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
285 {
286 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
287 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
288 exit (EXIT_FAILURE);
289 }
290
291 require (RSA_blinding_on (node->rsa_key, 0));
292
293 fclose (f);
294 }
295 else
296 {
297 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
298
299 if (need_keys)
300 exit (EXIT_FAILURE);
301 }
302
303 free (fname);
304 }
305
306 if (::thisnode && !strcmp (node->nodename, ::thisnode))
307 conf.thisnode = node;
308 }
309 else if (!strcmp (var, "private-key"))
310 free (conf.prikeyfile), conf.prikeyfile = strdup (val);
311 else if (!strcmp (var, "ifpersist"))
312 parse_bool (conf.ifpersist, "ifpersist", true, false);
313 else if (!strcmp (var, "ifname"))
314 free (conf.ifname), conf.ifname = strdup (val);
315 else if (!strcmp (var, "rekey"))
316 conf.rekey = atoi (val);
317 else if (!strcmp (var, "keepalive"))
318 conf.keepalive = atoi (val);
319 else if (!strcmp (var, "mtu"))
320 conf.mtu = atoi (val);
321 else if (!strcmp (var, "if-up"))
322 free (conf.script_if_up), conf.script_if_up = strdup (val);
323 else if (!strcmp (var, "node-up"))
324 free (conf.script_node_up), conf.script_node_up = strdup (val);
325 else if (!strcmp (var, "node-down"))
326 free (conf.script_node_down), conf.script_node_down = strdup (val);
327 else if (!strcmp (var, "pid-file"))
328 free (conf.pidfilename), conf.pidfilename = strdup (val);
329 else if (!strcmp (var, "dns-forw-host"))
330 {
331#if ENABLE_DNS
332 free (conf.dns_forw_host), conf.dns_forw_host = strdup (val);
333#endif
334 }
335 else if (!strcmp (var, "dns-forw-port"))
336 {
337#if ENABLE_DNS
338 conf.dns_forw_port = atoi (val);
339#endif
340 }
341 else if (!strcmp (var, "dns-timeout-factor"))
342 {
343#if ENABLE_DNS
344 conf.dns_timeout_factor = atof (val);
345#endif
346 }
347 else if (!strcmp (var, "dns-send-interval"))
348 {
349#if ENABLE_DNS
350 conf.dns_send_interval = atoi (val);
351#endif
352 }
353 else if (!strcmp (var, "dns-overlap-factor"))
354 {
355#if ENABLE_DNS
356 conf.dns_overlap_factor = atof (val);
357#endif
358 }
359 else if (!strcmp (var, "dns-max-outstanding"))
360 {
361#if ENABLE_DNS
362 conf.dns_max_outstanding = atoi (val);
363#endif
364 }
365 else if (!strcmp (var, "http-proxy-host"))
366 {
367#if ENABLE_HTTP_PROXY
368 free (conf.proxy_host), conf.proxy_host = strdup (val);
369#endif
370 }
371 else if (!strcmp (var, "http-proxy-port"))
372 {
373#if ENABLE_HTTP_PROXY
374 conf.proxy_port = atoi (val);
375#endif
376 }
377 else if (!strcmp (var, "http-proxy-auth"))
378 {
379#if ENABLE_HTTP_PROXY
380 conf.proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val));
381#endif
382 }
383
384 /* node-specific, non-defaultable */
385 else if (node != &conf.default_node && !strcmp (var, "hostname"))
386 free (node->hostname), node->hostname = strdup (val);
387
388 /* node-specific, defaultable */
389 else if (!strcmp (var, "udp-port"))
390 node->udp_port = atoi (val);
391 else if (!strcmp (var, "tcp-port"))
392 node->tcp_port = atoi (val);
393 else if (!strcmp (var, "dns-hostname"))
394 {
395#if ENABLE_DNS
396 free (node->dns_hostname), node->dns_hostname = strdup (val);
397#endif
398 }
399 else if (!strcmp (var, "dns-port"))
400 {
401#if ENABLE_DNS
402 node->dns_port = atoi (val);
403#endif
404 }
405 else if (!strcmp (var, "dns-domain"))
406 {
407#if ENABLE_DNS
408 free (node->domain), node->domain = strdup (val);
409#endif
410 }
411 else if (!strcmp (var, "if-up-data"))
412 free (node->if_up_data), node->if_up_data = strdup (val);
413 else if (!strcmp (var, "router-priority"))
414 node->routerprio = atoi (val);
415 else if (!strcmp (var, "max-retry"))
416 node->max_retry = atoi (val);
417 else if (!strcmp (var, "connect"))
418 {
419 if (!strcmp (val, "ondemand"))
420 node->connectmode = conf_node::C_ONDEMAND;
421 else if (!strcmp (val, "never"))
422 node->connectmode = conf_node::C_NEVER;
423 else if (!strcmp (val, "always"))
424 node->connectmode = conf_node::C_ALWAYS;
425 else if (!strcmp (val, "disabled"))
426 node->connectmode = conf_node::C_DISABLED;
427 else
428 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)");
429 }
430 else if (!strcmp (var, "inherit-tos"))
431 parse_bool (node->inherit_tos, "inherit-tos", true, false);
432 else if (!strcmp (var, "compress"))
433 parse_bool (node->compress, "compress", true, false);
434 // all these bool options really really cost a lot of executable size!
435 else if (!strcmp (var, "enable-tcp"))
436 {
437#if ENABLE_TCP
438 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
439#endif
440 }
441 else if (!strcmp (var, "enable-icmp"))
442 {
443#if ENABLE_ICMP
444 u8 v; parse_bool (v, "enable-icmp" , PROT_ICMPv4, 0); node->protocols = (node->protocols & ~PROT_ICMPv4) | v;
445#endif
446 }
447 else if (!strcmp (var, "enable-dns"))
448 {
449#if ENABLE_DNS
450 u8 v; parse_bool (v, "enable-dns" , PROT_DNSv4, 0); node->protocols = (node->protocols & ~PROT_DNSv4) | v;
451#endif
452 }
453 else if (!strcmp (var, "enable-udp"))
454 {
455 u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v;
456 }
457 else if (!strcmp (var, "enable-rawip"))
458 {
459 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
460 }
461 else if (!strcmp (var, "allow-direct"))
462 node->allow_direct.push_back (strdup (val));
463 else if (!strcmp (var, "deny-direct"))
464 node->deny_direct.push_back (strdup (val));
465
466 // unknown or misplaced
467 else
468 return _("unknown configuration directive. (ignored)");
469
470 return 0;
471}
472
473void configuration_parser::parse_argv ()
474{
475 for (int i = 0; i < argc; ++i)
476 {
477 char *v = argv [i];
478
479 if (!*v)
480 continue;
481
482 char *enode = v;
483
484 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
485 enode++;
486
487 if (*enode != '.')
488 enode = 0;
489
490 char *wnode = node == &conf.default_node
491 ? 0
492 : node->nodename;
493
494 if ((!wnode && !enode)
495 || (wnode && enode && !strncmp (wnode, v, enode - v)))
496 {
497 const char *warn = parse_line (enode ? enode + 1 : v);
498
499 if (warn)
500 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
501
502 *v = 0;
503 }
504 }
505}
506
507configuration_parser::configuration_parser (configuration &conf,
508 bool need_keys,
509 int argc,
510 char **argv)
511: conf (conf),need_keys (need_keys), argc (argc), argv (argv)
170{ 512{
171 char *fname; 513 char *fname;
172 FILE *f; 514 FILE *f;
173 515
174 clear_config (); 516 conf.clear ();
175 517
176 asprintf (&fname, "%s/vped.conf", confbase); 518 asprintf (&fname, "%s/gvpe.conf", confbase);
177 f = fopen (fname, "r"); 519 f = fopen (fname, "r");
178 520
179 if (f) 521 if (f)
180 { 522 {
181 char line[16384]; 523 char line[16384];
182 int lineno = 0; 524 int lineno = 0;
183 char *var, *val; 525 node = &conf.default_node;
184 conf_node *node = &default_node;
185 526
186 while (fgets (line, sizeof (line), f)) 527 while (fgets (line, sizeof (line), f))
187 { 528 {
188 lineno++; 529 lineno++;
189 530
190 { 531 const char *warn = parse_line (line);
191 char *end = line + strlen (line);
192 532
193 while (*end < ' ' && end >= line) 533 if (warn)
194 end--; 534 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
195
196 *++end = 0;
197 }
198
199 char *tok = line;
200
201retry:
202 var = strtok (tok, "\t =");
203 tok = 0;
204
205 if (!var || !var[0])
206 continue; /* no tokens on this line */
207
208 if (var[0] == '#')
209 continue; /* comment: ignore */
210
211 val = strtok (NULL, "\t\n\r =");
212
213 if (!val || val[0] == '#')
214 {
215 slog (L_WARN,
216 _("no value for variable `%s', at '%s' line %d"),
217 var, fname, lineno);
218 break;
219 }
220
221 if (!strcmp (var, "on"))
222 {
223 if (!::thisnode
224 || (val[0] == '!' && strcmp (val + 1, ::thisnode))
225 || !strcmp (val, ::thisnode))
226 goto retry;
227
228 continue;
229 }
230
231 // truly global
232 if (!strcmp (var, "loglevel"))
233 {
234 loglevel l = string_to_loglevel (val);
235
236 if (l != L_NONE)
237 llevel = l;
238 else
239 slog (L_WARN, "'%s': %s, at '%s' line %d", val, UNKNOWN_LOGLEVEL, fname, line);
240 }
241 else if (!strcmp (var, "ip-proto"))
242 ip_proto = atoi (val);
243#if ENABLE_ICMP
244 //TODO: error message
245 else if (!strcmp (var, "icmp-type"))
246 icmp_type = atoi (val);
247#endif
248
249 // per config
250 else if (!strcmp (var, "node"))
251 {
252 default_node.id++;
253
254 node = new conf_node (default_node);
255
256 nodes.push_back (node);
257
258 node->nodename = strdup (val);
259
260 {
261 char *fname;
262 FILE *f;
263
264 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
265
266 f = fopen (fname, "r");
267 if (f)
268 {
269 node->rsa_key = RSA_new ();
270
271 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
272 {
273 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
274 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
275 exit (1);
276 }
277
278 RSA_blinding_on (node->rsa_key, 0);
279
280 fclose (f);
281 }
282 else
283 {
284 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
285
286 if (need_keys)
287 exit (1);
288 }
289
290 free (fname);
291 }
292
293 if (!::thisnode || !strcmp (node->nodename, ::thisnode))
294 thisnode = node;
295 }
296 else if (!strcmp (var, "private-key"))
297 prikeyfile = strdup (val);
298 else if (!strcmp (var, "ifpersist"))
299 {
300 parse_bool (ifpersist, "ifpersist", true, false);
301 }
302 else if (!strcmp (var, "ifname"))
303 ifname = strdup (val);
304 else if (!strcmp (var, "rekey"))
305 rekey = atoi (val);
306 else if (!strcmp (var, "keepalive"))
307 keepalive = atoi (val);
308 else if (!strcmp (var, "mtu"))
309 mtu = atoi (val);
310 else if (!strcmp (var, "if-up"))
311 script_if_up = strdup (val);
312 else if (!strcmp (var, "node-up"))
313 script_node_up = strdup (val);
314 else if (!strcmp (var, "node-down"))
315 script_node_down = strdup (val);
316#if ENABLE_HTTP_PROXY
317 else if (!strcmp (var, "http-proxy-host"))
318 proxy_host = strdup (val);
319 else if (!strcmp (var, "http-proxy-port"))
320 proxy_port = atoi (val);
321 else if (!strcmp (var, "http-proxy-auth"))
322 proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val));
323#endif
324
325 /* node-specific, non-defaultable */
326 else if (node != &default_node && !strcmp (var, "hostname"))
327 {
328 free (node->hostname);
329 node->hostname = strdup (val);
330 }
331
332 /* node-specific, defaultable */
333 else if (!strcmp (var, "udp-port"))
334 node->udp_port = atoi (val);
335 else if (!strcmp (var, "tcp-port"))
336 node->tcp_port = atoi (val);
337 else if (!strcmp (var, "router-priority"))
338 node->routerprio = atoi (val);
339 else if (!strcmp (var, "connect"))
340 {
341 if (!strcmp (val, "ondemand"))
342 node->connectmode = conf_node::C_ONDEMAND;
343 else if (!strcmp (val, "never"))
344 node->connectmode = conf_node::C_NEVER;
345 else if (!strcmp (val, "always"))
346 node->connectmode = conf_node::C_ALWAYS;
347 else if (!strcmp (val, "disabled"))
348 node->connectmode = conf_node::C_DISABLED;
349 else
350 slog (L_WARN,
351 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"),
352 var, fname, lineno);
353 }
354 else if (!strcmp (var, "inherit-tos"))
355 {
356 parse_bool (node->inherit_tos, "inherit-tos", true, false);
357 }
358 else if (!strcmp (var, "compress"))
359 {
360 parse_bool (node->compress, "compress", true, false);
361 }
362 // all these bool options really really cost a lot of executable size!
363 else if (!strcmp (var, "enable-tcp"))
364 {
365#if ENABLE_TCP
366 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
367#endif
368 }
369 else if (!strcmp (var, "enable-icmp"))
370 {
371#if ENABLE_ICMP
372 u8 v; parse_bool (v, "enable-icmp" , PROT_ICMPv4, 0); node->protocols = (node->protocols & ~PROT_ICMPv4) | v;
373#endif
374 }
375 else if (!strcmp (var, "enable-udp"))
376 {
377 u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v;
378 }
379 else if (!strcmp (var, "enable-rawip"))
380 {
381 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
382 }
383
384 // unknown or misplaced
385 else
386 slog (L_WARN,
387 _("unknown or misplaced variable `%s', at '%s' line %d"),
388 var, fname, lineno);
389 } 535 }
390 536
391 fclose (f); 537 fclose (f);
538
539 parse_argv ();
392 } 540 }
393 else 541 else
394 { 542 {
395 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno)); 543 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
396 exit (1); 544 exit (EXIT_FAILURE);
397 } 545 }
398 546
399 free (fname); 547 free (fname);
400 548
401 fname = config_filename (prikeyfile, "hostkey"); 549 fname = conf.config_filename (conf.prikeyfile, "hostkey");
402 550
403 f = fopen (fname, "r"); 551 f = fopen (fname, "r");
404 if (f) 552 if (f)
405 { 553 {
406 rsa_key = RSA_new (); 554 conf.rsa_key = RSA_new ();
407 555
408 if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL)) 556 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
409 { 557 {
410 ERR_load_RSA_strings (); ERR_load_PEM_strings (); 558 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
411 slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0)); 559 slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
412 exit (1); 560 exit (EXIT_FAILURE);
413 } 561 }
414 562
415 RSA_blinding_on (rsa_key, 0); 563 require (RSA_blinding_on (conf.rsa_key, 0));
416 564
417 fclose (f); 565 fclose (f);
418 } 566 }
419 else 567 else
420 { 568 {
421 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); 569 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
422 570
423 if (need_keys) 571 if (need_keys)
424 exit (1); 572 exit (EXIT_FAILURE);
573 }
574
575 if (need_keys && ::thisnode
576 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
577 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
578 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
579 {
580 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
581 exit (EXIT_FAILURE);
425 } 582 }
426 583
427 free (fname); 584 free (fname);
428} 585}
429 586
430char *configuration::config_filename (const char *name, const char *dflt) 587char *configuration::config_filename (const char *name, const char *dflt)
466 printf ("\n"); 623 printf ("\n");
467} 624}
468 625
469configuration::configuration () 626configuration::configuration ()
470{ 627{
628 asprintf (&confbase, "%s/gvpe", CONFDIR);
629
471 init (); 630 init ();
472} 631}
473 632
474configuration::~configuration () 633configuration::~configuration ()
475{ 634{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines