ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.25
Committed: Thu Oct 6 03:03:09 2022 UTC (19 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.24: +1 -2 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-2016 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 /* some libcs are buggy and require an extra seek to the end */
252
253 FILE *pubf = fopen (pub, "ab");
254 if (!pubf || fseek (pubf, 0, SEEK_END))
255 {
256 perror (pub);
257 exit (EXIT_FAILURE);
258 }
259
260 if (ftell (pubf))
261 {
262 fclose (pubf);
263 return 1;
264 }
265
266 FILE *privf = fopen (priv, "ab");
267 if (!privf || fseek (privf, 0, SEEK_END))
268 {
269 perror (priv);
270 exit (EXIT_FAILURE);
271 }
272
273 if (ftell (privf))
274 {
275 fclose (pubf);
276 fclose (privf);
277 return 1;
278 }
279
280 RSA *rsa = RSA_new ();
281 BIGNUM *e = BN_new ();
282 BN_set_bit (e, 0); BN_set_bit (e, 16); // 0x10001, 65537
283
284 #if 0
285 #if OPENSSL_VERSION_NUMBER < 0x10100000
286 BN_GENCB cb_100;
287 BN_GENCB *cb = &cb_100;
288 #else
289 BN_GENCB *cb = BN_GENCB_new ();
290 require (cb);
291 #endif
292
293 BN_GENCB_set (cb, indicator, 0);
294 require (RSA_generate_key_ex (rsa, RSABITS, e, cb));
295 #else
296 require (RSA_generate_key_ex (rsa, RSABITS, e, 0));
297 #endif
298
299 require (PEM_write_RSAPublicKey (pubf, rsa));
300 require (PEM_write_RSAPrivateKey (privf, rsa, NULL, NULL, 0, NULL, NULL));
301
302 fclose (pubf);
303 fclose (privf);
304
305 BN_free (e);
306 RSA_free (rsa);
307
308 return 0;
309 }
310
311 static int
312 keygen_all ()
313 {
314 char *fname;
315
316 asprintf (&fname, "%s/pubkey", confbase);
317 mkdir (fname, 0700);
318 free (fname);
319
320 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
321 {
322 conf_node *node = *i;
323
324 ::thisnode = node->nodename;
325
326 char *pub = conf.config_filename ("pubkey/%s", 0);
327 char *priv = conf.config_filename (conf.prikeyfile, "hostkey");
328
329 int status = keygen (pub, priv);
330
331 if (status == 0)
332 {
333 if (!quiet)
334 fprintf (stderr, _("generated %d bits key for %s.\n"), RSABITS, node->nodename);
335 }
336 else if (status == 1)
337 fprintf (stderr, _("'%s' keypair already exists, skipping node %s.\n"), pub, node->nodename);
338
339 free (priv);
340 free (pub);
341 }
342
343 return 0;
344 }
345
346 static int
347 keygen_one (const char *pubname)
348 {
349 char *privname;
350
351 asprintf (&privname, "%s.privkey", pubname);
352
353 int status = keygen (pubname, privname);
354
355 if (status == 0)
356 {
357 if (!quiet)
358 fprintf (stderr, _("generated %d bits key as %s.\n"), RSABITS, pubname);
359 }
360 else if (status == 1)
361 {
362 fprintf (stderr, _("'%s' keypair already exists, not generating key.\n"), pubname);
363 exit (EXIT_FAILURE);
364 }
365
366 free (privname);
367
368 return 0;
369 }
370
371 int
372 main (int argc, char **argv, char **envp)
373 {
374 set_identity (argv[0]);
375 log_to (LOGTO_STDERR);
376
377 setlocale (LC_ALL, "");
378 bindtextdomain (PACKAGE, LOCALEDIR);
379 textdomain (PACKAGE);
380
381 parse_options (argc, argv, envp);
382
383 if (show_version)
384 {
385 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
386 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
387 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
388 printf (_
389 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
390 "See the AUTHORS file for a complete list.\n\n"
391 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
392 "and you are welcome to redistribute it under certain conditions;\n"
393 "see the file COPYING for details.\n"));
394
395 return 0;
396 }
397
398 if (show_help)
399 usage (0);
400
401 {
402 configuration_parser (conf, false, 0, 0);
403 }
404
405 if (debug_info)
406 {
407 printf ("cipher_nid=%d\n", EVP_CIPHER_nid (CIPHER ()));
408 printf ("mac_nid=%d\n", EVP_MD_type (MAC_DIGEST ()));
409 printf ("auth_nid=%d\n", EVP_MD_type (AUTH_DIGEST ()));
410 printf ("sizeof_auth_data=%d\n", sizeof (auth_data));
411 printf ("sizeof_rsa_data=%d\n", sizeof (rsa_data));
412 printf ("sizeof_rsa_data_extra_auth=%d\n", sizeof (((rsa_data *)0)->extra_auth));
413 printf ("raw_overhead=%d\n", VPE_OVERHEAD);
414 printf ("vpn_overhead=%d\n", VPE_OVERHEAD + 6 + 6);
415 printf ("udp_overhead=%d\n", UDP_OVERHEAD + VPE_OVERHEAD + 6 + 6);
416 exit (EXIT_SUCCESS);
417 }
418
419 if (generate_key)
420 {
421 RAND_load_file (conf.seed_dev, SEED_SIZE);
422 exit (keygen_one (generate_key));
423 }
424
425 if (generate_keys)
426 {
427 RAND_load_file (conf.seed_dev, SEED_SIZE);
428 exit (keygen_all ());
429 }
430
431 if (kill_gvpe)
432 exit (kill_other (kill_gvpe));
433
434 if (show_config)
435 {
436 conf.print ();
437 exit (EXIT_SUCCESS);
438 }
439
440 usage (1);
441 }
442