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.1 by pcg, Fri Mar 18 01:53:05 2005 UTC vs.
Revision 1.27 by root, Thu Oct 6 03:25:54 2022 UTC

1/* 1/*
2 vped.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-2005 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 9 GVPE is free software; you can redistribute it and/or modify it
10 it under the terms of the GNU General Public License as published by 10 under the terms of the GNU General Public License as published by the
11 the Free Software Foundation; either version 2 of the License, or 11 Free Software Foundation; either version 3 of the License, or (at your
12 (at your option) any later version. 12 option) any later version.
13 13
14 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful, but
15 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 GNU General Public License for more details. 17 Public License for more details.
18 18
19 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License along
20 along with gvpe; if not, write to the Free Software 20 with this program; if not, see <http://www.gnu.org/licenses/>.
21 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21
22 Additional permission under GNU GPL version 3 section 7
23
24 If you modify this Program, or any covered work, by linking or
25 combining it with the OpenSSL project's OpenSSL library (or a modified
26 version of that library), containing parts covered by the terms of the
27 OpenSSL or SSLeay licenses, the licensors of this Program grant you
28 additional permission to convey the resulting work. Corresponding
29 Source for a non-source form of such a combination shall include the
30 source code for the parts of OpenSSL used as well as that of the
31 covered work.
22*/ 32*/
23 33
24#include "config.h" 34#include "config.h"
25 35
26#include <cstdio> 36#include <cstdio>
30#include <errno.h> 40#include <errno.h>
31#include <fcntl.h> 41#include <fcntl.h>
32#include <getopt.h> 42#include <getopt.h>
33#include <signal.h> 43#include <signal.h>
34#include <sys/types.h> 44#include <sys/types.h>
45#include <sys/stat.h>
35#include <unistd.h> 46#include <unistd.h>
36#include <signal.h> 47#include <signal.h>
37#include <termios.h> 48#include <termios.h>
38 49
39#if HAVE_SYS_MMAN_H 50#if HAVE_SYS_MMAN_H
41#endif 52#endif
42 53
43#include <openssl/err.h> 54#include <openssl/err.h>
44#include <openssl/rand.h> 55#include <openssl/rand.h>
45 56
57#include "gettext.h"
46#include "pidfile.h" 58#include "pidfile.h"
47 59
48#include "conf.h" 60#include "conf.h"
49#include "slog.h" 61#include "slog.h"
50#include "util.h" 62#include "util.h"
51#include "vpn.h" 63#include "vpn.h"
64#include "ev_cpp.h"
52#include "iom.h" 65#include "hkdf.h"
53 66
54static loglevel llevel = L_NONE; 67static loglevel llevel = L_NONE;
55 68
56/* If nonzero, display usage information and exit. */ 69/* If nonzero, display usage information and exit. */
57static int show_help; 70static int show_help;
64 77
65/* If zero, don't detach from the terminal. */ 78/* If zero, don't detach from the terminal. */
66static int do_detach = 1; 79static int do_detach = 1;
67 80
68static struct option const long_options[] = 81static struct option const long_options[] =
69 { 82{
70 {"config", required_argument, NULL, 'c'}, 83 {"config", required_argument, NULL, 'c'},
71 {"help", no_argument, &show_help, 1}, 84 {"help", no_argument, &show_help, 1},
72 {"version", no_argument, &show_version, 1}, 85 {"version", no_argument, &show_version, 1},
73 {"no-detach", no_argument, &do_detach, 0}, 86 {"no-detach", no_argument, &do_detach, 0},
74 {"log-level", required_argument, NULL, 'l'}, 87 {"log-level", required_argument, NULL, 'l'},
75 {"mlock", no_argument, &do_mlock, 1}, 88 {"mlock", no_argument, &do_mlock, 1},
76 {NULL, 0, NULL, 0} 89 {NULL, 0, NULL, 0}
77 }; 90};
78 91
79static void 92static void
80usage (int status) 93usage (int status)
81{ 94{
82 if (status != 0) 95 if (status != 0)
86 printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ()); 99 printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ());
87 printf (_ 100 printf (_
88 (" -c, --config=DIR Read configuration options from DIR.\n" 101 (" -c, --config=DIR Read configuration options from DIR.\n"
89 " -D, --no-detach Don't fork and detach.\n" 102 " -D, --no-detach Don't fork and detach.\n"
90 " -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"
91 " -L, --mlock Lock tinc into main memory.\n" 104 " -L, --mlock Lock gvpe into main memory.\n"
92 " --help Display this help and exit.\n" 105 " --help Display this help and exit.\n"
93 " --version Output version information and exit.\n\n")); 106 " --version Output version information and exit.\n\n"));
94 printf (_("Report bugs to <vpe@plan9.de>.\n")); 107 printf (_("Report bugs to <gvpe@schmorp.de>.\n"));
95 } 108 }
96 109
97 exit (status); 110 exit (status);
98} 111}
99 112
100void 113static void
101parse_options (int argc, char **argv, char **envp) 114parse_options (int argc, char **argv, char **envp)
102{ 115{
103 int r; 116 int r;
104 int option_index = 0; 117 int option_index = 0;
105 118
106 while ((r = getopt_long (argc, argv, "-c:DLl:", long_options, &option_index)) != EOF) 119 while ((r = getopt_long (argc, argv, "c:DLl:", long_options, &option_index)) != EOF)
107 { 120 {
108 switch (r) 121 switch (r)
109 { 122 {
110 case 0: /* long option */ 123 case 0: /* long option */
111 break; 124 break;
112 125
113 case 1: /* this node name */
114 thisnode = strdup (optarg);
115 break;
116
117 case 'c': /* config file */ 126 case 'c': /* config file */
118 confbase = strdup (optarg); 127 confbase = strdup (optarg);
119 break; 128 break;
120 129
121 case 'D': /* no detach */ 130 case 'D': /* no detach */
142 break; 151 break;
143 } 152 }
144 } 153 }
145} 154}
146 155
147/*
148 Close network connections, and terminate neatly 156// close network connections, and terminate neatly
149*/ 157static void
150void cleanup_and_exit(int c) 158cleanup_and_exit (int c)
151{ 159{
152 network.shutdown_all (); 160 network.shutdown_all ();
153 161
154 if (conf.pidfilename) 162 if (conf.pidfilename)
155 remove_pid (conf.pidfilename); 163 remove_pid (conf.pidfilename);
157 slog (L_INFO, _("terminating with exit code %d"), c); 165 slog (L_INFO, _("terminating with exit code %d"), c);
158 166
159 exit (c); 167 exit (c);
160} 168}
161 169
162/*
163 Signal handlers. 170// signal handlers
164*/ 171static void
165RETSIGTYPE
166sigterm_handler (int a) 172sigterm_handler (int a)
167{ 173{
168 network.events |= vpn::EVENT_SHUTDOWN; 174 network.events |= vpn::EVENT_SHUTDOWN;
169 network.event.start (0); 175 network.event.start ();
170} 176}
171 177
172RETSIGTYPE 178static void
173sighup_handler (int a) 179sighup_handler (int a)
174{ 180{
175 network.events |= vpn::EVENT_RECONNECT; 181 network.events |= vpn::EVENT_RECONNECT;
176 network.event.start (0); 182 network.event.start ();
177} 183}
178 184
179RETSIGTYPE 185static void
180sigusr1_handler (int a) 186sigusr1_handler (int a)
181{ 187{
182 network.dump_status (); 188 network.dump_status ();
183} 189}
184 190
185RETSIGTYPE 191static void
186sigusr2_handler (int a) 192sigusr2_handler (int a)
187{ 193{
188} 194}
189 195
190void 196static void
191setup_signals (void) 197setup_signals (void)
192{ 198{
193 struct sigaction act; 199 struct sigaction act;
194 200
195 sigfillset (&act.sa_mask); 201 sigfillset (&act.sa_mask);
196 act.sa_flags = 0; 202 act.sa_flags = 0;
197 203
198 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL); 204 act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL);
199 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL); 205 act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL);
200 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL); 206 act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL);
201 act.sa_handler = SIG_IGN; sigaction (SIGCHLD, &act, NULL);
202 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL); 207 act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL);
203 act.sa_flags = SA_RESETHAND; 208 act.sa_flags = SA_RESETHAND;
204 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL); 209 act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL);
205 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL); 210 act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL);
206} 211}
207 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
208int 259int
209main (int argc, char **argv, char **envp) 260main (int argc, char **argv, char **envp)
210{ 261{
211 ERR_load_crypto_strings (); // we have the RAM 262 ERR_load_crypto_strings (); // we have the RAM
263
264 // m,ake sure openssl agrees with us on the important bits
265 require (EVP_MD_size (MAC_DIGEST ()) == HASH_SIZE (MAC_DIGEST ));
266 require (EVP_MD_size (AUTH_DIGEST ()) == HASH_SIZE (AUTH_DIGEST));
267 require (EVP_CIPHER_key_length (CIPHER ()) == KEY_SIZE (CIPHER ));
268 require (EVP_CIPHER_block_size (CIPHER ()) == BLOCK_SIZE (CIPHER ));
269 require (EVP_CIPHER_iv_length (CIPHER ()) == IV_SIZE (CIPHER ));
270 require (EVP_CIPHER_mode (CIPHER ()) == EVP_CIPH_CTR_MODE);
271
272 curve25519_verify ();
273 hkdf::verify ();
212 274
213 set_loglevel (L_INFO); 275 set_loglevel (L_INFO);
214 set_identity (argv[0]); 276 set_identity (argv[0]);
215 log_to (LOGTO_SYSLOG | LOGTO_STDERR); 277 log_to (LOGTO_SYSLOG | LOGTO_STDERR);
216 278
218 bindtextdomain (PACKAGE, LOCALEDIR); 280 bindtextdomain (PACKAGE, LOCALEDIR);
219 textdomain (PACKAGE); 281 textdomain (PACKAGE);
220 282
221 parse_options (argc, argv, envp); 283 parse_options (argc, argv, envp);
222 284
285 argc -= optind;
286 argv += optind;
287
223 if (show_version) 288 if (show_version)
224 { 289 {
225 printf (_("%s version %s (built %s %s, protocol %d.%d)\n"), get_identity (), 290 printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (),
226 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); 291 VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR);
227 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); 292 printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE);
228 printf (_ 293 printf (_
229 ("Copyright (C) 2003 Marc Lehmann <vpe@plan9.de> and others.\n" 294 ("Copyright (C) 2003-2011 Marc Lehmann <gvpe@schmorp.de> and others.\n"
230 "See the AUTHORS file for a complete list.\n\n" 295 "See the AUTHORS file for a complete list.\n\n"
231 "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" 296 "GVPE comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
232 "and you are welcome to redistribute it under certain conditions;\n" 297 "and you are welcome to redistribute it under certain conditions;\n"
233 "see the file COPYING for details.\n")); 298 "see the file COPYING for details.\n"));
234 299
235 return 0; 300 return 0;
236 } 301 }
246 if (do_mlock) 311 if (do_mlock)
247 if (mlockall (MCL_CURRENT | MCL_FUTURE)) 312 if (mlockall (MCL_CURRENT | MCL_FUTURE))
248 slog (L_ERR, _("system call `%s' failed: %s"), "mlockall", strerror (errno)); 313 slog (L_ERR, _("system call `%s' failed: %s"), "mlockall", strerror (errno));
249#endif 314#endif
250 315
251 conf.read_config (true); 316 if (argc >= 1)
317 {
318 thisnode = *argv++;
319 argc--;
320 }
321
322 if (!ev_default_loop (0))
323 {
324 slog (L_ERR, _("unable to initialise the event loop (bad $LIBEV_METHODS?)"));
325 exit (EXIT_FAILURE);
326 }
327
328 {
329 configuration_parser (conf, true, argc, argv);
330 }
252 331
253 set_loglevel (llevel != L_NONE ? llevel : conf.llevel); 332 set_loglevel (llevel != L_NONE ? llevel : conf.llevel);
254 333
255 RAND_load_file ("/dev/urandom", 1024); 334 setup_rng ();
256 335
257 if (!THISNODE) 336 if (!THISNODE)
258 { 337 {
259 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting vped."), 338 slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."),
260 thisnode ? thisnode : "<unset>"); 339 thisnode ? thisnode : "<unset>");
261 exit (EXIT_FAILURE); 340 exit (EXIT_FAILURE);
262 } 341 }
263 342
264 if (detach (do_detach)) 343 if (detach (do_detach))
265 exit (EXIT_SUCCESS); 344 exit (EXIT_SUCCESS);
266 345
267 setup_signals (); 346 setup_signals ();
268 347
269 if (!network.setup ()) 348 if (!network.setup ())
349 if (network.drop_privileges ())
270 { 350 {
271 io_manager::loop (); 351 ev_run (EV_DEFAULT_ 0);
272 cleanup_and_exit (EXIT_FAILURE); 352 cleanup_and_exit (EXIT_FAILURE);
273 } 353 }
274 354
275 slog (L_ERR, _("unable to setup network, unrecoverable error, exiting.")); 355 slog (L_CRIT, _("unrecoverable error while setting up network, exiting."));
276 cleanup_and_exit (EXIT_FAILURE); 356 cleanup_and_exit (EXIT_FAILURE);
277} 357}
278 358

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines