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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines