ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.4
Committed: Sun Mar 23 14:49:16 2003 UTC (21 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +6 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2     conf.c -- configuration code
3     Copyright (C) 1998 Robert van der Meulen
4     1998-2002 Ivo Timmermans <ivo@o2w.nl>
5     2000-2002 Guus Sliepen <guus@sliepen.eu.org>
6     2000 Cris van Pelt <tribbel@arise.dhs.org>
7     2003 Marc Lehmann <pcg@goof.com>
8    
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 2 of the License, or
12     (at your option) any later version.
13    
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17     GNU General Public License for more details.
18    
19     You should have received a copy of the GNU General Public License
20     along with this program; if not, write to the Free Software
21     Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22     */
23    
24     #include "config.h"
25    
26     #include <cstdio>
27     #include <cstdlib>
28     #include <cstring>
29    
30     #include <errno.h>
31     #include <netdb.h>
32     #include <sys/stat.h>
33     #include <sys/types.h>
34     #include <unistd.h>
35    
36     #include <openssl/err.h>
37     #include <openssl/pem.h>
38     #include <openssl/rsa.h>
39     #include <openssl/rand.h>
40    
41     #include "gettext.h"
42    
43     #include "conf.h"
44     #include "slog.h"
45     #include "util.h"
46    
47     char *confbase;
48     char *thisnode;
49     char *identname;
50     char *pidfilename;
51    
52     struct configuration conf;
53    
54     configuration::configuration ()
55     {
56     init ();
57     }
58    
59     configuration::~configuration ()
60     {
61     cleanup ();
62     }
63    
64     void configuration::init ()
65     {
66     memset (this, 0, sizeof (*this));
67    
68     rekey = DEFAULT_REKEY;
69     keepalive = DEFAULT_KEEPALIVE;
70 pcg 1.2 llevel = L_INFO;
71 pcg 1.1
72     default_node.port = DEFAULT_PORT;
73     default_node.connectmode = conf_node::C_ALWAYS;
74     default_node.compress = true;
75     }
76    
77     void configuration::cleanup()
78     {
79     if (rsa_key)
80     RSA_free (rsa_key);
81    
82     free (ifname);
83    
84     rsa_key = 0;
85     ifname = 0;
86     }
87    
88     void
89     configuration::clear_config ()
90     {
91     for (configuration::node_vector::iterator i = nodes.begin(); i != nodes.end(); ++i)
92     delete *i;
93    
94     nodes.clear ();
95    
96     cleanup ();
97     init ();
98     }
99    
100     void configuration::read_config (bool need_keys)
101     {
102     char *fname;
103     FILE *f;
104    
105     clear_config ();
106    
107     asprintf (&fname, "%s/vped.conf", confbase);
108     f = fopen (fname, "r");
109    
110     if (f)
111     {
112     char line[16384];
113     int lineno = 0;
114     char *var, *val;
115     conf_node *node = &default_node;
116    
117     while (fgets (line, sizeof (line), f))
118     {
119     lineno++;
120    
121     {
122     char *end = line + strlen (line);
123    
124     while (*end < ' ' && end >= line)
125     end--;
126    
127     *++end = 0;
128     }
129    
130     char *tok = line;
131    
132     retry:
133     var = strtok (tok, "\t =");
134     tok = 0;
135    
136     if (!var || !var[0])
137     continue; /* no tokens on this line */
138    
139     if (var[0] == '#')
140     continue; /* comment: ignore */
141    
142     val = strtok (NULL, "\t\n\r =");
143    
144     if (!val || val[0] == '#')
145     {
146     slog (L_WARN,
147     _("no value for variable `%s', at '%s' line %d"),
148     var, fname, lineno);
149     break;
150     }
151    
152     if (!strcmp (var, "on"))
153     {
154     if (!::thisnode
155     || (val[0] == '!' && strcmp (val + 1, ::thisnode))
156     || !strcmp (val, ::thisnode))
157     goto retry;
158    
159     continue;
160     }
161    
162     // truly global
163     if (!strcmp (var, "loglevel"))
164     {
165     loglevel l = string_to_loglevel (val);
166    
167     if (l != L_NONE)
168 pcg 1.2 llevel = l;
169 pcg 1.1 else
170     slog (L_WARN, "'%s': %s, at '%s' line %d", val, UNKNOWN_LOGLEVEL, fname, line);
171     }
172    
173     // per config
174     else if (!strcmp (var, "node"))
175     {
176     default_node.id++;
177    
178     node = new conf_node (default_node);
179    
180     nodes.push_back (node);
181    
182     node->nodename = strdup (val);
183    
184     {
185     char *fname;
186     FILE *f;
187    
188     asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
189    
190     f = fopen (fname, "r");
191     if (f)
192     {
193     node->rsa_key = RSA_new ();
194    
195     if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
196     {
197     ERR_load_RSA_strings (); ERR_load_PEM_strings ();
198     slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
199     exit (1);
200     }
201    
202     RSA_blinding_on (node->rsa_key, 0);
203    
204     fclose (f);
205     }
206     else
207     {
208     slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
209    
210     if (need_keys)
211     exit (1);
212     }
213    
214     free (fname);
215     }
216    
217     if (!::thisnode || !strcmp (node->nodename, ::thisnode))
218     thisnode = node;
219     }
220     else if (!strcmp (var, "private-key"))
221     prikeyfile = strdup (val);
222     else if (!strcmp (var, "ifpersist"))
223     {
224     if (!strcmp (val, "yes"))
225     ifpersist = true;
226     else if (!strcmp (val, "no"))
227     ifpersist = false;
228     else
229     slog (L_WARN,
230     _("illegal value for 'ifpersist', only 'yes' or 'no' allowed, at '%s' line %d"),
231     var, fname, lineno);
232     }
233     else if (!strcmp (var, "ifname"))
234     ifname = strdup (val);
235     else if (!strcmp (var, "rekey"))
236     rekey = atoi (val);
237     else if (!strcmp (var, "keepalive"))
238     keepalive = atoi (val);
239     else if (!strcmp (var, "mtu"))
240     mtu = atoi (val);
241     else if (!strcmp (var, "if-up"))
242     script_if_up = strdup (val);
243     else if (!strcmp (var, "node-up"))
244     script_node_up = strdup (val);
245     else if (!strcmp (var, "node-down"))
246     script_node_down = strdup (val);
247    
248     /* node-specific, non-defaultable */
249     else if (node != &default_node && !strcmp (var, "hostname"))
250     {
251     free (node->hostname);
252     node->hostname = strdup (val);
253     }
254    
255     /* node-specific, defaultable */
256 pcg 1.4 else if (!strcmp (var, "udp-port"))
257     node->port = atoi (val);
258     else if (!strcmp (var, "port")) //deprecated
259 pcg 1.1 node->port = atoi (val);
260     else if (!strcmp (var, "router-priority"))
261     node->routerprio = atoi (val);
262     else if (!strcmp (var, "connect"))
263     {
264     if (!strcmp (val, "ondemand"))
265     node->connectmode = conf_node::C_ONDEMAND;
266     else if (!strcmp (val, "never"))
267     node->connectmode = conf_node::C_NEVER;
268     else if (!strcmp (val, "always"))
269     node->connectmode = conf_node::C_ALWAYS;
270 pcg 1.4 else if (!strcmp (val, "disabled"))
271     node->connectmode = conf_node::C_DISABLED;
272 pcg 1.1 else
273     slog (L_WARN,
274 pcg 1.4 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"),
275 pcg 1.1 var, fname, lineno);
276     }
277 pcg 1.3 else if (!strcmp (var, "inherit-tos"))
278     {
279     if (!strcmp (val, "yes"))
280     node->inherit_tos = true;
281     else if (!strcmp (val, "no"))
282     node->inherit_tos = false;
283     else
284     slog (L_WARN,
285     _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"),
286     var, fname, lineno);
287     }
288    
289 pcg 1.1 else if (!strcmp (var, "compress"))
290     {
291     if (!strcmp (val, "yes"))
292     node->compress = true;
293     else if (!strcmp (val, "no"))
294     node->compress = false;
295     else
296     slog (L_WARN,
297     _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"),
298     var, fname, lineno);
299     }
300    
301     // unknown or misplaced
302     else
303     {
304     slog (L_WARN,
305     _("unknown or misplaced variable `%s', at '%s' line %d"),
306     var, fname, lineno);
307     }
308     }
309    
310     fclose (f);
311     }
312     else
313     {
314     slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
315     exit (1);
316     }
317    
318     free (fname);
319    
320     fname = config_filename (prikeyfile, "hostkey");
321    
322     f = fopen (fname, "r");
323     if (f)
324     {
325     rsa_key = RSA_new ();
326    
327     if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL))
328     {
329     ERR_load_RSA_strings (); ERR_load_PEM_strings ();
330     slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
331     exit (1);
332     }
333    
334     RSA_blinding_on (rsa_key, 0);
335    
336     fclose (f);
337     }
338     else
339     {
340     slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
341    
342     if (need_keys)
343     exit (1);
344     }
345    
346     free (fname);
347     }
348    
349     char *configuration::config_filename (const char *name, const char *dflt)
350     {
351     char *fname;
352    
353     asprintf (&fname, name ? name : dflt, ::thisnode);
354    
355     if (!ABSOLUTE_PATH (fname))
356     {
357     char *rname = fname;
358     asprintf (&fname, "%s/%s", confbase, rname);
359     free (rname);
360     }
361    
362     return fname;
363     }
364    
365     void
366     configuration::print ()
367     {
368     printf (_("\nConfiguration\n\n"));
369     printf (_("# of nodes: %d\n"), nodes.size ());
370     printf (_("this node: %s\n"), thisnode ? thisnode->nodename : "<unset>");
371     printf (_("MTU: %d\n"), mtu);
372     printf (_("rekeying interval: %d\n"), rekey);
373     printf (_("keepalive interval: %d\n"), keepalive);
374     printf (_("interface: %s\n"), ifname);
375     printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
376     printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) : -1);
377     printf ("\n");
378    
379     printf ("%4s %-17s %s %-8.8s %-10.10s %s\n",
380     _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port"));
381    
382     for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
383     (*i)->print ();
384    
385     printf ("\n");
386     }
387    
388     void
389     conf_node::print ()
390     {
391     printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
392     id,
393     id >> 8, id & 0xff,
394     compress ? 'Y' : 'N',
395     connectmode == C_ONDEMAND ? "ondemand" :
396     connectmode == C_NEVER ? "never" :
397     connectmode == C_ALWAYS ? "always" : "",
398     nodename,
399     hostname ? hostname : "",
400     hostname ? ":" : "",
401     hostname ? port : 0
402     );
403     }
404