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.3 by pcg, Mon Mar 28 20:39:18 2005 UTC vs.
Revision 1.24 by root, Thu Oct 25 03:13:13 2018 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-2005 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 9 GVPE is free software; you can redistribute it and/or modify it
10 it under the terms of the GNU General Public License as published by 10 under the terms of the GNU General Public License as published by the
11 the Free Software Foundation; either version 2 of the License, or 11 Free Software Foundation; either version 3 of the License, or (at your
12 (at your option) any later version. 12 option) any later version.
13 13
14 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful, but
15 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 GNU General Public License for more details. 17 Public License for more details.
18 18
19 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License along
20 along with gvpe; if not, write to the Free Software 20 with this program; if not, see <http://www.gnu.org/licenses/>.
21 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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.
22*/ 32*/
23 33
24#include "config.h" 34#include "config.h"
25 35
26#include <cstdio> 36#include <cstdio>
34#include <sys/stat.h> 44#include <sys/stat.h>
35#include <sys/types.h> 45#include <sys/types.h>
36#include <unistd.h> 46#include <unistd.h>
37#include <signal.h> 47#include <signal.h>
38 48
49#include <openssl/bn.h>
39#include <openssl/rand.h> 50#include <openssl/rand.h>
40#include <openssl/rsa.h> 51#include <openssl/rsa.h>
41#include <openssl/pem.h> 52#include <openssl/pem.h>
42#include <openssl/evp.h> 53#include <openssl/evp.h>
43 54
58static int kill_gvpe; 69static int kill_gvpe;
59 70
60/* 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. */
61static int show_config; 72static int show_config;
62 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
63/* If nonzero, generate public/private keypair for this net. */ 80/* If nonzero, generate public/private keypair for this net. */
64static int generate_keys; 81static int generate_keys;
65 82
83// output some debugging info, interna constants &c
84static int debug_info;
85
66static struct option const long_options[] = 86static struct option const long_options[] =
67 { 87{
68 {"config", required_argument, NULL, 'c'}, 88 {"config", required_argument, NULL, 'c'},
69 {"kill", optional_argument, NULL, 'k'}, 89 {"kill", optional_argument, NULL, 'k'},
70 {"help", no_argument, &show_help, 1}, 90 {"help", no_argument, &show_help, 1},
71 {"version", no_argument, &show_version, 1}, 91 {"version", no_argument, &show_version, 1},
92 {"generate-key", required_argument, NULL, 'g'},
72 {"generate-keys", no_argument, NULL, 'g'}, 93 {"generate-keys", no_argument, NULL, 'G'},
94 {"quiet", no_argument, &quiet, 1},
73 {"show-config", no_argument, &show_config, 's'}, 95 {"show-config", no_argument, &show_config, 's'},
96 {"debug-info", no_argument, &debug_info, 1},
74 {NULL, 0, NULL, 0} 97 {NULL, 0, NULL, 0}
75 }; 98};
76 99
77static void 100static void
78usage (int status) 101usage (int status)
79{ 102{
80 if (status != 0) 103 if (status != 0)
83 { 106 {
84 printf (_("Usage: %s [option]...\n\n"), get_identity ()); 107 printf (_("Usage: %s [option]...\n\n"), get_identity ());
85 printf (_ 108 printf (_
86 (" -c, --config=DIR Read configuration options from DIR.\n" 109 (" -c, --config=DIR Read configuration options from DIR.\n"
87 " -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"
88 " -g, --generate-keys Generate public/private RSA keypair.\n" 112 " -G, --generate-keys Generate all public/private RSA keypairs.\n"
89 " -s, --show-config Display the configuration information.\n" 113 " -s, --show-config Display the configuration information.\n"
114 " -q, --quiet Be quite quiet.\n"
90 " --help Display this help and exit.\n" 115 " --help Display this help and exit.\n"
91 " --version Output version information and exit.\n\n")); 116 " --version Output version information and exit.\n\n"));
92 printf (_("Report bugs to <vpe@plan9.de>.\n")); 117 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
93 } 118 }
94 119
95 exit (status); 120 exit (status);
96} 121}
97 122
98void 123static void
99parse_options (int argc, char **argv, char **envp) 124parse_options (int argc, char **argv, char **envp)
100{ 125{
101 int r; 126 int r;
102 int option_index = 0; 127 int option_index = 0;
103 128
104 while ((r = 129 while ((r = getopt_long (argc, argv, "c:k::qg:Gs", long_options, &option_index)) != EOF)
105 getopt_long (argc, argv, "c:k::gs", long_options,
106 &option_index)) != EOF)
107 { 130 {
108 switch (r) 131 switch (r)
109 { 132 {
110 case 0: /* long option */ 133 case 0: /* long option */
111 break; 134 break;
112 135
113 case 'c': /* config file */ 136 case 'c': /* config file */
114 confbase = strdup (optarg); 137 confbase = strdup (optarg);
115 break; 138 break;
116 139
117 case 'k': /* kill old gvpes */ 140 case 'k': /* kill old gvpes */
118 if (optarg) 141 if (optarg)
119 { 142 {
120 if (!strcasecmp (optarg, "HUP")) 143 if (!strcasecmp (optarg, "HUP"))
121 kill_gvpe = SIGHUP; 144 kill_gvpe = SIGHUP;
122 else if (!strcasecmp (optarg, "TERM")) 145 else if (!strcasecmp (optarg, "TERM"))
123 kill_gvpe = SIGTERM; 146 kill_gvpe = SIGTERM;
124 else if (!strcasecmp (optarg, "KILL")) 147 else if (!strcasecmp (optarg, "KILL"))
125 kill_gvpe = SIGKILL; 148 kill_gvpe = SIGKILL;
126 else if (!strcasecmp (optarg, "USR1")) 149 else if (!strcasecmp (optarg, "USR1"))
127 kill_gvpe = SIGUSR1; 150 kill_gvpe = SIGUSR1;
128 else if (!strcasecmp (optarg, "USR2")) 151 else if (!strcasecmp (optarg, "USR2"))
129 kill_gvpe = SIGUSR2; 152 kill_gvpe = SIGUSR2;
130 else if (!strcasecmp (optarg, "INT")) 153 else if (!strcasecmp (optarg, "INT"))
131 kill_gvpe = SIGINT; 154 kill_gvpe = SIGINT;
132 else if (!strcasecmp (optarg, "ALRM")) 155 else if (!strcasecmp (optarg, "ALRM"))
133 kill_gvpe = SIGALRM; 156 kill_gvpe = SIGALRM;
134 else 157 else
135 { 158 {
136 kill_gvpe = atoi (optarg); 159 kill_gvpe = atoi (optarg);
137 160
138 if (!kill_gvpe) 161 if (!kill_gvpe)
139 { 162 {
140 fprintf (stderr, 163 fprintf (stderr,
141 _ 164 _
142 ("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"),
143 optarg); 166 optarg);
144 usage (1); 167 usage (1);
145 } 168 }
146 } 169 }
147 } 170 }
148 else 171 else
149 kill_gvpe = SIGTERM; 172 kill_gvpe = SIGTERM;
150 173
151 break; 174 break;
152 175
153 case 'g': /* generate public/private keypair */ 176 case 'g': /* generate public/private keypair */
154 generate_keys = RSA_KEYBITS; 177 generate_key = optarg;
155 break; 178 break;
156 179
180 case 'G': /* generate public/private keypairs */
181 generate_keys = 1;
182 break;
183
157 case 's': 184 case 's':
158 show_config = 1; 185 show_config = 1;
159 break; 186 break;
160 187
188 case 'q':
189 quiet = 1;
190 break;
191
161 case '?': 192 case '?':
162 usage (1); 193 usage (1);
163 194
164 default: 195 default:
165 break; 196 break;
166 } 197 }
167 } 198 }
168} 199}
169 200
170/* This function prettyprints the key generation process */ 201// this function prettyprints the key generation process
171 202static int
172void
173indicator (int a, int b, void *p) 203indicator (int a, int b, BN_GENCB *cb)
174{ 204{
205 if (quiet)
206 return 1;
207
175 switch (a) 208 switch (a)
176 { 209 {
177 case 0: 210 case 0:
178 fprintf (stderr, "."); 211 fprintf (stderr, ".");
179 break; 212 break;
180 213
181 case 1: 214 case 1:
182 fprintf (stderr, "+"); 215 fprintf (stderr, "+");
183 break; 216 break;
184 217
185 case 2: 218 case 2:
186 fprintf (stderr, "-"); 219 fprintf (stderr, "-");
187 break; 220 break;
188 221
189 case 3: 222 case 3:
190 switch (b) 223 switch (b)
191 { 224 {
192 case 0: 225 case 0:
193 fprintf (stderr, " p\n"); 226 fprintf (stderr, " p\n");
194 break; 227 break;
195 228
196 case 1: 229 case 1:
197 fprintf (stderr, " q\n"); 230 fprintf (stderr, " q\n");
198 break; 231 break;
199 232
200 default: 233 default:
201 fprintf (stderr, "?"); 234 fprintf (stderr, "?");
202 } 235 }
203 break; 236 break;
204 237
205 default: 238 default:
206 fprintf (stderr, "?"); 239 fprintf (stderr, "?");
207 } 240 }
241
242 return 1;
208} 243}
209 244
210/* 245/*
211 * 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.
212 */ 247 */
213int 248static int
214keygen (int bits) 249keygen (const char *pub, const char *priv)
215{ 250{
216 RSA *rsa_key; 251
217 FILE *f; 252 FILE *pubf = fopen (pub, "ab");
218 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{
219 char *fname; 315 char *fname;
220
221 asprintf (&fname, "%s/hostkeys", confbase);
222 mkdir (fname, 0700);
223 free (fname);
224 316
225 asprintf (&fname, "%s/pubkey", confbase); 317 asprintf (&fname, "%s/pubkey", confbase);
226 mkdir (fname, 0700); 318 mkdir (fname, 0700);
227 free (fname); 319 free (fname);
228 320
229 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)
230 { 322 {
231 conf_node *node = *i; 323 conf_node *node = *i;
232 324
233 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename); 325 ::thisnode = node->nodename;
234 326
235 f = fopen (fname, "a"); 327 char *pub = conf.config_filename ("pubkey/%s", 0);
328 char *priv = conf.config_filename (conf.prikeyfile, "hostkey");
236 329
237 if (!f) 330 int status = keygen (pub, priv);
331
332 if (status == 0)
238 { 333 {
239 perror (fname); 334 if (!quiet)
240 exit (EXIT_FAILURE); 335 fprintf (stderr, _("generated %d bits key for %s.\n"), RSABITS, node->nodename);
241 } 336 }
337 else if (status == 1)
338 fprintf (stderr, _("'%s' keypair already exists, skipping node %s.\n"), pub, node->nodename);
242 339
243 if (ftell (f)) 340 free (priv);
244 {
245 fprintf (stderr, "'%s' already exists, skipping this node\n",
246 fname);
247 fclose (f);
248 continue;
249 }
250
251 fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
252 node->nodename);
253
254 rsa_key = RSA_generate_key (bits, 0xFFFF, indicator, NULL);
255
256 if (!rsa_key)
257 {
258 fprintf (stderr, _("error during key generation!\n"));
259 return -1;
260 }
261 else
262 fprintf (stderr, _("Done.\n"));
263
264 require (PEM_write_RSAPublicKey (f, rsa_key));
265 fclose (f);
266 free (fname); 341 free (pub);
342 }
267 343
268 asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename); 344 return 0;
345}
269 346
270 f = fopen (fname, "a"); 347static int
348keygen_one (const char *pubname)
349{
350 char *privname;
351
352 asprintf (&privname, "%s.privkey", pubname);
353
354 int status = keygen (pubname, privname);
355
356 if (status == 0)
357 {
271 if (!f) 358 if (!quiet)
272 { 359 fprintf (stderr, _("generated %d bits key as %s.\n"), RSABITS, pubname);
273 perror (fname); 360 }
361 else if (status == 1)
362 {
363 fprintf (stderr, _("'%s' keypair already exists, not generating key.\n"), pubname);
274 exit (EXIT_FAILURE); 364 exit (EXIT_FAILURE);
275 } 365 }
276 366
277 require (PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL));
278 fclose (f);
279 free (fname); 367 free (privname);
280 }
281 368
282 return 0; 369 return 0;
283} 370}
284 371
285int 372int
294 381
295 parse_options (argc, argv, envp); 382 parse_options (argc, argv, envp);
296 383
297 if (show_version) 384 if (show_version)
298 { 385 {
299 printf (_("%s version %s (built %s %s, protocol %d.%d)\n"), get_identity (), 386 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
300 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); 387 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
301 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); 388 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
302 printf (_ 389 printf (_
303 ("Copyright (C) 2003 Marc Lehmann <vpe@plan9.de> and others.\n" 390 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
304 "See the AUTHORS file for a complete list.\n\n" 391 "See the AUTHORS file for a complete list.\n\n"
305 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n" 392 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
306 "and you are welcome to redistribute it under certain conditions;\n" 393 "and you are welcome to redistribute it under certain conditions;\n"
307 "see the file COPYING for details.\n")); 394 "see the file COPYING for details.\n"));
308 395
314 401
315 { 402 {
316 configuration_parser (conf, false, 0, 0); 403 configuration_parser (conf, false, 0, 0);
317 } 404 }
318 405
406 if (debug_info)
407 {
408 printf ("cipher_nid=%d\n", EVP_CIPHER_nid (CIPHER ()));
409 printf ("mac_nid=%d\n", EVP_MD_type (MAC_DIGEST ()));
410 printf ("auth_nid=%d\n", EVP_MD_type (AUTH_DIGEST ()));
411 printf ("sizeof_auth_data=%d\n", sizeof (auth_data));
412 printf ("sizeof_rsa_data=%d\n", sizeof (rsa_data));
413 printf ("sizeof_rsa_data_extra_auth=%d\n", sizeof (((rsa_data *)0)->extra_auth));
414 printf ("raw_overhead=%d\n", VPE_OVERHEAD);
415 printf ("vpn_overhead=%d\n", VPE_OVERHEAD + 6 + 6);
416 printf ("udp_overhead=%d\n", UDP_OVERHEAD + VPE_OVERHEAD + 6 + 6);
417 exit (EXIT_SUCCESS);
418 }
419
420 if (generate_key)
421 {
422 RAND_load_file (conf.seed_dev, SEED_SIZE);
423 exit (keygen_one (generate_key));
424 }
425
319 if (generate_keys) 426 if (generate_keys)
320 { 427 {
321 RAND_load_file ("/dev/urandom", 1024); 428 RAND_load_file (conf.seed_dev, SEED_SIZE);
322 exit (keygen (generate_keys)); 429 exit (keygen_all ());
323 } 430 }
324 431
325 if (kill_gvpe) 432 if (kill_gvpe)
326 exit (kill_other (kill_gvpe)); 433 exit (kill_other (kill_gvpe));
327 434
331 exit (EXIT_SUCCESS); 438 exit (EXIT_SUCCESS);
332 } 439 }
333 440
334 usage (1); 441 usage (1);
335} 442}
443

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines