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.4 by pcg, Sun Mar 23 14:49:16 2003 UTC vs.
Revision 1.33 by pcg, Sun Mar 6 18:34:46 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. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*/ 20*/
23 21
24#include "config.h" 22#include "config.h"
25 23
31#include <netdb.h> 29#include <netdb.h>
32#include <sys/stat.h> 30#include <sys/stat.h>
33#include <sys/types.h> 31#include <sys/types.h>
34#include <unistd.h> 32#include <unistd.h>
35 33
34#include "netcompat.h"
35
36#include <openssl/err.h> 36#include <openssl/err.h>
37#include <openssl/pem.h> 37#include <openssl/pem.h>
38#include <openssl/rsa.h> 38#include <openssl/rsa.h>
39#include <openssl/rand.h> 39#include <openssl/rand.h>
40#include <openssl/bn.h>
40 41
41#include "gettext.h" 42#include "gettext.h"
42 43
43#include "conf.h" 44#include "conf.h"
44#include "slog.h" 45#include "slog.h"
45#include "util.h" 46#include "util.h"
46 47
47char *confbase; 48char *confbase;
48char *thisnode; 49char *thisnode;
49char *identname; 50char *identname;
50char *pidfilename;
51 51
52struct configuration conf; 52struct configuration conf;
53 53
54configuration::configuration () 54u8 best_protocol (u8 protset)
55{ 55{
56 init (); 56 if (protset & PROT_IPv4 ) return PROT_IPv4;
57} 57 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
58 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
59 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
60 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
58 61
59configuration::~configuration () 62 return 0;
63}
64
65const char *strprotocol (u8 protocol)
60{ 66{
61 cleanup (); 67 if (protocol & PROT_IPv4 ) return "rawip";
68 if (protocol & PROT_ICMPv4) return "icmp";
69 if (protocol & PROT_UDPv4 ) return "udp";
70 if (protocol & PROT_TCPv4 ) return "tcp";
71 if (protocol & PROT_DNSv4 ) return "dns";
72
73 return "<unknown>";
74}
75
76void
77conf_node::print ()
78{
79 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
80 id,
81 id >> 8, id & 0xff,
82 compress ? 'Y' : 'N',
83 connectmode == C_ONDEMAND ? "ondemand" :
84 connectmode == C_NEVER ? "never" :
85 connectmode == C_ALWAYS ? "always" : "",
86 nodename,
87 hostname ? hostname : "",
88 hostname ? ":" : "",
89 hostname ? udp_port : 0
90 );
91}
92
93conf_node::~conf_node ()
94{
95 if (rsa_key)
96 RSA_free (rsa_key);
97
98 free (nodename);
99 free (hostname);
100#if ENABLE_DNS
101 free (domain);
102 free (dns_hostname);
103#endif
62} 104}
63 105
64void configuration::init () 106void configuration::init ()
65{ 107{
66 memset (this, 0, sizeof (*this)); 108 memset (this, 0, sizeof (*this));
67 109
110 mtu = DEFAULT_MTU;
68 rekey = DEFAULT_REKEY; 111 rekey = DEFAULT_REKEY;
69 keepalive = DEFAULT_KEEPALIVE; 112 keepalive = DEFAULT_KEEPALIVE;
70 llevel = L_INFO; 113 llevel = L_INFO;
114 ip_proto = IPPROTO_GRE;
115#if ENABLE_ICMP
116 icmp_type = ICMP_ECHOREPLY;
117#endif
71 118
72 default_node.port = DEFAULT_PORT; 119 default_node.udp_port = DEFAULT_UDPPORT;
120 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm
73 default_node.connectmode = conf_node::C_ALWAYS; 121 default_node.connectmode = conf_node::C_ALWAYS;
74 default_node.compress = true; 122 default_node.compress = true;
123 default_node.protocols = 0;
124 default_node.max_retry = DEFAULT_MAX_RETRY;
125
126#if ENABLE_DNS
127 default_node.dns_port = 0; // default is 0 == client
128 dns_forw_host = strdup ("127.0.0.1");
129 dns_forw_port = 53;
130#endif
131
132 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
75} 133}
76 134
77void configuration::cleanup() 135void configuration::cleanup()
78{ 136{
79 if (rsa_key) 137 if (rsa_key)
80 RSA_free (rsa_key); 138 RSA_free (rsa_key);
81 139
82 free (ifname);
83
84 rsa_key = 0; 140 rsa_key = 0;
85 ifname = 0; 141
142 free (pidfilename); pidfilename = 0;
143 free (ifname); ifname = 0;
144#if ENABLE_HTTP_PROXY
145 free (proxy_host); proxy_host = 0;
146 free (proxy_auth); proxy_auth = 0;
147#endif
148#if ENABLE_DNS
149 free (dns_forw_host); dns_forw_host = 0;
150#endif
86} 151}
87 152
88void 153void
89configuration::clear_config () 154configuration::clear_config ()
90{ 155{
95 160
96 cleanup (); 161 cleanup ();
97 init (); 162 init ();
98} 163}
99 164
165#define parse_bool(target,name,trueval,falseval) \
166 if (!strcmp (val, "yes")) target = trueval; \
167 else if (!strcmp (val, "no")) target = falseval; \
168 else if (!strcmp (val, "true")) target = trueval; \
169 else if (!strcmp (val, "false")) target = falseval; \
170 else if (!strcmp (val, "on")) target = trueval; \
171 else if (!strcmp (val, "off")) target = falseval; \
172 else \
173 slog (L_WARN, \
174 _("illegal value for '%s', only 'yes|true|on' or 'no|false|off' allowed, at '%s' line %d"), \
175 name, var, fname, lineno);
176
100void configuration::read_config (bool need_keys) 177void configuration::read_config (bool need_keys)
101{ 178{
102 char *fname; 179 char *fname;
103 FILE *f; 180 FILE *f;
104 181
105 clear_config (); 182 clear_config ();
106 183
107 asprintf (&fname, "%s/vped.conf", confbase); 184 asprintf (&fname, "%s/gvpe.conf", confbase);
108 f = fopen (fname, "r"); 185 f = fopen (fname, "r");
109 186
110 if (f) 187 if (f)
111 { 188 {
112 char line[16384]; 189 char line[16384];
167 if (l != L_NONE) 244 if (l != L_NONE)
168 llevel = l; 245 llevel = l;
169 else 246 else
170 slog (L_WARN, "'%s': %s, at '%s' line %d", val, UNKNOWN_LOGLEVEL, fname, line); 247 slog (L_WARN, "'%s': %s, at '%s' line %d", val, UNKNOWN_LOGLEVEL, fname, line);
171 } 248 }
249 else if (!strcmp (var, "ip-proto"))
250 ip_proto = atoi (val);
251 else if (!strcmp (var, "icmp-type"))
252 {
253#if ENABLE_ICMP
254 icmp_type = atoi (val);
255#endif
256 }
172 257
173 // per config 258 // per config
174 else if (!strcmp (var, "node")) 259 else if (!strcmp (var, "node"))
175 { 260 {
176 default_node.id++; 261 default_node.id++;
194 279
195 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL)) 280 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
196 { 281 {
197 ERR_load_RSA_strings (); ERR_load_PEM_strings (); 282 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
198 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0)); 283 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
199 exit (1); 284 exit (EXIT_FAILURE);
200 } 285 }
201 286
202 RSA_blinding_on (node->rsa_key, 0); 287 require (RSA_blinding_on (node->rsa_key, 0));
203 288
204 fclose (f); 289 fclose (f);
205 } 290 }
206 else 291 else
207 { 292 {
208 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno)); 293 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
209 294
210 if (need_keys) 295 if (need_keys)
211 exit (1); 296 exit (EXIT_FAILURE);
212 } 297 }
213 298
214 free (fname); 299 free (fname);
215 } 300 }
216 301
217 if (!::thisnode || !strcmp (node->nodename, ::thisnode)) 302 if (::thisnode && !strcmp (node->nodename, ::thisnode))
218 thisnode = node; 303 thisnode = node;
219 } 304 }
220 else if (!strcmp (var, "private-key")) 305 else if (!strcmp (var, "private-key"))
221 prikeyfile = strdup (val); 306 free (prikeyfile), prikeyfile = strdup (val);
222 else if (!strcmp (var, "ifpersist")) 307 else if (!strcmp (var, "ifpersist"))
223 { 308 {
224 if (!strcmp (val, "yes")) 309 parse_bool (ifpersist, "ifpersist", true, false);
225 ifpersist = true;
226 else if (!strcmp (val, "no"))
227 ifpersist = false;
228 else
229 slog (L_WARN,
230 _("illegal value for 'ifpersist', only 'yes' or 'no' allowed, at '%s' line %d"),
231 var, fname, lineno);
232 } 310 }
233 else if (!strcmp (var, "ifname")) 311 else if (!strcmp (var, "ifname"))
234 ifname = strdup (val); 312 free (ifname), ifname = strdup (val);
235 else if (!strcmp (var, "rekey")) 313 else if (!strcmp (var, "rekey"))
236 rekey = atoi (val); 314 rekey = atoi (val);
237 else if (!strcmp (var, "keepalive")) 315 else if (!strcmp (var, "keepalive"))
238 keepalive = atoi (val); 316 keepalive = atoi (val);
239 else if (!strcmp (var, "mtu")) 317 else if (!strcmp (var, "mtu"))
240 mtu = atoi (val); 318 mtu = atoi (val);
241 else if (!strcmp (var, "if-up")) 319 else if (!strcmp (var, "if-up"))
242 script_if_up = strdup (val); 320 free (script_if_up), script_if_up = strdup (val);
243 else if (!strcmp (var, "node-up")) 321 else if (!strcmp (var, "node-up"))
244 script_node_up = strdup (val); 322 free (script_node_up), script_node_up = strdup (val);
245 else if (!strcmp (var, "node-down")) 323 else if (!strcmp (var, "node-down"))
246 script_node_down = strdup (val); 324 free (script_node_down), script_node_down = strdup (val);
325 else if (!strcmp (var, "pid-file"))
326 free (pidfilename), pidfilename = strdup (val);
327#if ENABLE_DNS
328 else if (!strcmp (var, "dns-forw-host"))
329 free (dns_forw_host), dns_forw_host = strdup (val);
330 else if (!strcmp (var, "dns-forw-port"))
331 dns_forw_port = atoi (val);
332#endif
333 else if (!strcmp (var, "http-proxy-host"))
334 {
335#if ENABLE_HTTP_PROXY
336 free (proxy_host), proxy_host = strdup (val);
337#endif
338 }
339 else if (!strcmp (var, "http-proxy-port"))
340 {
341#if ENABLE_HTTP_PROXY
342 proxy_port = atoi (val);
343#endif
344 }
345 else if (!strcmp (var, "http-proxy-auth"))
346 {
347#if ENABLE_HTTP_PROXY
348 proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val));
349#endif
350 }
247 351
248 /* node-specific, non-defaultable */ 352 /* node-specific, non-defaultable */
249 else if (node != &default_node && !strcmp (var, "hostname")) 353 else if (node != &default_node && !strcmp (var, "hostname"))
250 {
251 free (node->hostname);
252 node->hostname = strdup (val); 354 free (node->hostname), node->hostname = strdup (val);
253 }
254 355
255 /* node-specific, defaultable */ 356 /* node-specific, defaultable */
256 else if (!strcmp (var, "udp-port")) 357 else if (!strcmp (var, "udp-port"))
257 node->port = atoi (val); 358 node->udp_port = atoi (val);
258 else if (!strcmp (var, "port")) //deprecated 359 else if (!strcmp (var, "tcp-port"))
259 node->port = atoi (val); 360 node->tcp_port = atoi (val);
361#if ENABLE_DNS
362 else if (!strcmp (var, "dns-hostname"))
363 free (node->dns_hostname), node->dns_hostname = strdup (val);
364 else if (!strcmp (var, "dns-port"))
365 node->dns_port = atoi (val);
366 else if (!strcmp (var, "dns-domain"))
367 free (node->domain), node->domain = strdup (val);
368#endif
260 else if (!strcmp (var, "router-priority")) 369 else if (!strcmp (var, "router-priority"))
261 node->routerprio = atoi (val); 370 node->routerprio = atoi (val);
371 else if (!strcmp (var, "max-retry"))
372 node->max_retry = atoi (val);
262 else if (!strcmp (var, "connect")) 373 else if (!strcmp (var, "connect"))
263 { 374 {
264 if (!strcmp (val, "ondemand")) 375 if (!strcmp (val, "ondemand"))
265 node->connectmode = conf_node::C_ONDEMAND; 376 node->connectmode = conf_node::C_ONDEMAND;
266 else if (!strcmp (val, "never")) 377 else if (!strcmp (val, "never"))
269 node->connectmode = conf_node::C_ALWAYS; 380 node->connectmode = conf_node::C_ALWAYS;
270 else if (!strcmp (val, "disabled")) 381 else if (!strcmp (val, "disabled"))
271 node->connectmode = conf_node::C_DISABLED; 382 node->connectmode = conf_node::C_DISABLED;
272 else 383 else
273 slog (L_WARN, 384 slog (L_WARN,
274 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"), 385 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"),
275 var, fname, lineno); 386 var, fname, lineno);
276 } 387 }
277 else if (!strcmp (var, "inherit-tos")) 388 else if (!strcmp (var, "inherit-tos"))
278 { 389 {
279 if (!strcmp (val, "yes")) 390 parse_bool (node->inherit_tos, "inherit-tos", true, false);
280 node->inherit_tos = true;
281 else if (!strcmp (val, "no"))
282 node->inherit_tos = false;
283 else 391 }
284 slog (L_WARN,
285 _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"),
286 var, fname, lineno);
287 }
288
289 else if (!strcmp (var, "compress")) 392 else if (!strcmp (var, "compress"))
290 { 393 {
291 if (!strcmp (val, "yes")) 394 parse_bool (node->compress, "compress", true, false);
292 node->compress = true; 395 }
396 // all these bool options really really cost a lot of executable size!
397 else if (!strcmp (var, "enable-tcp"))
398 {
399#if ENABLE_TCP
400 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
401#endif
402 }
403 else if (!strcmp (var, "enable-icmp"))
404 {
405#if ENABLE_ICMP
406 u8 v; parse_bool (v, "enable-icmp" , PROT_ICMPv4, 0); node->protocols = (node->protocols & ~PROT_ICMPv4) | v;
407#endif
408 }
293 else if (!strcmp (val, "no")) 409 else if (!strcmp (var, "enable-dns"))
294 node->compress = false;
295 else 410 {
296 slog (L_WARN, 411#if ENABLE_DNS
297 _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"), 412 u8 v; parse_bool (v, "enable-dns" , PROT_DNSv4, 0); node->protocols = (node->protocols & ~PROT_DNSv4) | v;
298 var, fname, lineno); 413#endif
414 }
415 else if (!strcmp (var, "enable-udp"))
416 {
417 u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v;
418 }
419 else if (!strcmp (var, "enable-rawip"))
420 {
421 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
299 } 422 }
300 423
301 // unknown or misplaced 424 // unknown or misplaced
302 else 425 else
303 {
304 slog (L_WARN, 426 slog (L_WARN,
305 _("unknown or misplaced variable `%s', at '%s' line %d"), 427 _("unknown or misplaced variable `%s', at '%s' line %d"),
306 var, fname, lineno); 428 var, fname, lineno);
307 }
308 } 429 }
309 430
310 fclose (f); 431 fclose (f);
311 } 432 }
312 else 433 else
313 { 434 {
314 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno)); 435 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
315 exit (1); 436 exit (EXIT_FAILURE);
316 } 437 }
317 438
318 free (fname); 439 free (fname);
319 440
320 fname = config_filename (prikeyfile, "hostkey"); 441 fname = config_filename (prikeyfile, "hostkey");
326 447
327 if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL)) 448 if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL))
328 { 449 {
329 ERR_load_RSA_strings (); ERR_load_PEM_strings (); 450 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
330 slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0)); 451 slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
331 exit (1); 452 exit (EXIT_FAILURE);
332 } 453 }
333 454
334 RSA_blinding_on (rsa_key, 0); 455 require (RSA_blinding_on (rsa_key, 0));
335 456
336 fclose (f); 457 fclose (f);
337 } 458 }
338 else 459 else
339 { 460 {
340 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); 461 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
341 462
342 if (need_keys) 463 if (need_keys)
343 exit (1); 464 exit (EXIT_FAILURE);
344 } 465 }
466
467 if (need_keys && ::thisnode
468 && rsa_key && thisnode && thisnode->rsa_key)
469 if (BN_cmp (rsa_key->n, thisnode->rsa_key->n) != 0
470 || BN_cmp (rsa_key->e, thisnode->rsa_key->e) != 0)
471 {
472 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
473 exit (EXIT_FAILURE);
474 }
345 475
346 free (fname); 476 free (fname);
347} 477}
348 478
349char *configuration::config_filename (const char *name, const char *dflt) 479char *configuration::config_filename (const char *name, const char *dflt)
371 printf (_("MTU: %d\n"), mtu); 501 printf (_("MTU: %d\n"), mtu);
372 printf (_("rekeying interval: %d\n"), rekey); 502 printf (_("rekeying interval: %d\n"), rekey);
373 printf (_("keepalive interval: %d\n"), keepalive); 503 printf (_("keepalive interval: %d\n"), keepalive);
374 printf (_("interface: %s\n"), ifname); 504 printf (_("interface: %s\n"), ifname);
375 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 505 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
376 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) : -1); 506 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
377 printf ("\n"); 507 printf ("\n");
378 508
379 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 509 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n",
380 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 510 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port"));
381 511
383 (*i)->print (); 513 (*i)->print ();
384 514
385 printf ("\n"); 515 printf ("\n");
386} 516}
387 517
388void 518configuration::configuration ()
389conf_node::print ()
390{ 519{
391 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n", 520 asprintf (&confbase, "%s/gvpe", CONFDIR);
392 id,
393 id >> 8, id & 0xff,
394 compress ? 'Y' : 'N',
395 connectmode == C_ONDEMAND ? "ondemand" :
396 connectmode == C_NEVER ? "never" :
397 connectmode == C_ALWAYS ? "always" : "",
398 nodename,
399 hostname ? hostname : "",
400 hostname ? ":" : "",
401 hostname ? port : 0
402 );
403}
404 521
522 init ();
523}
524
525configuration::~configuration ()
526{
527 cleanup ();
528}
529
530

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines