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.34 by pcg, Thu Mar 17 23:59:37 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 else if (!strcmp (var, "dns-forw-host"))
328 {
329#if ENABLE_DNS
330 free (dns_forw_host), dns_forw_host = strdup (val);
331#endif
332 }
333 else if (!strcmp (var, "dns-forw-port"))
334 {
335#if ENABLE_DNS
336 dns_forw_port = atoi (val);
337#endif
338 }
339 else if (!strcmp (var, "http-proxy-host"))
340 {
341#if ENABLE_HTTP_PROXY
342 free (proxy_host), proxy_host = strdup (val);
343#endif
344 }
345 else if (!strcmp (var, "http-proxy-port"))
346 {
347#if ENABLE_HTTP_PROXY
348 proxy_port = atoi (val);
349#endif
350 }
351 else if (!strcmp (var, "http-proxy-auth"))
352 {
353#if ENABLE_HTTP_PROXY
354 proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val));
355#endif
356 }
247 357
248 /* node-specific, non-defaultable */ 358 /* node-specific, non-defaultable */
249 else if (node != &default_node && !strcmp (var, "hostname")) 359 else if (node != &default_node && !strcmp (var, "hostname"))
250 {
251 free (node->hostname);
252 node->hostname = strdup (val); 360 free (node->hostname), node->hostname = strdup (val);
253 }
254 361
255 /* node-specific, defaultable */ 362 /* node-specific, defaultable */
256 else if (!strcmp (var, "udp-port")) 363 else if (!strcmp (var, "udp-port"))
257 node->port = atoi (val); 364 node->udp_port = atoi (val);
258 else if (!strcmp (var, "port")) //deprecated 365 else if (!strcmp (var, "tcp-port"))
259 node->port = atoi (val); 366 node->tcp_port = atoi (val);
367 else if (!strcmp (var, "dns-hostname"))
368 {
369#if ENABLE_DNS
370 free (node->dns_hostname), node->dns_hostname = strdup (val);
371#endif
372 }
373 else if (!strcmp (var, "dns-port"))
374 {
375#if ENABLE_DNS
376 node->dns_port = atoi (val);
377#endif
378 }
379 else if (!strcmp (var, "dns-domain"))
380 {
381#if ENABLE_DNS
382 free (node->domain), node->domain = strdup (val);
383#endif
384 }
260 else if (!strcmp (var, "router-priority")) 385 else if (!strcmp (var, "router-priority"))
261 node->routerprio = atoi (val); 386 node->routerprio = atoi (val);
387 else if (!strcmp (var, "max-retry"))
388 node->max_retry = atoi (val);
262 else if (!strcmp (var, "connect")) 389 else if (!strcmp (var, "connect"))
263 { 390 {
264 if (!strcmp (val, "ondemand")) 391 if (!strcmp (val, "ondemand"))
265 node->connectmode = conf_node::C_ONDEMAND; 392 node->connectmode = conf_node::C_ONDEMAND;
266 else if (!strcmp (val, "never")) 393 else if (!strcmp (val, "never"))
269 node->connectmode = conf_node::C_ALWAYS; 396 node->connectmode = conf_node::C_ALWAYS;
270 else if (!strcmp (val, "disabled")) 397 else if (!strcmp (val, "disabled"))
271 node->connectmode = conf_node::C_DISABLED; 398 node->connectmode = conf_node::C_DISABLED;
272 else 399 else
273 slog (L_WARN, 400 slog (L_WARN,
274 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"), 401 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"),
275 var, fname, lineno); 402 var, fname, lineno);
276 } 403 }
277 else if (!strcmp (var, "inherit-tos")) 404 else if (!strcmp (var, "inherit-tos"))
278 { 405 {
279 if (!strcmp (val, "yes")) 406 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 407 }
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")) 408 else if (!strcmp (var, "compress"))
290 { 409 {
291 if (!strcmp (val, "yes")) 410 parse_bool (node->compress, "compress", true, false);
292 node->compress = true; 411 }
412 // all these bool options really really cost a lot of executable size!
413 else if (!strcmp (var, "enable-tcp"))
414 {
415#if ENABLE_TCP
416 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
417#endif
418 }
419 else if (!strcmp (var, "enable-icmp"))
420 {
421#if ENABLE_ICMP
422 u8 v; parse_bool (v, "enable-icmp" , PROT_ICMPv4, 0); node->protocols = (node->protocols & ~PROT_ICMPv4) | v;
423#endif
424 }
293 else if (!strcmp (val, "no")) 425 else if (!strcmp (var, "enable-dns"))
294 node->compress = false;
295 else 426 {
296 slog (L_WARN, 427#if ENABLE_DNS
297 _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"), 428 u8 v; parse_bool (v, "enable-dns" , PROT_DNSv4, 0); node->protocols = (node->protocols & ~PROT_DNSv4) | v;
298 var, fname, lineno); 429#endif
430 }
431 else if (!strcmp (var, "enable-udp"))
432 {
433 u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v;
434 }
435 else if (!strcmp (var, "enable-rawip"))
436 {
437 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
299 } 438 }
300 439
301 // unknown or misplaced 440 // unknown or misplaced
302 else 441 else
303 {
304 slog (L_WARN, 442 slog (L_WARN,
305 _("unknown or misplaced variable `%s', at '%s' line %d"), 443 _("unknown or misplaced variable `%s', at '%s' line %d"),
306 var, fname, lineno); 444 var, fname, lineno);
307 }
308 } 445 }
309 446
310 fclose (f); 447 fclose (f);
311 } 448 }
312 else 449 else
313 { 450 {
314 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno)); 451 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
315 exit (1); 452 exit (EXIT_FAILURE);
316 } 453 }
317 454
318 free (fname); 455 free (fname);
319 456
320 fname = config_filename (prikeyfile, "hostkey"); 457 fname = config_filename (prikeyfile, "hostkey");
326 463
327 if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL)) 464 if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL))
328 { 465 {
329 ERR_load_RSA_strings (); ERR_load_PEM_strings (); 466 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)); 467 slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
331 exit (1); 468 exit (EXIT_FAILURE);
332 } 469 }
333 470
334 RSA_blinding_on (rsa_key, 0); 471 require (RSA_blinding_on (rsa_key, 0));
335 472
336 fclose (f); 473 fclose (f);
337 } 474 }
338 else 475 else
339 { 476 {
340 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); 477 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
341 478
342 if (need_keys) 479 if (need_keys)
343 exit (1); 480 exit (EXIT_FAILURE);
344 } 481 }
482
483 if (need_keys && ::thisnode
484 && rsa_key && thisnode && thisnode->rsa_key)
485 if (BN_cmp (rsa_key->n, thisnode->rsa_key->n) != 0
486 || BN_cmp (rsa_key->e, thisnode->rsa_key->e) != 0)
487 {
488 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
489 exit (EXIT_FAILURE);
490 }
345 491
346 free (fname); 492 free (fname);
347} 493}
348 494
349char *configuration::config_filename (const char *name, const char *dflt) 495char *configuration::config_filename (const char *name, const char *dflt)
371 printf (_("MTU: %d\n"), mtu); 517 printf (_("MTU: %d\n"), mtu);
372 printf (_("rekeying interval: %d\n"), rekey); 518 printf (_("rekeying interval: %d\n"), rekey);
373 printf (_("keepalive interval: %d\n"), keepalive); 519 printf (_("keepalive interval: %d\n"), keepalive);
374 printf (_("interface: %s\n"), ifname); 520 printf (_("interface: %s\n"), ifname);
375 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 521 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
376 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) : -1); 522 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
377 printf ("\n"); 523 printf ("\n");
378 524
379 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 525 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n",
380 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 526 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port"));
381 527
383 (*i)->print (); 529 (*i)->print ();
384 530
385 printf ("\n"); 531 printf ("\n");
386} 532}
387 533
388void 534configuration::configuration ()
389conf_node::print ()
390{ 535{
391 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n", 536 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 537
538 init ();
539}
540
541configuration::~configuration ()
542{
543 cleanup ();
544}
545
546

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines