ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.21
Committed: Wed Nov 2 05:58:53 2016 UTC (7 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.20: +113 -57 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 single public/private keypair. */
78 static const char *generate_key;
79
80 /* If nonzero, generate public/private keypair for this net. */
81 static int generate_keys;
82
83 // output some debugging info, interna constants &c
84 static int debug_info;
85
86 static struct option const long_options[] =
87 {
88 {"config", required_argument, NULL, 'c'},
89 {"kill", optional_argument, NULL, 'k'},
90 {"help", no_argument, &show_help, 1},
91 {"version", no_argument, &show_version, 1},
92 {"generate-key", required_argument, NULL, 'g'},
93 {"generate-keys", no_argument, NULL, 'G'},
94 {"quiet", no_argument, &quiet, 1},
95 {"show-config", no_argument, &show_config, 's'},
96 {"debug-info", no_argument, &debug_info, 1},
97 {NULL, 0, NULL, 0}
98 };
99
100 static void
101 usage (int status)
102 {
103 if (status != 0)
104 fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ());
105 else
106 {
107 printf (_("Usage: %s [option]...\n\n"), get_identity ());
108 printf (_
109 (" -c, --config=DIR Read configuration options from DIR.\n"
110 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
111 " -g, --generate-key=file Generate public/private RSA keypair.\n"
112 " -G, --generate-keys Generate all public/private RSA keypairs.\n"
113 " -s, --show-config Display the configuration information.\n"
114 " -q, --quiet Be quite quiet.\n"
115 " --help Display this help and exit.\n"
116 " --version Output version information and exit.\n\n"));
117 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
118 }
119
120 exit (status);
121 }
122
123 static void
124 parse_options (int argc, char **argv, char **envp)
125 {
126 int r;
127 int option_index = 0;
128
129 while ((r = getopt_long (argc, argv, "c:k::qg:Gs", long_options, &option_index)) != EOF)
130 {
131 switch (r)
132 {
133 case 0: /* long option */
134 break;
135
136 case 'c': /* config file */
137 confbase = strdup (optarg);
138 break;
139
140 case 'k': /* kill old gvpes */
141 if (optarg)
142 {
143 if (!strcasecmp (optarg, "HUP"))
144 kill_gvpe = SIGHUP;
145 else if (!strcasecmp (optarg, "TERM"))
146 kill_gvpe = SIGTERM;
147 else if (!strcasecmp (optarg, "KILL"))
148 kill_gvpe = SIGKILL;
149 else if (!strcasecmp (optarg, "USR1"))
150 kill_gvpe = SIGUSR1;
151 else if (!strcasecmp (optarg, "USR2"))
152 kill_gvpe = SIGUSR2;
153 else if (!strcasecmp (optarg, "INT"))
154 kill_gvpe = SIGINT;
155 else if (!strcasecmp (optarg, "ALRM"))
156 kill_gvpe = SIGALRM;
157 else
158 {
159 kill_gvpe = atoi (optarg);
160
161 if (!kill_gvpe)
162 {
163 fprintf (stderr,
164 _
165 ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
166 optarg);
167 usage (1);
168 }
169 }
170 }
171 else
172 kill_gvpe = SIGTERM;
173
174 break;
175
176 case 'g': /* generate public/private keypair */
177 generate_key = optarg;
178 break;
179
180 case 'G': /* generate public/private keypairs */
181 generate_keys = 1;
182 break;
183
184 case 's':
185 show_config = 1;
186 break;
187
188 case 'q':
189 quiet = 1;
190 break;
191
192 case '?':
193 usage (1);
194
195 default:
196 break;
197 }
198 }
199 }
200
201 // this function prettyprints the key generation process
202 static int
203 indicator (int a, int b, BN_GENCB *cb)
204 {
205 if (quiet)
206 return 1;
207
208 switch (a)
209 {
210 case 0:
211 fprintf (stderr, ".");
212 break;
213
214 case 1:
215 fprintf (stderr, "+");
216 break;
217
218 case 2:
219 fprintf (stderr, "-");
220 break;
221
222 case 3:
223 switch (b)
224 {
225 case 0:
226 fprintf (stderr, " p\n");
227 break;
228
229 case 1:
230 fprintf (stderr, " q\n");
231 break;
232
233 default:
234 fprintf (stderr, "?");
235 }
236 break;
237
238 default:
239 fprintf (stderr, "?");
240 }
241
242 return 1;
243 }
244
245 /*
246 * generate public/private RSA keypairs for all hosts that don't have one.
247 */
248 static int
249 keygen (const char *pub, const char *priv)
250 {
251
252 FILE *pubf = fopen (pub, "ab");
253 if (!pubf || fseek (pubf, 0, SEEK_END))
254 {
255 perror (pub);
256 exit (EXIT_FAILURE);
257 }
258
259 if (ftell (pubf))
260 {
261 fclose (pubf);
262 return 1;
263 }
264
265 FILE *privf = fopen (priv, "ab");
266
267 /* some libcs are buggy and require an extra seek to the end */
268 if (!privf || fseek (privf, 0, SEEK_END))
269 {
270 perror (priv);
271 exit (EXIT_FAILURE);
272 }
273
274 if (ftell (privf))
275 {
276 fclose (pubf);
277 fclose (privf);
278 return 1;
279 }
280
281 RSA *rsa = RSA_new ();
282 BIGNUM *e = BN_new ();
283 BN_set_bit (e, 0); BN_set_bit (e, 16); // 0x10001, 65537
284
285 #if 0
286 #if OPENSSL_VERSION_NUMBER < 0x10100000
287 BN_GENCB cb_100;
288 BN_GENCB *cb = &cb_100;
289 #else
290 BN_GENCB *cb = BN_GENCB_new ();
291 require (cb);
292 #endif
293
294 BN_GENCB_set (cb, indicator, 0);
295 require (RSA_generate_key_ex (rsa, RSABITS, e, cb));
296 #else
297 require (RSA_generate_key_ex (rsa, RSABITS, e, 0));
298 #endif
299
300 require (PEM_write_RSAPublicKey (pubf, rsa));
301 require (PEM_write_RSAPrivateKey (privf, rsa, NULL, NULL, 0, NULL, NULL));
302
303 fclose (pubf);
304 fclose (privf);
305
306 BN_free (e);
307 RSA_free (rsa);
308
309 return 0;
310 }
311
312 static int
313 keygen_all ()
314 {
315 char *fname;
316
317 asprintf (&fname, "%s/pubkey", confbase);
318 mkdir (fname, 0700);
319 free (fname);
320
321 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
322 {
323 conf_node *node = *i;
324
325 ::thisnode = node->nodename;
326
327 char *pub = conf.config_filename ("pubkey/%s", 0);
328 char *priv = conf.config_filename (conf.prikeyfile, "hostkey");
329
330 int status = keygen (pub, priv);
331
332 if (status == 0)
333 {
334 if (!quiet)
335 fprintf (stderr, _("generated %d bits key for %s.\n"), RSABITS, node->nodename);
336 }
337 else if (status == 1)
338 fprintf (stderr, _("'%s' keypair already exists, skipping node %s.\n"), pub, node->nodename);
339
340 free (priv);
341 free (pub);
342 }
343
344 return 0;
345 }
346
347 static int
348 keygen_one (const char *pubname)
349 {
350 char *privname;
351
352 asprintf (&privname, "%s.key", pubname);
353
354 int status = keygen (pubname, privname);
355
356 if (status == 0)
357 {
358 if (!quiet)
359 fprintf (stderr, _("generated %d bits key as %s.\n"), RSABITS, pubname);
360 }
361 else if (status == 1)
362 {
363 fprintf (stderr, _("'%s' keypair already exists, not generating key.\n"), pubname);
364 exit (EXIT_FAILURE);
365 }
366
367 free(privname);
368 }
369
370 int
371 main (int argc, char **argv, char **envp)
372 {
373 set_identity (argv[0]);
374 log_to (LOGTO_STDERR);
375
376 setlocale (LC_ALL, "");
377 bindtextdomain (PACKAGE, LOCALEDIR);
378 textdomain (PACKAGE);
379
380 parse_options (argc, argv, envp);
381
382 if (show_version)
383 {
384 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
385 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
386 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
387 printf (_
388 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
389 "See the AUTHORS file for a complete list.\n\n"
390 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
391 "and you are welcome to redistribute it under certain conditions;\n"
392 "see the file COPYING for details.\n"));
393
394 return 0;
395 }
396
397 if (show_help)
398 usage (0);
399
400 {
401 configuration_parser (conf, false, 0, 0);
402 }
403
404 if (debug_info)
405 {
406 printf ("cipher_nid=%d\n", EVP_CIPHER_nid (CIPHER ()));
407 printf ("mac_nid=%d\n", EVP_MD_type (MAC_DIGEST ()));
408 printf ("auth_nid=%d\n", EVP_MD_type (AUTH_DIGEST ()));
409 printf ("sizeof_auth_data=%d\n", sizeof (auth_data));
410 printf ("sizeof_rsa_data=%d\n", sizeof (rsa_data));
411 printf ("sizeof_rsa_data_extra_auth=%d\n", sizeof (((rsa_data *)0)->extra_auth));
412 printf ("raw_overhead=%d\n", VPE_OVERHEAD);
413 printf ("vpn_overhead=%d\n", VPE_OVERHEAD + 6 + 6);
414 printf ("udp_overhead=%d\n", UDP_OVERHEAD + VPE_OVERHEAD + 6 + 6);
415 exit (EXIT_SUCCESS);
416 }
417
418 if (generate_key)
419 {
420 RAND_load_file (conf.seed_dev, SEED_SIZE);
421 exit (keygen_one (generate_key));
422 }
423
424 if (generate_keys)
425 {
426 RAND_load_file (conf.seed_dev, SEED_SIZE);
427 exit (keygen_all ());
428 }
429
430 if (kill_gvpe)
431 exit (kill_other (kill_gvpe));
432
433 if (show_config)
434 {
435 conf.print ();
436 exit (EXIT_SUCCESS);
437 }
438
439 usage (1);
440 }
441