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

# Content
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 llevel = L_INFO;
71
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 llevel = l;
169 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, "udp-port"))
257 node->port = atoi (val);
258 else if (!strcmp (var, "port")) //deprecated
259 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 else if (!strcmp (val, "disabled"))
271 node->connectmode = conf_node::C_DISABLED;
272 else
273 slog (L_WARN,
274 _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', at '%s' line %d"),
275 var, fname, lineno);
276 }
277 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 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