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