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.12 by pcg, Mon Apr 7 01:12:56 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 35
38#include <openssl/err.h> 36#include <openssl/err.h>
39#include <openssl/pem.h> 37#include <openssl/pem.h>
40#include <openssl/rsa.h> 38#include <openssl/rsa.h>
41#include <openssl/rand.h> 39#include <openssl/rand.h>
42 40#include <openssl/bn.h>
43#include "gettext.h"
44 41
45#include "conf.h" 42#include "conf.h"
46#include "slog.h" 43#include "slog.h"
47#include "util.h" 44#include "util.h"
48 45
49char *confbase; 46char *confbase;
50char *thisnode; 47char *thisnode;
51char *identname; 48char *identname;
52char *pidfilename;
53 49
54struct configuration conf; 50struct configuration conf;
55 51
56u8 best_protocol (u8 protset) 52u8 best_protocol (u8 protset)
57{ 53{
58 if (protset & PROT_IPv4 ) return PROT_IPv4; 54 if (protset & PROT_IPv4 ) return PROT_IPv4;
55 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
59 if (protset & PROT_UDPv4) return PROT_UDPv4; 56 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
60 if (protset & PROT_TCPv4) return PROT_TCPv4; 57 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
58 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
61 59
62 return 0; 60 return 0;
63} 61}
64 62
65const char *strprotocol (u8 protocol) 63const char *strprotocol (u8 protocol)
66{ 64{
67 if (protocol & PROT_IPv4 ) return "rawip"; 65 if (protocol & PROT_IPv4 ) return "rawip";
66 if (protocol & PROT_ICMPv4) return "icmp";
68 if (protocol & PROT_UDPv4) return "udp"; 67 if (protocol & PROT_UDPv4 ) return "udp";
69 if (protocol & PROT_TCPv4) return "tcp"; 68 if (protocol & PROT_TCPv4 ) return "tcp";
69 if (protocol & PROT_DNSv4 ) return "dns";
70 70
71 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;
72} 96}
73 97
74void 98void
75conf_node::print () 99conf_node::print ()
76{ 100{
88 ); 112 );
89} 113}
90 114
91conf_node::~conf_node () 115conf_node::~conf_node ()
92{ 116{
117#if 0
118 // does not work, because string pointers etc. are shared
119 // is not called, however
93 if (rsa_key) 120 if (rsa_key)
94 RSA_free (rsa_key); 121 RSA_free (rsa_key);
95 122
96 free (nodename); 123 free (nodename);
97 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
98} 131}
99 132
100void configuration::init () 133void configuration::init ()
101{ 134{
102 memset (this, 0, sizeof (*this)); 135 memset (this, 0, sizeof (*this));
103 136
137 mtu = DEFAULT_MTU;
104 rekey = DEFAULT_REKEY; 138 rekey = DEFAULT_REKEY;
105 keepalive = DEFAULT_KEEPALIVE; 139 keepalive = DEFAULT_KEEPALIVE;
106 llevel = L_INFO; 140 llevel = L_INFO;
107 ip_proto = IPPROTO_GRE; 141 ip_proto = IPPROTO_GRE;
142#if ENABLE_ICMP
143 icmp_type = ICMP_ECHOREPLY;
144#endif
108 145
109 default_node.udp_port = DEFAULT_UDPPORT; 146 default_node.udp_port = DEFAULT_UDPPORT;
110 default_node.tcp_port = DEFAULT_UDPPORT; 147 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm
111 default_node.connectmode = conf_node::C_ALWAYS; 148 default_node.connectmode = conf_node::C_ALWAYS;
112 default_node.compress = true; 149 default_node.compress = true;
113 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");
114} 166}
115 167
116void configuration::cleanup() 168void configuration::cleanup()
117{ 169{
118 if (rsa_key) 170 if (rsa_key)
119 RSA_free (rsa_key); 171 RSA_free (rsa_key);
120 172
121 rsa_key = 0; 173 rsa_key = 0;
122 174
175 free (pidfilename); pidfilename = 0;
123 free (ifname); ifname = 0; 176 free (ifname); ifname = 0;
124#if ENABLE_HTTP_PROXY 177#if ENABLE_HTTP_PROXY
125 free (proxy_host); proxy_host = 0; 178 free (proxy_host); proxy_host = 0;
126 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;
127#endif 183#endif
128} 184}
129 185
130void 186void
131configuration::clear_config () 187configuration::clear ()
132{ 188{
133 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)
134 delete *i; 190 delete *i;
135 191
136 nodes.clear (); 192 nodes.clear ();
137 193
138 cleanup (); 194 cleanup ();
139 init (); 195 init ();
140} 196}
141 197
142#define parse_bool(target,name,trueval,falseval) \ 198#define parse_bool(target,name,trueval,falseval) do { \
143 if (!strcmp (val, "yes")) target = trueval; \ 199 if (!strcmp (val, "yes")) target = trueval; \
144 else if (!strcmp (val, "no")) target = falseval; \ 200 else if (!strcmp (val, "no")) target = falseval; \
145 else if (!strcmp (val, "true")) target = trueval; \ 201 else if (!strcmp (val, "true")) target = trueval; \
146 else if (!strcmp (val, "false")) target = falseval; \ 202 else if (!strcmp (val, "false")) target = falseval; \
147 else if (!strcmp (val, "on")) target = trueval; \ 203 else if (!strcmp (val, "on")) target = trueval; \
148 else if (!strcmp (val, "off")) target = falseval; \ 204 else if (!strcmp (val, "off")) target = falseval; \
149 else \ 205 else \
150 slog (L_WARN, \ 206 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \
151 _("illegal value for '%s', only 'yes|true|on' or 'no|false|off' allowed, at '%s' line %d"), \ 207} while (0)
152 name, var, fname, lineno);
153 208
154void 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)
155{ 512{
156 char *fname; 513 char *fname;
157 FILE *f; 514 FILE *f;
158 515
159 clear_config (); 516 conf.clear ();
160 517
161 asprintf (&fname, "%s/vped.conf", confbase); 518 asprintf (&fname, "%s/gvpe.conf", confbase);
162 f = fopen (fname, "r"); 519 f = fopen (fname, "r");
163 520
164 if (f) 521 if (f)
165 { 522 {
166 char line[16384]; 523 char line[16384];
167 int lineno = 0; 524 int lineno = 0;
168 char *var, *val; 525 node = &conf.default_node;
169 conf_node *node = &default_node;
170 526
171 while (fgets (line, sizeof (line), f)) 527 while (fgets (line, sizeof (line), f))
172 { 528 {
173 lineno++; 529 lineno++;
174 530
175 { 531 const char *warn = parse_line (line);
176 char *end = line + strlen (line);
177 532
178 while (*end < ' ' && end >= line) 533 if (warn)
179 end--; 534 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
180
181 *++end = 0;
182 }
183
184 char *tok = line;
185
186retry:
187 var = strtok (tok, "\t =");
188 tok = 0;
189
190 if (!var || !var[0])
191 continue; /* no tokens on this line */
192
193 if (var[0] == '#')
194 continue; /* comment: ignore */
195
196 val = strtok (NULL, "\t\n\r =");
197
198 if (!val || val[0] == '#')
199 {
200 slog (L_WARN,
201 _("no value for variable `%s', at '%s' line %d"),
202 var, fname, lineno);
203 break;
204 }
205
206 if (!strcmp (var, "on"))
207 {
208 if (!::thisnode
209 || (val[0] == '!' && strcmp (val + 1, ::thisnode))
210 || !strcmp (val, ::thisnode))
211 goto retry;
212
213 continue;
214 }
215
216 // truly global
217 if (!strcmp (var, "loglevel"))
218 {
219 loglevel l = string_to_loglevel (val);
220
221 if (l != L_NONE)
222 llevel = l;
223 else
224 slog (L_WARN, "'%s': %s, at '%s' line %d", val, UNKNOWN_LOGLEVEL, fname, line);
225 }
226 else if (!strcmp (var, "ip-proto"))
227 ip_proto = atoi (val);
228
229 // per config
230 else if (!strcmp (var, "node"))
231 {
232 default_node.id++;
233
234 node = new conf_node (default_node);
235
236 nodes.push_back (node);
237
238 node->nodename = strdup (val);
239
240 {
241 char *fname;
242 FILE *f;
243
244 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
245
246 f = fopen (fname, "r");
247 if (f)
248 {
249 node->rsa_key = RSA_new ();
250
251 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
252 {
253 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
254 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
255 exit (1);
256 }
257
258 RSA_blinding_on (node->rsa_key, 0);
259
260 fclose (f);
261 }
262 else
263 {
264 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
265
266 if (need_keys)
267 exit (1);
268 }
269
270 free (fname);
271 }
272
273 if (!::thisnode || !strcmp (node->nodename, ::thisnode))
274 thisnode = node;
275 }
276 else if (!strcmp (var, "private-key"))
277 prikeyfile = strdup (val);
278 else if (!strcmp (var, "ifpersist"))
279 {
280 parse_bool (ifpersist, "ifpersist", true, false);
281 }
282 else if (!strcmp (var, "ifname"))
283 ifname = strdup (val);
284 else if (!strcmp (var, "rekey"))
285 rekey = atoi (val);
286 else if (!strcmp (var, "keepalive"))
287 keepalive = atoi (val);
288 else if (!strcmp (var, "mtu"))
289 mtu = atoi (val);
290 else if (!strcmp (var, "if-up"))
291 script_if_up = strdup (val);
292 else if (!strcmp (var, "node-up"))
293 script_node_up = strdup (val);
294 else if (!strcmp (var, "node-down"))
295 script_node_down = strdup (val);
296#if ENABLE_HTTP_PROXY
297 else if (!strcmp (var, "http-proxy-host"))
298 proxy_host = strdup (val);
299 else if (!strcmp (var, "http-proxy-port"))
300 proxy_port = atoi (val);
301 else if (!strcmp (var, "http-proxy-auth"))
302 proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val));
303#endif
304
305 /* node-specific, non-defaultable */
306 else if (node != &default_node && !strcmp (var, "hostname"))
307 {
308 free (node->hostname);
309 node->hostname = strdup (val);
310 }
311
312 /* node-specific, defaultable */
313 else if (!strcmp (var, "udp-port"))
314 node->udp_port = atoi (val);
315 else if (!strcmp (var, "tcp-port"))
316 node->tcp_port = atoi (val);
317 else if (!strcmp (var, "router-priority"))
318 node->routerprio = atoi (val);
319 else if (!strcmp (var, "connect"))
320 {
321 if (!strcmp (val, "ondemand"))
322 node->connectmode = conf_node::C_ONDEMAND;
323 else if (!strcmp (val, "never"))
324 node->connectmode = conf_node::C_NEVER;
325 else if (!strcmp (val, "always"))
326 node->connectmode = conf_node::C_ALWAYS;
327 else if (!strcmp (val, "disabled"))
328 node->connectmode = conf_node::C_DISABLED;
329 else
330 slog (L_WARN,
331 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"),
332 var, fname, lineno);
333 }
334 else if (!strcmp (var, "inherit-tos"))
335 {
336 parse_bool (node->inherit_tos, "inherit-tos", true, false);
337 }
338 else if (!strcmp (var, "compress"))
339 {
340 parse_bool (node->compress, "compress", true, false);
341 }
342 // all these bool options really really cost a lot of executable size!
343 else if (!strcmp (var, "enable-tcp"))
344 {
345#if ENABLE_TCP
346 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
347#endif
348 }
349 else if (!strcmp (var, "enable-udp"))
350 {
351 u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v;
352 }
353 else if (!strcmp (var, "enable-rawip"))
354 {
355 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
356 }
357
358 // unknown or misplaced
359 else
360 slog (L_WARN,
361 _("unknown or misplaced variable `%s', at '%s' line %d"),
362 var, fname, lineno);
363 } 535 }
364 536
365 fclose (f); 537 fclose (f);
538
539 parse_argv ();
366 } 540 }
367 else 541 else
368 { 542 {
369 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));
370 exit (1); 544 exit (EXIT_FAILURE);
371 } 545 }
372 546
373 free (fname); 547 free (fname);
374 548
375 fname = config_filename (prikeyfile, "hostkey"); 549 fname = conf.config_filename (conf.prikeyfile, "hostkey");
376 550
377 f = fopen (fname, "r"); 551 f = fopen (fname, "r");
378 if (f) 552 if (f)
379 { 553 {
380 rsa_key = RSA_new (); 554 conf.rsa_key = RSA_new ();
381 555
382 if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL)) 556 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
383 { 557 {
384 ERR_load_RSA_strings (); ERR_load_PEM_strings (); 558 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
385 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));
386 exit (1); 560 exit (EXIT_FAILURE);
387 } 561 }
388 562
389 RSA_blinding_on (rsa_key, 0); 563 require (RSA_blinding_on (conf.rsa_key, 0));
390 564
391 fclose (f); 565 fclose (f);
392 } 566 }
393 else 567 else
394 { 568 {
395 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));
396 570
397 if (need_keys) 571 if (need_keys)
398 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);
399 } 582 }
400 583
401 free (fname); 584 free (fname);
402} 585}
403 586
404char *configuration::config_filename (const char *name, const char *dflt) 587char *configuration::config_filename (const char *name, const char *dflt)
426 printf (_("MTU: %d\n"), mtu); 609 printf (_("MTU: %d\n"), mtu);
427 printf (_("rekeying interval: %d\n"), rekey); 610 printf (_("rekeying interval: %d\n"), rekey);
428 printf (_("keepalive interval: %d\n"), keepalive); 611 printf (_("keepalive interval: %d\n"), keepalive);
429 printf (_("interface: %s\n"), ifname); 612 printf (_("interface: %s\n"), ifname);
430 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 613 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
431 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) : -1); 614 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
432 printf ("\n"); 615 printf ("\n");
433 616
434 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 617 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n",
435 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 618 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port"));
436 619
440 printf ("\n"); 623 printf ("\n");
441} 624}
442 625
443configuration::configuration () 626configuration::configuration ()
444{ 627{
628 asprintf (&confbase, "%s/gvpe", CONFDIR);
629
445 init (); 630 init ();
446} 631}
447 632
448configuration::~configuration () 633configuration::~configuration ()
449{ 634{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines