ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
(Generate patch)

Comparing gvpe/src/gvpectrl.C (file contents):
Revision 1.7 by pcg, Thu Aug 7 17:54:27 2008 UTC vs.
Revision 1.25 by root, Thu Oct 6 03:03:09 2022 UTC

1/* 1/*
2 gvpectrl.C -- the main file for gvpectrl 2 gvpectrl.C -- the main file for gvpectrl
3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl> 3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org> 4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 2003-2008 Marc Lehmann <gvpe@schmorp.de> 5 2003-2016 Marc Lehmann <gvpe@schmorp.de>
6 6
7 This file is part of GVPE. 7 This file is part of GVPE.
8 8
9 GVPE is free software; you can redistribute it and/or modify it 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 10 under the terms of the GNU General Public License as published by the
44#include <sys/stat.h> 44#include <sys/stat.h>
45#include <sys/types.h> 45#include <sys/types.h>
46#include <unistd.h> 46#include <unistd.h>
47#include <signal.h> 47#include <signal.h>
48 48
49#include <openssl/bn.h>
49#include <openssl/rand.h> 50#include <openssl/rand.h>
50#include <openssl/rsa.h> 51#include <openssl/rsa.h>
51#include <openssl/pem.h> 52#include <openssl/pem.h>
52#include <openssl/evp.h> 53#include <openssl/evp.h>
53 54
68static int kill_gvpe; 69static int kill_gvpe;
69 70
70/* If nonzero, it will attempt to kill a running gvpe and exit. */ 71/* If nonzero, it will attempt to kill a running gvpe and exit. */
71static int show_config; 72static int show_config;
72 73
74/* If nonzero, do not output anything but warnings/errors/very unusual conditions */
75static int quiet;
76
77/* If nonzero, generate single public/private keypair. */
78static const char *generate_key;
79
73/* If nonzero, generate public/private keypair for this net. */ 80/* If nonzero, generate public/private keypair for this net. */
74static int generate_keys; 81static int generate_keys;
75 82
83// output some debugging info, interna constants &c
84static int debug_info;
85
76static struct option const long_options[] = 86static struct option const long_options[] =
77 { 87{
78 {"config", required_argument, NULL, 'c'}, 88 {"config", required_argument, NULL, 'c'},
79 {"kill", optional_argument, NULL, 'k'}, 89 {"kill", optional_argument, NULL, 'k'},
80 {"help", no_argument, &show_help, 1}, 90 {"help", no_argument, &show_help, 1},
81 {"version", no_argument, &show_version, 1}, 91 {"version", no_argument, &show_version, 1},
92 {"generate-key", required_argument, NULL, 'g'},
82 {"generate-keys", no_argument, NULL, 'g'}, 93 {"generate-keys", no_argument, NULL, 'G'},
94 {"quiet", no_argument, &quiet, 1},
83 {"show-config", no_argument, &show_config, 's'}, 95 {"show-config", no_argument, &show_config, 's'},
96 {"debug-info", no_argument, &debug_info, 1},
84 {NULL, 0, NULL, 0} 97 {NULL, 0, NULL, 0}
85 }; 98};
86 99
87static void 100static void
88usage (int status) 101usage (int status)
89{ 102{
90 if (status != 0) 103 if (status != 0)
93 { 106 {
94 printf (_("Usage: %s [option]...\n\n"), get_identity ()); 107 printf (_("Usage: %s [option]...\n\n"), get_identity ());
95 printf (_ 108 printf (_
96 (" -c, --config=DIR Read configuration options from DIR.\n" 109 (" -c, --config=DIR Read configuration options from DIR.\n"
97 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\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"
98 " -g, --generate-keys Generate public/private RSA keypair.\n" 112 " -G, --generate-keys Generate all public/private RSA keypairs.\n"
99 " -s, --show-config Display the configuration information.\n" 113 " -s, --show-config Display the configuration information.\n"
114 " -q, --quiet Be quite quiet.\n"
100 " --help Display this help and exit.\n" 115 " --help Display this help and exit.\n"
101 " --version Output version information and exit.\n\n")); 116 " --version Output version information and exit.\n\n"));
102 printf (_("Report bugs to <gvpe@schmorp.de>.\n")); 117 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
103 } 118 }
104 119
105 exit (status); 120 exit (status);
106} 121}
107 122
108void 123static void
109parse_options (int argc, char **argv, char **envp) 124parse_options (int argc, char **argv, char **envp)
110{ 125{
111 int r; 126 int r;
112 int option_index = 0; 127 int option_index = 0;
113 128
114 while ((r = 129 while ((r = getopt_long (argc, argv, "c:k::qg:Gs", long_options, &option_index)) != EOF)
115 getopt_long (argc, argv, "c:k::gs", long_options,
116 &option_index)) != EOF)
117 { 130 {
118 switch (r) 131 switch (r)
119 { 132 {
120 case 0: /* long option */ 133 case 0: /* long option */
121 break; 134 break;
122 135
123 case 'c': /* config file */ 136 case 'c': /* config file */
124 confbase = strdup (optarg); 137 confbase = strdup (optarg);
125 break; 138 break;
126 139
127 case 'k': /* kill old gvpes */ 140 case 'k': /* kill old gvpes */
128 if (optarg) 141 if (optarg)
129 { 142 {
130 if (!strcasecmp (optarg, "HUP")) 143 if (!strcasecmp (optarg, "HUP"))
131 kill_gvpe = SIGHUP; 144 kill_gvpe = SIGHUP;
132 else if (!strcasecmp (optarg, "TERM")) 145 else if (!strcasecmp (optarg, "TERM"))
133 kill_gvpe = SIGTERM; 146 kill_gvpe = SIGTERM;
134 else if (!strcasecmp (optarg, "KILL")) 147 else if (!strcasecmp (optarg, "KILL"))
135 kill_gvpe = SIGKILL; 148 kill_gvpe = SIGKILL;
136 else if (!strcasecmp (optarg, "USR1")) 149 else if (!strcasecmp (optarg, "USR1"))
137 kill_gvpe = SIGUSR1; 150 kill_gvpe = SIGUSR1;
138 else if (!strcasecmp (optarg, "USR2")) 151 else if (!strcasecmp (optarg, "USR2"))
139 kill_gvpe = SIGUSR2; 152 kill_gvpe = SIGUSR2;
140 else if (!strcasecmp (optarg, "INT")) 153 else if (!strcasecmp (optarg, "INT"))
141 kill_gvpe = SIGINT; 154 kill_gvpe = SIGINT;
142 else if (!strcasecmp (optarg, "ALRM")) 155 else if (!strcasecmp (optarg, "ALRM"))
143 kill_gvpe = SIGALRM; 156 kill_gvpe = SIGALRM;
144 else 157 else
145 { 158 {
146 kill_gvpe = atoi (optarg); 159 kill_gvpe = atoi (optarg);
147 160
148 if (!kill_gvpe) 161 if (!kill_gvpe)
149 { 162 {
150 fprintf (stderr, 163 fprintf (stderr,
151 _ 164 _
152 ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"), 165 ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
153 optarg); 166 optarg);
154 usage (1); 167 usage (1);
155 } 168 }
156 } 169 }
157 } 170 }
158 else 171 else
159 kill_gvpe = SIGTERM; 172 kill_gvpe = SIGTERM;
160 173
161 break; 174 break;
162 175
163 case 'g': /* generate public/private keypair */ 176 case 'g': /* generate public/private keypair */
164 generate_keys = RSA_KEYBITS; 177 generate_key = optarg;
165 break; 178 break;
166 179
180 case 'G': /* generate public/private keypairs */
181 generate_keys = 1;
182 break;
183
167 case 's': 184 case 's':
168 show_config = 1; 185 show_config = 1;
169 break; 186 break;
170 187
188 case 'q':
189 quiet = 1;
190 break;
191
171 case '?': 192 case '?':
172 usage (1); 193 usage (1);
173 194
174 default: 195 default:
175 break; 196 break;
176 } 197 }
177 } 198 }
178} 199}
179 200
180/* This function prettyprints the key generation process */ 201// this function prettyprints the key generation process
181 202static int
182void
183indicator (int a, int b, void *p) 203indicator (int a, int b, BN_GENCB *cb)
184{ 204{
205 if (quiet)
206 return 1;
207
185 switch (a) 208 switch (a)
186 { 209 {
187 case 0: 210 case 0:
188 fprintf (stderr, "."); 211 fprintf (stderr, ".");
189 break; 212 break;
190 213
191 case 1: 214 case 1:
192 fprintf (stderr, "+"); 215 fprintf (stderr, "+");
193 break; 216 break;
194 217
195 case 2: 218 case 2:
196 fprintf (stderr, "-"); 219 fprintf (stderr, "-");
197 break; 220 break;
198 221
199 case 3: 222 case 3:
200 switch (b) 223 switch (b)
201 { 224 {
202 case 0: 225 case 0:
203 fprintf (stderr, " p\n"); 226 fprintf (stderr, " p\n");
204 break; 227 break;
205 228
206 case 1: 229 case 1:
207 fprintf (stderr, " q\n"); 230 fprintf (stderr, " q\n");
208 break; 231 break;
209 232
210 default: 233 default:
211 fprintf (stderr, "?"); 234 fprintf (stderr, "?");
212 } 235 }
213 break; 236 break;
214 237
215 default: 238 default:
216 fprintf (stderr, "?"); 239 fprintf (stderr, "?");
217 } 240 }
241
242 return 1;
218} 243}
219 244
220/* 245/*
221 * generate public/private RSA keypairs for all hosts that don't have one. 246 * generate public/private RSA keypairs for all hosts that don't have one.
222 */ 247 */
223int 248static int
224keygen (int bits) 249keygen (const char *pub, const char *priv)
225{ 250{
226 RSA *rsa_key; 251 /* some libcs are buggy and require an extra seek to the end */
227 FILE *f; 252
228 char *name = NULL; 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
311static int
312keygen_all ()
313{
229 char *fname; 314 char *fname;
230
231 asprintf (&fname, "%s/hostkeys", confbase);
232 mkdir (fname, 0700);
233 free (fname);
234 315
235 asprintf (&fname, "%s/pubkey", confbase); 316 asprintf (&fname, "%s/pubkey", confbase);
236 mkdir (fname, 0700); 317 mkdir (fname, 0700);
237 free (fname); 318 free (fname);
238 319
239 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i) 320 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
240 { 321 {
241 conf_node *node = *i; 322 conf_node *node = *i;
242 323
243 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename); 324 ::thisnode = node->nodename;
244 325
245 f = fopen (fname, "a"); 326 char *pub = conf.config_filename ("pubkey/%s", 0);
327 char *priv = conf.config_filename (conf.prikeyfile, "hostkey");
246 328
247 if (!f) 329 int status = keygen (pub, priv);
330
331 if (status == 0)
248 { 332 {
249 perror (fname); 333 if (!quiet)
250 exit (EXIT_FAILURE); 334 fprintf (stderr, _("generated %d bits key for %s.\n"), RSABITS, node->nodename);
251 } 335 }
336 else if (status == 1)
337 fprintf (stderr, _("'%s' keypair already exists, skipping node %s.\n"), pub, node->nodename);
252 338
253 if (ftell (f)) 339 free (priv);
254 {
255 fprintf (stderr, "'%s' already exists, skipping this node\n",
256 fname);
257 fclose (f);
258 continue;
259 }
260
261 fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
262 node->nodename);
263
264 rsa_key = RSA_generate_key (bits, 0xFFFF, indicator, NULL);
265
266 if (!rsa_key)
267 {
268 fprintf (stderr, _("error during key generation!\n"));
269 return -1;
270 }
271 else
272 fprintf (stderr, _("Done.\n"));
273
274 require (PEM_write_RSAPublicKey (f, rsa_key));
275 fclose (f);
276 free (fname); 340 free (pub);
341 }
277 342
278 asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename); 343 return 0;
344}
279 345
280 f = fopen (fname, "a"); 346static int
347keygen_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 {
281 if (!f) 357 if (!quiet)
282 { 358 fprintf (stderr, _("generated %d bits key as %s.\n"), RSABITS, pubname);
283 perror (fname); 359 }
360 else if (status == 1)
361 {
362 fprintf (stderr, _("'%s' keypair already exists, not generating key.\n"), pubname);
284 exit (EXIT_FAILURE); 363 exit (EXIT_FAILURE);
285 } 364 }
286 365
287 require (PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL));
288 fclose (f);
289 free (fname); 366 free (privname);
290 }
291 367
292 return 0; 368 return 0;
293} 369}
294 370
295int 371int
308 { 384 {
309 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (), 385 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
310 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); 386 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
311 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); 387 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
312 printf (_ 388 printf (_
313 ("Copyright (C) 2003 Marc Lehmann <gvpe@schmorp.de> and others.\n" 389 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
314 "See the AUTHORS file for a complete list.\n\n" 390 "See the AUTHORS file for a complete list.\n\n"
315 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n" 391 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
316 "and you are welcome to redistribute it under certain conditions;\n" 392 "and you are welcome to redistribute it under certain conditions;\n"
317 "see the file COPYING for details.\n")); 393 "see the file COPYING for details.\n"));
318 394
324 400
325 { 401 {
326 configuration_parser (conf, false, 0, 0); 402 configuration_parser (conf, false, 0, 0);
327 } 403 }
328 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
329 if (generate_keys) 425 if (generate_keys)
330 { 426 {
331 RAND_load_file ("/dev/urandom", 1024); 427 RAND_load_file (conf.seed_dev, SEED_SIZE);
332 exit (keygen (generate_keys)); 428 exit (keygen_all ());
333 } 429 }
334 430
335 if (kill_gvpe) 431 if (kill_gvpe)
336 exit (kill_other (kill_gvpe)); 432 exit (kill_other (kill_gvpe));
337 433
341 exit (EXIT_SUCCESS); 437 exit (EXIT_SUCCESS);
342 } 438 }
343 439
344 usage (1); 440 usage (1);
345} 441}
442

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines