ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.52
Committed: Tue Feb 8 23:11:35 2011 UTC (13 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.51: +14 -8 lines
Log Message:
*** empty log message ***

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