ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.18
Committed: Wed Jun 29 22:32:48 2016 UTC (7 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.17: +6 -0 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.13 BN_GENCB cb;
286     BN_GENCB_set (&cb, indicator, 0);
287 root 1.18 #else
288     BN_GENCB *cb = BN_GENCB_new ();
289     BN_GENCB_set (cb, indicator, 0);
290     #endif
291 root 1.13
292     require (RSA_generate_key_ex (rsa, bits, e, &cb));
293 pcg 1.1
294 root 1.13 fprintf (stderr, _("Done.\n"));
295 pcg 1.1
296 root 1.15 fname = conf.config_filename ("pubkey/%s", 0);
297     pubf = fopen (fname, "wb");
298     if (!pubf)
299 pcg 1.1 {
300     perror (fname);
301     exit (EXIT_FAILURE);
302     }
303    
304 root 1.15 free (fname);
305    
306     require (PEM_write_RSAPublicKey (pubf, rsa));
307     fclose (pubf);
308    
309 root 1.13 require (PEM_write_RSAPrivateKey (f, rsa, NULL, NULL, 0, NULL, NULL));
310 pcg 1.1 fclose (f);
311 root 1.13
312     BN_free (e);
313     RSA_free (rsa);
314 pcg 1.1 }
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 pcg 1.6 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
334 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
335     printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
336     printf (_
337 root 1.13 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
338 pcg 1.1 "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 pcg 1.3 {
350     configuration_parser (conf, false, 0, 0);
351     }
352 pcg 1.1
353 root 1.15 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 root 1.17 printf ("sizeof_rsa_data_extra_auth=%d\n", sizeof (((rsa_data *)0)->extra_auth));
361 root 1.16 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 root 1.15 exit (EXIT_SUCCESS);
365     }
366    
367 pcg 1.1 if (generate_keys)
368     {
369 root 1.14 RAND_load_file (conf.seed_dev, SEED_SIZE);
370 pcg 1.1 exit (keygen (generate_keys));
371     }
372    
373 pcg 1.2 if (kill_gvpe)
374     exit (kill_other (kill_gvpe));
375 pcg 1.1
376     if (show_config)
377     {
378     conf.print ();
379     exit (EXIT_SUCCESS);
380     }
381    
382     usage (1);
383     }
384 root 1.15