ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.10
Committed: Tue Feb 8 23:11:36 2011 UTC (13 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.9: +100 -101 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 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     if (!f)
257     {
258     perror (fname);
259     exit (EXIT_FAILURE);
260     }
261    
262     if (ftell (f))
263     {
264 pcg 1.8 if (!quiet)
265     fprintf (stderr, "'%s' already exists, skipping this node %d\n",
266     fname, quiet);
267    
268 pcg 1.1 fclose (f);
269     continue;
270     }
271    
272     fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
273     node->nodename);
274    
275     rsa_key = RSA_generate_key (bits, 0xFFFF, indicator, NULL);
276    
277     if (!rsa_key)
278     {
279     fprintf (stderr, _("error during key generation!\n"));
280     return -1;
281     }
282     else
283     fprintf (stderr, _("Done.\n"));
284    
285     require (PEM_write_RSAPublicKey (f, rsa_key));
286     fclose (f);
287     free (fname);
288    
289     asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename);
290    
291     f = fopen (fname, "a");
292     if (!f)
293     {
294     perror (fname);
295     exit (EXIT_FAILURE);
296     }
297    
298     require (PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL));
299     fclose (f);
300     free (fname);
301     }
302    
303     return 0;
304     }
305    
306     int
307     main (int argc, char **argv, char **envp)
308     {
309     set_identity (argv[0]);
310     log_to (LOGTO_STDERR);
311    
312     setlocale (LC_ALL, "");
313     bindtextdomain (PACKAGE, LOCALEDIR);
314     textdomain (PACKAGE);
315    
316     parse_options (argc, argv, envp);
317    
318     if (show_version)
319     {
320 pcg 1.6 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
321 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
322     printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
323     printf (_
324 pcg 1.9 ("Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> and others.\n"
325 pcg 1.1 "See the AUTHORS file for a complete list.\n\n"
326     "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
327     "and you are welcome to redistribute it under certain conditions;\n"
328     "see the file COPYING for details.\n"));
329    
330     return 0;
331     }
332    
333     if (show_help)
334     usage (0);
335    
336 pcg 1.3 {
337     configuration_parser (conf, false, 0, 0);
338     }
339 pcg 1.1
340     if (generate_keys)
341     {
342     RAND_load_file ("/dev/urandom", 1024);
343     exit (keygen (generate_keys));
344     }
345    
346 pcg 1.2 if (kill_gvpe)
347     exit (kill_other (kill_gvpe));
348 pcg 1.1
349     if (show_config)
350     {
351     conf.print ();
352     exit (EXIT_SUCCESS);
353     }
354    
355     usage (1);
356     }