ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.7
Committed: Thu Aug 7 17:54:27 2008 UTC (15 years, 9 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +24 -14 lines
Log Message:
update to gplv3, finally

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