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