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.4 by pcg, Tue Apr 26 00:55:56 2005 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-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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 /* some libcs are buggy and require an extra seek to the end */
217 FILE *f; 252
218 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{
219 char *fname; 314 char *fname;
220
221 asprintf (&fname, "%s/hostkeys", confbase);
222 mkdir (fname, 0700);
223 free (fname);
224 315
225 asprintf (&fname, "%s/pubkey", confbase); 316 asprintf (&fname, "%s/pubkey", confbase);
226 mkdir (fname, 0700); 317 mkdir (fname, 0700);
227 free (fname); 318 free (fname);
228 319
229 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)
230 { 321 {
231 conf_node *node = *i; 322 conf_node *node = *i;
232 323
233 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename); 324 ::thisnode = node->nodename;
234 325
235 f = fopen (fname, "a"); 326 char *pub = conf.config_filename ("pubkey/%s", 0);
327 char *priv = conf.config_filename (conf.prikeyfile, "hostkey");
236 328
237 if (!f) 329 int status = keygen (pub, priv);
330
331 if (status == 0)
238 { 332 {
239 perror (fname); 333 if (!quiet)
240 exit (EXIT_FAILURE); 334 fprintf (stderr, _("generated %d bits key for %s.\n"), RSABITS, node->nodename);
241 } 335 }
336 else if (status == 1)
337 fprintf (stderr, _("'%s' keypair already exists, skipping node %s.\n"), pub, node->nodename);
242 338
243 if (ftell (f)) 339 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); 340 free (pub);
341 }
267 342
268 asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename); 343 return 0;
344}
269 345
270 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 {
271 if (!f) 357 if (!quiet)
272 { 358 fprintf (stderr, _("generated %d bits key as %s.\n"), RSABITS, pubname);
273 perror (fname); 359 }
360 else if (status == 1)
361 {
362 fprintf (stderr, _("'%s' keypair already exists, not generating key.\n"), pubname);
274 exit (EXIT_FAILURE); 363 exit (EXIT_FAILURE);
275 } 364 }
276 365
277 require (PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL));
278 fclose (f);
279 free (fname); 366 free (privname);
280 }
281 367
282 return 0; 368 return 0;
283} 369}
284 370
285int 371int
294 380
295 parse_options (argc, argv, envp); 381 parse_options (argc, argv, envp);
296 382
297 if (show_version) 383 if (show_version)
298 { 384 {
299 printf (_("%s version %s (built %s %s, protocol %d.%d)\n"), get_identity (), 385 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
300 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); 386 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
301 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); 387 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
302 printf (_ 388 printf (_
303 ("Copyright (C) 2003 Marc Lehmann <vpe@plan9.de> and others.\n" 389 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
304 "See the AUTHORS file for a complete list.\n\n" 390 "See the AUTHORS file for a complete list.\n\n"
305 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n" 391 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
306 "and you are welcome to redistribute it under certain conditions;\n" 392 "and you are welcome to redistribute it under certain conditions;\n"
307 "see the file COPYING for details.\n")); 393 "see the file COPYING for details.\n"));
308 394
314 400
315 { 401 {
316 configuration_parser (conf, false, 0, 0); 402 configuration_parser (conf, false, 0, 0);
317 } 403 }
318 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
319 if (generate_keys) 425 if (generate_keys)
320 { 426 {
321 RAND_load_file ("/dev/urandom", 1024); 427 RAND_load_file (conf.seed_dev, SEED_SIZE);
322 exit (keygen (generate_keys)); 428 exit (keygen_all ());
323 } 429 }
324 430
325 if (kill_gvpe) 431 if (kill_gvpe)
326 exit (kill_other (kill_gvpe)); 432 exit (kill_other (kill_gvpe));
327 433
331 exit (EXIT_SUCCESS); 437 exit (EXIT_SUCCESS);
332 } 438 }
333 439
334 usage (1); 440 usage (1);
335} 441}
442

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines