ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/gvpe.C
(Generate patch)

Comparing gvpe/src/gvpe.C (file contents):
Revision 1.13 by pcg, Thu Aug 7 17:54:27 2008 UTC vs.
Revision 1.25 by root, Tue Jul 16 16:44:36 2013 UTC

1/* 1/*
2 gvpe.C -- the main file for gvpe 2 gvpe.C -- the main file for gvpe
3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl> 3 Copyright (C) 1998-2002 Ivo Timmermans <ivo@o2w.nl>
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org> 4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
5 2003-2008 Marc Lehmann <gvpe@schmorp.de> 5 2003-2013 Marc Lehmann <gvpe@schmorp.de>
6 6
7 This file is part of GVPE. 7 This file is part of GVPE.
8 8
9 GVPE is free software; you can redistribute it and/or modify it 9 GVPE is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the 10 under the terms of the GNU General Public License as published by the
40#include <errno.h> 40#include <errno.h>
41#include <fcntl.h> 41#include <fcntl.h>
42#include <getopt.h> 42#include <getopt.h>
43#include <signal.h> 43#include <signal.h>
44#include <sys/types.h> 44#include <sys/types.h>
45#include <sys/stat.h>
45#include <unistd.h> 46#include <unistd.h>
46#include <signal.h> 47#include <signal.h>
47#include <termios.h> 48#include <termios.h>
48 49
49#if HAVE_SYS_MMAN_H 50#if HAVE_SYS_MMAN_H
59#include "conf.h" 60#include "conf.h"
60#include "slog.h" 61#include "slog.h"
61#include "util.h" 62#include "util.h"
62#include "vpn.h" 63#include "vpn.h"
63#include "ev_cpp.h" 64#include "ev_cpp.h"
65#include "hkdf.h"
64 66
65static loglevel llevel = L_NONE; 67static loglevel llevel = L_NONE;
66 68
67/* If nonzero, display usage information and exit. */ 69/* If nonzero, display usage information and exit. */
68static int show_help; 70static int show_help;
75 77
76/* If zero, don't detach from the terminal. */ 78/* If zero, don't detach from the terminal. */
77static int do_detach = 1; 79static int do_detach = 1;
78 80
79static struct option const long_options[] = 81static struct option const long_options[] =
80 { 82{
81 {"config", required_argument, NULL, 'c'}, 83 {"config", required_argument, NULL, 'c'},
82 {"help", no_argument, &show_help, 1}, 84 {"help", no_argument, &show_help, 1},
83 {"version", no_argument, &show_version, 1}, 85 {"version", no_argument, &show_version, 1},
84 {"no-detach", no_argument, &do_detach, 0}, 86 {"no-detach", no_argument, &do_detach, 0},
85 {"log-level", required_argument, NULL, 'l'}, 87 {"log-level", required_argument, NULL, 'l'},
86 {"mlock", no_argument, &do_mlock, 1}, 88 {"mlock", no_argument, &do_mlock, 1},
87 {NULL, 0, NULL, 0} 89 {NULL, 0, NULL, 0}
88 }; 90};
89 91
90static void 92static void
91usage (int status) 93usage (int status)
92{ 94{
93 if (status != 0) 95 if (status != 0)
97 printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ()); 99 printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ());
98 printf (_ 100 printf (_
99 (" -c, --config=DIR Read configuration options from DIR.\n" 101 (" -c, --config=DIR Read configuration options from DIR.\n"
100 " -D, --no-detach Don't fork and detach.\n" 102 " -D, --no-detach Don't fork and detach.\n"
101 " -l, --log-level=LEVEL Set logging level (info, notice, warn are common).\n" 103 " -l, --log-level=LEVEL Set logging level (info, notice, warn are common).\n"
102 " -L, --mlock Lock tinc into main memory.\n" 104 " -L, --mlock Lock gvpe into main memory.\n"
103 " --help Display this help and exit.\n" 105 " --help Display this help and exit.\n"
104 " --version Output version information and exit.\n\n")); 106 " --version Output version information and exit.\n\n"));
105 printf (_("Report bugs to <gvpe@schmorp.de>.\n")); 107 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
106 } 108 }
107 109
108 exit (status); 110 exit (status);
109} 111}
110 112
111void 113static void
112parse_options (int argc, char **argv, char **envp) 114parse_options (int argc, char **argv, char **envp)
113{ 115{
114 int r; 116 int r;
115 int option_index = 0; 117 int option_index = 0;
116 118
149 break; 151 break;
150 } 152 }
151 } 153 }
152} 154}
153 155
154/*
155 Close network connections, and terminate neatly 156// close network connections, and terminate neatly
156*/ 157static void
157void cleanup_and_exit(int c) 158cleanup_and_exit (int c)
158{ 159{
159 network.shutdown_all (); 160 network.shutdown_all ();
160 161
161 if (conf.pidfilename) 162 if (conf.pidfilename)
162 remove_pid (conf.pidfilename); 163 remove_pid (conf.pidfilename);
164 slog (L_INFO, _("terminating with exit code %d"), c); 165 slog (L_INFO, _("terminating with exit code %d"), c);
165 166
166 exit (c); 167 exit (c);
167} 168}
168 169
169/*
170 Signal handlers. 170// signal handlers
171*/ 171static RETSIGTYPE
172RETSIGTYPE
173sigterm_handler (int a) 172sigterm_handler (int a)
174{ 173{
175 network.events |= vpn::EVENT_SHUTDOWN; 174 network.events |= vpn::EVENT_SHUTDOWN;
176 network.event.start (); 175 network.event.start ();
177} 176}
178 177
179RETSIGTYPE 178static RETSIGTYPE
180sighup_handler (int a) 179sighup_handler (int a)
181{ 180{
182 network.events |= vpn::EVENT_RECONNECT; 181 network.events |= vpn::EVENT_RECONNECT;
183 network.event.start (); 182 network.event.start ();
184} 183}
185 184
186RETSIGTYPE 185static RETSIGTYPE
187sigusr1_handler (int a) 186sigusr1_handler (int a)
188{ 187{
189 network.dump_status (); 188 network.dump_status ();
190} 189}
191 190
192RETSIGTYPE 191static RETSIGTYPE
193sigusr2_handler (int a) 192sigusr2_handler (int a)
194{ 193{
195} 194}
196 195
197void 196static void
198setup_signals (void) 197setup_signals (void)
199{ 198{
200 struct sigaction act; 199 struct sigaction act;
201 200
202 sigfillset (&act.sa_mask); 201 sigfillset (&act.sa_mask);
203 act.sa_flags = 0; 202 act.sa_flags = 0;
204 203
205 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL); 204 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL);
206 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL); 205 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL);
207 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL); 206 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL);
208 act.sa_handler = SIG_IGN; sigaction (SIGCHLD, &act, NULL);
209 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL); 207 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL);
210 act.sa_flags = SA_RESETHAND; 208 act.sa_flags = SA_RESETHAND;
211 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL); 209 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL);
212 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL); 210 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL);
213} 211}
214 212
213static int rand_fd;
214
215// antique C++ requires external linkage :/
216void
217reseed_rng (ev::timer &w, int revents)
218{
219 char buf [SEED_SIZE];
220 int n = read (rand_fd, buf, sizeof (buf));
221
222 if (n > 0)
223 RAND_seed (buf, n);
224}
225
226static void
227setup_rng (void)
228{
229 if (!*conf.seed_dev)
230 return;
231
232#ifndef O_BINARY
233# define O_BINARY 0
234#endif
235#ifndef O_NONBLOCK
236# define O_NONBLOCK 0
237#endif
238
239 rand_fd = open (conf.seed_dev, O_RDONLY | O_NONBLOCK | O_BINARY);
240
241 if (rand_fd < 0)
242 {
243 slog (L_ERR, _("unable to open seed device '%s': %s, exiting."), conf.seed_dev, strerror (errno));
244 exit (EXIT_FAILURE);
245 }
246
247 static ev::timer reseed_timer;
248
249 if (conf.reseed)
250 {
251 reseed_timer.set<reseed_rng> ();
252 reseed_timer.set (conf.reseed, conf.reseed);
253 reseed_timer.start (EV_DEFAULT);
254 }
255
256 reseed_rng (reseed_timer, 0);
257}
258
215int 259int
216main (int argc, char **argv, char **envp) 260main (int argc, char **argv, char **envp)
217{ 261{
218 ERR_load_crypto_strings (); // we have the RAM 262 ERR_load_crypto_strings (); // we have the RAM
263
264 require (EVP_MD_size (MAC_DIGEST ()) == HASH_SIZE (MAC_DIGEST ));
265 require (EVP_MD_size (AUTH_DIGEST ()) == HASH_SIZE (AUTH_DIGEST));
266 require (EVP_CIPHER_key_length (CIPHER ()) == KEY_SIZE (CIPHER ));
267 require (EVP_CIPHER_block_size (CIPHER ()) == BLOCK_SIZE (CIPHER ));
268
269 curve25519_verify ();
270 hkdf::verify ();
219 271
220 set_loglevel (L_INFO); 272 set_loglevel (L_INFO);
221 set_identity (argv[0]); 273 set_identity (argv[0]);
222 log_to (LOGTO_SYSLOG | LOGTO_STDERR); 274 log_to (LOGTO_SYSLOG | LOGTO_STDERR);
223 275
234 { 286 {
235 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (), 287 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
236 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); 288 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
237 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); 289 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
238 printf (_ 290 printf (_
239 ("Copyright (C) 2003 Marc Lehmann <gvpe@schmorp.de> and others.\n" 291 ("Copyright (C) 2003-2011 Marc Lehmann <gvpe@schmorp.de> and others.\n"
240 "See the AUTHORS file for a complete list.\n\n" 292 "See the AUTHORS file for a complete list.\n\n"
241 "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" 293 "GVPE comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
242 "and you are welcome to redistribute it under certain conditions;\n" 294 "and you are welcome to redistribute it under certain conditions;\n"
243 "see the file COPYING for details.\n")); 295 "see the file COPYING for details.\n"));
244 296
245 return 0; 297 return 0;
246 } 298 }
274 configuration_parser (conf, true, argc, argv); 326 configuration_parser (conf, true, argc, argv);
275 } 327 }
276 328
277 set_loglevel (llevel != L_NONE ? llevel : conf.llevel); 329 set_loglevel (llevel != L_NONE ? llevel : conf.llevel);
278 330
279 RAND_load_file ("/dev/urandom", 1024); 331 setup_rng ();
280 332
281 if (!THISNODE) 333 if (!THISNODE)
282 { 334 {
283 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."), 335 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."),
284 thisnode ? thisnode : "<unset>"); 336 thisnode ? thisnode : "<unset>");
289 exit (EXIT_SUCCESS); 341 exit (EXIT_SUCCESS);
290 342
291 setup_signals (); 343 setup_signals ();
292 344
293 if (!network.setup ()) 345 if (!network.setup ())
346 if (network.drop_privileges ())
294 { 347 {
295 ev_loop (EV_DEFAULT_ 0); 348 ev_run (EV_DEFAULT_ 0);
296 cleanup_and_exit (EXIT_FAILURE); 349 cleanup_and_exit (EXIT_FAILURE);
297 } 350 }
298 351
299 slog (L_ERR, _("unable to setup network, unrecoverable error, exiting.")); 352 slog (L_CRIT, _("unrecoverable error while setting up network, exiting."));
300 cleanup_and_exit (EXIT_FAILURE); 353 cleanup_and_exit (EXIT_FAILURE);
301} 354}
302 355

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines