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.39 by pcg, Sat Mar 26 03:16:24 2005 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-2005 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2011 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>
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{
93#if 0 118#if 0
104 free (dns_hostname); 129 free (dns_hostname);
105#endif 130#endif
106#endif 131#endif
107} 132}
108 133
134void
109void configuration::init () 135configuration::init ()
110{ 136{
111 memset (this, 0, sizeof (*this)); 137 memset (this, 0, sizeof (*this));
112 138
113 mtu = DEFAULT_MTU; 139 mtu = DEFAULT_MTU;
140 nfmark = 0;
114 rekey = DEFAULT_REKEY; 141 rekey = DEFAULT_REKEY;
115 keepalive = DEFAULT_KEEPALIVE; 142 keepalive = DEFAULT_KEEPALIVE;
116 llevel = L_INFO; 143 llevel = L_INFO;
117 ip_proto = IPPROTO_GRE; 144 ip_proto = IPPROTO_GRE;
145#if 1 //D2
146 ip2_proto = 7;
147#endif
118#if ENABLE_ICMP 148#if ENABLE_ICMP
119 icmp_type = ICMP_ECHOREPLY; 149 icmp_type = ICMP_ECHOREPLY;
120#endif 150#endif
121 151
122 default_node.udp_port = DEFAULT_UDPPORT; 152 default_node.udp_port = DEFAULT_UDPPORT;
123 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm 153 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm
124 default_node.connectmode = conf_node::C_ALWAYS; 154 default_node.connectmode = conf_node::C_ALWAYS;
125 default_node.compress = true; 155 default_node.compress = true;
126 default_node.protocols = 0; 156 default_node.protocols = 0;
127 default_node.max_retry = DEFAULT_MAX_RETRY; 157 default_node.max_retry = DEFAULT_MAX_RETRY;
158 default_node.max_ttl = DEFAULT_MAX_TTL;
159 default_node.max_queue = DEFAULT_MAX_QUEUE;
128 default_node.if_up_data = strdup (""); 160 default_node.if_up_data = strdup ("");
129 161
130#if ENABLE_DNS 162#if ENABLE_DNS
131 default_node.dns_port = 0; // default is 0 == client 163 default_node.dns_port = 0; // default is 0 == client
132 164
165 dns_case_preserving = true;
133 dns_forw_host = strdup ("127.0.0.1"); 166 dns_forw_host = strdup ("127.0.0.1");
134 dns_forw_port = 53; 167 dns_forw_port = 53;
135 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; 168 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
136 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 169 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
137 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 170 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
139#endif 172#endif
140 173
141 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 174 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
142} 175}
143 176
177void
144void configuration::cleanup() 178configuration::cleanup ()
145{ 179{
146 if (rsa_key) 180 if (rsa_key)
147 RSA_free (rsa_key); 181 RSA_free (rsa_key);
148 182
149 rsa_key = 0; 183 rsa_key = 0;
150 184
151 free (pidfilename); pidfilename = 0; 185 free (pidfilename); pidfilename = 0;
152 free (ifname); ifname = 0; 186 free (ifname); ifname = 0;
153#if ENABLE_HTTP_PROXY 187#if ENABLE_HTTP_PROXY
154 free (proxy_host); proxy_host = 0; 188 free (proxy_host); proxy_host = 0;
155 free (proxy_auth); proxy_auth = 0; 189 free (proxy_auth); proxy_auth = 0;
156#endif 190#endif
157#if ENABLE_DNS 191#if ENABLE_DNS
158 free (dns_forw_host); dns_forw_host = 0; 192 free (dns_forw_host); dns_forw_host = 0;
159#endif 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;
160} 198}
161 199
162void 200void
163configuration::clear_config () 201configuration::clear ()
164{ 202{
165 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)
166 delete *i; 204 delete *i;
167 205
168 nodes.clear (); 206 nodes.clear ();
169 207
170 cleanup (); 208 cleanup ();
171 init (); 209 init ();
172} 210}
211
212//static bool
213//is_true (const char *name)
214//{
215 //re
216//}
173 217
174#define parse_bool(target,name,trueval,falseval) do { \ 218#define parse_bool(target,name,trueval,falseval) do { \
175 if (!strcmp (val, "yes")) target = trueval; \ 219 if (!strcmp (val, "yes")) target = trueval; \
176 else if (!strcmp (val, "no")) target = falseval; \ 220 else if (!strcmp (val, "no")) target = falseval; \
177 else if (!strcmp (val, "true")) target = trueval; \ 221 else if (!strcmp (val, "true")) target = trueval; \
178 else if (!strcmp (val, "false")) target = falseval; \ 222 else if (!strcmp (val, "false")) target = falseval; \
179 else if (!strcmp (val, "on")) target = trueval; \ 223 else if (!strcmp (val, "on")) target = trueval; \
180 else if (!strcmp (val, "off")) target = falseval; \ 224 else if (!strcmp (val, "off")) target = falseval; \
181 else \ 225 else \
182 slog (L_WARN, \
183 _("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"); \
184 name, var, fname, lineno); \
185} while (0) 227} while (0)
186 228
187void configuration::read_config (bool need_keys) 229const char *
230configuration_parser::parse_line (char *line)
188{ 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 {
189 char *fname; 303 char *fname;
190 FILE *f; 304 FILE *f;
191 305
192 clear_config (); 306 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
193 307
194 asprintf (&fname, "%s/gvpe.conf", confbase);
195 f = fopen (fname, "r"); 308 f = fopen (fname, "r");
309 if (f)
310 {
311 node->rsa_key = RSA_new ();
196 312
197 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;
198 { 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 {
199 char line[16384]; 578 char line [2048];
200 int lineno = 0; 579 int lineno = 0;
201 char *var, *val;
202 conf_node *node = &default_node;
203 580
204 while (fgets (line, sizeof (line), f)) 581 while (fgets (line, sizeof (line), f))
205 { 582 {
206 lineno++; 583 lineno++;
207 584
208 { 585 const char *warn = parse_line (line);
209 char *end = line + strlen (line);
210 586
211 while (*end < ' ' && end >= line) 587 if (warn)
212 end--; 588 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
213
214 *++end = 0;
215 }
216
217 char *tok = line;
218
219retry:
220 var = strtok (tok, "\t =");
221 tok = 0;
222
223 if (!var || !var[0])
224 continue; /* no tokens on this line */
225
226 if (var[0] == '#')
227 continue; /* comment: ignore */
228
229 val = strtok (NULL, "\t\n\r =");
230
231 if (!val || val[0] == '#')
232 {
233 slog (L_WARN,
234 _("no value for variable `%s', at '%s' line %d, skipping."),
235 var, fname, lineno);
236 continue;
237 }
238
239 if (!strcmp (var, "on"))
240 {
241 if (!::thisnode
242 || (val[0] == '!' && strcmp (val + 1, ::thisnode))
243 || !strcmp (val, ::thisnode))
244 goto retry;
245
246 continue;
247 }
248
249 // truly global
250 if (!strcmp (var, "loglevel"))
251 {
252 loglevel l = string_to_loglevel (val);
253
254 if (l != L_NONE)
255 llevel = l;
256 else
257 slog (L_WARN, "'%s': %s, at '%s' line %d", val, UNKNOWN_LOGLEVEL, fname, line);
258 }
259 else if (!strcmp (var, "ip-proto"))
260 ip_proto = atoi (val);
261 else if (!strcmp (var, "icmp-type"))
262 {
263#if ENABLE_ICMP
264 icmp_type = atoi (val);
265#endif
266 }
267
268 // per config
269 else if (!strcmp (var, "node"))
270 {
271 default_node.id++;
272
273 node = new conf_node (default_node);
274
275 nodes.push_back (node);
276
277 node->nodename = strdup (val);
278
279 {
280 char *fname;
281 FILE *f;
282
283 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
284
285 f = fopen (fname, "r");
286 if (f)
287 {
288 node->rsa_key = RSA_new ();
289
290 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
291 {
292 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
293 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
294 exit (EXIT_FAILURE);
295 }
296
297 require (RSA_blinding_on (node->rsa_key, 0));
298
299 fclose (f);
300 }
301 else
302 {
303 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
304
305 if (need_keys)
306 exit (EXIT_FAILURE);
307 }
308
309 free (fname);
310 }
311
312 if (::thisnode && !strcmp (node->nodename, ::thisnode))
313 thisnode = node;
314 }
315 else if (!strcmp (var, "private-key"))
316 free (prikeyfile), prikeyfile = strdup (val);
317 else if (!strcmp (var, "ifpersist"))
318 parse_bool (ifpersist, "ifpersist", true, false);
319 else if (!strcmp (var, "ifname"))
320 free (ifname), ifname = strdup (val);
321 else if (!strcmp (var, "rekey"))
322 rekey = atoi (val);
323 else if (!strcmp (var, "keepalive"))
324 keepalive = atoi (val);
325 else if (!strcmp (var, "mtu"))
326 mtu = atoi (val);
327 else if (!strcmp (var, "if-up"))
328 free (script_if_up), script_if_up = strdup (val);
329 else if (!strcmp (var, "node-up"))
330 free (script_node_up), script_node_up = strdup (val);
331 else if (!strcmp (var, "node-down"))
332 free (script_node_down), script_node_down = strdup (val);
333 else if (!strcmp (var, "pid-file"))
334 free (pidfilename), pidfilename = strdup (val);
335 else if (!strcmp (var, "dns-forw-host"))
336 {
337#if ENABLE_DNS
338 free (dns_forw_host), dns_forw_host = strdup (val);
339#endif
340 }
341 else if (!strcmp (var, "dns-forw-port"))
342 {
343#if ENABLE_DNS
344 dns_forw_port = atoi (val);
345#endif
346 }
347 else if (!strcmp (var, "dns-timeout-factor"))
348 {
349#if ENABLE_DNS
350 dns_timeout_factor = atof (val);
351#endif
352 }
353 else if (!strcmp (var, "dns-send-interval"))
354 {
355#if ENABLE_DNS
356 dns_send_interval = atoi (val);
357#endif
358 }
359 else if (!strcmp (var, "dns-overlap-factor"))
360 {
361#if ENABLE_DNS
362 dns_overlap_factor = atof (val);
363#endif
364 }
365 else if (!strcmp (var, "dns-max-outstanding"))
366 {
367#if ENABLE_DNS
368 dns_max_outstanding = atoi (val);
369#endif
370 }
371 else if (!strcmp (var, "http-proxy-host"))
372 {
373#if ENABLE_HTTP_PROXY
374 free (proxy_host), proxy_host = strdup (val);
375#endif
376 }
377 else if (!strcmp (var, "http-proxy-port"))
378 {
379#if ENABLE_HTTP_PROXY
380 proxy_port = atoi (val);
381#endif
382 }
383 else if (!strcmp (var, "http-proxy-auth"))
384 {
385#if ENABLE_HTTP_PROXY
386 proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val));
387#endif
388 }
389
390 /* node-specific, non-defaultable */
391 else if (node != &default_node && !strcmp (var, "hostname"))
392 free (node->hostname), node->hostname = strdup (val);
393
394 /* node-specific, defaultable */
395 else if (!strcmp (var, "udp-port"))
396 node->udp_port = atoi (val);
397 else if (!strcmp (var, "tcp-port"))
398 node->tcp_port = atoi (val);
399 else if (!strcmp (var, "dns-hostname"))
400 {
401#if ENABLE_DNS
402 free (node->dns_hostname), node->dns_hostname = strdup (val);
403#endif
404 }
405 else if (!strcmp (var, "dns-port"))
406 {
407#if ENABLE_DNS
408 node->dns_port = atoi (val);
409#endif
410 }
411 else if (!strcmp (var, "dns-domain"))
412 {
413#if ENABLE_DNS
414 free (node->domain), node->domain = strdup (val);
415#endif
416 }
417 else if (!strcmp (var, "if-up-data"))
418 free (node->if_up_data), node->if_up_data = strdup (val);
419 else if (!strcmp (var, "router-priority"))
420 node->routerprio = atoi (val);
421 else if (!strcmp (var, "max-retry"))
422 node->max_retry = atoi (val);
423 else if (!strcmp (var, "connect"))
424 {
425 if (!strcmp (val, "ondemand"))
426 node->connectmode = conf_node::C_ONDEMAND;
427 else if (!strcmp (val, "never"))
428 node->connectmode = conf_node::C_NEVER;
429 else if (!strcmp (val, "always"))
430 node->connectmode = conf_node::C_ALWAYS;
431 else if (!strcmp (val, "disabled"))
432 node->connectmode = conf_node::C_DISABLED;
433 else
434 slog (L_WARN,
435 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d, ignoring."),
436 var, fname, lineno);
437 }
438 else if (!strcmp (var, "inherit-tos"))
439 parse_bool (node->inherit_tos, "inherit-tos", true, false);
440 else if (!strcmp (var, "compress"))
441 parse_bool (node->compress, "compress", true, false);
442 // all these bool options really really cost a lot of executable size!
443 else if (!strcmp (var, "enable-tcp"))
444 {
445#if ENABLE_TCP
446 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
447#endif
448 }
449 else if (!strcmp (var, "enable-icmp"))
450 {
451#if ENABLE_ICMP
452 u8 v; parse_bool (v, "enable-icmp" , PROT_ICMPv4, 0); node->protocols = (node->protocols & ~PROT_ICMPv4) | v;
453#endif
454 }
455 else if (!strcmp (var, "enable-dns"))
456 {
457#if ENABLE_DNS
458 u8 v; parse_bool (v, "enable-dns" , PROT_DNSv4, 0); node->protocols = (node->protocols & ~PROT_DNSv4) | v;
459#endif
460 }
461 else if (!strcmp (var, "enable-udp"))
462 {
463 u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v;
464 }
465 else if (!strcmp (var, "enable-rawip"))
466 {
467 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
468 }
469
470 // unknown or misplaced
471 else
472 slog (L_WARN,
473 _("unknown or misplaced variable `%s', at '%s' line %d, skipping."),
474 var, fname, lineno);
475 } 589 }
476 590
477 fclose (f); 591 fclose (f);
592
593 parse_argv ();
478 } 594 }
479 else 595 else
480 { 596 {
481 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));
482 exit (EXIT_FAILURE); 598 exit (EXIT_FAILURE);
483 } 599 }
600}
484 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);
485 free (fname); 615 free (fname);
486 616
487 fname = config_filename (prikeyfile, "hostkey"); 617 fname = conf.config_filename (conf.prikeyfile, "hostkey");
488 618
489 f = fopen (fname, "r"); 619 if (FILE *f = fopen (fname, "r"))
490 if (f)
491 { 620 {
492 rsa_key = RSA_new (); 621 conf.rsa_key = RSA_new ();
493 622
494 if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL)) 623 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
495 { 624 {
496 ERR_load_RSA_strings (); ERR_load_PEM_strings (); 625 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
497 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));
498 exit (EXIT_FAILURE); 627 exit (EXIT_FAILURE);
499 } 628 }
500 629
501 require (RSA_blinding_on (rsa_key, 0)); 630 require (RSA_blinding_on (conf.rsa_key, 0));
502 631
503 fclose (f); 632 fclose (f);
504 } 633 }
505 else 634 else
506 { 635 {
508 637
509 if (need_keys) 638 if (need_keys)
510 exit (EXIT_FAILURE); 639 exit (EXIT_FAILURE);
511 } 640 }
512 641
642 free (fname);
643
513 if (need_keys && ::thisnode 644 if (need_keys && ::thisnode
514 && rsa_key && thisnode && thisnode->rsa_key) 645 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
515 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
516 || BN_cmp (rsa_key->e, thisnode->rsa_key->e) != 0) 647 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
517 { 648 {
518 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);
519 exit (EXIT_FAILURE); 650 exit (EXIT_FAILURE);
520 } 651 }
521 652
522 free (fname); 653 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
654 (*i)->finalise ();
523} 655}
524 656
657char *
525char *configuration::config_filename (const char *name, const char *dflt) 658configuration::config_filename (const char *name, const char *dflt)
526{ 659{
527 char *fname; 660 char *fname;
528 661
529 asprintf (&fname, name ? name : dflt, ::thisnode); 662 asprintf (&fname, name ? name : dflt, ::thisnode);
530 663
534 asprintf (&fname, "%s/%s", confbase, rname); 667 asprintf (&fname, "%s/%s", confbase, rname);
535 free (rname); 668 free (rname);
536 } 669 }
537 670
538 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 );
539} 692}
540 693
541void 694void
542configuration::print () 695configuration::print ()
543{ 696{
550 printf (_("interface: %s\n"), ifname); 703 printf (_("interface: %s\n"), ifname);
551 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 704 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
552 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);
553 printf ("\n"); 706 printf ("\n");
554 707
555 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 708 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
556 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 709 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
557 710
558 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 711 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
559 (*i)->print (); 712 (*i)->print ();
560 713
561 printf ("\n"); 714 printf ("\n");
571configuration::~configuration () 724configuration::~configuration ()
572{ 725{
573 cleanup (); 726 cleanup ();
574} 727}
575 728
576

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines