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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines