1 /* $NetBSD: session.c,v 1.35 2018/05/19 20:14:56 maxv Exp $ */
2
3 /* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/time.h>
39 #include <sys/socket.h>
40 #if HAVE_SYS_WAIT_H
41 # include <sys/wait.h>
42 #endif
43 #ifndef WEXITSTATUS
44 # define WEXITSTATUS(s) ((unsigned)(s) >> 8)
45 #endif
46 #ifndef WIFEXITED
47 # define WIFEXITED(s) (((s) & 255) == 0)
48 #endif
49
50 #include PATH_IPSEC_H
51
52 #include <stdlib.h>
53 #include <stdio.h>
54 #include <string.h>
55 #include <errno.h>
56 #ifdef HAVE_UNISTD_H
57 #include <unistd.h>
58 #endif
59 #include <signal.h>
60 #include <sys/stat.h>
61 #include <paths.h>
62 #include <err.h>
63
64 #include <netinet/in.h>
65 #include <resolv.h>
66
67 #include "libpfkey.h"
68
69 #include "var.h"
70 #include "misc.h"
71 #include "vmbuf.h"
72 #include "plog.h"
73 #include "debug.h"
74
75 #include "schedule.h"
76 #include "session.h"
77 #include "grabmyaddr.h"
78 #include "evt.h"
79 #include "cfparse_proto.h"
80 #include "isakmp_var.h"
81 #include "isakmp.h"
82 #include "isakmp_var.h"
83 #include "isakmp_xauth.h"
84 #include "isakmp_cfg.h"
85 #include "admin_var.h"
86 #include "admin.h"
87 #include "privsep.h"
88 #include "oakley.h"
89 #include "pfkey.h"
90 #include "handler.h"
91 #include "localconf.h"
92 #include "remoteconf.h"
93 #include "backupsa.h"
94 #include "remoteconf.h"
95 #ifdef ENABLE_NATT
96 #include "nattraversal.h"
97 #endif
98
99 #include "algorithm.h" /* XXX ??? */
100
101 #include "sainfo.h"
102
103 struct fd_monitor {
104 int (*callback)(void *ctx, int fd);
105 void *ctx;
106 int prio;
107 int fd;
108 TAILQ_ENTRY(fd_monitor) chain;
109 };
110
111 #define NUM_PRIORITIES 2
112
113 static void close_session __P((void));
114 static void init_signal __P((void));
115 static int set_signal __P((int sig, RETSIGTYPE (*func) __P((int))));
116 static void check_sigreq __P((void));
117 static int close_sockets __P((void));
118
119 static fd_set preset_mask, active_mask;
120 static struct fd_monitor fd_monitors[FD_SETSIZE];
121 static TAILQ_HEAD(fd_monitor_list, fd_monitor) fd_monitor_tree[NUM_PRIORITIES];
122 static int nfds = 0;
123
124 static volatile sig_atomic_t sigreq[NSIG + 1];
125
126 void
monitor_fd(int fd,int (* callback)(void *,int),void * ctx,int priority)127 monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority)
128 {
129 if (fd < 0 || fd >= FD_SETSIZE) {
130 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun");
131 exit(1);
132 }
133
134 FD_SET(fd, &preset_mask);
135 if (fd > nfds)
136 nfds = fd;
137 if (priority <= 0)
138 priority = 0;
139 if (priority >= NUM_PRIORITIES)
140 priority = NUM_PRIORITIES - 1;
141
142 fd_monitors[fd].callback = callback;
143 fd_monitors[fd].ctx = ctx;
144 fd_monitors[fd].prio = priority;
145 fd_monitors[fd].fd = fd;
146 TAILQ_INSERT_TAIL(&fd_monitor_tree[priority],
147 &fd_monitors[fd], chain);
148 }
149
150 void
unmonitor_fd(int fd)151 unmonitor_fd(int fd)
152 {
153 if (fd < 0 || fd >= FD_SETSIZE) {
154 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun");
155 exit(1);
156 }
157
158 if (fd_monitors[fd].callback == NULL)
159 return;
160
161 FD_CLR(fd, &preset_mask);
162 FD_CLR(fd, &active_mask);
163 fd_monitors[fd].callback = NULL;
164 fd_monitors[fd].ctx = NULL;
165 TAILQ_REMOVE(&fd_monitor_tree[fd_monitors[fd].prio],
166 &fd_monitors[fd], chain);
167 }
168
169 int
session(void)170 session(void)
171 {
172 struct timeval *timeout;
173 int error;
174 char pid_file[MAXPATHLEN];
175 FILE *fp;
176 pid_t racoon_pid = 0;
177 int i, count;
178 struct fd_monitor *fdm;
179
180 nfds = 0;
181 FD_ZERO(&preset_mask);
182
183 for (i = 0; i < NUM_PRIORITIES; i++)
184 TAILQ_INIT(&fd_monitor_tree[i]);
185
186 /* initialize schedular */
187 sched_init();
188 init_signal();
189
190 if (pfkey_init() < 0)
191 errx(1, "failed to initialize pfkey socket");
192
193 if (isakmp_init() < 0)
194 errx(1, "failed to initialize ISAKMP structures");
195
196 #ifdef ENABLE_HYBRID
197 if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD))
198 errx(1, "could not initialize ISAKMP mode config structures");
199 #endif
200
201 #ifdef HAVE_LIBLDAP
202 if (xauth_ldap_init_conf() != 0)
203 errx(1, "could not initialize ldap config");
204 #endif
205
206 #ifdef HAVE_LIBRADIUS
207 if (xauth_radius_init_conf(0) != 0)
208 errx(1, "could not initialize radius config");
209 #endif
210
211 myaddr_init_lists();
212
213 /*
214 * in order to prefer the parameters by command line,
215 * saving some parameters before parsing configuration file.
216 */
217 save_params();
218 if (cfparse() != 0)
219 errx(1, "failed to parse configuration file.");
220 restore_params();
221
222 #ifdef ENABLE_ADMINPORT
223 if (admin_init() < 0)
224 errx(1, "failed to initialize admin port socket");
225 #endif
226
227
228 #ifdef ENABLE_HYBRID
229 if(isakmp_cfg_config.network4 && isakmp_cfg_config.pool_size == 0)
230 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
231 return error;
232 #endif
233
234 if (dump_config)
235 dumprmconf();
236
237 #ifdef HAVE_LIBRADIUS
238 if (xauth_radius_init() != 0)
239 errx(1, "could not initialize libradius");
240 #endif
241
242 if (myaddr_init() != 0)
243 errx(1, "failed to listen to configured addresses");
244 myaddr_sync();
245
246 #ifdef ENABLE_NATT
247 natt_keepalive_init ();
248 #endif
249
250 /* write .pid file */
251 if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL)
252 strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN);
253 else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/')
254 strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
255 else {
256 strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN);
257 strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
258 }
259 fp = fopen(pid_file, "w");
260 if (fp) {
261 if (fchmod(fileno(fp),
262 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
263 syslog(LOG_ERR, "%s", strerror(errno));
264 fclose(fp);
265 exit(1);
266 }
267 } else {
268 plog(LLV_ERROR, LOCATION, NULL,
269 "cannot open %s", pid_file);
270 }
271
272 if (privsep_init() != 0)
273 exit(1);
274
275 /*
276 * The fork()'ed privileged side will close its copy of fp. We wait
277 * until here to get the correct child pid.
278 */
279 racoon_pid = getpid();
280 fprintf(fp, "%ld\n", (long)racoon_pid);
281 fclose(fp);
282
283 for (i = 0; i <= NSIG; i++)
284 sigreq[i] = 0;
285
286 while (1) {
287 /*
288 * asynchronous requests via signal.
289 * make sure to reset sigreq to 0.
290 */
291 check_sigreq();
292
293 /* scheduling */
294 timeout = schedular();
295
296 /* schedular can change select() mask, so we reset
297 * the working copy here */
298 active_mask = preset_mask;
299
300 error = select(nfds + 1, &active_mask, NULL, NULL, timeout);
301 if (error < 0) {
302 switch (errno) {
303 case EINTR:
304 continue;
305 default:
306 plog(LLV_ERROR, LOCATION, NULL,
307 "failed to select (%s)\n",
308 strerror(errno));
309 return -1;
310 }
311 /*NOTREACHED*/
312 }
313
314 count = 0;
315 for (i = 0; i < NUM_PRIORITIES; i++) {
316 TAILQ_FOREACH(fdm, &fd_monitor_tree[i], chain) {
317 if (!FD_ISSET(fdm->fd, &active_mask))
318 continue;
319
320 FD_CLR(fdm->fd, &active_mask);
321 if (fdm->callback != NULL) {
322 fdm->callback(fdm->ctx, fdm->fd);
323 count++;
324 } else
325 plog(LLV_ERROR, LOCATION, NULL,
326 "fd %d set, but no active callback\n", i);
327 }
328 if (count != 0)
329 break;
330 }
331
332 }
333 }
334
335 /* clear all status and exit program. */
336 static void
close_session()337 close_session()
338 {
339 evt_generic(EVT_RACOON_QUIT, NULL);
340 pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC);
341 flushph2();
342 flushph1();
343 flushrmconf();
344 flushsainfo();
345 close_sockets();
346 backupsa_clean();
347
348 plog(LLV_INFO, LOCATION, NULL, "racoon process %d shutdown\n", getpid());
349
350 exit(0);
351 }
352
353 static int signals[] = {
354 SIGHUP,
355 SIGINT,
356 SIGTERM,
357 SIGUSR1,
358 SIGUSR2,
359 SIGCHLD,
360 0
361 };
362
363 /*
364 * asynchronous requests will actually dispatched in the
365 * main loop in session().
366 */
367 RETSIGTYPE
signal_handler(sig)368 signal_handler(sig)
369 int sig;
370 {
371 sigreq[sig] = 1;
372 }
373
374
375 /* XXX possible mem leaks and no way to go back for now !!!
376 */
reload_conf(void)377 static void reload_conf(void)
378 {
379 int error;
380
381 #ifdef ENABLE_HYBRID
382 if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM)) != 0) {
383 plog(LLV_ERROR, LOCATION, NULL,
384 "ISAKMP mode config structure reset failed, "
385 "not reloading\n");
386 return;
387 }
388 #endif
389
390 sainfo_start_reload();
391
392 /* TODO: save / restore / flush old lcconf (?) / rmtree
393 */
394 rmconf_start_reload();
395
396 #ifdef HAVE_LIBRADIUS
397 /* free and init radius configuration */
398 xauth_radius_init_conf(1);
399 #endif
400
401 pfkey_reload();
402
403 save_params();
404 flushlcconf();
405 error = cfparse();
406 if (error != 0){
407 plog(LLV_ERROR, LOCATION, NULL, "config reload failed\n");
408 /* We are probably in an inconsistant state... */
409 return;
410 }
411 restore_params();
412
413 #if 0
414 if (dump_config)
415 dumprmconf ();
416 #endif
417
418 myaddr_sync();
419
420 #ifdef HAVE_LIBRADIUS
421 /* re-initialize radius state */
422 xauth_radius_init();
423 #endif
424
425 /* Revalidate ph1 / ph2tree !!!
426 * update ctdtree if removing some ph1 !
427 */
428 revalidate_ph12();
429 /* Update ctdtree ?
430 */
431
432 sainfo_finish_reload();
433 rmconf_finish_reload();
434 }
435
436 static void
check_sigreq()437 check_sigreq()
438 {
439 int sig, s;
440
441 for (sig = 0; sig <= NSIG; sig++) {
442 if (sigreq[sig] == 0)
443 continue;
444 sigreq[sig] = 0;
445
446 switch(sig) {
447 case 0:
448 return;
449
450 case SIGCHLD:
451 /* Reap all pending children */
452 while (waitpid(-1, &s, WNOHANG) > 0)
453 ;
454 break;
455
456 #ifdef DEBUG_RECORD_MALLOCATION
457 /*
458 * XXX This operation is signal handler unsafe and may lead to
459 * crashes and security breaches: See Henning Brauer talk at
460 * EuroBSDCon 2005. Do not run in production with this option
461 * enabled.
462 */
463 case SIGUSR2:
464 DRM_dump();
465 break;
466 #endif
467
468 case SIGHUP:
469 /* Save old configuration, load new one... */
470 reload_conf();
471 break;
472
473 case SIGINT:
474 case SIGTERM:
475 plog(LLV_INFO, LOCATION, NULL,
476 "caught signal %d\n", sig);
477 close_session();
478 break;
479
480 default:
481 plog(LLV_INFO, LOCATION, NULL,
482 "caught signal %d\n", sig);
483 break;
484 }
485 }
486 }
487
488 static void
init_signal()489 init_signal()
490 {
491 int i;
492
493 /*
494 * Ignore SIGPIPE as we check the return value of system calls
495 * that write to pipe-like fds.
496 */
497 signal(SIGPIPE, SIG_IGN);
498
499 for (i = 0; signals[i] != 0; i++)
500 if (set_signal(signals[i], signal_handler) < 0) {
501 plog(LLV_ERROR, LOCATION, NULL,
502 "failed to set_signal (%s)\n",
503 strerror(errno));
504 exit(1);
505 }
506 }
507
508 static int
set_signal(sig,func)509 set_signal(sig, func)
510 int sig;
511 RETSIGTYPE (*func) __P((int));
512 {
513 struct sigaction sa;
514
515 memset((caddr_t)&sa, 0, sizeof(sa));
516 sa.sa_handler = func;
517 sa.sa_flags = SA_RESTART;
518
519 if (sigemptyset(&sa.sa_mask) < 0)
520 return -1;
521
522 if (sigaction(sig, &sa, (struct sigaction *)0) < 0)
523 return(-1);
524
525 return 0;
526 }
527
528 static int
close_sockets()529 close_sockets()
530 {
531 myaddr_close();
532 pfkey_close(lcconf->sock_pfkey);
533 #ifdef ENABLE_ADMINPORT
534 (void)admin_close();
535 #endif
536 return 0;
537 }
538
539