ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.12
Committed: Sun Mar 6 13:49:50 2011 UTC (13 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.11: +2 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 gvpectrl.C -- the main file for gvpectrl
3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 2003-2011 Marc Lehmann <gvpe@schmorp.de>
6
7 This file is part of GVPE.
8
9 GVPE is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 Public License for more details.
18
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, see <http://www.gnu.org/licenses/>.
21
22 Additional permission under GNU GPL version 3 section 7
23
24 If you modify this Program, or any covered work, by linking or
25 combining it with the OpenSSL project's OpenSSL library (or a modified
26 version of that library), containing parts covered by the terms of the
27 OpenSSL or SSLeay licenses, the licensors of this Program grant you
28 additional permission to convey the resulting work. Corresponding
29 Source for a non-source form of such a combination shall include the
30 source code for the parts of OpenSSL used as well as that of the
31 covered work.
32 */
33
34 #include "config.h"
35
36 #include <cstdio>
37 #include <cstring>
38 #include <cstdlib>
39
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <getopt.h>
43 #include <signal.h>
44 #include <sys/stat.h>
45 #include <sys/types.h>
46 #include <unistd.h>
47 #include <signal.h>
48
49 #include <openssl/rand.h>
50 #include <openssl/rsa.h>
51 #include <openssl/pem.h>
52 #include <openssl/evp.h>
53
54 #include "pidfile.h"
55
56 #include "conf.h"
57 #include "slog.h"
58 #include "util.h"
59 #include "vpn.h"
60
61 /* If nonzero, display usage information and exit. */
62 static int show_help;
63
64 /* If nonzero, print the version on standard output and exit. */
65 static int show_version;
66
67 /* If nonzero, it will attempt to kill a running gvpe and exit. */
68 static int kill_gvpe;
69
70 /* If nonzero, it will attempt to kill a running gvpe and exit. */
71 static int show_config;
72
73 /* If nonzero, do not output anything but warnings/errors/very unusual conditions */
74 static int quiet;
75
76 /* If nonzero, generate public/private keypair for this net. */
77 static int generate_keys;
78
79 static struct option const long_options[] =
80 {
81 {"config", required_argument, NULL, 'c'},
82 {"kill", optional_argument, NULL, 'k'},
83 {"help", no_argument, &show_help, 1},
84 {"version", no_argument, &show_version, 1},
85 {"generate-keys", no_argument, NULL, 'g'},
86 {"quiet", no_argument, &quiet, 1},
87 {"show-config", no_argument, &show_config, 's'},
88 {NULL, 0, NULL, 0}
89 };
90
91 static void
92 usage (int status)
93 {
94 if (status != 0)
95 fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ());
96 else
97 {
98 printf (_("Usage: %s [option]...\n\n"), get_identity ());
99 printf (_
100 (" -c, --config=DIR Read configuration options from DIR.\n"
101 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
102 " -g, --generate-keys Generate public/private RSA keypair.\n"
103 " -s, --show-config Display the configuration information.\n"
104 " -q, --quiet Be quite quiet.\n"
105 " --help Display this help and exit.\n"
106 " --version Output version information and exit.\n\n"));
107 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
108 }
109
110 exit (status);
111 }
112
113 static void
114 parse_options (int argc, char **argv, char **envp)
115 {
116 int r;
117 int option_index = 0;
118
119 while ((r = getopt_long (argc, argv, "c:k::qgs", long_options, &option_index)) != EOF)
120 {
121 switch (r)
122 {
123 case 0: /* long option */
124 break;
125
126 case 'c': /* config file */
127 confbase = strdup (optarg);
128 break;
129
130 case 'k': /* kill old gvpes */
131 if (optarg)
132 {
133 if (!strcasecmp (optarg, "HUP"))
134 kill_gvpe = SIGHUP;
135 else if (!strcasecmp (optarg, "TERM"))
136 kill_gvpe = SIGTERM;
137 else if (!strcasecmp (optarg, "KILL"))
138 kill_gvpe = SIGKILL;
139 else if (!strcasecmp (optarg, "USR1"))
140 kill_gvpe = SIGUSR1;
141 else if (!strcasecmp (optarg, "USR2"))
142 kill_gvpe = SIGUSR2;
143 else if (!strcasecmp (optarg, "INT"))
144 kill_gvpe = SIGINT;
145 else if (!strcasecmp (optarg, "ALRM"))
146 kill_gvpe = SIGALRM;
147 else
148 {
149 kill_gvpe = atoi (optarg);
150
151 if (!kill_gvpe)
152 {
153 fprintf (stderr,
154 _
155 ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
156 optarg);
157 usage (1);
158 }
159 }
160 }
161 else
162 kill_gvpe = SIGTERM;
163
164 break;
165
166 case 'g': /* generate public/private keypair */
167 generate_keys = RSA_KEYBITS;
168 break;
169
170 case 's':
171 show_config = 1;
172 break;
173
174 case 'q':
175 quiet = 1;
176 break;
177
178 case '?':
179 usage (1);
180
181 default:
182 break;
183 }
184 }
185 }
186
187 // this function prettyprints the key generation process
188 static void
189 indicator (int a, int b, void *p)
190 {
191 if (quiet)
192 return;
193
194 switch (a)
195 {
196 case 0:
197 fprintf (stderr, ".");
198 break;
199
200 case 1:
201 fprintf (stderr, "+");
202 break;
203
204 case 2:
205 fprintf (stderr, "-");
206 break;
207
208 case 3:
209 switch (b)
210 {
211 case 0:
212 fprintf (stderr, " p\n");
213 break;
214
215 case 1:
216 fprintf (stderr, " q\n");
217 break;
218
219 default:
220 fprintf (stderr, "?");
221 }
222 break;
223
224 default:
225 fprintf (stderr, "?");
226 }
227 }
228
229 /*
230 * generate public/private RSA keypairs for all hosts that don't have one.
231 */
232 static int
233 keygen (int bits)
234 {
235 RSA *rsa_key;
236 FILE *f;
237 char *name = NULL;
238 char *fname;
239
240 asprintf (&fname, "%s/hostkeys", confbase);
241 mkdir (fname, 0700);
242 free (fname);
243
244 asprintf (&fname, "%s/pubkey", confbase);
245 mkdir (fname, 0700);
246 free (fname);
247
248 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
249 {
250 conf_node *node = *i;
251
252 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
253
254 f = fopen (fname, "a");
255
256 /* some libcs are buggy and require an extra seek to the end */
257 if (!f || fseek (f, 0, SEEK_END))
258 {
259 perror (fname);
260 exit (EXIT_FAILURE);
261 }
262
263 if (ftell (f))
264 {
265 if (!quiet)
266 fprintf (stderr, "'%s' already exists, skipping this node %d\n",
267 fname, quiet);
268
269 fclose (f);
270 continue;
271 }
272
273 fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
274 node->nodename);
275
276 rsa_key = RSA_generate_key (bits, 0xFFFF, indicator, NULL);
277
278 if (!rsa_key)
279 {
280 fprintf (stderr, _("error during key generation!\n"));
281 return -1;
282 }
283 else
284 fprintf (stderr, _("Done.\n"));
285
286 require (PEM_write_RSAPublicKey (f, rsa_key));
287 fclose (f);
288 free (fname);
289
290 asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename);
291
292 f = fopen (fname, "a");
293 if (!f)
294 {
295 perror (fname);
296 exit (EXIT_FAILURE);
297 }
298
299 require (PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL));
300 fclose (f);
301 free (fname);
302 }
303
304 return 0;
305 }
306
307 int
308 main (int argc, char **argv, char **envp)
309 {
310 set_identity (argv[0]);
311 log_to (LOGTO_STDERR);
312
313 setlocale (LC_ALL, "");
314 bindtextdomain (PACKAGE, LOCALEDIR);
315 textdomain (PACKAGE);
316
317 parse_options (argc, argv, envp);
318
319 if (show_version)
320 {
321 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
322 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
323 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
324 printf (_
325 ("Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> and others.\n"
326 "See the AUTHORS file for a complete list.\n\n"
327 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
328 "and you are welcome to redistribute it under certain conditions;\n"
329 "see the file COPYING for details.\n"));
330
331 return 0;
332 }
333
334 if (show_help)
335 usage (0);
336
337 {
338 configuration_parser (conf, false, 0, 0);
339 }
340
341 if (generate_keys)
342 {
343 RAND_load_file ("/dev/urandom", 1024);
344 exit (keygen (generate_keys));
345 }
346
347 if (kill_gvpe)
348 exit (kill_other (kill_gvpe));
349
350 if (show_config)
351 {
352 conf.print ();
353 exit (EXIT_SUCCESS);
354 }
355
356 usage (1);
357 }