ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.1
Committed: Sat Mar 1 15:53:03 2003 UTC (21 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
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    
71     default_node.port = DEFAULT_PORT;
72     default_node.connectmode = conf_node::C_ALWAYS;
73     default_node.compress = true;
74     }
75    
76     void configuration::cleanup()
77     {
78     if (rsa_key)
79     RSA_free (rsa_key);
80    
81     free (ifname);
82    
83     rsa_key = 0;
84     ifname = 0;
85     }
86    
87     void
88     configuration::clear_config ()
89     {
90     for (configuration::node_vector::iterator i = nodes.begin(); i != nodes.end(); ++i)
91     delete *i;
92    
93     nodes.clear ();
94    
95     cleanup ();
96     init ();
97     }
98    
99     void configuration::read_config (bool need_keys)
100     {
101     char *fname;
102     FILE *f;
103    
104     clear_config ();
105    
106     asprintf (&fname, "%s/vped.conf", confbase);
107     f = fopen (fname, "r");
108    
109     if (f)
110     {
111     char line[16384];
112     int lineno = 0;
113     char *var, *val;
114     conf_node *node = &default_node;
115    
116     while (fgets (line, sizeof (line), f))
117     {
118     lineno++;
119    
120     {
121     char *end = line + strlen (line);
122    
123     while (*end < ' ' && end >= line)
124     end--;
125    
126     *++end = 0;
127     }
128    
129     char *tok = line;
130    
131     retry:
132     var = strtok (tok, "\t =");
133     tok = 0;
134    
135     if (!var || !var[0])
136     continue; /* no tokens on this line */
137    
138     if (var[0] == '#')
139     continue; /* comment: ignore */
140    
141     val = strtok (NULL, "\t\n\r =");
142    
143     if (!val || val[0] == '#')
144     {
145     slog (L_WARN,
146     _("no value for variable `%s', at '%s' line %d"),
147     var, fname, lineno);
148     break;
149     }
150    
151     if (!strcmp (var, "on"))
152     {
153     if (!::thisnode
154     || (val[0] == '!' && strcmp (val + 1, ::thisnode))
155     || !strcmp (val, ::thisnode))
156     goto retry;
157    
158     continue;
159     }
160    
161     // truly global
162     if (!strcmp (var, "loglevel"))
163     {
164     loglevel l = string_to_loglevel (val);
165    
166     if (l != L_NONE)
167     set_loglevel (l);
168     else
169     slog (L_WARN, "'%s': %s, at '%s' line %d", val, UNKNOWN_LOGLEVEL, fname, line);
170     }
171    
172     // per config
173     else if (!strcmp (var, "node"))
174     {
175     default_node.id++;
176    
177     node = new conf_node (default_node);
178    
179     nodes.push_back (node);
180    
181     node->nodename = strdup (val);
182    
183     {
184     char *fname;
185     FILE *f;
186    
187     asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
188    
189     f = fopen (fname, "r");
190     if (f)
191     {
192     node->rsa_key = RSA_new ();
193    
194     if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
195     {
196     ERR_load_RSA_strings (); ERR_load_PEM_strings ();
197     slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
198     exit (1);
199     }
200    
201     RSA_blinding_on (node->rsa_key, 0);
202    
203     fclose (f);
204     }
205     else
206     {
207     slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
208    
209     if (need_keys)
210     exit (1);
211     }
212    
213     free (fname);
214     }
215    
216     if (!::thisnode || !strcmp (node->nodename, ::thisnode))
217     thisnode = node;
218     }
219     else if (!strcmp (var, "private-key"))
220     prikeyfile = strdup (val);
221     else if (!strcmp (var, "ifpersist"))
222     {
223     if (!strcmp (val, "yes"))
224     ifpersist = true;
225     else if (!strcmp (val, "no"))
226     ifpersist = false;
227     else
228     slog (L_WARN,
229     _("illegal value for 'ifpersist', only 'yes' or 'no' allowed, at '%s' line %d"),
230     var, fname, lineno);
231     }
232     else if (!strcmp (var, "ifname"))
233     ifname = strdup (val);
234     else if (!strcmp (var, "rekey"))
235     rekey = atoi (val);
236     else if (!strcmp (var, "keepalive"))
237     keepalive = atoi (val);
238     else if (!strcmp (var, "mtu"))
239     mtu = atoi (val);
240     else if (!strcmp (var, "if-up"))
241     script_if_up = strdup (val);
242     else if (!strcmp (var, "node-up"))
243     script_node_up = strdup (val);
244     else if (!strcmp (var, "node-down"))
245     script_node_down = strdup (val);
246    
247     /* node-specific, non-defaultable */
248     else if (node != &default_node && !strcmp (var, "hostname"))
249     {
250     free (node->hostname);
251     node->hostname = strdup (val);
252     }
253    
254     /* node-specific, defaultable */
255     else if (!strcmp (var, "port"))
256     node->port = atoi (val);
257     else if (!strcmp (var, "router-priority"))
258     node->routerprio = atoi (val);
259     else if (!strcmp (var, "connect"))
260     {
261     if (!strcmp (val, "ondemand"))
262     node->connectmode = conf_node::C_ONDEMAND;
263     else if (!strcmp (val, "never"))
264     node->connectmode = conf_node::C_NEVER;
265     else if (!strcmp (val, "always"))
266     node->connectmode = conf_node::C_ALWAYS;
267     else
268     slog (L_WARN,
269     _("illegal value for 'connectmode', use one of 'ondemand', 'never' or 'always', at '%s' line %d"),
270     var, fname, lineno);
271     }
272     else if (!strcmp (var, "compress"))
273     {
274     if (!strcmp (val, "yes"))
275     node->compress = true;
276     else if (!strcmp (val, "no"))
277     node->compress = false;
278     else
279     slog (L_WARN,
280     _("illegal value for 'compress', only 'yes' or 'no' allowed, at '%s' line %d"),
281     var, fname, lineno);
282     }
283    
284     // unknown or misplaced
285     else
286     {
287     slog (L_WARN,
288     _("unknown or misplaced variable `%s', at '%s' line %d"),
289     var, fname, lineno);
290     }
291     }
292    
293     fclose (f);
294     }
295     else
296     {
297     slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
298     exit (1);
299     }
300    
301     free (fname);
302    
303     fname = config_filename (prikeyfile, "hostkey");
304    
305     f = fopen (fname, "r");
306     if (f)
307     {
308     rsa_key = RSA_new ();
309    
310     if (!PEM_read_RSAPrivateKey (f, &rsa_key, NULL, NULL))
311     {
312     ERR_load_RSA_strings (); ERR_load_PEM_strings ();
313     slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
314     exit (1);
315     }
316    
317     RSA_blinding_on (rsa_key, 0);
318    
319     fclose (f);
320     }
321     else
322     {
323     slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
324    
325     if (need_keys)
326     exit (1);
327     }
328    
329     free (fname);
330     }
331    
332     char *configuration::config_filename (const char *name, const char *dflt)
333     {
334     char *fname;
335    
336     asprintf (&fname, name ? name : dflt, ::thisnode);
337    
338     if (!ABSOLUTE_PATH (fname))
339     {
340     char *rname = fname;
341     asprintf (&fname, "%s/%s", confbase, rname);
342     free (rname);
343     }
344    
345     return fname;
346     }
347    
348     void
349     configuration::print ()
350     {
351     printf (_("\nConfiguration\n\n"));
352     printf (_("# of nodes: %d\n"), nodes.size ());
353     printf (_("this node: %s\n"), thisnode ? thisnode->nodename : "<unset>");
354     printf (_("MTU: %d\n"), mtu);
355     printf (_("rekeying interval: %d\n"), rekey);
356     printf (_("keepalive interval: %d\n"), keepalive);
357     printf (_("interface: %s\n"), ifname);
358     printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
359     printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) : -1);
360     printf ("\n");
361    
362     printf ("%4s %-17s %s %-8.8s %-10.10s %s\n",
363     _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port"));
364    
365     for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
366     (*i)->print ();
367    
368     printf ("\n");
369     }
370    
371     void
372     conf_node::print ()
373     {
374     printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
375     id,
376     id >> 8, id & 0xff,
377     compress ? 'Y' : 'N',
378     connectmode == C_ONDEMAND ? "ondemand" :
379     connectmode == C_NEVER ? "never" :
380     connectmode == C_ALWAYS ? "always" : "",
381     nodename,
382     hostname ? hostname : "",
383     hostname ? ":" : "",
384     hostname ? port : 0
385     );
386     }
387