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

# Content
1 /*
2 gvpectrl.C -- the main file for gvpectrl
3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 2003-2008 Marc Lehmann <gvpe@schmorp.de>
6
7 This file is part of GVPE.
8
9 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 */
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 /* If nonzero, it will attempt to kill a running gvpe and exit. */
68 static int kill_gvpe;
69
70 /* If nonzero, it will attempt to kill a running gvpe and exit. */
71 static int show_config;
72
73 /* If nonzero, do not output anything but warnings/errors/very unusual conditions */
74 static int quiet;
75
76 /* 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 {"quiet", no_argument, &quiet, 1},
87 {"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 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
102 " -g, --generate-keys Generate public/private RSA keypair.\n"
103 " -s, --show-config Display the configuration information.\n"
104 " -q, --quiet Be quite quiet.\n"
105 " --help Display this help and exit.\n"
106 " --version Output version information and exit.\n\n"));
107 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
108 }
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 while ((r = getopt_long (argc, argv, "c:k::qgs", long_options, &option_index)) != EOF)
120 {
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 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
178 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 if (quiet)
193 return;
194
195 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 if (!quiet)
266 fprintf (stderr, "'%s' already exists, skipping this node %d\n",
267 fname, quiet);
268
269 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 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
322 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
323 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
324 printf (_
325 ("Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> and others.\n"
326 "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 {
338 configuration_parser (conf, false, 0, 0);
339 }
340
341 if (generate_keys)
342 {
343 RAND_load_file ("/dev/urandom", 1024);
344 exit (keygen (generate_keys));
345 }
346
347 if (kill_gvpe)
348 exit (kill_other (kill_gvpe));
349
350 if (show_config)
351 {
352 conf.print ();
353 exit (EXIT_SUCCESS);
354 }
355
356 usage (1);
357 }