ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.12
Committed: Sun Mar 6 13:49:50 2011 UTC (13 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.11: +2 -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 root 1.11 2003-2011 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 root 1.10 {
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     {"quiet", no_argument, &quiet, 1},
87     {"show-config", no_argument, &show_config, 's'},
88     {NULL, 0, NULL, 0}
89     };
90 pcg 1.1
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 root 1.10 static void
114 pcg 1.1 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 root 1.10 case 0: /* long option */
124     break;
125 pcg 1.1
126 root 1.10 case 'c': /* config file */
127     confbase = strdup (optarg);
128     break;
129    
130     case 'k': /* kill old gvpes */
131     if (optarg)
132     {
133     if (!strcasecmp (optarg, "HUP"))
134     kill_gvpe = SIGHUP;
135     else if (!strcasecmp (optarg, "TERM"))
136     kill_gvpe = SIGTERM;
137     else if (!strcasecmp (optarg, "KILL"))
138     kill_gvpe = SIGKILL;
139     else if (!strcasecmp (optarg, "USR1"))
140     kill_gvpe = SIGUSR1;
141     else if (!strcasecmp (optarg, "USR2"))
142     kill_gvpe = SIGUSR2;
143     else if (!strcasecmp (optarg, "INT"))
144     kill_gvpe = SIGINT;
145     else if (!strcasecmp (optarg, "ALRM"))
146     kill_gvpe = SIGALRM;
147     else
148     {
149     kill_gvpe = atoi (optarg);
150    
151     if (!kill_gvpe)
152     {
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     kill_gvpe = SIGTERM;
163    
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     case 'q':
175     quiet = 1;
176     break;
177 pcg 1.8
178 root 1.10 case '?':
179     usage (1);
180 pcg 1.1
181 root 1.10 default:
182     break;
183 pcg 1.1 }
184     }
185     }
186    
187 root 1.10 // this function prettyprints the key generation process
188     static void
189 pcg 1.1 indicator (int a, int b, void *p)
190     {
191 pcg 1.8 if (quiet)
192     return;
193    
194 pcg 1.1 switch (a)
195     {
196 root 1.10 case 0:
197     fprintf (stderr, ".");
198     break;
199    
200     case 1:
201     fprintf (stderr, "+");
202     break;
203    
204     case 2:
205     fprintf (stderr, "-");
206     break;
207    
208     case 3:
209     switch (b)
210     {
211     case 0:
212     fprintf (stderr, " p\n");
213     break;
214    
215     case 1:
216     fprintf (stderr, " q\n");
217     break;
218    
219     default:
220     fprintf (stderr, "?");
221     }
222     break;
223 pcg 1.1
224 root 1.10 default:
225     fprintf (stderr, "?");
226 pcg 1.1 }
227     }
228    
229     /*
230     * generate public/private RSA keypairs for all hosts that don't have one.
231     */
232 root 1.10 static int
233 pcg 1.1 keygen (int bits)
234     {
235     RSA *rsa_key;
236     FILE *f;
237     char *name = NULL;
238     char *fname;
239    
240     asprintf (&fname, "%s/hostkeys", confbase);
241     mkdir (fname, 0700);
242     free (fname);
243    
244     asprintf (&fname, "%s/pubkey", confbase);
245     mkdir (fname, 0700);
246     free (fname);
247    
248     for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
249     {
250     conf_node *node = *i;
251    
252     asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
253    
254     f = fopen (fname, "a");
255    
256 root 1.12 /* some libcs are buggy and require an extra seek to the end */
257     if (!f || fseek (f, 0, SEEK_END))
258 pcg 1.1 {
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     }