ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.10
Committed: Tue Feb 8 23:11:36 2011 UTC (13 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.9: +100 -101 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-2008 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 if (!f)
257 {
258 perror (fname);
259 exit (EXIT_FAILURE);
260 }
261
262 if (ftell (f))
263 {
264 if (!quiet)
265 fprintf (stderr, "'%s' already exists, skipping this node %d\n",
266 fname, quiet);
267
268 fclose (f);
269 continue;
270 }
271
272 fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
273 node->nodename);
274
275 rsa_key = RSA_generate_key (bits, 0xFFFF, indicator, NULL);
276
277 if (!rsa_key)
278 {
279 fprintf (stderr, _("error during key generation!\n"));
280 return -1;
281 }
282 else
283 fprintf (stderr, _("Done.\n"));
284
285 require (PEM_write_RSAPublicKey (f, rsa_key));
286 fclose (f);
287 free (fname);
288
289 asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename);
290
291 f = fopen (fname, "a");
292 if (!f)
293 {
294 perror (fname);
295 exit (EXIT_FAILURE);
296 }
297
298 require (PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL));
299 fclose (f);
300 free (fname);
301 }
302
303 return 0;
304 }
305
306 int
307 main (int argc, char **argv, char **envp)
308 {
309 set_identity (argv[0]);
310 log_to (LOGTO_STDERR);
311
312 setlocale (LC_ALL, "");
313 bindtextdomain (PACKAGE, LOCALEDIR);
314 textdomain (PACKAGE);
315
316 parse_options (argc, argv, envp);
317
318 if (show_version)
319 {
320 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
321 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
322 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
323 printf (_
324 ("Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> and others.\n"
325 "See the AUTHORS file for a complete list.\n\n"
326 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
327 "and you are welcome to redistribute it under certain conditions;\n"
328 "see the file COPYING for details.\n"));
329
330 return 0;
331 }
332
333 if (show_help)
334 usage (0);
335
336 {
337 configuration_parser (conf, false, 0, 0);
338 }
339
340 if (generate_keys)
341 {
342 RAND_load_file ("/dev/urandom", 1024);
343 exit (keygen (generate_keys));
344 }
345
346 if (kill_gvpe)
347 exit (kill_other (kill_gvpe));
348
349 if (show_config)
350 {
351 conf.print ();
352 exit (EXIT_SUCCESS);
353 }
354
355 usage (1);
356 }