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