ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.15
Committed: Tue Jul 16 16:44:36 2013 UTC (10 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.14: +35 -22 lines
Log Message:
3.x

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-2013 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 public/private keypair for this net. */
78 static int generate_keys;
79
80 // output some debugging info, interna constants &c
81 static int debug_info;
82
83 static struct option const long_options[] =
84 {
85 {"config", required_argument, NULL, 'c'},
86 {"kill", optional_argument, NULL, 'k'},
87 {"help", no_argument, &show_help, 1},
88 {"version", no_argument, &show_version, 1},
89 {"generate-keys", no_argument, NULL, 'g'},
90 {"quiet", no_argument, &quiet, 1},
91 {"show-config", no_argument, &show_config, 's'},
92 {"debug-info", no_argument, &debug_info, 1},
93 {NULL, 0, NULL, 0}
94 };
95
96 static void
97 usage (int status)
98 {
99 if (status != 0)
100 fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ());
101 else
102 {
103 printf (_("Usage: %s [option]...\n\n"), get_identity ());
104 printf (_
105 (" -c, --config=DIR Read configuration options from DIR.\n"
106 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
107 " -g, --generate-keys Generate public/private RSA keypair.\n"
108 " -s, --show-config Display the configuration information.\n"
109 " -q, --quiet Be quite quiet.\n"
110 " --help Display this help and exit.\n"
111 " --version Output version information and exit.\n\n"));
112 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
113 }
114
115 exit (status);
116 }
117
118 static void
119 parse_options (int argc, char **argv, char **envp)
120 {
121 int r;
122 int option_index = 0;
123
124 while ((r = getopt_long (argc, argv, "c:k::qgs", long_options, &option_index)) != EOF)
125 {
126 switch (r)
127 {
128 case 0: /* long option */
129 break;
130
131 case 'c': /* config file */
132 confbase = strdup (optarg);
133 break;
134
135 case 'k': /* kill old gvpes */
136 if (optarg)
137 {
138 if (!strcasecmp (optarg, "HUP"))
139 kill_gvpe = SIGHUP;
140 else if (!strcasecmp (optarg, "TERM"))
141 kill_gvpe = SIGTERM;
142 else if (!strcasecmp (optarg, "KILL"))
143 kill_gvpe = SIGKILL;
144 else if (!strcasecmp (optarg, "USR1"))
145 kill_gvpe = SIGUSR1;
146 else if (!strcasecmp (optarg, "USR2"))
147 kill_gvpe = SIGUSR2;
148 else if (!strcasecmp (optarg, "INT"))
149 kill_gvpe = SIGINT;
150 else if (!strcasecmp (optarg, "ALRM"))
151 kill_gvpe = SIGALRM;
152 else
153 {
154 kill_gvpe = atoi (optarg);
155
156 if (!kill_gvpe)
157 {
158 fprintf (stderr,
159 _
160 ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
161 optarg);
162 usage (1);
163 }
164 }
165 }
166 else
167 kill_gvpe = SIGTERM;
168
169 break;
170
171 case 'g': /* generate public/private keypair */
172 generate_keys = RSABITS;
173 break;
174
175 case 's':
176 show_config = 1;
177 break;
178
179 case 'q':
180 quiet = 1;
181 break;
182
183 case '?':
184 usage (1);
185
186 default:
187 break;
188 }
189 }
190 }
191
192 // this function prettyprints the key generation process
193 static int
194 indicator (int a, int b, BN_GENCB *cb)
195 {
196 if (quiet)
197 return 1;
198
199 switch (a)
200 {
201 case 0:
202 fprintf (stderr, ".");
203 break;
204
205 case 1:
206 fprintf (stderr, "+");
207 break;
208
209 case 2:
210 fprintf (stderr, "-");
211 break;
212
213 case 3:
214 switch (b)
215 {
216 case 0:
217 fprintf (stderr, " p\n");
218 break;
219
220 case 1:
221 fprintf (stderr, " q\n");
222 break;
223
224 default:
225 fprintf (stderr, "?");
226 }
227 break;
228
229 default:
230 fprintf (stderr, "?");
231 }
232
233 return 1;
234 }
235
236 /*
237 * generate public/private RSA keypairs for all hosts that don't have one.
238 */
239 static int
240 keygen (int bits)
241 {
242 FILE *f, *pubf;
243 char *fname;
244
245 asprintf (&fname, "%s/pubkey", confbase);
246 mkdir (fname, 0700);
247 free (fname);
248
249 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
250 {
251 conf_node *node = *i;
252
253 ::thisnode = node->nodename;
254
255 fname = conf.config_filename (conf.prikeyfile, "hostkey");
256
257 f = fopen (fname, "ab");
258
259 /* some libcs are buggy and require an extra seek to the end */
260 if (!f || fseek (f, 0, SEEK_END))
261 {
262 perror (fname);
263 exit (EXIT_FAILURE);
264 }
265
266 if (ftell (f))
267 {
268 if (!quiet)
269 fprintf (stderr, "'%s' already exists, skipping node %s\n", fname, node->nodename);
270
271 free (fname);
272 fclose (f);
273 continue;
274 }
275
276 free (fname);
277
278 fprintf (stderr, _("generating %d bits key for %s:\n"), bits, node->nodename);
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 BN_GENCB cb;
284 BN_GENCB_set (&cb, indicator, 0);
285
286 require (RSA_generate_key_ex (rsa, bits, e, &cb));
287
288 fprintf (stderr, _("Done.\n"));
289
290 fname = conf.config_filename ("pubkey/%s", 0);
291 pubf = fopen (fname, "wb");
292 if (!pubf)
293 {
294 perror (fname);
295 exit (EXIT_FAILURE);
296 }
297
298 free (fname);
299
300 require (PEM_write_RSAPublicKey (pubf, rsa));
301 fclose (pubf);
302
303 require (PEM_write_RSAPrivateKey (f, rsa, NULL, NULL, 0, NULL, NULL));
304 fclose (f);
305
306 BN_free (e);
307 RSA_free (rsa);
308 }
309
310 return 0;
311 }
312
313 int
314 main (int argc, char **argv, char **envp)
315 {
316 set_identity (argv[0]);
317 log_to (LOGTO_STDERR);
318
319 setlocale (LC_ALL, "");
320 bindtextdomain (PACKAGE, LOCALEDIR);
321 textdomain (PACKAGE);
322
323 parse_options (argc, argv, envp);
324
325 if (show_version)
326 {
327 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
328 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
329 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
330 printf (_
331 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
332 "See the AUTHORS file for a complete list.\n\n"
333 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
334 "and you are welcome to redistribute it under certain conditions;\n"
335 "see the file COPYING for details.\n"));
336
337 return 0;
338 }
339
340 if (show_help)
341 usage (0);
342
343 {
344 configuration_parser (conf, false, 0, 0);
345 }
346
347 if (debug_info)
348 {
349 printf ("cipher_nid=%d\n", EVP_CIPHER_nid (CIPHER ()));
350 printf ("mac_nid=%d\n", EVP_MD_type (MAC_DIGEST ()));
351 printf ("auth_nid=%d\n", EVP_MD_type (AUTH_DIGEST ()));
352 printf ("sizeof_auth_data=%d\n", sizeof (auth_data));
353 printf ("sizeof_rsa_data=%d\n", sizeof (rsa_data));
354 printf ("sizeof_rsa_data_pad=%d\n", sizeof (((rsa_data *)0)->pad));
355 exit (EXIT_SUCCESS);
356 }
357
358 if (generate_keys)
359 {
360 RAND_load_file (conf.seed_dev, SEED_SIZE);
361 exit (keygen (generate_keys));
362 }
363
364 if (kill_gvpe)
365 exit (kill_other (kill_gvpe));
366
367 if (show_config)
368 {
369 conf.print ();
370 exit (EXIT_SUCCESS);
371 }
372
373 usage (1);
374 }
375