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.26 by pcg, Wed May 12 13:32:13 2004 UTC vs.
Revision 1.57 by root, Sat Dec 17 22:05:34 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines