ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpectrl.C
Revision: 1.5
Committed: Tue Jun 21 08:46:53 2005 UTC (18 years, 11 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +2 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2 pcg 1.2 gvpectrl.C -- the main file for gvpectrl
3 pcg 1.1 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4     2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5     2003-2005 Marc Lehmann <gvpe@schmorp.de>
6    
7     This file is part of GVPE.
8    
9     GVPE is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 2 of the License, or
12     (at your option) any later version.
13    
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17     GNU General Public License for more details.
18    
19     You should have received a copy of the GNU General Public License
20     along with gvpe; if not, write to the Free Software
21 pcg 1.4 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 pcg 1.1 */
23    
24     #include "config.h"
25    
26     #include <cstdio>
27     #include <cstring>
28     #include <cstdlib>
29    
30     #include <errno.h>
31     #include <fcntl.h>
32     #include <getopt.h>
33     #include <signal.h>
34     #include <sys/stat.h>
35     #include <sys/types.h>
36     #include <unistd.h>
37     #include <signal.h>
38    
39     #include <openssl/rand.h>
40     #include <openssl/rsa.h>
41     #include <openssl/pem.h>
42     #include <openssl/evp.h>
43    
44     #include "pidfile.h"
45    
46     #include "conf.h"
47     #include "slog.h"
48     #include "util.h"
49     #include "vpn.h"
50    
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 pcg 1.2 /* If nonzero, it will attempt to kill a running gvpe and exit. */
58     static int kill_gvpe;
59 pcg 1.1
60 pcg 1.2 /* If nonzero, it will attempt to kill a running gvpe and exit. */
61 pcg 1.1 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 pcg 1.2 " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n"
88 pcg 1.1 " -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 pcg 1.5 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
93 pcg 1.1 }
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 pcg 1.2 case 'k': /* kill old gvpes */
118 pcg 1.1 if (optarg)
119     {
120     if (!strcasecmp (optarg, "HUP"))
121 pcg 1.2 kill_gvpe = SIGHUP;
122 pcg 1.1 else if (!strcasecmp (optarg, "TERM"))
123 pcg 1.2 kill_gvpe = SIGTERM;
124 pcg 1.1 else if (!strcasecmp (optarg, "KILL"))
125 pcg 1.2 kill_gvpe = SIGKILL;
126 pcg 1.1 else if (!strcasecmp (optarg, "USR1"))
127 pcg 1.2 kill_gvpe = SIGUSR1;
128 pcg 1.1 else if (!strcasecmp (optarg, "USR2"))
129 pcg 1.2 kill_gvpe = SIGUSR2;
130 pcg 1.1 else if (!strcasecmp (optarg, "INT"))
131 pcg 1.2 kill_gvpe = SIGINT;
132 pcg 1.1 else if (!strcasecmp (optarg, "ALRM"))
133 pcg 1.2 kill_gvpe = SIGALRM;
134 pcg 1.1 else
135     {
136 pcg 1.2 kill_gvpe = atoi (optarg);
137 pcg 1.1
138 pcg 1.2 if (!kill_gvpe)
139 pcg 1.1 {
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 pcg 1.2 kill_gvpe = SIGTERM;
150 pcg 1.1
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 (EXIT_FAILURE);
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     require (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 (EXIT_FAILURE);
275     }
276    
277     require (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 (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
302     printf (_
303 pcg 1.5 ("Copyright (C) 2003 Marc Lehmann <gvpe@schmorp.de> and others.\n"
304 pcg 1.1 "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 pcg 1.3 {
316     configuration_parser (conf, false, 0, 0);
317     }
318 pcg 1.1
319     if (generate_keys)
320     {
321     RAND_load_file ("/dev/urandom", 1024);
322     exit (keygen (generate_keys));
323     }
324    
325 pcg 1.2 if (kill_gvpe)
326     exit (kill_other (kill_gvpe));
327 pcg 1.1
328     if (show_config)
329     {
330     conf.print ();
331     exit (EXIT_SUCCESS);
332     }
333    
334     usage (1);
335     }