ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.19
Committed: Wed Jun 29 22:36:23 2016 UTC (7 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.18: +2 -2 lines
Log Message:
*** empty log message ***

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
284 #if OPENSSL_VERSION_NUMBER < 0x10100000
285 BN_GENCB cb;
286 BN_GENCB_set (&cb, indicator, 0);
287 require (RSA_generate_key_ex (rsa, bits, e, &cb));
288 #else
289 BN_GENCB *cb = BN_GENCB_new ();
290 BN_GENCB_set (cb, indicator, 0);
291 require (RSA_generate_key_ex (rsa, bits, e, cb));
292 #endif
293
294 fprintf (stderr, _("Done.\n"));
295
296 fname = conf.config_filename ("pubkey/%s", 0);
297 pubf = fopen (fname, "wb");
298 if (!pubf)
299 {
300 perror (fname);
301 exit (EXIT_FAILURE);
302 }
303
304 free (fname);
305
306 require (PEM_write_RSAPublicKey (pubf, rsa));
307 fclose (pubf);
308
309 require (PEM_write_RSAPrivateKey (f, rsa, NULL, NULL, 0, NULL, NULL));
310 fclose (f);
311
312 BN_free (e);
313 RSA_free (rsa);
314 }
315
316 return 0;
317 }
318
319 int
320 main (int argc, char **argv, char **envp)
321 {
322 set_identity (argv[0]);
323 log_to (LOGTO_STDERR);
324
325 setlocale (LC_ALL, "");
326 bindtextdomain (PACKAGE, LOCALEDIR);
327 textdomain (PACKAGE);
328
329 parse_options (argc, argv, envp);
330
331 if (show_version)
332 {
333 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
334 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
335 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
336 printf (_
337 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
338 "See the AUTHORS file for a complete list.\n\n"
339 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
340 "and you are welcome to redistribute it under certain conditions;\n"
341 "see the file COPYING for details.\n"));
342
343 return 0;
344 }
345
346 if (show_help)
347 usage (0);
348
349 {
350 configuration_parser (conf, false, 0, 0);
351 }
352
353 if (debug_info)
354 {
355 printf ("cipher_nid=%d\n", EVP_CIPHER_nid (CIPHER ()));
356 printf ("mac_nid=%d\n", EVP_MD_type (MAC_DIGEST ()));
357 printf ("auth_nid=%d\n", EVP_MD_type (AUTH_DIGEST ()));
358 printf ("sizeof_auth_data=%d\n", sizeof (auth_data));
359 printf ("sizeof_rsa_data=%d\n", sizeof (rsa_data));
360 printf ("sizeof_rsa_data_extra_auth=%d\n", sizeof (((rsa_data *)0)->extra_auth));
361 printf ("raw_overhead=%d\n", VPE_OVERHEAD);
362 printf ("vpn_overhead=%d\n", VPE_OVERHEAD + 6 + 6);
363 printf ("udp_overhead=%d\n", UDP_OVERHEAD + VPE_OVERHEAD + 6 + 6);
364 exit (EXIT_SUCCESS);
365 }
366
367 if (generate_keys)
368 {
369 RAND_load_file (conf.seed_dev, SEED_SIZE);
370 exit (keygen (generate_keys));
371 }
372
373 if (kill_gvpe)
374 exit (kill_other (kill_gvpe));
375
376 if (show_config)
377 {
378 conf.print ();
379 exit (EXIT_SUCCESS);
380 }
381
382 usage (1);
383 }
384