ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpectrl.C
Revision: 1.7
Committed: Sat Jan 17 14:50:40 2004 UTC (20 years, 4 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 vpectrl.C -- the main file for vpectrl
3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 2003 Marc Lehmann <pcg@goof.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #include "config.h"
23
24 #include <cstdio>
25 #include <cstring>
26 #include <clocale>
27
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <getopt.h>
31 #include <signal.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35 #include <signal.h>
36
37 #include <openssl/rand.h>
38 #include <openssl/rsa.h>
39 #include <openssl/pem.h>
40 #include <openssl/evp.h>
41
42 #include "pidfile.h"
43
44 #include "gettext.h"
45
46 #include "conf.h"
47 #include "slog.h"
48 #include "util.h"
49 #include "vpn.h"
50
51 /* If nonzero, display usage information and exit. */
52 static int show_help;
53
54 /* If nonzero, print the version on standard output and exit. */
55 static int show_version;
56
57 /* If nonzero, it will attempt to kill a running vped and exit. */
58 static int kill_vped;
59
60 /* If nonzero, it will attempt to kill a running vped and exit. */
61 static int show_config;
62
63 /* If nonzero, generate public/private keypair for this net. */
64 static int generate_keys;
65
66 static struct option const long_options[] =
67 {
68 {"config", required_argument, NULL, 'c'},
69 {"kill", optional_argument, NULL, 'k'},
70 {"help", no_argument, &show_help, 1},
71 {"version", no_argument, &show_version, 1},
72 {"generate-keys", no_argument, NULL, 'g'},
73 {"show-config", no_argument, &show_config, 's'},
74 {NULL, 0, NULL, 0}
75 };
76
77 static void
78 usage (int status)
79 {
80 if (status != 0)
81 fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ());
82 else
83 {
84 printf (_("Usage: %s [option]...\n\n"), get_identity ());
85 printf (_
86 (" -c, --config=DIR Read configuration options from DIR.\n"
87 " -k, --kill[=SIGNAL] Attempt to kill a running vped and exit.\n"
88 " -g, --generate-keys Generate public/private RSA keypair.\n"
89 " -s, --show-config Display the configuration information.\n"
90 " --help Display this help and exit.\n"
91 " --version Output version information and exit.\n\n"));
92 printf (_("Report bugs to <vpe@plan9.de>.\n"));
93 }
94
95 exit (status);
96 }
97
98 void
99 parse_options (int argc, char **argv, char **envp)
100 {
101 int r;
102 int option_index = 0;
103
104 while ((r =
105 getopt_long (argc, argv, "c:k::gs", long_options,
106 &option_index)) != EOF)
107 {
108 switch (r)
109 {
110 case 0: /* long option */
111 break;
112
113 case 'c': /* config file */
114 confbase = strdup (optarg);
115 break;
116
117 case 'k': /* kill old vpeds */
118 if (optarg)
119 {
120 if (!strcasecmp (optarg, "HUP"))
121 kill_vped = SIGHUP;
122 else if (!strcasecmp (optarg, "TERM"))
123 kill_vped = SIGTERM;
124 else if (!strcasecmp (optarg, "KILL"))
125 kill_vped = SIGKILL;
126 else if (!strcasecmp (optarg, "USR1"))
127 kill_vped = SIGUSR1;
128 else if (!strcasecmp (optarg, "USR2"))
129 kill_vped = SIGUSR2;
130 else if (!strcasecmp (optarg, "WINCH"))
131 kill_vped = SIGWINCH;
132 else if (!strcasecmp (optarg, "INT"))
133 kill_vped = SIGINT;
134 else if (!strcasecmp (optarg, "ALRM"))
135 kill_vped = SIGALRM;
136 else
137 {
138 kill_vped = atoi (optarg);
139
140 if (!kill_vped)
141 {
142 fprintf (stderr,
143 _
144 ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
145 optarg);
146 usage (1);
147 }
148 }
149 }
150 else
151 kill_vped = SIGTERM;
152
153 break;
154
155 case 'g': /* generate public/private keypair */
156 generate_keys = RSA_KEYBITS;
157 break;
158
159 case 's':
160 show_config = 1;
161 break;
162
163 case '?':
164 usage (1);
165
166 default:
167 break;
168 }
169 }
170 }
171
172 /* This function prettyprints the key generation process */
173
174 void
175 indicator (int a, int b, void *p)
176 {
177 switch (a)
178 {
179 case 0:
180 fprintf (stderr, ".");
181 break;
182
183 case 1:
184 fprintf (stderr, "+");
185 break;
186
187 case 2:
188 fprintf (stderr, "-");
189 break;
190
191 case 3:
192 switch (b)
193 {
194 case 0:
195 fprintf (stderr, " p\n");
196 break;
197
198 case 1:
199 fprintf (stderr, " q\n");
200 break;
201
202 default:
203 fprintf (stderr, "?");
204 }
205 break;
206
207 default:
208 fprintf (stderr, "?");
209 }
210 }
211
212 /*
213 * generate public/private RSA keypairs for all hosts that don't have one.
214 */
215 int
216 keygen (int bits)
217 {
218 RSA *rsa_key;
219 FILE *f;
220 char *name = NULL;
221 char *fname;
222
223 asprintf (&fname, "%s/hostkeys", confbase);
224 mkdir (fname, 0700);
225 free (fname);
226
227 asprintf (&fname, "%s/pubkey", confbase);
228 mkdir (fname, 0700);
229 free (fname);
230
231 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
232 {
233 conf_node *node = *i;
234
235 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
236
237 f = fopen (fname, "a");
238
239 if (!f)
240 {
241 perror (fname);
242 exit (1);
243 }
244
245 if (ftell (f))
246 {
247 fprintf (stderr, "'%s' already exists, skipping this node\n",
248 fname);
249 fclose (f);
250 continue;
251 }
252
253 fprintf (stderr, _("generating %d bits key for %s:\n"), bits,
254 node->nodename);
255
256 rsa_key = RSA_generate_key (bits, 0xFFFF, indicator, NULL);
257
258 if (!rsa_key)
259 {
260 fprintf (stderr, _("error during key generation!\n"));
261 return -1;
262 }
263 else
264 fprintf (stderr, _("Done.\n"));
265
266 PEM_write_RSAPublicKey (f, rsa_key);
267 fclose (f);
268 free (fname);
269
270 asprintf (&fname, "%s/hostkeys/%s", confbase, node->nodename);
271
272 f = fopen (fname, "a");
273 if (!f)
274 {
275 perror (fname);
276 exit (1);
277 }
278
279 PEM_write_RSAPrivateKey (f, rsa_key, NULL, NULL, 0, NULL, NULL);
280 fclose (f);
281 free (fname);
282 }
283
284 return 0;
285 }
286
287 int
288 main (int argc, char **argv, char **envp)
289 {
290 set_identity (argv[0]);
291 log_to (LOGTO_STDERR);
292
293 setlocale (LC_ALL, "");
294 bindtextdomain (PACKAGE, LOCALEDIR);
295 textdomain (PACKAGE);
296
297 parse_options (argc, argv, envp);
298
299 if (show_version)
300 {
301 printf (_("%s version %s (built %s %s, protocol %d.%d)\n"), get_identity (),
302 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
303 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
304 printf (_
305 ("Copyright (C) 2003 Marc Lehmann <vpe@plan9.de> and others.\n"
306 "See the AUTHORS file for a complete list.\n\n"
307 "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
308 "and you are welcome to redistribute it under certain conditions;\n"
309 "see the file COPYING for details.\n"));
310
311 return 0;
312 }
313
314 if (show_help)
315 usage (0);
316
317 make_names ();
318 conf.read_config (false);
319
320 if (generate_keys)
321 {
322 RAND_load_file ("/dev/urandom", 1024);
323 exit (keygen (generate_keys));
324 }
325
326 if (kill_vped)
327 exit (kill_other (kill_vped));
328
329 if (show_config)
330 {
331 conf.print ();
332 exit (0);
333 }
334
335 usage (1);
336 }