ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.13
Committed: Fri Jul 5 10:04:22 2013 UTC (10 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.12: +21 -16 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-2013 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/bn.h>
50 #include <openssl/rand.h>
51 #include <openssl/rsa.h>
52 #include <openssl/pem.h>
53 #include <openssl/evp.h>
54
55 #include "pidfile.h"
56
57 #include "conf.h"
58 #include "slog.h"
59 #include "util.h"
60 #include "vpn.h"
61
62 /* If nonzero, display usage information and exit. */
63 static int show_help;
64
65 /* If nonzero, print the version on standard output and exit. */
66 static int show_version;
67
68 /* If nonzero, it will attempt to kill a running gvpe and exit. */
69 static int kill_gvpe;
70
71 /* If nonzero, it will attempt to kill a running gvpe and exit. */
72 static int show_config;
73
74 /* If nonzero, do not output anything but warnings/errors/very unusual conditions */
75 static int quiet;
76
77 /* If nonzero, generate public/private keypair for this net. */
78 static int generate_keys;
79
80 static struct option const long_options[] =
81 {
82 {"config", required_argument, NULL, 'c'},
83 {"kill", optional_argument, NULL, 'k'},
84 {"help", no_argument, &show_help, 1},
85 {"version", no_argument, &show_version, 1},
86 {"generate-keys", no_argument, NULL, 'g'},
87 {"quiet", no_argument, &quiet, 1},
88 {"show-config", no_argument, &show_config, 's'},
89 {NULL, 0, NULL, 0}
90 };
91
92 static void
93 usage (int status)
94 {
95 if (status != 0)
96 fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ());
97 else
98 {
99 printf (_("Usage: %s [option]...\n\n"), get_identity ());
100 printf (_
101 (" -c, --config=DIR Read configuration options from DIR.\n"
102 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
103 " -g, --generate-keys Generate public/private RSA keypair.\n"
104 " -s, --show-config Display the configuration information.\n"
105 " -q, --quiet Be quite quiet.\n"
106 " --help Display this help and exit.\n"
107 " --version Output version information and exit.\n\n"));
108 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
109 }
110
111 exit (status);
112 }
113
114 static void
115 parse_options (int argc, char **argv, char **envp)
116 {
117 int r;
118 int option_index = 0;
119
120 while ((r = getopt_long (argc, argv, "c:k::qgs", long_options, &option_index)) != EOF)
121 {
122 switch (r)
123 {
124 case 0: /* long option */
125 break;
126
127 case 'c': /* config file */
128 confbase = strdup (optarg);
129 break;
130
131 case 'k': /* kill old gvpes */
132 if (optarg)
133 {
134 if (!strcasecmp (optarg, "HUP"))
135 kill_gvpe = SIGHUP;
136 else if (!strcasecmp (optarg, "TERM"))
137 kill_gvpe = SIGTERM;
138 else if (!strcasecmp (optarg, "KILL"))
139 kill_gvpe = SIGKILL;
140 else if (!strcasecmp (optarg, "USR1"))
141 kill_gvpe = SIGUSR1;
142 else if (!strcasecmp (optarg, "USR2"))
143 kill_gvpe = SIGUSR2;
144 else if (!strcasecmp (optarg, "INT"))
145 kill_gvpe = SIGINT;
146 else if (!strcasecmp (optarg, "ALRM"))
147 kill_gvpe = SIGALRM;
148 else
149 {
150 kill_gvpe = atoi (optarg);
151
152 if (!kill_gvpe)
153 {
154 fprintf (stderr,
155 _
156 ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
157 optarg);
158 usage (1);
159 }
160 }
161 }
162 else
163 kill_gvpe = SIGTERM;
164
165 break;
166
167 case 'g': /* generate public/private keypair */
168 generate_keys = RSA_KEYBITS;
169 break;
170
171 case 's':
172 show_config = 1;
173 break;
174
175 case 'q':
176 quiet = 1;
177 break;
178
179 case '?':
180 usage (1);
181
182 default:
183 break;
184 }
185 }
186 }
187
188 // this function prettyprints the key generation process
189 static int
190 indicator (int a, int b, BN_GENCB *cb)
191 {
192 if (quiet)
193 return 1;
194
195 switch (a)
196 {
197 case 0:
198 fprintf (stderr, ".");
199 break;
200
201 case 1:
202 fprintf (stderr, "+");
203 break;
204
205 case 2:
206 fprintf (stderr, "-");
207 break;
208
209 case 3:
210 switch (b)
211 {
212 case 0:
213 fprintf (stderr, " p\n");
214 break;
215
216 case 1:
217 fprintf (stderr, " q\n");
218 break;
219
220 default:
221 fprintf (stderr, "?");
222 }
223 break;
224
225 default:
226 fprintf (stderr, "?");
227 }
228
229 return 1;
230 }
231
232 /*
233 * generate public/private RSA keypairs for all hosts that don't have one.
234 */
235 static int
236 keygen (int bits)
237 {
238 FILE *f;
239 char *name = NULL;
240 char *fname;
241
242 asprintf (&fname, "%s/hostkeys", confbase);
243 mkdir (fname, 0700);
244 free (fname);
245
246 asprintf (&fname, "%s/pubkey", confbase);
247 mkdir (fname, 0700);
248 free (fname);
249
250 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
251 {
252 conf_node *node = *i;
253
254 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
255
256 f = fopen (fname, "a");
257
258 /* some libcs are buggy and require an extra seek to the end */
259 if (!f || fseek (f, 0, SEEK_END))
260 {
261 perror (fname);
262 exit (EXIT_FAILURE);
263 }
264
265 if (ftell (f))
266 {
267 if (!quiet)
268 fprintf (stderr, "'%s' already exists, skipping this node %d\n",
269 fname, quiet);
270
271 fclose (f);
272 continue;
273 }
274
275 fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
276 node->nodename);
277
278 RSA *rsa = RSA_new ();
279 BIGNUM *e = BN_new ();
280 BN_set_bit (e, 0); BN_set_bit (e, 16); // 0x10001, 65537
281 BN_GENCB cb;
282 BN_GENCB_set (&cb, indicator, 0);
283
284 require (RSA_generate_key_ex (rsa, bits, e, &cb));
285
286 fprintf (stderr, _("Done.\n"));
287
288 require (PEM_write_RSAPublicKey (f, rsa));
289 fclose (f);
290 free (fname);
291
292 asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename);
293
294 f = fopen (fname, "a");
295 if (!f)
296 {
297 perror (fname);
298 exit (EXIT_FAILURE);
299 }
300
301 require (PEM_write_RSAPrivateKey (f, rsa, NULL, NULL, 0, NULL, NULL));
302 fclose (f);
303 free (fname);
304
305 BN_free (e);
306 RSA_free (rsa);
307 }
308
309 return 0;
310 }
311
312 int
313 main (int argc, char **argv, char **envp)
314 {
315 set_identity (argv[0]);
316 log_to (LOGTO_STDERR);
317
318 setlocale (LC_ALL, "");
319 bindtextdomain (PACKAGE, LOCALEDIR);
320 textdomain (PACKAGE);
321
322 parse_options (argc, argv, envp);
323
324 if (show_version)
325 {
326 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
327 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
328 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
329 printf (_
330 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
331 "See the AUTHORS file for a complete list.\n\n"
332 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
333 "and you are welcome to redistribute it under certain conditions;\n"
334 "see the file COPYING for details.\n"));
335
336 return 0;
337 }
338
339 if (show_help)
340 usage (0);
341
342 {
343 configuration_parser (conf, false, 0, 0);
344 }
345
346 if (generate_keys)
347 {
348 RAND_load_file ("/dev/urandom", 1024);
349 exit (keygen (generate_keys));
350 }
351
352 if (kill_gvpe)
353 exit (kill_other (kill_gvpe));
354
355 if (show_config)
356 {
357 conf.print ();
358 exit (EXIT_SUCCESS);
359 }
360
361 usage (1);
362 }