ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpectrl.C
Revision: 1.3
Committed: Tue Apr 15 03:48:40 2003 UTC (21 years, 1 month ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: VPE_1_0
Changes since 1.2: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.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 pcg 1.2 #include "vpn.h"
48 pcg 1.1
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 pcg 1.3 printf (_("%s version %s (built %s %s, protocol %d.%d)\n"), get_identity (),
300 pcg 1.1 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     }