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.17 by pcg, Tue Oct 14 15:48:15 2003 UTC vs.
Revision 1.41 by pcg, Tue Apr 26 00:55:55 2005 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines