ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.3
Committed: Sun Mar 9 12:40:18 2003 UTC (21 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +12 -0 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     else if (!strcmp (var, "port"))
257     node->port = atoi (val);
258     else if (!strcmp (var, "router-priority"))
259     node->routerprio = atoi (val);
260     else if (!strcmp (var, "connect"))
261     {
262     if (!strcmp (val, "ondemand"))
263     node->connectmode = conf_node::C_ONDEMAND;
264     else if (!strcmp (val, "never"))
265     node->connectmode = conf_node::C_NEVER;
266     else if (!strcmp (val, "always"))
267     node->connectmode = conf_node::C_ALWAYS;
268     else
269     slog (L_WARN,
270     _("illegal value for 'connectmode', use one of 'ondemand', 'never' or 'always', at '%s' line %d"),
271     var, fname, lineno);
272     }
273 pcg 1.3 else if (!strcmp (var, "inherit-tos"))
274     {
275     if (!strcmp (val, "yes"))
276     node->inherit_tos = true;
277     else if (!strcmp (val, "no"))
278     node->inherit_tos = false;
279     else
280     slog (L_WARN,
281     _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"),
282     var, fname, lineno);
283     }
284    
285 pcg 1.1 else if (!strcmp (var, "compress"))
286     {
287     if (!strcmp (val, "yes"))
288     node->compress = true;
289     else if (!strcmp (val, "no"))
290     node->compress = false;
291     else
292     slog (L_WARN,
293     _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"),
294     var, fname, lineno);
295     }
296    
297     // unknown or misplaced
298     else
299     {
300     slog (L_WARN,
301     _("unknown or misplaced variable `%s', at '%s' line %d"),
302     var, fname, lineno);
303     }
304     }
305    
306     fclose (f);
307     }
308     else
309     {
310     slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
311     exit (1);
312     }
313    
314     free (fname);
315    
316     fname = config_filename (prikeyfile, "hostkey");
317    
318     f = fopen (fname, "r");
319     if (f)
320     {
321     rsa_key = RSA_new ();
322    
323     if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL))
324     {
325     ERR_load_RSA_strings (); ERR_load_PEM_strings ();
326     slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
327     exit (1);
328     }
329    
330     RSA_blinding_on (rsa_key, 0);
331    
332     fclose (f);
333     }
334     else
335     {
336     slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
337    
338     if (need_keys)
339     exit (1);
340     }
341    
342     free (fname);
343     }
344    
345     char *configuration::config_filename (const char *name, const char *dflt)
346     {
347     char *fname;
348    
349     asprintf (&fname, name ? name : dflt, ::thisnode);
350    
351     if (!ABSOLUTE_PATH (fname))
352     {
353     char *rname = fname;
354     asprintf (&fname, "%s/%s", confbase, rname);
355     free (rname);
356     }
357    
358     return fname;
359     }
360    
361     void
362     configuration::print ()
363     {
364     printf (_("\nConfiguration\n\n"));
365     printf (_("# of nodes: %d\n"), nodes.size ());
366     printf (_("this node: %s\n"), thisnode ? thisnode->nodename : "<unset>");
367     printf (_("MTU: %d\n"), mtu);
368     printf (_("rekeying interval: %d\n"), rekey);
369     printf (_("keepalive interval: %d\n"), keepalive);
370     printf (_("interface: %s\n"), ifname);
371     printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
372     printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) : -1);
373     printf ("\n");
374    
375     printf ("%4s %-17s %s %-8.8s %-10.10s %s\n",
376     _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port"));
377    
378     for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
379     (*i)->print ();
380    
381     printf ("\n");
382     }
383    
384     void
385     conf_node::print ()
386     {
387     printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
388     id,
389     id >> 8, id & 0xff,
390     compress ? 'Y' : 'N',
391     connectmode == C_ONDEMAND ? "ondemand" :
392     connectmode == C_NEVER ? "never" :
393     connectmode == C_ALWAYS ? "always" : "",
394     nodename,
395     hostname ? hostname : "",
396     hostname ? ":" : "",
397     hostname ? port : 0
398     );
399     }
400