ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.9
Committed: Fri Nov 21 05:02:08 2008 UTC (15 years, 6 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_22
Changes since 1.8: +1 -1 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 pcg 1.7 2003-2008 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     #include <openssl/rand.h>
50     #include <openssl/rsa.h>
51     #include <openssl/pem.h>
52     #include <openssl/evp.h>
53    
54     #include "pidfile.h"
55    
56     #include "conf.h"
57     #include "slog.h"
58     #include "util.h"
59     #include "vpn.h"
60    
61     /* If nonzero, display usage information and exit. */
62     static int show_help;
63    
64     /* If nonzero, print the version on standard output and exit. */
65     static int show_version;
66    
67 pcg 1.2 /* If nonzero, it will attempt to kill a running gvpe and exit. */
68     static int kill_gvpe;
69 pcg 1.1
70 pcg 1.2 /* If nonzero, it will attempt to kill a running gvpe and exit. */
71 pcg 1.1 static int show_config;
72    
73 pcg 1.8 /* If nonzero, do not output anything but warnings/errors/very unusual conditions */
74     static int quiet;
75    
76 pcg 1.1 /* If nonzero, generate public/private keypair for this net. */
77     static int generate_keys;
78    
79     static struct option const long_options[] =
80     {
81     {"config", required_argument, NULL, 'c'},
82     {"kill", optional_argument, NULL, 'k'},
83     {"help", no_argument, &show_help, 1},
84     {"version", no_argument, &show_version, 1},
85     {"generate-keys", no_argument, NULL, 'g'},
86 pcg 1.8 {"quiet", no_argument, &quiet, 1},
87 pcg 1.1 {"show-config", no_argument, &show_config, 's'},
88     {NULL, 0, NULL, 0}
89     };
90    
91     static void
92     usage (int status)
93     {
94     if (status != 0)
95     fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ());
96     else
97     {
98     printf (_("Usage: %s [option]...\n\n"), get_identity ());
99     printf (_
100     (" -c, --config=DIR Read configuration options from DIR.\n"
101 pcg 1.2 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
102 pcg 1.1 " -g, --generate-keys Generate public/private RSA keypair.\n"
103     " -s, --show-config Display the configuration information.\n"
104 pcg 1.8 " -q, --quiet Be quite quiet.\n"
105 pcg 1.1 " --help Display this help and exit.\n"
106     " --version Output version information and exit.\n\n"));
107 pcg 1.5 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
108 pcg 1.1 }
109    
110     exit (status);
111     }
112    
113     void
114     parse_options (int argc, char **argv, char **envp)
115     {
116     int r;
117     int option_index = 0;
118    
119 pcg 1.8 while ((r = getopt_long (argc, argv, "c:k::qgs", long_options, &option_index)) != EOF)
120 pcg 1.1 {
121     switch (r)
122     {
123     case 0: /* long option */
124     break;
125    
126     case 'c': /* config file */
127     confbase = strdup (optarg);
128     break;
129    
130 pcg 1.2 case 'k': /* kill old gvpes */
131 pcg 1.1 if (optarg)
132     {
133     if (!strcasecmp (optarg, "HUP"))
134 pcg 1.2 kill_gvpe = SIGHUP;
135 pcg 1.1 else if (!strcasecmp (optarg, "TERM"))
136 pcg 1.2 kill_gvpe = SIGTERM;
137 pcg 1.1 else if (!strcasecmp (optarg, "KILL"))
138 pcg 1.2 kill_gvpe = SIGKILL;
139 pcg 1.1 else if (!strcasecmp (optarg, "USR1"))
140 pcg 1.2 kill_gvpe = SIGUSR1;
141 pcg 1.1 else if (!strcasecmp (optarg, "USR2"))
142 pcg 1.2 kill_gvpe = SIGUSR2;
143 pcg 1.1 else if (!strcasecmp (optarg, "INT"))
144 pcg 1.2 kill_gvpe = SIGINT;
145 pcg 1.1 else if (!strcasecmp (optarg, "ALRM"))
146 pcg 1.2 kill_gvpe = SIGALRM;
147 pcg 1.1 else
148     {
149 pcg 1.2 kill_gvpe = atoi (optarg);
150 pcg 1.1
151 pcg 1.2 if (!kill_gvpe)
152 pcg 1.1 {
153     fprintf (stderr,
154     _
155     ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
156     optarg);
157     usage (1);
158     }
159     }
160     }
161     else
162 pcg 1.2 kill_gvpe = SIGTERM;
163 pcg 1.1
164     break;
165    
166     case 'g': /* generate public/private keypair */
167     generate_keys = RSA_KEYBITS;
168     break;
169    
170     case 's':
171     show_config = 1;
172     break;
173    
174 pcg 1.8 case 'q':
175     quiet = 1;
176     break;
177    
178 pcg 1.1 case '?':
179     usage (1);
180    
181     default:
182     break;
183     }
184     }
185     }
186    
187     /* This function prettyprints the key generation process */
188    
189     void
190     indicator (int a, int b, void *p)
191     {
192 pcg 1.8 if (quiet)
193     return;
194    
195 pcg 1.1 switch (a)
196     {
197     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    
225     default:
226     fprintf (stderr, "?");
227     }
228     }
229    
230     /*
231     * generate public/private RSA keypairs for all hosts that don't have one.
232     */
233     int
234     keygen (int bits)
235     {
236     RSA *rsa_key;
237     FILE *f;
238     char *name = NULL;
239     char *fname;
240    
241     asprintf (&fname, "%s/hostkeys", confbase);
242     mkdir (fname, 0700);
243     free (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     asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
254    
255     f = fopen (fname, "a");
256    
257     if (!f)
258     {
259     perror (fname);
260     exit (EXIT_FAILURE);
261     }
262    
263     if (ftell (f))
264     {
265 pcg 1.8 if (!quiet)
266     fprintf (stderr, "'%s' already exists, skipping this node %d\n",
267     fname, quiet);
268    
269 pcg 1.1 fclose (f);
270     continue;
271     }
272    
273     fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
274     node->nodename);
275    
276     rsa_key = RSA_generate_key (bits, 0xFFFF, indicator, NULL);
277    
278     if (!rsa_key)
279     {
280     fprintf (stderr, _("error during key generation!\n"));
281     return -1;
282     }
283     else
284     fprintf (stderr, _("Done.\n"));
285    
286     require (PEM_write_RSAPublicKey (f, rsa_key));
287     fclose (f);
288     free (fname);
289    
290     asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename);
291    
292     f = fopen (fname, "a");
293     if (!f)
294     {
295     perror (fname);
296     exit (EXIT_FAILURE);
297     }
298    
299     require (PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL));
300     fclose (f);
301     free (fname);
302     }
303    
304     return 0;
305     }
306    
307     int
308     main (int argc, char **argv, char **envp)
309     {
310     set_identity (argv[0]);
311     log_to (LOGTO_STDERR);
312    
313     setlocale (LC_ALL, "");
314     bindtextdomain (PACKAGE, LOCALEDIR);
315     textdomain (PACKAGE);
316    
317     parse_options (argc, argv, envp);
318    
319     if (show_version)
320     {
321 pcg 1.6 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
322 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
323     printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
324     printf (_
325 pcg 1.9 ("Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> and others.\n"
326 pcg 1.1 "See the AUTHORS file for a complete list.\n\n"
327     "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
328     "and you are welcome to redistribute it under certain conditions;\n"
329     "see the file COPYING for details.\n"));
330    
331     return 0;
332     }
333    
334     if (show_help)
335     usage (0);
336    
337 pcg 1.3 {
338     configuration_parser (conf, false, 0, 0);
339     }
340 pcg 1.1
341     if (generate_keys)
342     {
343     RAND_load_file ("/dev/urandom", 1024);
344     exit (keygen (generate_keys));
345     }
346    
347 pcg 1.2 if (kill_gvpe)
348     exit (kill_other (kill_gvpe));
349 pcg 1.1
350     if (show_config)
351     {
352     conf.print ();
353     exit (EXIT_SUCCESS);
354     }
355    
356     usage (1);
357     }