ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpectrl.C
Revision: 1.8
Committed: Sat Jan 17 15:43:02 2004 UTC (20 years, 4 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: VPE_1_4
Changes since 1.7: +0 -2 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 pcg 1.7 #include <clocale>
27 pcg 1.1
28     #include <errno.h>
29     #include <fcntl.h>
30     #include <getopt.h>
31     #include <signal.h>
32 pcg 1.4 #include <sys/stat.h>
33 pcg 1.1 #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 pcg 1.2 #include "vpn.h"
50 pcg 1.1
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, "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 pcg 1.6 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
302 pcg 1.1 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     }