ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.57
Committed: Sat Dec 17 22:05:34 2011 UTC (12 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.56: +19 -0 lines
Log Message:
ipv42_hack

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