ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.55
Committed: Sun Mar 6 19:40:28 2011 UTC (13 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.54: +45 -26 lines
Log Message:
*** empty log message ***

File Contents

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