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.32 by pcg, Sat Mar 5 15:48:54 2005 UTC vs.
Revision 1.48 by pcg, Sun Aug 10 02:49:27 2008 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines