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

File Contents

# User Rev Content
1 pcg 1.1 /*
2 pcg 1.2 gvpectrl.C -- the main file for gvpectrl
3 pcg 1.1 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4     2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 root 1.13 2003-2013 Marc Lehmann <gvpe@schmorp.de>
6 pcg 1.1
7     This file is part of GVPE.
8    
9 pcg 1.7 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 pcg 1.1 */
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 root 1.13 #include <openssl/bn.h>
50 pcg 1.1 #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 pcg 1.2 /* If nonzero, it will attempt to kill a running gvpe and exit. */
69     static int kill_gvpe;
70 pcg 1.1
71 pcg 1.2 /* If nonzero, it will attempt to kill a running gvpe and exit. */
72 pcg 1.1 static int show_config;
73    
74 pcg 1.8 /* If nonzero, do not output anything but warnings/errors/very unusual conditions */
75     static int quiet;
76    
77 pcg 1.1 /* If nonzero, generate public/private keypair for this net. */
78     static int generate_keys;
79    
80 root 1.15 // output some debugging info, interna constants &c
81     static int debug_info;
82    
83 pcg 1.1 static struct option const long_options[] =
84 root 1.10 {
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 root 1.15 {"debug-info", no_argument, &debug_info, 1},
93 root 1.10 {NULL, 0, NULL, 0}
94     };
95 pcg 1.1
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 pcg 1.2 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
107 pcg 1.1 " -g, --generate-keys Generate public/private RSA keypair.\n"
108     " -s, --show-config Display the configuration information.\n"
109 pcg 1.8 " -q, --quiet Be quite quiet.\n"
110 pcg 1.1 " --help Display this help and exit.\n"
111     " --version Output version information and exit.\n\n"));
112 pcg 1.5 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
113 pcg 1.1 }
114    
115     exit (status);
116     }
117    
118 root 1.10 static void
119 pcg 1.1 parse_options (int argc, char **argv, char **envp)
120     {
121     int r;
122     int option_index = 0;
123    
124 pcg 1.8 while ((r = getopt_long (argc, argv, "c:k::qgs", long_options, &option_index)) != EOF)
125 pcg 1.1 {
126     switch (r)
127     {
128 root 1.10 case 0: /* long option */
129     break;
130 pcg 1.1
131 root 1.10 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 root 1.15 generate_keys = RSABITS;
173 root 1.10 break;
174    
175     case 's':
176     show_config = 1;
177     break;
178    
179     case 'q':
180     quiet = 1;
181     break;
182 pcg 1.8
183 root 1.10 case '?':
184     usage (1);
185 pcg 1.1
186 root 1.10 default:
187     break;
188 pcg 1.1 }
189     }
190     }
191    
192 root 1.10 // this function prettyprints the key generation process
193 root 1.13 static int
194     indicator (int a, int b, BN_GENCB *cb)
195 pcg 1.1 {
196 pcg 1.8 if (quiet)
197 root 1.13 return 1;
198 pcg 1.8
199 pcg 1.1 switch (a)
200     {
201 root 1.10 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 pcg 1.1
229 root 1.10 default:
230     fprintf (stderr, "?");
231 pcg 1.1 }
232 root 1.13
233     return 1;
234 pcg 1.1 }
235    
236     /*
237     * generate public/private RSA keypairs for all hosts that don't have one.
238     */
239 root 1.10 static int
240 pcg 1.1 keygen (int bits)
241     {
242 root 1.15 FILE *f, *pubf;
243 pcg 1.1 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 root 1.15 ::thisnode = node->nodename;
254    
255     fname = conf.config_filename (conf.prikeyfile, "hostkey");
256 pcg 1.1
257 root 1.15 f = fopen (fname, "ab");
258 pcg 1.1
259 root 1.12 /* some libcs are buggy and require an extra seek to the end */
260     if (!f || fseek (f, 0, SEEK_END))
261 pcg 1.1 {
262     perror (fname);
263     exit (EXIT_FAILURE);
264     }
265    
266     if (ftell (f))
267     {
268 pcg 1.8 if (!quiet)
269 root 1.15 fprintf (stderr, "'%s' already exists, skipping node %s\n", fname, node->nodename);
270 pcg 1.8
271 root 1.15 free (fname);
272 pcg 1.1 fclose (f);
273     continue;
274     }
275    
276 root 1.15 free (fname);
277    
278     fprintf (stderr, _("generating %d bits key for %s:\n"), bits, node->nodename);
279 pcg 1.1
280 root 1.13 RSA *rsa = RSA_new ();
281     BIGNUM *e = BN_new ();
282     BN_set_bit (e, 0); BN_set_bit (e, 16); // 0x10001, 65537
283 root 1.18
284     #if OPENSSL_VERSION_NUMBER < 0x10100000
285 root 1.20 BN_GENCB cb_100;
286     BN_GENCB *cb = &cb_100;
287 root 1.18 #else
288     BN_GENCB *cb = BN_GENCB_new ();
289 root 1.20 require (cb);
290     #endif
291    
292 root 1.18 BN_GENCB_set (cb, indicator, 0);
293 root 1.19 require (RSA_generate_key_ex (rsa, bits, e, cb));
294 root 1.13
295     fprintf (stderr, _("Done.\n"));
296 pcg 1.1
297 root 1.15 fname = conf.config_filename ("pubkey/%s", 0);
298     pubf = fopen (fname, "wb");
299     if (!pubf)
300 pcg 1.1 {
301     perror (fname);
302     exit (EXIT_FAILURE);
303     }
304    
305 root 1.15 free (fname);
306    
307     require (PEM_write_RSAPublicKey (pubf, rsa));
308     fclose (pubf);
309    
310 root 1.13 require (PEM_write_RSAPrivateKey (f, rsa, NULL, NULL, 0, NULL, NULL));
311 pcg 1.1 fclose (f);
312 root 1.13
313     BN_free (e);
314     RSA_free (rsa);
315 pcg 1.1 }
316    
317     return 0;
318     }
319    
320     int
321     main (int argc, char **argv, char **envp)
322     {
323     set_identity (argv[0]);
324     log_to (LOGTO_STDERR);
325    
326     setlocale (LC_ALL, "");
327     bindtextdomain (PACKAGE, LOCALEDIR);
328     textdomain (PACKAGE);
329    
330     parse_options (argc, argv, envp);
331    
332     if (show_version)
333     {
334 pcg 1.6 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
335 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
336     printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
337     printf (_
338 root 1.13 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
339 pcg 1.1 "See the AUTHORS file for a complete list.\n\n"
340     "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
341     "and you are welcome to redistribute it under certain conditions;\n"
342     "see the file COPYING for details.\n"));
343    
344     return 0;
345     }
346    
347     if (show_help)
348     usage (0);
349    
350 pcg 1.3 {
351     configuration_parser (conf, false, 0, 0);
352     }
353 pcg 1.1
354 root 1.15 if (debug_info)
355     {
356     printf ("cipher_nid=%d\n", EVP_CIPHER_nid (CIPHER ()));
357     printf ("mac_nid=%d\n", EVP_MD_type (MAC_DIGEST ()));
358     printf ("auth_nid=%d\n", EVP_MD_type (AUTH_DIGEST ()));
359     printf ("sizeof_auth_data=%d\n", sizeof (auth_data));
360     printf ("sizeof_rsa_data=%d\n", sizeof (rsa_data));
361 root 1.17 printf ("sizeof_rsa_data_extra_auth=%d\n", sizeof (((rsa_data *)0)->extra_auth));
362 root 1.16 printf ("raw_overhead=%d\n", VPE_OVERHEAD);
363     printf ("vpn_overhead=%d\n", VPE_OVERHEAD + 6 + 6);
364     printf ("udp_overhead=%d\n", UDP_OVERHEAD + VPE_OVERHEAD + 6 + 6);
365 root 1.15 exit (EXIT_SUCCESS);
366     }
367    
368 pcg 1.1 if (generate_keys)
369     {
370 root 1.14 RAND_load_file (conf.seed_dev, SEED_SIZE);
371 pcg 1.1 exit (keygen (generate_keys));
372     }
373    
374 pcg 1.2 if (kill_gvpe)
375     exit (kill_other (kill_gvpe));
376 pcg 1.1
377     if (show_config)
378     {
379     conf.print ();
380     exit (EXIT_SUCCESS);
381     }
382    
383     usage (1);
384     }
385 root 1.15