ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpectrl.C
Revision: 1.5
Committed: Thu Oct 16 02:41:21 2003 UTC (20 years, 7 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +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 pcg 1.5 2003 Marc Lehmann <pcg@goof.com>
6 pcg 1.1
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 pcg 1.4 #include <sys/stat.h>
32 pcg 1.1 #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 pcg 1.2 #include "vpn.h"
49 pcg 1.1
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 pcg 1.3 printf (_("%s version %s (built %s %s, protocol %d.%d)\n"), get_identity (),
301 pcg 1.1 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
302     printf (_
303     ("Copyright (C) 2003 Marc Lehmann <vpe@plan9.de> and others.\n"
304     "See the AUTHORS file for a complete list.\n\n"
305     "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
306     "and you are welcome to redistribute it under certain conditions;\n"
307     "see the file COPYING for details.\n"));
308    
309     return 0;
310     }
311    
312     if (show_help)
313     usage (0);
314    
315     make_names ();
316     conf.read_config (false);
317    
318     if (generate_keys)
319     {
320     RAND_load_file ("/dev/urandom", 1024);
321     exit (keygen (generate_keys));
322     }
323    
324     if (kill_vped)
325     exit (kill_other (kill_vped));
326    
327     if (show_config)
328     {
329     conf.print ();
330     exit (0);
331     }
332    
333     usage (1);
334     }