ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.16
Committed: Thu Jul 18 13:35:16 2013 UTC (10 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.15: +3 -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     BN_GENCB cb;
284     BN_GENCB_set (&cb, indicator, 0);
285    
286     require (RSA_generate_key_ex (rsa, bits, e, &cb));
287 pcg 1.1
288 root 1.13 fprintf (stderr, _("Done.\n"));
289 pcg 1.1
290 root 1.15 fname = conf.config_filename ("pubkey/%s", 0);
291     pubf = fopen (fname, "wb");
292     if (!pubf)
293 pcg 1.1 {
294     perror (fname);
295     exit (EXIT_FAILURE);
296     }
297    
298 root 1.15 free (fname);
299    
300     require (PEM_write_RSAPublicKey (pubf, rsa));
301     fclose (pubf);
302    
303 root 1.13 require (PEM_write_RSAPrivateKey (f, rsa, NULL, NULL, 0, NULL, NULL));
304 pcg 1.1 fclose (f);
305 root 1.13
306     BN_free (e);
307     RSA_free (rsa);
308 pcg 1.1 }
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 pcg 1.6 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
328 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
329     printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
330     printf (_
331 root 1.13 ("Copyright (C) 2003-2013 Marc Lehmann <gvpe@schmorp.de> and others.\n"
332 pcg 1.1 "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 pcg 1.3 {
344     configuration_parser (conf, false, 0, 0);
345     }
346 pcg 1.1
347 root 1.15 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 root 1.16 printf ("raw_overhead=%d\n", VPE_OVERHEAD);
356     printf ("vpn_overhead=%d\n", VPE_OVERHEAD + 6 + 6);
357     printf ("udp_overhead=%d\n", UDP_OVERHEAD + VPE_OVERHEAD + 6 + 6);
358 root 1.15 exit (EXIT_SUCCESS);
359     }
360    
361 pcg 1.1 if (generate_keys)
362     {
363 root 1.14 RAND_load_file (conf.seed_dev, SEED_SIZE);
364 pcg 1.1 exit (keygen (generate_keys));
365     }
366    
367 pcg 1.2 if (kill_gvpe)
368     exit (kill_other (kill_gvpe));
369 pcg 1.1
370     if (show_config)
371     {
372     conf.print ();
373     exit (EXIT_SUCCESS);
374     }
375    
376     usage (1);
377     }
378 root 1.15