ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.48
Committed: Sun Aug 10 02:49:27 2008 UTC (15 years, 9 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.47: +1 -1 lines
Log Message:
lots bugfixing

File Contents

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