1 /* $OpenBSD: npppd.c,v 1.56 2024/08/02 12:43:55 yasuoka Exp $ */
2
3 /*-
4 * Copyright (c) 2005-2008,2009 Internet Initiative Japan Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 /**@file
29 * Next pppd(nppd). This file provides a npppd daemon process and operations
30 * for npppd instance.
31 * @author Yasuoka Masahiko
32 * $Id: npppd.c,v 1.56 2024/08/02 12:43:55 yasuoka Exp $
33 */
34 #include "version.h"
35 #include <sys/param.h> /* ALIGNED_POINTER */
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/sysctl.h>
39 #include <sys/wait.h>
40 #include <netinet/in.h>
41 #include <netinet/ip.h>
42 #include <net/route.h>
43 #include <arpa/inet.h>
44 #include <net/if_dl.h>
45 #include <unistd.h>
46 #include <time.h>
47 #include <syslog.h>
48 #include <string.h>
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <signal.h>
52 #include <netdb.h>
53 #include <fcntl.h>
54 #include <event.h>
55 #include <errno.h>
56 #include <err.h>
57 #include <pwd.h>
58
59 #include "pathnames.h"
60 #include "debugutil.h"
61 #include "addr_range.h"
62 #include "npppd_subr.h"
63 #include "npppd_local.h"
64 #include "npppd_auth.h"
65 #include "radish.h"
66 #include "net_utils.h"
67 #include "time_utils.h"
68
69 #include "l2tp_local.h" /* XXX sa_cookie */
70
71 #ifdef USE_NPPPD_ARP
72 #include "npppd_arp.h"
73 #endif
74
75 #ifdef USE_NPPPD_PIPEX
76 #ifdef USE_NPPPD_PPPOE
77 #include "pppoe_local.h"
78 #endif /* USE_NPPPD_PPPOE */
79 #include "psm-opt.h"
80 #include <sys/ioctl.h>
81 #include <net/pipex.h>
82 #endif /* USE_NPPPD_PIPEX */
83
84 #include "accept.h"
85 #include "log.h"
86
87 static npppd s_npppd; /* singleton */
88
89 static void npppd_reload0 (npppd *);
90 static void npppd_update_pool_reference (npppd *);
91 static int npppd_rd_walktree_delete(struct radish_head *);
92 static __dead void usage (void);
93 static void npppd_stop_really (npppd *);
94 static uint32_t str_hash(const void *, int);
95 static void npppd_on_sighup (int, short, void *);
96 static void npppd_on_sigterm (int, short, void *);
97 static void npppd_on_sigint (int, short, void *);
98 static void npppd_on_sigchld (int, short, void *);
99 static void npppd_reset_timer(npppd *);
100 static void npppd_timer(int, short, void *);
101 static void npppd_auth_finalizer_periodic(npppd *);
102 static int rd2slist_walk (struct radish *, void *);
103 static int rd2slist (struct radish_head *, slist *);
104 static int npppd_get_all_users (npppd *, slist *);
105 static struct ipcpstat
106 *npppd_get_ipcp_stat(struct ipcpstat_head *, const char *);
107 static void npppd_destroy_ipcp_stats(struct ipcpstat_head *);
108 static void npppd_ipcp_stats_reload(npppd *);
109
110 #ifndef NO_ROUTE_FOR_POOLED_ADDRESS
111 static struct in_addr loop; /* initialize at npppd_init() */
112 #endif
113 static uint32_t str_hash(const void *, int);
114
115 #ifdef USE_NPPPD_PIPEX
116 static void pipex_periodic(npppd *);
117 #endif /* USE_NPPPD_PIPEX */
118
119 #ifdef NPPPD_DEBUG
120 #define NPPPD_DBG(x) log_printf x
121 #define NPPPD_ASSERT(x) ASSERT(x)
122 #else
123 #define NPPPD_DBG(x)
124 #define NPPPD_ASSERT(x)
125 #endif
126
127 /***********************************************************************
128 * Daemon process
129 ***********************************************************************/
130 int main (int, char *[]);
131 int debugsyslog = 0; /* used by log.c */
132
133 int
main(int argc,char * argv[])134 main(int argc, char *argv[])
135 {
136 int ch, stop_by_error, runasdaemon = 1, nflag = 0;
137 const char *npppd_conf0 = DEFAULT_NPPPD_CONF;
138 struct passwd *pw;
139
140 while ((ch = getopt(argc, argv, "nf:d")) != -1) {
141 switch (ch) {
142 case 'n':
143 nflag = 1;
144 break;
145 case 'f':
146 npppd_conf0 = optarg;
147 break;
148 case 'd':
149 debuglevel++;
150 runasdaemon = 0;
151 break;
152 default:
153 usage();
154 }
155 }
156 argc -= optind;
157 argv += optind;
158 if (argc != 0)
159 usage();
160 if (nflag) {
161 debuglevel++;
162 runasdaemon = 0;
163 }
164
165 /* for log.c */
166 log_init(debuglevel);
167 if (debuglevel > 0) {
168 /* for ../common/debugutil.c */
169 debug_set_debugfp(stderr);
170 debug_use_syslog(0);
171 }
172 if (runasdaemon)
173 daemon(0, 0);
174
175 /* check for root privileges */
176 if (geteuid())
177 errx(1, "need root privileges");
178 /* check for npppd user */
179 if (getpwnam(NPPPD_USER) == NULL)
180 errx(1, "unknown user %s", NPPPD_USER);
181
182 if (privsep_init() != 0)
183 err(1, "cannot drop privileges");
184
185 if (nflag) {
186 if (npppd_config_check(npppd_conf0) == 0) {
187 fprintf(stderr, "configuration OK\n");
188 exit(EXIT_SUCCESS);
189 }
190 exit(EXIT_FAILURE);
191 }
192 if (npppd_init(&s_npppd, npppd_conf0) != 0)
193 exit(EXIT_FAILURE);
194
195 if ((pw = getpwnam(NPPPD_USER)) == NULL)
196 err(EXIT_FAILURE, "gwpwnam");
197 if (chroot(pw->pw_dir) == -1)
198 err(EXIT_FAILURE, "chroot");
199 if (chdir("/") == -1)
200 err(EXIT_FAILURE, "chdir(\"/\")");
201 if (setgroups(1, &pw->pw_gid) ||
202 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
203 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
204 err(EXIT_FAILURE, "cannot drop privileges");
205 /* privileges is dropped */
206
207 npppd_start(&s_npppd);
208 stop_by_error = s_npppd.stop_by_error;
209 npppd_fini(&s_npppd);
210 privsep_fini();
211 log_printf(LOG_NOTICE, "Terminate npppd.");
212
213 exit((!stop_by_error)? EXIT_SUCCESS : EXIT_FAILURE);
214 }
215
216 static __dead void
usage(void)217 usage(void)
218 {
219 fprintf(stderr, "usage: npppd [-dn] [-f config_file]\n");
220 exit(1);
221 }
222
223 /** Returns the singleton npppd instance */
224 npppd *
npppd_get_npppd()225 npppd_get_npppd()
226 {
227 return &s_npppd;
228 }
229
230 /***********************************************************************
231 * Operations to npppd itself (initialize/finalize/start/stop)
232 ***********************************************************************/
233 /** Initialize the npppd */
234 int
npppd_init(npppd * _this,const char * config_file)235 npppd_init(npppd *_this, const char *config_file)
236 {
237 int i, status = -1, value;
238 const char *pidpath0;
239 FILE *pidfp = NULL;
240 struct tunnconf *tunn;
241 struct ipcpconf *ipcpconf;
242 struct ipcpstat *ipcpstat;
243 int mib[] = { CTL_NET, PF_PIPEX, PIPEXCTL_ENABLE };
244 size_t size;
245
246 memset(_this, 0, sizeof(npppd));
247 #ifndef NO_ROUTE_FOR_POOLED_ADDRESS
248 loop.s_addr = htonl(INADDR_LOOPBACK);
249 #endif
250
251 NPPPD_ASSERT(config_file != NULL);
252
253 pidpath0 = NULL;
254 _this->pid = getpid();
255 slist_init(&_this->realms);
256 npppd_conf_init(&_this->conf);
257 TAILQ_INIT(&_this->raddae_listens);
258
259 log_printf(LOG_NOTICE, "Starting npppd pid=%u version=%s",
260 _this->pid, VERSION);
261 #if defined(BUILD_DATE) && defined(BUILD_TIME)
262 log_printf(LOG_INFO, "Build %s %s ", BUILD_DATE, BUILD_TIME);
263 #endif
264 if (get_nanotime() == INT64_MIN) {
265 log_printf(LOG_ERR, "get_nanotime() failed: %m");
266 return 1;
267 }
268
269 if (realpath(config_file, _this->config_file) == NULL) {
270 log_printf(LOG_ERR, "realpath(%s,) failed in %s(): %m",
271 config_file, __func__);
272 return 1;
273 }
274 /* we assume 4.4 compatible realpath(). See realpath(3) on BSD. */
275 NPPPD_ASSERT(_this->config_file[0] == '/');
276
277 _this->boot_id = arc4random();
278
279 #ifdef USE_NPPPD_L2TP
280 if (l2tpd_init(&_this->l2tpd) != 0)
281 return (-1);
282 #endif
283 #ifdef USE_NPPPD_PPTP
284 if (pptpd_init(&_this->pptpd) != 0)
285 return (-1);
286 #endif
287 #ifdef USE_NPPPD_PPPOE
288 if (pppoed_init(&_this->pppoed) != 0)
289 return (-1);
290 #endif
291 LIST_INIT(&_this->ipcpstats);
292
293 /* load configuration */
294 if ((status = npppd_reload_config(_this)) != 0)
295 return status;
296
297 TAILQ_FOREACH(tunn, &_this->conf.tunnconfs, entry) {
298 if (tunn->pipex) {
299 size = sizeof(value);
300 if (!sysctl(mib, nitems(mib), &value, &size, NULL, 0)
301 && value == 0)
302 log_printf(LOG_WARNING,
303 "pipex(4) is disabled by sysctl");
304 break;
305 }
306 }
307
308 if ((_this->map_user_ppp = hash_create(
309 (int (*) (const void *, const void *))strcmp, str_hash,
310 NPPPD_USER_HASH_SIZ)) == NULL) {
311 log_printf(LOG_ERR, "hash_create() failed in %s(): %m",
312 __func__);
313 return -1;
314 }
315
316 if (npppd_ifaces_load_config(_this) != 0) {
317 return -1;
318 }
319
320 TAILQ_FOREACH(ipcpconf, &_this->conf.ipcpconfs, entry) {
321 ipcpstat = malloc(sizeof(*ipcpstat));
322 if (ipcpstat == NULL) {
323 log_printf(LOG_ERR, "initializing ipcp_stats failed : %m");
324 npppd_destroy_ipcp_stats(&_this->ipcpstats);
325 return -1;
326 }
327 memset(ipcpstat, 0, sizeof(*ipcpstat));
328 strlcpy(ipcpstat->name, ipcpconf->name, sizeof(ipcpstat->name));
329 LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry);
330 }
331
332 pidpath0 = DEFAULT_NPPPD_PIDFILE;
333
334 /* initialize event(3) */
335 event_init();
336 _this->ctl_sock.cs_name = NPPPD_SOCKET;
337 _this->ctl_sock.cs_ctx = _this;
338 if (control_init(&_this->ctl_sock) == -1) {
339 log_printf(LOG_ERR, "control_init() failed %s(): %m",
340 __func__);
341 return (-1);
342 }
343 if (control_listen(&_this->ctl_sock) == -1) {
344 log_printf(LOG_ERR, "control_listen() failed %s(): %m",
345 __func__);
346 return (-1);
347 }
348 accept_init();
349
350 /* ignore signals */
351 signal(SIGPIPE, SIG_IGN);
352 signal(SIGURG, SIG_IGN);
353
354 /* set signal handlers */
355 signal_set(&_this->ev_sigterm, SIGTERM, npppd_on_sigterm, _this);
356 signal_set(&_this->ev_sigint, SIGINT, npppd_on_sigint, _this);
357 signal_set(&_this->ev_sighup, SIGHUP, npppd_on_sighup, _this);
358 signal_set(&_this->ev_sigchld, SIGCHLD, npppd_on_sigchld, _this);
359 signal_add(&_this->ev_sigterm, NULL);
360 signal_add(&_this->ev_sigint, NULL);
361 signal_add(&_this->ev_sighup, NULL);
362 signal_add(&_this->ev_sigchld, NULL);
363
364 evtimer_set(&_this->ev_timer, npppd_timer, _this);
365
366 /* start tun(4) or pppac(4) */
367 status = 0;
368 for (i = 0; i < countof(_this->iface); i++) {
369 if (_this->iface[i].initialized != 0)
370 status |= npppd_iface_start(&_this->iface[i]);
371 }
372 if (status != 0)
373 return -1;
374
375 /*
376 * If the npppd can start(open) interfaces successfully, it can
377 * act as only one npppd process on the system and overwrite the pid
378 * file.
379 */
380 if ((pidfp = fopen(pidpath0, "w+")) == NULL) {
381 log_printf(LOG_ERR, "fopen(%s,w+) failed in %s(): %m",
382 pidpath0, __func__);
383 return -1;
384 }
385 strlcpy(_this->pidpath, pidpath0, sizeof(_this->pidpath));
386 fprintf(pidfp, "%u\n", _this->pid);
387 fclose(pidfp);
388 pidfp = NULL;
389 #ifdef USE_NPPPD_ARP
390 arp_set_strictintfnetwork(npppd_config_str_equali(_this, "arpd.strictintfnetwork", "true", ARPD_STRICTINTFNETWORK_DEFAULT));
391 if (npppd_config_str_equali(_this, "arpd.enabled", "true", ARPD_DEFAULT) == 1)
392 arp_sock_init();
393 #endif
394 if ((status = npppd_modules_reload(_this)) != 0)
395 return status;
396
397 npppd_update_pool_reference(_this);
398
399 return 0;
400 }
401
402 /** start the npppd */
403 void
npppd_start(npppd * _this)404 npppd_start(npppd *_this)
405 {
406 int rval = 0;
407
408 npppd_reset_timer(_this);
409 while ((rval = event_loop(EVLOOP_ONCE)) == 0) {
410 if (_this->finalized != 0)
411 break;
412 }
413 if (rval != 0) {
414 log_printf(LOG_CRIT, "event_loop() failed: %m");
415 abort();
416 }
417 }
418
419 /** stop the npppd */
420 void
npppd_stop(npppd * _this)421 npppd_stop(npppd *_this)
422 {
423 int i;
424 #ifdef USE_NPPPD_L2TP
425 l2tpd_stop(&_this->l2tpd);
426 #endif
427 #ifdef USE_NPPPD_PPTP
428 pptpd_stop(&_this->pptpd);
429 #endif
430 #ifdef USE_NPPPD_PPPOE
431 pppoed_stop(&_this->pppoed);
432 #endif
433 #ifdef USE_NPPPD_ARP
434 arp_sock_fini();
435 #endif
436 close(_this->ctl_sock.cs_fd);
437 control_cleanup(&_this->ctl_sock);
438
439 for (i = countof(_this->iface) - 1; i >= 0; i--) {
440 if (_this->iface[i].initialized != 0)
441 npppd_iface_stop(&_this->iface[i]);
442 }
443 npppd_set_radish(_this, NULL);
444
445 _this->finalizing = 1;
446 npppd_reset_timer(_this);
447
448 #ifdef USE_NPPPD_RADIUS
449 npppd_radius_dae_fini(_this);
450 #endif
451 }
452
453 static void
npppd_stop_really(npppd * _this)454 npppd_stop_really(npppd *_this)
455 {
456 int i;
457 #if defined(USE_NPPPD_L2TP) || defined(USE_NPPPD_PPTP)
458 int wait_again;
459
460 wait_again = 0;
461
462 #ifdef USE_NPPPD_L2TP
463 if (!l2tpd_is_stopped(&_this->l2tpd))
464 wait_again |= 1;
465 #endif
466 #ifdef USE_NPPPD_PPTP
467 if (!pptpd_is_stopped(&_this->pptpd))
468 wait_again |= 1;
469 #endif
470 if (wait_again != 0) {
471 npppd_reset_timer(_this);
472 return;
473 }
474 #endif
475 for (i = countof(_this->iface) - 1; i >= 0; i--) {
476 npppd_iface_fini(&_this->iface[i]);
477 }
478 _this->finalized = 1;
479 }
480
481 /** finalize the npppd */
482 void
npppd_fini(npppd * _this)483 npppd_fini(npppd *_this)
484 {
485 int i;
486 npppd_auth_base *auth_base;
487
488 #ifdef USE_NPPPD_L2TP
489 l2tpd_uninit(&_this->l2tpd);
490 #endif
491 #ifdef USE_NPPPD_PPTP
492 pptpd_uninit(&_this->pptpd);
493 #endif
494 #ifdef USE_NPPPD_PPPOE
495 pppoed_uninit(&_this->pppoed);
496 #endif
497 for (slist_itr_first(&_this->realms);
498 slist_itr_has_next(&_this->realms);) {
499 auth_base = slist_itr_next(&_this->realms);
500 npppd_auth_destroy(auth_base);
501 }
502 for (i = countof(_this->iface) - 1; i >= 0; i--) {
503 if (_this->iface[i].initialized != 0)
504 npppd_iface_fini(&_this->iface[i]);
505 }
506
507 for (i = countof(_this->pool) - 1; i >= 0; i--) {
508 if (_this->pool[i].initialized != 0)
509 npppd_pool_uninit(&_this->pool[i]);
510 }
511
512 npppd_destroy_ipcp_stats(&_this->ipcpstats);
513
514 signal_del(&_this->ev_sigterm);
515 signal_del(&_this->ev_sigint);
516 signal_del(&_this->ev_sighup);
517 signal_del(&_this->ev_sigchld);
518
519 npppd_conf_fini(&_this->conf);
520
521 slist_fini(&_this->realms);
522
523 if (_this->map_user_ppp != NULL)
524 hash_free(_this->map_user_ppp);
525 }
526
527 /***********************************************************************
528 * Timer related functions
529 ***********************************************************************/
530 static void
npppd_reset_timer(npppd * _this)531 npppd_reset_timer(npppd *_this)
532 {
533 struct timeval tv;
534
535 if (_this->finalizing != 0) {
536 /* we can use the timer exclusively on finalizing */
537 tv.tv_usec = 500000;
538 tv.tv_sec = 0;
539 evtimer_add(&_this->ev_timer, &tv);
540 } else {
541 tv.tv_usec = 0;
542 tv.tv_sec = NPPPD_TIMER_TICK_IVAL;
543 evtimer_add(&_this->ev_timer, &tv);
544 }
545 }
546
547 static void
npppd_timer(int fd,short evtype,void * ctx)548 npppd_timer(int fd, short evtype, void *ctx)
549 {
550 npppd *_this;
551
552 _this = ctx;
553 if (_this->finalizing != 0) {
554 npppd_stop_really(_this); /* The timer has been reset */
555 return; /* we can use the timer exclusively on finalizing */
556 }
557 _this->secs += NPPPD_TIMER_TICK_IVAL;
558 if (_this->reloading_count > 0) {
559 _this->reloading_count -= NPPPD_TIMER_TICK_IVAL;
560 if (_this->reloading_count <= 0) {
561 npppd_reload0(_this);
562 _this->reloading_count = 0;
563 }
564 } else {
565 if ((_this->secs % TIMER_TICK_RUP(
566 NPPPD_AUTH_REALM_FINALIZER_INTERVAL)) == 0)
567 npppd_auth_finalizer_periodic(_this);
568 }
569
570 #ifdef USE_NPPPD_PPPOE
571 if (pppoed_need_polling(&_this->pppoed))
572 pppoed_reload_listeners(&_this->pppoed);
573 #endif
574 #ifdef USE_NPPPD_PIPEX
575 pipex_periodic(_this);
576 #endif
577
578 npppd_reset_timer(_this);
579 }
580
581 int
npppd_reset_routing_table(npppd * _this,int pool_only)582 npppd_reset_routing_table(npppd *_this, int pool_only)
583 {
584 #ifndef NO_ROUTE_FOR_POOLED_ADDRESS
585 slist rtlist0;
586
587 if (_this->iface[0].using_pppx)
588 return 0;
589
590 slist_init(&rtlist0);
591 if (rd2slist(_this->rd, &rtlist0) != 0)
592 return 1;
593
594 for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0); ) {
595 struct radish *rd;
596 struct sockaddr_npppd *snp;
597 npppd_ppp *ppp;
598 int is_first;
599
600 rd = slist_itr_next(&rtlist0);
601 snp = rd->rd_rtent;
602
603 is_first = 1;
604 for (snp = rd->rd_rtent; snp != NULL; snp = snp->snp_next) {
605 switch (snp->snp_type) {
606 case SNP_POOL:
607 case SNP_DYN_POOL:
608 if (is_first)
609 in_route_add(&snp->snp_addr,
610 &snp->snp_mask, &loop,
611 LOOPBACK_IFNAME, RTF_BLACKHOLE, 0);
612 break;
613
614 case SNP_PPP:
615 if (pool_only)
616 break;
617 ppp = snp->snp_data_ptr;
618 if (ppp->ppp_framed_ip_netmask.s_addr
619 == 0xffffffffL) {
620 in_host_route_add(&ppp->
621 ppp_framed_ip_address,
622 &ppp_iface(ppp)->ip4addr,
623 ppp_iface(ppp)->ifname,
624 MRU_IPMTU(ppp->peer_mru));
625 } else {
626 in_route_add(&ppp->
627 ppp_framed_ip_address,
628 &ppp->ppp_framed_ip_netmask,
629 &ppp_iface(ppp)->ip4addr,
630 ppp_iface(ppp)->ifname, 0,
631 MRU_IPMTU(ppp->peer_mru));
632 }
633 break;
634 }
635 is_first = 0;
636 }
637
638 }
639
640 slist_fini(&rtlist0);
641 #endif
642 return 0;
643 }
644
645 /***********************************************************************
646 * Other npppd related functions.
647 ***********************************************************************/
648 /**
649 * Get the user's password. Return 0 on success.
650 *
651 * @param username Username who acquires password
652 * @param password A pointer to a buffer space to store the password.
653 * Use NULL when you need to know only the length of
654 * the password.
655 * @param plpassword A pointer to the length of the password parameter.
656 * This function uses this parameter value and stores
657 * the required length value pointed to by this
658 * parameter. Use NULL when use don't need to know
659 * the password and its length.
660 * @return If the function succeeds, 0 is returned. The function returns
661 * 1 if the username is unknown, returns 2 if the password buffer
662 * length is not enough. It returns negative value for other
663 * errors.
664 */
665 int
npppd_get_user_password(npppd * _this,npppd_ppp * ppp,const char * username,char * password,int * plpassword)666 npppd_get_user_password(npppd *_this, npppd_ppp *ppp,
667 const char *username, char *password, int *plpassword)
668 {
669 char buf0[MAX_USERNAME_LENGTH];
670
671 NPPPD_ASSERT(ppp->realm != NULL);
672 return npppd_auth_get_user_password(ppp->realm,
673 npppd_auth_username_for_auth(ppp->realm, username, buf0), password,
674 plpassword);
675 }
676
677 /** Get the Framed-IP-Address attribute of the user */
678 struct in_addr *
npppd_get_user_framed_ip_address(npppd * _this,npppd_ppp * ppp,const char * username)679 npppd_get_user_framed_ip_address(npppd *_this, npppd_ppp *ppp,
680 const char *username)
681 {
682
683 if (ppp->peer_auth == 0) {
684 ppp->realm_framed_ip_address.s_addr = 0;
685 goto do_default;
686 }
687 NPPPD_ASSERT(ppp->realm != NULL);
688
689 if (ppp->realm_framed_ip_address.s_addr != 0)
690 return &ppp->realm_framed_ip_address;
691
692 /* assign by the authentication realm */
693 if (npppd_auth_get_framed_ip(ppp->realm, username,
694 &ppp->realm_framed_ip_address,
695 &ppp->realm_framed_ip_netmask) != 0)
696 ppp->realm_framed_ip_address.s_addr = 0;
697
698 do_default:
699 /* Use USER_SELECT if the realm doesn't specify the ip address */
700 if (ppp->realm_framed_ip_address.s_addr == 0)
701 ppp->realm_framed_ip_address.s_addr = INADDR_USER_SELECT;
702
703
704 if (ppp->realm_framed_ip_address.s_addr == INADDR_USER_SELECT) {
705 /* Use NAS_SELECT if USER_SELECT is not allowed by the config */
706 if (!ppp_ipcp(ppp)->allow_user_select)
707 ppp->realm_framed_ip_address.s_addr = INADDR_NAS_SELECT;
708 }
709 NPPPD_DBG((LOG_DEBUG, "%s() = %s", __func__,
710 inet_ntoa(ppp->realm_framed_ip_address)));
711
712 return &ppp->realm_framed_ip_address;
713 }
714
715 /** XXX */
716 int
npppd_check_calling_number(npppd * _this,npppd_ppp * ppp)717 npppd_check_calling_number(npppd *_this, npppd_ppp *ppp)
718 {
719 struct tunnconf *conf;
720 int lnumber, rval;
721 char number[NPPPD_PHONE_NUMBER_LEN + 1];
722
723 conf = ppp_get_tunnconf(ppp);
724 if (conf->callnum_check != 0) {
725 lnumber = sizeof(number);
726 if ((rval = npppd_auth_get_calling_number(ppp->realm,
727 ppp->username, number, &lnumber)) == 0)
728 return
729 (strcmp(number, ppp->calling_number) == 0)? 1 : 0;
730 if ((conf->callnum_check & NPPPD_CALLNUM_CHECK_STRICT) != 0)
731 return 0;
732 }
733
734 return 1;
735 }
736
737 /**
738 * This function finds a {@link npppd_ppp} instance that is assigned the
739 * specified ip address and returns it
740 * @param ipaddr IP Address(Specify in network byte order)
741 */
742 npppd_ppp *
npppd_get_ppp_by_ip(npppd * _this,struct in_addr ipaddr)743 npppd_get_ppp_by_ip(npppd *_this, struct in_addr ipaddr)
744 {
745 struct sockaddr_npppd *snp;
746 struct radish *rdp;
747 struct sockaddr_in npppd_get_ppp_by_ip_sin4;
748
749 npppd_get_ppp_by_ip_sin4.sin_family = AF_INET;
750 npppd_get_ppp_by_ip_sin4.sin_len = sizeof(struct sockaddr_in);
751 npppd_get_ppp_by_ip_sin4.sin_addr = ipaddr;
752 if (_this->rd == NULL)
753 return NULL; /* no radix tree on startup */
754 if (rd_match((struct sockaddr *)&npppd_get_ppp_by_ip_sin4, _this->rd,
755 &rdp)) {
756 snp = rdp->rd_rtent;
757 if (snp->snp_type == SNP_PPP)
758 return snp->snp_data_ptr;
759 }
760 return NULL;
761 }
762
763 /**
764 * This function finds {@link npppd_ppp} instances that are authenticated
765 * as the specified username and returns them as a {@link slist} list.
766 * @param username PPP Username.
767 * @return {@link slist} that contains the {@link npppd_ppp} instances.
768 * NULL may be returned if no instance has been found.
769 */
770 slist *
npppd_get_ppp_by_user(npppd * _this,const char * username)771 npppd_get_ppp_by_user(npppd *_this, const char *username)
772 {
773 hash_link *hl;
774
775 if ((hl = hash_lookup(_this->map_user_ppp, username)) != NULL)
776 return hl->item;
777
778 return NULL;
779 }
780
781 /**
782 * This function finds a {@link npppd_ppp} instance that matches the specified
783 * ppp id and returns it.
784 * @param id {@link npppd_ppp#id ppp's id}
785 * @return This function returns the pointer if the instance which has
786 * specified ID is found, otherwise it returns NULL.
787 */
788 npppd_ppp *
npppd_get_ppp_by_id(npppd * _this,u_int ppp_id)789 npppd_get_ppp_by_id(npppd *_this, u_int ppp_id)
790 {
791 slist users;
792 npppd_ppp *ppp0, *ppp;
793
794 NPPPD_ASSERT(_this != NULL);
795
796 ppp = NULL;
797 slist_init(&users);
798 if (npppd_get_all_users(_this, &users) != 0) {
799 log_printf(LOG_WARNING,
800 "npppd_get_all_users() failed in %s()", __func__);
801 } else {
802 /* FIXME: This linear search eats CPU. */
803 for (slist_itr_first(&users); slist_itr_has_next(&users); ) {
804 ppp0 = slist_itr_next(&users);
805 if (ppp0->id == ppp_id) {
806 ppp = ppp0;
807 break;
808 }
809 }
810 }
811 slist_fini(&users);
812
813 return ppp;
814 }
815
816 static struct ipcpstat *
npppd_get_ipcp_stat(struct ipcpstat_head * head,const char * ipcp_name)817 npppd_get_ipcp_stat(struct ipcpstat_head *head , const char *ipcp_name)
818 {
819 struct ipcpstat *ipcpstat = NULL;
820
821 LIST_FOREACH(ipcpstat, head, entry) {
822 if (strncmp(ipcpstat->name, ipcp_name,
823 sizeof(ipcpstat->name)) == 0)
824 return ipcpstat;
825 }
826
827 return NULL;
828 }
829
830 static void
npppd_destroy_ipcp_stats(struct ipcpstat_head * head)831 npppd_destroy_ipcp_stats(struct ipcpstat_head *head)
832 {
833 struct ipcpstat *ipcpstat, *tipcpstat;
834 npppd_ppp *ppp, *tppp;
835
836 LIST_FOREACH_SAFE(ipcpstat, head, entry, tipcpstat) {
837 LIST_FOREACH_SAFE(ppp, &ipcpstat->ppp, ipcpstat_entry, tppp) {
838 ppp->ipcpstat = NULL;
839 LIST_REMOVE(ppp, ipcpstat_entry);
840 }
841 free(ipcpstat);
842 }
843 }
844
845 static void
npppd_ipcp_stats_reload(npppd * _this)846 npppd_ipcp_stats_reload(npppd *_this)
847 {
848 struct ipcpstat *ipcpstat, *tipcpstat;
849 struct ipcpconf *ipcpconf;
850 struct ipcpstat_head destroy_list;
851
852 LIST_INIT(&destroy_list);
853 LIST_FOREACH_SAFE(ipcpstat, &_this->ipcpstats, entry, tipcpstat) {
854 LIST_REMOVE(ipcpstat, entry);
855 LIST_INSERT_HEAD(&destroy_list, ipcpstat, entry);
856 }
857
858 TAILQ_FOREACH(ipcpconf, &_this->conf.ipcpconfs, entry) {
859 ipcpstat = npppd_get_ipcp_stat(&destroy_list, ipcpconf->name);
860 if (ipcpstat != NULL) {
861 LIST_REMOVE(ipcpstat, entry);
862 LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry);
863 continue;
864 }
865
866 ipcpstat = malloc(sizeof(*ipcpstat));
867 if (ipcpstat == NULL) {
868 log_printf(LOG_ERR, "initializing ipcp_stats failed : %m");
869 continue;
870 }
871 memset(ipcpstat, 0, sizeof(*ipcpstat));
872 strlcpy(ipcpstat->name, ipcpconf->name, sizeof(ipcpconf->name));
873 LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry);
874 }
875 npppd_destroy_ipcp_stats(&destroy_list);
876 }
877
878 /**
879 * Checks whether the user reaches the maximum session limit
880 * (user_max_serssion).
881 * @return This function returns 1(true) if the user does not reach the
882 * limit, otherwise it returns 0(false).
883 */
884 int
npppd_check_user_max_session(npppd * _this,npppd_ppp * ppp)885 npppd_check_user_max_session(npppd *_this, npppd_ppp *ppp)
886 {
887 int global_count, realm_count;
888 npppd_ppp *ppp1;
889 slist *uppp;
890
891 /* user_max_session == 0 means unlimit */
892 if (_this->conf.user_max_session == 0 &&
893 npppd_auth_user_session_unlimited(ppp->realm))
894 return 1;
895
896 global_count = realm_count = 0;
897 if ((uppp = npppd_get_ppp_by_user(_this, ppp->username)) != NULL) {
898 for (slist_itr_first(uppp); slist_itr_has_next(uppp); ) {
899 ppp1 = slist_itr_next(uppp);
900 if (ppp->realm == ppp1->realm)
901 realm_count++;
902 global_count++;
903 }
904 }
905
906 if (npppd_check_auth_user_max_session(ppp->realm, realm_count)) {
907 ppp_log(ppp, LOG_WARNING,
908 "user %s exceeds user-max-session limit per auth",
909 ppp->username);
910 return 0;
911 } else if (_this->conf.user_max_session != 0 &&
912 _this->conf.user_max_session <= global_count) {
913 ppp_log(ppp, LOG_WARNING,
914 "user %s exceeds user-max-session limit", ppp->username);
915 return 0;
916 } else
917 return 1;
918 }
919
920 /***********************************************************************
921 * Network I/O ralated functions.
922 ***********************************************************************/
923 /**
924 * Call this function to output packets to the network(tun). This function
925 * currently assumes the packet is a IPv4 datagram.
926 */
927 void
npppd_network_output(npppd * _this,npppd_ppp * ppp,int proto,u_char * pktp,int lpktp)928 npppd_network_output(npppd *_this, npppd_ppp *ppp, int proto, u_char *pktp,
929 int lpktp)
930 {
931 struct ip *pip;
932 int lbuf;
933 u_char buf[256]; /* enough size for TCP/IP header */
934
935 NPPPD_ASSERT(ppp != NULL);
936
937 if (!ppp_ip_assigned(ppp))
938 return;
939
940 if (lpktp < sizeof(struct ip)) {
941 ppp_log(ppp, LOG_DEBUG, "Received IP packet is too small");
942 return;
943 }
944 lbuf = MINIMUM(lpktp, sizeof(buf));
945 if (!ALIGNED_POINTER(pktp, struct ip)) {
946 memcpy(buf, pktp, lbuf);
947 pip = (struct ip *)buf;
948 } else {
949 pip = (struct ip *)pktp;
950 }
951
952 if (ppp->ingress_filter != 0 &&
953 (pip->ip_src.s_addr & ppp->ppp_framed_ip_netmask.s_addr)
954 != (ppp->ppp_framed_ip_address.s_addr &
955 ppp->ppp_framed_ip_netmask.s_addr)) {
956 char logbuf[80];
957 strlcpy(logbuf, inet_ntoa(pip->ip_dst), sizeof(logbuf));
958 ppp_log(ppp, LOG_INFO,
959 "Drop packet by ingress filter. %s => %s",
960 inet_ntoa(pip->ip_src), logbuf);
961
962 return;
963 }
964 if (ppp->timeout_sec > 0 && !ip_is_idle_packet(pip, lbuf))
965 ppp_reset_idle_timeout(ppp);
966
967 #ifndef NO_ADJUST_MSS
968 if (ppp->adjust_mss) {
969 if (lpktp == lbuf) {
970 /*
971 * We can assume the packet length is less than
972 * sizeof(buf).
973 */
974 if (!ALIGNED_POINTER(pktp, struct ip))
975 pktp = buf;
976 adjust_tcp_mss(pktp, lpktp, MRU_IPMTU(ppp->peer_mru));
977 }
978 }
979 #endif
980 npppd_iface_write(ppp_iface(ppp), ppp, proto, pktp, lpktp);
981 }
982
983 #ifdef USE_NPPPD_PIPEX
984 /***********************************************************************
985 * PIPEX related functions
986 ***********************************************************************/
987 static void
pipex_setup_common(npppd_ppp * ppp,struct pipex_session_req * req)988 pipex_setup_common(npppd_ppp *ppp, struct pipex_session_req *req)
989 {
990 memset(req, 0, sizeof(*req));
991 if (psm_opt_is_accepted(&ppp->lcp, acfc))
992 req->pr_ppp_flags |= PIPEX_PPP_ACFC_ENABLED;
993 if (psm_peer_opt_is_accepted(&ppp->lcp, acfc))
994 req->pr_ppp_flags |= PIPEX_PPP_ACFC_ACCEPTED;
995
996 if (psm_peer_opt_is_accepted(&ppp->lcp, pfc))
997 req->pr_ppp_flags |= PIPEX_PPP_PFC_ACCEPTED;
998 if (psm_opt_is_accepted(&ppp->lcp, pfc))
999 req->pr_ppp_flags |= PIPEX_PPP_PFC_ENABLED;
1000
1001 if (ppp->has_acf != 0)
1002 req->pr_ppp_flags |= PIPEX_PPP_HAS_ACF;
1003
1004 if (ppp->adjust_mss != 0)
1005 req->pr_ppp_flags |= PIPEX_PPP_ADJUST_TCPMSS;
1006 if (ppp->ingress_filter != 0)
1007 req->pr_ppp_flags |= PIPEX_PPP_INGRESS_FILTER;
1008
1009 req->pr_ip_srcaddr = ppp->pppd->iface[0].ip4addr;
1010 req->pr_ip_address = ppp->ppp_framed_ip_address;
1011 req->pr_ip_netmask = ppp->ppp_framed_ip_netmask;
1012 req->pr_peer_mru = ppp->peer_mru;
1013 req->pr_ppp_id = ppp->id;
1014
1015 req->pr_timeout_sec = ppp->timeout_sec;
1016
1017 #ifdef USE_NPPPD_MPPE
1018 req->pr_ccp_id = ppp->ccp.fsm.id;
1019 if (ppp->mppe.send.keybits > 0) {
1020 memcpy(req->pr_mppe_send.master_key,
1021 ppp->mppe.send.master_key,
1022 sizeof(req->pr_mppe_send.master_key));
1023 req->pr_mppe_send.stateless = ppp->mppe.send.stateless;
1024 req->pr_mppe_send.keylenbits = ppp->mppe.send.keybits;
1025 req->pr_ppp_flags |= PIPEX_PPP_MPPE_ENABLED;
1026 }
1027 if (ppp->mppe.recv.keybits > 0) {
1028 memcpy(req->pr_mppe_recv.master_key,
1029 ppp->mppe.recv.master_key,
1030 sizeof(req->pr_mppe_recv.master_key));
1031 req->pr_mppe_recv.stateless = ppp->mppe.recv.stateless;
1032 req->pr_mppe_recv.keylenbits = ppp->mppe.recv.keybits;
1033 req->pr_ppp_flags |= PIPEX_PPP_MPPE_ACCEPTED;
1034 }
1035 if (ppp->mppe.required)
1036 req->pr_ppp_flags |= PIPEX_PPP_MPPE_REQUIRED;
1037 #endif /* USE_NPPPD_MPPE */
1038 }
1039
1040 /** Enable PIPEX of the {@link npppd_ppp ppp} */
1041 int
npppd_ppp_pipex_enable(npppd * _this,npppd_ppp * ppp)1042 npppd_ppp_pipex_enable(npppd *_this, npppd_ppp *ppp)
1043 {
1044 struct pipex_session_req req;
1045 #ifdef USE_NPPPD_PPPOE
1046 pppoe_session *pppoe;
1047 #endif
1048 #ifdef USE_NPPPD_PPTP
1049 pptp_call *call;
1050 #endif
1051 #ifdef USE_NPPPD_L2TP
1052 l2tp_call *l2tp;
1053 l2tp_ctrl *l2tpctrl;
1054 #endif
1055 int error;
1056
1057 NPPPD_ASSERT(ppp != NULL);
1058 NPPPD_ASSERT(ppp->phy_context != NULL);
1059 NPPPD_ASSERT(ppp->use_pipex != 0);
1060
1061 pipex_setup_common(ppp, &req);
1062
1063 switch (ppp->tunnel_type) {
1064 #ifdef USE_NPPPD_PPPOE
1065 case NPPPD_TUNNEL_PPPOE:
1066 {
1067 struct sockaddr *sa;
1068 struct ether_header *eh;
1069 pppoe = (pppoe_session *)ppp->phy_context;
1070
1071 /* PPPoE specific information */
1072 req.pr_protocol = PIPEX_PROTO_PPPOE;
1073 req.pr_session_id = pppoe->session_id;
1074 req.pr_peer_session_id = 0;
1075 strlcpy(req.pr_proto.pppoe.over_ifname,
1076 pppoe_session_listen_ifname(pppoe),
1077 sizeof(req.pr_proto.pppoe.over_ifname));
1078
1079 sa = (struct sockaddr *)&req.pr_peer_address;
1080 sa->sa_family = AF_UNSPEC;
1081 sa->sa_len = sizeof(struct sockaddr);
1082
1083 eh = (struct ether_header *)sa->sa_data;
1084 eh->ether_type = htons(ETHERTYPE_PPPOE);
1085 memcpy(eh->ether_dhost, pppoe->ether_addr, ETHER_ADDR_LEN);
1086 memset(eh->ether_shost, 0, ETHER_ADDR_LEN);
1087
1088 break;
1089 }
1090 #endif
1091 #ifdef USE_NPPPD_PPTP
1092 case NPPPD_TUNNEL_PPTP:
1093 call = (pptp_call *)ppp->phy_context;
1094
1095 /* PPTP specific information */
1096 req.pr_session_id = call->id;
1097 req.pr_protocol = PIPEX_PROTO_PPTP;
1098
1099 req.pr_peer_session_id = call->peers_call_id;
1100 req.pr_proto.pptp.snd_nxt = call->snd_nxt;
1101 req.pr_proto.pptp.snd_una = call->snd_una;
1102 req.pr_proto.pptp.rcv_nxt = call->rcv_nxt;
1103 req.pr_proto.pptp.rcv_acked = call->rcv_acked;
1104 req.pr_proto.pptp.winsz = call->winsz;
1105 req.pr_proto.pptp.maxwinsz = call->maxwinsz;
1106 req.pr_proto.pptp.peer_maxwinsz = call->peers_maxwinsz;
1107
1108 NPPPD_ASSERT(call->ctrl->peer.ss_family == AF_INET);
1109 NPPPD_ASSERT(call->ctrl->our.ss_family == AF_INET);
1110
1111 memcpy(&req.pr_peer_address, &call->ctrl->peer,
1112 call->ctrl->peer.ss_len);
1113 memcpy(&req.pr_local_address, &call->ctrl->our,
1114 call->ctrl->our.ss_len);
1115 break;
1116 #endif
1117 #ifdef USE_NPPPD_L2TP
1118 case NPPPD_TUNNEL_L2TP:
1119 l2tp = (l2tp_call *)ppp->phy_context;
1120 l2tpctrl = l2tp->ctrl;
1121
1122 /* L2TPv2 specific context */
1123 /* Session KEYS */
1124 req.pr_protocol = PIPEX_PROTO_L2TP;
1125 req.pr_proto.l2tp.tunnel_id = l2tpctrl->tunnel_id;
1126 req.pr_proto.l2tp.peer_tunnel_id = l2tpctrl->peer_tunnel_id;
1127 req.pr_session_id = l2tp->session_id;
1128 req.pr_peer_session_id = l2tp->peer_session_id;
1129
1130 if (l2tpctrl->data_use_seq)
1131 req.pr_proto.l2tp.option_flags |=
1132 PIPEX_L2TP_USE_SEQUENCING;
1133
1134 /* transmission control contexts */
1135 req.pr_proto.l2tp.ns_nxt = l2tp->snd_nxt;
1136 req.pr_proto.l2tp.nr_nxt = l2tp->rcv_nxt;
1137
1138 memcpy(&req.pr_peer_address, &l2tpctrl->peer,
1139 l2tpctrl->peer.ss_len);
1140 memcpy(&req.pr_local_address, &l2tpctrl->sock,
1141 l2tpctrl->sock.ss_len);
1142 #ifdef USE_SA_COOKIE
1143 if (l2tpctrl->sa_cookie != NULL) {
1144 req.pr_proto.l2tp.ipsecflowinfo =
1145 ((struct in_ipsec_sa_cookie *)l2tpctrl->sa_cookie)
1146 ->ipsecflow;
1147 }
1148 #endif
1149 break;
1150 #endif
1151 default:
1152 return 1;
1153 }
1154
1155 if ((error = ioctl(_this->iface[ppp->ifidx].devf, PIPEXASESSION, &req))
1156 != 0) {
1157 if (errno == ENXIO) /* pipex is disabled on runtime */
1158 error = 0;
1159 ppp->pipex_enabled = 0;
1160 return error;
1161 }
1162
1163 if (_this->iface[ppp->ifidx].using_pppx) {
1164 struct pipex_session_descr_req descr_req;
1165
1166 descr_req.pdr_protocol = req.pr_protocol;
1167 descr_req.pdr_session_id = req.pr_session_id;
1168 memset(descr_req.pdr_descr, 0, sizeof(descr_req.pdr_descr));
1169 strlcpy(descr_req.pdr_descr, ppp->username, sizeof(descr_req.pdr_descr));
1170 error = ioctl(_this->iface[ppp->ifidx].devf, PIPEXSIFDESCR, &descr_req);
1171 if (error != 0) {
1172 log_printf(LOG_WARNING, "PIPEXSIFDESCR(%s) failed: %d\n", ppp->username, error);
1173 }
1174 }
1175
1176 ppp->pipex_enabled = 1;
1177 if (ppp->timeout_sec > 0) {
1178 /* Stop the npppd's idle-timer. We use pipex's idle-timer */
1179 ppp->timeout_sec = 0;
1180 ppp_reset_idle_timeout(ppp);
1181 }
1182
1183 return error;
1184 }
1185
1186 /** Disable PIPEX of the {@link npppd_ppp ppp} */
1187 int
npppd_ppp_pipex_disable(npppd * _this,npppd_ppp * ppp)1188 npppd_ppp_pipex_disable(npppd *_this, npppd_ppp *ppp)
1189 {
1190 struct pipex_session_close_req req;
1191 #ifdef USE_NPPPD_PPPOE
1192 pppoe_session *pppoe;
1193 #endif
1194 #ifdef USE_NPPPD_PPTP
1195 pptp_call *call;
1196 #endif
1197 #ifdef USE_NPPPD_L2TP
1198 l2tp_call *l2tp;
1199 #endif
1200 int error;
1201
1202 if (ppp->pipex_started == 0)
1203 return 0; /* not started */
1204
1205 bzero(&req, sizeof(req));
1206 switch(ppp->tunnel_type) {
1207 #ifdef USE_NPPPD_PPPOE
1208 case NPPPD_TUNNEL_PPPOE:
1209 pppoe = (pppoe_session *)ppp->phy_context;
1210
1211 /* PPPoE specific information */
1212 req.pcr_protocol = PIPEX_PROTO_PPPOE;
1213 req.pcr_session_id = pppoe->session_id;
1214 break;
1215 #endif
1216 #ifdef USE_NPPPD_PPTP
1217 case NPPPD_TUNNEL_PPTP:
1218 call = (pptp_call *)ppp->phy_context;
1219
1220 /* PPTP specific information */
1221 req.pcr_session_id = call->id;
1222 req.pcr_protocol = PIPEX_PROTO_PPTP;
1223 break;
1224 #endif
1225 #ifdef USE_NPPPD_L2TP
1226 case NPPPD_TUNNEL_L2TP:
1227 l2tp = (l2tp_call *)ppp->phy_context;
1228
1229 /* L2TP specific context */
1230 req.pcr_session_id = l2tp->session_id;
1231 req.pcr_protocol = PIPEX_PROTO_L2TP;
1232 break;
1233 #endif
1234 default:
1235 return 1;
1236 }
1237
1238 error = ioctl(_this->iface[ppp->ifidx].devf, PIPEXDSESSION, &req);
1239 if (error == 0) {
1240 ppp->ipackets += req.pcr_stat.ipackets;
1241 ppp->opackets += req.pcr_stat.opackets;
1242 ppp->ierrors += req.pcr_stat.ierrors;
1243 ppp->oerrors += req.pcr_stat.oerrors;
1244 ppp->ibytes += req.pcr_stat.ibytes;
1245 ppp->obytes += req.pcr_stat.obytes;
1246 ppp->pipex_enabled = 0;
1247 }
1248
1249 return error;
1250 }
1251
1252 static void
pipex_periodic(npppd * _this)1253 pipex_periodic(npppd *_this)
1254 {
1255 struct pipex_session_list_req req;
1256 npppd_ppp *ppp;
1257 int i, devf, error;
1258 u_int ppp_id;
1259 slist dlist, users;
1260
1261 slist_init(&dlist);
1262 slist_init(&users);
1263
1264 devf = -1;
1265 for (i = 0; i < nitems(_this->iface); i++) {
1266 if (_this->iface[i].initialized != 0) {
1267 devf = _this->iface[i].devf;
1268 break;
1269 }
1270 }
1271 if (devf >= 0) {
1272 do {
1273 error = ioctl(devf, PIPEXGCLOSED, &req);
1274 if (error) {
1275 if (errno != ENXIO)
1276 log_printf(LOG_WARNING,
1277 "PIPEXGCLOSED failed: %m");
1278 break;
1279 }
1280 for (i = 0; i < req.plr_ppp_id_count; i++) {
1281 ppp_id = req.plr_ppp_id[i];
1282 slist_add(&dlist, (void *)(uintptr_t)ppp_id);
1283 }
1284 } while (req.plr_flags & PIPEX_LISTREQ_MORE);
1285 }
1286
1287 if (slist_length(&dlist) <= 0)
1288 goto pipex_done;
1289 if (npppd_get_all_users(_this, &users) != 0) {
1290 log_printf(LOG_WARNING,
1291 "npppd_get_all_users() failed in %s()", __func__);
1292 slist_fini(&users);
1293 goto pipex_done;
1294 }
1295
1296 /* Disconnect request */
1297 slist_itr_first(&dlist);
1298 while (slist_itr_has_next(&dlist)) {
1299 /* FIXME: Linear search by PPP Id eats CPU */
1300 ppp_id = (uintptr_t)slist_itr_next(&dlist);
1301 slist_itr_first(&users);
1302 ppp = NULL;
1303 while (slist_itr_has_next(&users)) {
1304 ppp = slist_itr_next(&users);
1305 if (ppp_id == ppp->id) {
1306 /* found */
1307 slist_itr_remove(&users);
1308 break;
1309 }
1310 ppp = NULL;
1311 }
1312 if (ppp == NULL) {
1313 log_printf(LOG_WARNING,
1314 "kernel requested a ppp down, but it's not found. "
1315 "ppp=%d", ppp_id);
1316 continue;
1317 }
1318 ppp_log(ppp, LOG_INFO, "Stop requested by the kernel");
1319 /* TODO: PIPEX doesn't return the disconnect reason */
1320 #ifdef USE_NPPPD_RADIUS
1321 ppp_set_radius_terminate_cause(ppp,
1322 RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT);
1323 #endif
1324 ppp_stop(ppp, NULL);
1325 }
1326 pipex_done:
1327 slist_fini(&users);
1328 slist_fini(&dlist);
1329 }
1330 #endif /* USE_NPPPD_PIPEX */
1331
1332 /***********************************************************************
1333 * IP address assignment related functions
1334 ***********************************************************************/
1335 /** Prepare to use IP */
1336 int
npppd_prepare_ip(npppd * _this,npppd_ppp * ppp)1337 npppd_prepare_ip(npppd *_this, npppd_ppp *ppp)
1338 {
1339
1340 if (ppp_ipcp(ppp) == NULL)
1341 return 1;
1342
1343 npppd_get_user_framed_ip_address(_this, ppp, ppp->username);
1344
1345 if (npppd_iface_ip_is_ready(ppp_iface(ppp)))
1346 ppp->ipcp.ip4_our = ppp_iface(ppp)->ip4addr;
1347 else if (npppd_iface_ip_is_ready(&_this->iface[0]))
1348 ppp->ipcp.ip4_our = _this->iface[0].ip4addr;
1349 else
1350 return -1;
1351 ppp->ipcp.dns_pri = ppp_ipcp(ppp)->dns_servers[0];
1352 ppp->ipcp.dns_sec = ppp_ipcp(ppp)->dns_servers[1];
1353 ppp->ipcp.nbns_pri = ppp_ipcp(ppp)->nbns_servers[0];
1354 ppp->ipcp.nbns_sec = ppp_ipcp(ppp)->nbns_servers[1];
1355
1356 return 0;
1357 }
1358
1359 /** Notify stop using IP to npppd and release the resources. */
1360 void
npppd_release_ip(npppd * _this,npppd_ppp * ppp)1361 npppd_release_ip(npppd *_this, npppd_ppp *ppp)
1362 {
1363
1364 if (!ppp_ip_assigned(ppp))
1365 return;
1366
1367 npppd_set_ip_enabled(_this, ppp, 0);
1368 npppd_pool_release_ip(ppp->assigned_pool, ppp);
1369 ppp->assigned_pool = NULL;
1370 ppp->ppp_framed_ip_address.s_addr = 0;
1371 }
1372
1373 /**
1374 * Change IP enableness. When the enableness is change, npppd will operate
1375 * the route entry.
1376 */
1377 void
npppd_set_ip_enabled(npppd * _this,npppd_ppp * ppp,int enabled)1378 npppd_set_ip_enabled(npppd *_this, npppd_ppp *ppp, int enabled)
1379 {
1380 int was_enabled, found;
1381 slist *u;
1382 hash_link *hl;
1383 npppd_ppp *ppp1;
1384
1385 NPPPD_ASSERT(ppp_ip_assigned(ppp));
1386 NPPPD_DBG((LOG_DEBUG,
1387 "npppd_set_ip_enabled(%s/%s, %s)", ppp->username,
1388 inet_ntoa(ppp->ppp_framed_ip_address),
1389 (enabled)?"true" : "false"));
1390
1391 /*
1392 * Don't do anything if the enableness is not change. Changing route
1393 * makes many programs will wake up and do heavy operations, it causes
1394 * system overload, so we refrain useless changing route.
1395 */
1396 enabled = (enabled)? 1 : 0;
1397 was_enabled = (ppp->assigned_ip4_enabled != 0)? 1 : 0;
1398 if (enabled == was_enabled)
1399 return;
1400
1401 ppp->assigned_ip4_enabled = enabled;
1402 if (enabled) {
1403 if (ppp->username[0] != '\0') {
1404 if ((u = npppd_get_ppp_by_user(_this, ppp->username))
1405 == NULL) {
1406 if ((u = malloc(sizeof(slist))) == NULL) {
1407 ppp_log(ppp, LOG_ERR,
1408 "Out of memory on %s: %m",
1409 __func__);
1410 } else {
1411 slist_init(u);
1412 slist_set_size(u, 4);
1413 hash_insert(_this->map_user_ppp,
1414 ppp->username, u);
1415 NPPPD_DBG((LOG_DEBUG,
1416 "hash_insert(user->ppp, %s)",
1417 ppp->username));
1418 }
1419 }
1420 if (u != NULL) /* above malloc() may failed */
1421 slist_add(u, ppp);
1422 }
1423
1424 #ifndef NO_ROUTE_FOR_POOLED_ADDRESS
1425 if (_this->iface[ppp->ifidx].using_pppx == 0) {
1426 if (ppp->snp.snp_next != NULL)
1427 /*
1428 * There is a blackhole route that has same
1429 * address/mask.
1430 */
1431 in_route_delete(&ppp->ppp_framed_ip_address,
1432 &ppp->ppp_framed_ip_netmask, &loop,
1433 RTF_BLACKHOLE);
1434 /* See the comment for MRU_IPMTU() on ppp.h */
1435 if (ppp->ppp_framed_ip_netmask.s_addr == 0xffffffffL) {
1436 in_host_route_add(&ppp->ppp_framed_ip_address,
1437 &ppp_iface(ppp)->ip4addr,
1438 ppp_iface(ppp)->ifname,
1439 MRU_IPMTU(ppp->peer_mru));
1440 } else {
1441 in_route_add(&ppp->ppp_framed_ip_address,
1442 &ppp->ppp_framed_ip_netmask,
1443 &ppp_iface(ppp)->ip4addr,
1444 ppp_iface(ppp)->ifname, 0,
1445 MRU_IPMTU(ppp->peer_mru));
1446 }
1447 }
1448 #endif
1449 } else {
1450 #ifndef NO_ROUTE_FOR_POOLED_ADDRESS
1451 if (_this->iface[ppp->ifidx].using_pppx == 0) {
1452 if (ppp->ppp_framed_ip_netmask.s_addr == 0xffffffffL) {
1453 in_host_route_delete(&ppp->ppp_framed_ip_address,
1454 &ppp_iface(ppp)->ip4addr);
1455 } else {
1456 in_route_delete(&ppp->ppp_framed_ip_address,
1457 &ppp->ppp_framed_ip_netmask,
1458 &ppp_iface(ppp)->ip4addr, 0);
1459 }
1460 if (ppp->snp.snp_next != NULL)
1461 /*
1462 * There is a blackhole route that has same
1463 * address/mask.
1464 */
1465 in_route_add(&ppp->snp.snp_addr,
1466 &ppp->snp.snp_mask, &loop, LOOPBACK_IFNAME,
1467 RTF_BLACKHOLE, 0);
1468 }
1469 #endif
1470 if (ppp->username[0] != '\0') {
1471 hl = hash_lookup(_this->map_user_ppp, ppp->username);
1472 NPPPD_ASSERT(hl != NULL);
1473 if (hl == NULL) {
1474 ppp_log(ppp, LOG_ERR,
1475 "Unexpected error: cannot find user(%s) "
1476 "from user database", ppp->username);
1477 return;
1478 }
1479 found = 0;
1480 u = hl->item;
1481 for (slist_itr_first(u); slist_itr_has_next(u);) {
1482 ppp1 = slist_itr_next(u);
1483 if (ppp1 == ppp) {
1484 slist_itr_remove(u);
1485 found++;
1486 break;
1487 }
1488 }
1489 if (found == 0) {
1490 ppp_log(ppp, LOG_ERR,
1491 "Unexpected error: PPP instance is "
1492 "not found in the user's list.");
1493 }
1494 NPPPD_ASSERT(found != 0);
1495 if (slist_length(u) <= 0) {
1496 /* The last PPP */
1497 NPPPD_DBG((LOG_DEBUG,
1498 "hash_delete(user->ppp, %s)",
1499 ppp->username));
1500 if (hash_delete(_this->map_user_ppp,
1501 ppp->username, 0) != 0) {
1502 ppp_log(ppp, LOG_ERR,
1503 "Unexpected error: cannot delete "
1504 "user(%s) from user database",
1505 ppp->username);
1506 }
1507 slist_fini(u);
1508 free(u);
1509 } else {
1510 /* Replace the reference. */
1511 ppp1 = slist_get(u, 0);
1512 hl->key = ppp1->username;
1513 }
1514 }
1515 }
1516 }
1517
1518 /**
1519 * Assign the IP address. Returning "struct in_addr" is stored IP address
1520 * in network byte order.
1521 * @param req_ip4 IP address request to assign. If the address is used
1522 * already, this function will return fail.
1523 */
1524 int
npppd_assign_ip_addr(npppd * _this,npppd_ppp * ppp,uint32_t req_ip4)1525 npppd_assign_ip_addr(npppd *_this, npppd_ppp *ppp, uint32_t req_ip4)
1526 {
1527 uint32_t ip4, ip4mask;
1528 int dyna, rval, fallback_dyna;
1529 const char *reason = "out of the pool";
1530 struct sockaddr_npppd *snp;
1531 npppd_pool *pool;
1532 npppd_auth_base *realm;
1533
1534 NPPPD_DBG((LOG_DEBUG, "%s() assigned=%s", __func__,
1535 (ppp_ip_assigned(ppp))? "true" : "false"));
1536 if (ppp_ip_assigned(ppp))
1537 return 0;
1538
1539 ip4 = INADDR_ANY;
1540 ip4mask = 0xffffffffL;
1541 realm = ppp->realm;
1542 dyna = 0;
1543 fallback_dyna = 0;
1544 pool = NULL;
1545
1546 if (ppp->realm_framed_ip_address.s_addr == INADDR_USER_SELECT) {
1547 if (req_ip4 == INADDR_ANY)
1548 dyna = 1;
1549 } else if (ppp->realm_framed_ip_address.s_addr == INADDR_NAS_SELECT) {
1550 dyna = 1;
1551 } else {
1552 NPPPD_ASSERT(realm != NULL);
1553 fallback_dyna = 1;
1554 req_ip4 = ntohl(ppp->realm_framed_ip_address.s_addr);
1555 ip4mask = ntohl(ppp->realm_framed_ip_netmask.s_addr);
1556 }
1557 if (!dyna) {
1558 /*
1559 * Realm requires the fixed IP address, but the address
1560 * doesn't belong any address pool. Fallback to dynamic
1561 * assignment.
1562 */
1563 pool = ppp_pool(ppp);
1564 rval = npppd_pool_get_assignability(pool, req_ip4, ip4mask,
1565 &snp);
1566 switch (rval) {
1567 case ADDRESS_OK:
1568 if (snp->snp_type == SNP_POOL) {
1569 /*
1570 * Fixed address pool can be used only if the
1571 * realm specified to use it.
1572 */
1573 if (ppp->realm_framed_ip_address
1574 .s_addr != INADDR_USER_SELECT)
1575 ip4 = req_ip4;
1576 break;
1577 }
1578 ppp->assign_dynapool = 1;
1579 ip4 = req_ip4;
1580 break;
1581 case ADDRESS_RESERVED:
1582 reason = "reserved";
1583 break;
1584 case ADDRESS_OUT_OF_POOL:
1585 reason = "out of the pool";
1586 break;
1587 case ADDRESS_BUSY:
1588 fallback_dyna = 0;
1589 reason = "busy";
1590 break;
1591 default:
1592 case ADDRESS_INVALID:
1593 fallback_dyna = 0;
1594 reason = "invalid";
1595 break;
1596 }
1597 #define IP_4OCT(v) ((0xff000000 & (v)) >> 24), ((0x00ff0000 & (v)) >> 16),\
1598 ((0x0000ff00 & (v)) >> 8), (0x000000ff & (v))
1599 if (ip4 == 0) {
1600 ppp_log(ppp, LOG_NOTICE,
1601 "Requested IP address (%d.%d.%d.%d)/%d "
1602 "is %s", IP_4OCT(req_ip4),
1603 netmask2prefixlen(ip4mask), reason);
1604 if (fallback_dyna)
1605 goto dyna_assign;
1606 return 1;
1607 }
1608 ppp->assigned_pool = pool;
1609
1610 ppp->ppp_framed_ip_address.s_addr = htonl(ip4);
1611 ppp->ppp_framed_ip_netmask.s_addr = htonl(ip4mask);
1612 ppp->acct_framed_ip_address = ppp->ppp_framed_ip_address;
1613 } else {
1614 dyna_assign:
1615 pool = ppp_pool(ppp);
1616 ip4 = npppd_pool_get_dynamic(pool, ppp);
1617 if (ip4 == 0) {
1618 ppp_log(ppp, LOG_NOTICE,
1619 "No free address in the pool.");
1620 return 1;
1621 }
1622 ppp->assigned_pool = pool;
1623 ppp->assign_dynapool = 1;
1624 ppp->ppp_framed_ip_address.s_addr = htonl(ip4);
1625 ppp->ppp_framed_ip_netmask.s_addr = htonl(0xffffffffL);
1626 ppp->acct_framed_ip_address = ppp->ppp_framed_ip_address;
1627 }
1628
1629 return npppd_pool_assign_ip(ppp->assigned_pool, ppp);
1630 }
1631
1632 static void *
rtlist_remove(slist * prtlist,struct radish * radish)1633 rtlist_remove(slist *prtlist, struct radish *radish)
1634 {
1635 struct radish *r;
1636
1637 slist_itr_first(prtlist);
1638 while (slist_itr_has_next(prtlist)) {
1639 r = slist_itr_next(prtlist);
1640 if (!sockaddr_npppd_match(radish->rd_route, r->rd_route) ||
1641 !sockaddr_npppd_match(radish->rd_mask, r->rd_mask))
1642 continue;
1643
1644 return slist_itr_remove(prtlist);
1645 }
1646
1647 return NULL;
1648 }
1649
1650 /** Set {@link ::npppd#rd the only radish of npppd} */
1651 int
npppd_set_radish(npppd * _this,void * radish_head)1652 npppd_set_radish(npppd *_this, void *radish_head)
1653 {
1654 int rval, delppp0, count;
1655 struct sockaddr_npppd *snp;
1656 struct radish *radish, *r;
1657 slist rtlist0, rtlist1, delppp;
1658 npppd_ppp *ppp;
1659 void *dummy;
1660
1661 slist_init(&rtlist0);
1662 slist_init(&rtlist1);
1663 slist_init(&delppp);
1664
1665 if (radish_head != NULL) {
1666 if (rd2slist(radish_head, &rtlist1) != 0) {
1667 log_printf(LOG_WARNING, "rd2slist failed: %m");
1668 goto fail;
1669 }
1670 }
1671 if (_this->rd != NULL) {
1672 if (rd2slist(_this->rd, &rtlist0) != 0) {
1673 log_printf(LOG_WARNING, "rd2slist failed: %m");
1674 goto fail;
1675 }
1676 }
1677 if (_this->rd != NULL && radish_head != NULL) {
1678 for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0);) {
1679 radish = slist_itr_next(&rtlist0);
1680 snp = radish->rd_rtent;
1681 /*
1682 * replace the pool address
1683 */
1684 if (snp->snp_type == SNP_POOL ||
1685 snp->snp_type == SNP_DYN_POOL) {
1686 if (rd_lookup(radish->rd_route, radish->rd_mask,
1687 radish_head) == NULL)
1688 continue;
1689 /* don't add */
1690 rtlist_remove(&rtlist1, radish);
1691 /* don't delete */
1692 slist_itr_remove(&rtlist0);
1693 continue;
1694 }
1695 /*
1696 * handle the active PPP sessions.
1697 */
1698 NPPPD_ASSERT(snp->snp_type == SNP_PPP);
1699 ppp = snp->snp_data_ptr;
1700
1701 /* Don't delete the route of active PPP session */
1702 slist_itr_remove(&rtlist0);
1703
1704 /* clear information about old pool configuration */
1705 snp->snp_next = NULL;
1706
1707 delppp0 = 0;
1708 if (!rd_match((struct sockaddr *)snp, radish_head, &r)){
1709 /*
1710 * If the address doesn't belong the new pools,
1711 * add the PPP session to the deletion list.
1712 */
1713 slist_add(&delppp, snp->snp_data_ptr);
1714 delppp0 = 1;
1715 } else {
1716 NPPPD_ASSERT(
1717 ((struct sockaddr_npppd *)r->rd_rtent)
1718 ->snp_type == SNP_POOL ||
1719 ((struct sockaddr_npppd *)r->rd_rtent)
1720 ->snp_type == SNP_DYN_POOL);
1721 /*
1722 * If there is a pool entry that has same
1723 * address/mask, then make the RADISH entry a
1724 * list. Set SNP_PPP as the first in the list,
1725 * set current entry in snp->snp_next and
1726 * delete it.
1727 */
1728 if (sockaddr_npppd_match(
1729 radish->rd_route, r->rd_route) &&
1730 sockaddr_npppd_match(
1731 radish->rd_mask, r->rd_mask)) {
1732 /*
1733 * Releasing it, so remove it from the
1734 * new routing list.
1735 */
1736 rtlist_remove(&rtlist1, radish);
1737 /* set as snp_snp_next */
1738 snp->snp_next = r->rd_rtent;
1739 rval = rd_delete(r->rd_route,
1740 r->rd_mask, radish_head, &dummy);
1741 NPPPD_ASSERT(rval == 0);
1742 }
1743 }
1744 /* Register to the new radish */
1745 rval = rd_insert(radish->rd_route, radish->rd_mask,
1746 radish_head, snp);
1747 if (rval != 0) {
1748 errno = rval;
1749 ppp_log(((npppd_ppp *)snp->snp_data_ptr),
1750 LOG_ERR,
1751 "Fatal error on %s, cannot continue "
1752 "this ppp session: %m", __func__);
1753 if (!delppp0)
1754 slist_add(&delppp, snp->snp_data_ptr);
1755 }
1756 }
1757 }
1758 count = 0;
1759 #ifndef NO_ROUTE_FOR_POOLED_ADDRESS
1760 if (_this->iface[0].using_pppx == 0) {
1761 for (slist_itr_first(&rtlist0); slist_itr_has_next(&rtlist0);) {
1762 radish = slist_itr_next(&rtlist0);
1763 in_route_delete(&SIN(radish->rd_route)->sin_addr,
1764 &SIN(radish->rd_mask)->sin_addr, &loop,
1765 RTF_BLACKHOLE);
1766 count++;
1767 }
1768 if (count > 0)
1769 log_printf(LOG_INFO,
1770 "Deleted %d routes for old pool addresses", count);
1771
1772 count = 0;
1773 for (slist_itr_first(&rtlist1); slist_itr_has_next(&rtlist1);) {
1774 radish = slist_itr_next(&rtlist1);
1775 in_route_add(&(SIN(radish->rd_route)->sin_addr),
1776 &SIN(radish->rd_mask)->sin_addr, &loop,
1777 LOOPBACK_IFNAME, RTF_BLACKHOLE, 0);
1778 count++;
1779 }
1780 if (count > 0)
1781 log_printf(LOG_INFO,
1782 "Added %d routes for new pool addresses",
1783 count);
1784 }
1785 #endif
1786 slist_fini(&rtlist0);
1787 slist_fini(&rtlist1);
1788
1789 if (_this->rd != NULL) {
1790 npppd_rd_walktree_delete(_this->rd);
1791 _this->rd = NULL;
1792 }
1793 if (radish_head == NULL)
1794 npppd_get_all_users(_this, &delppp);
1795 _this->rd = radish_head;
1796
1797 for (slist_itr_first(&delppp); slist_itr_has_next(&delppp);) {
1798 ppp = slist_itr_next(&delppp);
1799 ppp_log(ppp, LOG_NOTICE,
1800 "stop. IP address of this ppp is out of the pool.: %s",
1801 inet_ntoa(ppp->ppp_framed_ip_address));
1802 ppp_stop(ppp, NULL);
1803 }
1804 slist_fini(&delppp);
1805
1806 return 0;
1807 fail:
1808 slist_fini(&rtlist0);
1809 slist_fini(&rtlist1);
1810 slist_fini(&delppp);
1811
1812 return 1;
1813 }
1814
1815 /**
1816 * This function stores all users to {@link slist} and returns them.
1817 * References to {@link ::npppd_ppp} will be stored in users.
1818 */
1819 static int
npppd_get_all_users(npppd * _this,slist * users)1820 npppd_get_all_users(npppd *_this, slist *users)
1821 {
1822 int rval;
1823 struct radish *rd;
1824 struct sockaddr_npppd *snp;
1825 slist list;
1826
1827 NPPPD_ASSERT(_this != NULL);
1828
1829 slist_init(&list);
1830 if (_this->rd == NULL)
1831 return 0;
1832 rval = rd2slist(_this->rd, &list);
1833 if (rval != 0)
1834 return rval;
1835
1836 for (slist_itr_first(&list); slist_itr_has_next(&list);) {
1837 rd = slist_itr_next(&list);
1838 snp = rd->rd_rtent;
1839 if (snp->snp_type == SNP_PPP) {
1840 if (slist_add(users, snp->snp_data_ptr) == NULL) {
1841 log_printf(LOG_ERR,
1842 "slist_add() failed in %s: %m", __func__);
1843 goto fail;
1844 }
1845 }
1846 }
1847 slist_fini(&list);
1848
1849 return 0;
1850 fail:
1851 slist_fini(&list);
1852
1853 return 1;
1854 }
1855
1856 static int
rd2slist_walk(struct radish * rd,void * list0)1857 rd2slist_walk(struct radish *rd, void *list0)
1858 {
1859 slist *list = list0;
1860 void *r;
1861
1862 r = slist_add(list, rd);
1863 if (r == NULL)
1864 return -1;
1865 return 0;
1866 }
1867 static int
rd2slist(struct radish_head * h,slist * list)1868 rd2slist(struct radish_head *h, slist *list)
1869 {
1870 return rd_walktree(h, rd2slist_walk, list);
1871 }
1872
1873 static void
npppd_reload0(npppd * _this)1874 npppd_reload0(npppd *_this)
1875 {
1876 int i;
1877
1878 npppd_reload_config(_this);
1879 #ifdef USE_NPPPD_ARP
1880 arp_set_strictintfnetwork(npppd_config_str_equali(_this, "arpd.strictintfnetwork", "true", ARPD_STRICTINTFNETWORK_DEFAULT));
1881 if (npppd_config_str_equali(_this, "arpd.enabled", "true", ARPD_DEFAULT) == 1)
1882 arp_sock_init();
1883 else
1884 arp_sock_fini();
1885 #endif
1886 npppd_modules_reload(_this);
1887 npppd_ifaces_load_config(_this);
1888 npppd_update_pool_reference(_this);
1889 npppd_auth_finalizer_periodic(_this);
1890 npppd_ipcp_stats_reload(_this);
1891
1892 for (i = 0; i < countof(_this->iface); i++) {
1893 if (_this->iface[i].initialized != 0 &&
1894 _this->iface[i].started == 0)
1895 npppd_iface_start(&_this->iface[i]);
1896 }
1897 }
1898
1899 static void
npppd_update_pool_reference(npppd * _this)1900 npppd_update_pool_reference(npppd *_this)
1901 {
1902 int i, j;
1903 /* update iface to pool reference */
1904 for (i = 0; i < countof(_this->iface_pool); i++) {
1905 _this->iface_pool[i] = NULL;
1906 if (_this->iface[i].initialized == 0)
1907 continue;
1908 if (_this->iface[i].ipcpconf == NULL)
1909 continue; /* no IPCP for this interface */
1910
1911 for (j = 0; j < countof(_this->pool); j++) {
1912 if (_this->pool[j].initialized == 0)
1913 continue;
1914 if (strcmp(_this->iface[i].ipcpconf->name,
1915 _this->pool[j].ipcp_name) == 0) {
1916 /* found the ipcp that has the pool */
1917 _this->iface_pool[i] = &_this->pool[j];
1918 break;
1919 }
1920 }
1921 }
1922 }
1923
1924 /***********************************************************************
1925 * Signal handlers
1926 ***********************************************************************/
1927 static void
npppd_on_sighup(int fd,short ev_type,void * ctx)1928 npppd_on_sighup(int fd, short ev_type, void *ctx)
1929 {
1930 npppd *_this;
1931
1932 _this = ctx;
1933 #ifndef NO_DELAYED_RELOAD
1934 if (_this->delayed_reload > 0)
1935 _this->reloading_count = _this->delayed_reload;
1936 else
1937 #endif
1938 npppd_reload0(_this);
1939 }
1940
1941 static void
npppd_on_sigterm(int fd,short ev_type,void * ctx)1942 npppd_on_sigterm(int fd, short ev_type, void *ctx)
1943 {
1944 npppd *_this;
1945
1946 _this = ctx;
1947 npppd_stop(_this);
1948 }
1949
1950 static void
npppd_on_sigint(int fd,short ev_type,void * ctx)1951 npppd_on_sigint(int fd, short ev_type, void *ctx)
1952 {
1953 npppd *_this;
1954
1955 _this = ctx;
1956 npppd_stop(_this);
1957 }
1958
1959 static void
npppd_on_sigchld(int fd,short ev_type,void * ctx)1960 npppd_on_sigchld(int fd, short ev_type, void *ctx)
1961 {
1962 int status;
1963 pid_t wpid;
1964 npppd *_this;
1965
1966 _this = ctx;
1967 wpid = privsep_priv_pid();
1968 if (wait4(wpid, &status, WNOHANG, NULL) == wpid) {
1969 if (WIFSIGNALED(status))
1970 log_printf(LOG_WARNING,
1971 "privileged process exits abnormally. signal=%d",
1972 WTERMSIG(status));
1973 else
1974 log_printf(LOG_WARNING,
1975 "privileged process exits abnormally. status=%d",
1976 WEXITSTATUS(status));
1977 _this->stop_by_error = 1;
1978 npppd_stop(_this);
1979 }
1980 }
1981 /***********************************************************************
1982 * Miscellaneous functions
1983 ***********************************************************************/
1984 static uint32_t
str_hash(const void * ptr,int sz)1985 str_hash(const void *ptr, int sz)
1986 {
1987 uint32_t hash = 0;
1988 int i, len;
1989 const char *str;
1990
1991 str = ptr;
1992 len = strlen(str);
1993 for (i = 0; i < len; i++)
1994 hash = hash*0x1F + str[i];
1995 hash = (hash << 16) ^ (hash & 0xffff);
1996
1997 return hash % sz;
1998 }
1999
2000 /**
2001 * Select a authentication realm that is for given {@link ::npppd_ppp PPP}.
2002 * Return 0 on success.
2003 */
2004 int
npppd_ppp_bind_realm(npppd * _this,npppd_ppp * ppp,const char * username,int eap_required)2005 npppd_ppp_bind_realm(npppd *_this, npppd_ppp *ppp, const char *username, int
2006 eap_required)
2007 {
2008 struct confbind *bind;
2009 npppd_auth_base *realm = NULL, *realm0 = NULL, *realm1 = NULL;
2010 char buf1[MAX_USERNAME_LENGTH];
2011 int lsuffix, lusername, lmax;
2012
2013 NPPPD_ASSERT(_this != NULL);
2014 NPPPD_ASSERT(ppp != NULL);
2015 NPPPD_ASSERT(username != NULL);
2016
2017 /*
2018 * If the PPP suffix is the longest, and the length of the suffix is
2019 * same, select the first one.
2020 */
2021 lusername = strlen(username);
2022 lmax = -1;
2023 realm = NULL;
2024
2025 TAILQ_FOREACH(bind, &_this->conf.confbinds, entry) {
2026 if (strcmp(bind->tunnconf->name, ppp->phy_label) != 0)
2027 continue;
2028
2029 realm0 = NULL;
2030 slist_itr_first(&_this->realms);
2031 while (slist_itr_has_next(&_this->realms)) {
2032 realm1 = slist_itr_next(&_this->realms);
2033 if (!npppd_auth_is_usable(realm1))
2034 continue;
2035 if (eap_required && !npppd_auth_is_eap_capable(realm1))
2036 continue;
2037 if (strcmp(npppd_auth_get_name(realm1),
2038 bind->authconf->name) == 0) {
2039 realm0 = realm1;
2040 break;
2041 }
2042 }
2043 if (realm0 == NULL)
2044 continue;
2045
2046 lsuffix = strlen(npppd_auth_get_suffix(realm0));
2047 if (lsuffix > lmax &&
2048 (lsuffix == 0 ||
2049 (lsuffix < lusername && strcmp(username + lusername
2050 - lsuffix, npppd_auth_get_suffix(realm0))
2051 == 0))) {
2052 lmax = lsuffix;
2053 realm = realm0;
2054 }
2055 }
2056
2057 if (realm == NULL) {
2058 log_printf(LOG_INFO, "user='%s' could not bind any realms",
2059 username);
2060 return 1;
2061 }
2062 NPPPD_DBG((LOG_DEBUG, "bind realm %s", npppd_auth_get_name(realm)));
2063
2064 if (npppd_auth_get_type(realm) == NPPPD_AUTH_TYPE_LOCAL)
2065 /* hook the auto reload */
2066 npppd_auth_get_user_password(realm,
2067 npppd_auth_username_for_auth(realm1, username, buf1), NULL,
2068 NULL);
2069 ppp->realm = realm;
2070
2071 return 0;
2072 }
2073
2074 /** Is assigned realm a LOCAL authentication? */
2075 int
npppd_ppp_is_realm_local(npppd * _this,npppd_ppp * ppp)2076 npppd_ppp_is_realm_local(npppd *_this, npppd_ppp *ppp)
2077 {
2078 NPPPD_ASSERT(_this != NULL);
2079 NPPPD_ASSERT(ppp != NULL);
2080
2081 if (ppp->realm == NULL)
2082 return 0;
2083
2084 return (npppd_auth_get_type(ppp->realm) == NPPPD_AUTH_TYPE_LOCAL)
2085 ? 1 : 0;
2086 }
2087
2088 /** Is assigned realm a RADIUS authentication? */
2089 int
npppd_ppp_is_realm_radius(npppd * _this,npppd_ppp * ppp)2090 npppd_ppp_is_realm_radius(npppd *_this, npppd_ppp *ppp)
2091 {
2092 NPPPD_ASSERT(_this != NULL);
2093 NPPPD_ASSERT(ppp != NULL);
2094
2095 if (ppp->realm == NULL)
2096 return 0;
2097
2098 return (npppd_auth_get_type(ppp->realm) == NPPPD_AUTH_TYPE_RADIUS)
2099 ? 1 : 0;
2100 }
2101
2102 /** Is assigned realm usable? */
2103 int
npppd_ppp_is_realm_ready(npppd * _this,npppd_ppp * ppp)2104 npppd_ppp_is_realm_ready(npppd *_this, npppd_ppp *ppp)
2105 {
2106 if (ppp->realm == NULL)
2107 return 0;
2108
2109 return npppd_auth_is_ready(ppp->realm);
2110 }
2111
2112 /** Return the name of assigned realm */
2113 const char *
npppd_ppp_get_realm_name(npppd * _this,npppd_ppp * ppp)2114 npppd_ppp_get_realm_name(npppd *_this, npppd_ppp *ppp)
2115 {
2116 if (ppp->realm == NULL)
2117 return "(none)";
2118 return npppd_auth_get_name(ppp->realm);
2119 }
2120
2121 /** Return the interface name that bound given {@link ::npppd_ppp PPP} */
2122 const char *
npppd_ppp_get_iface_name(npppd * _this,npppd_ppp * ppp)2123 npppd_ppp_get_iface_name(npppd *_this, npppd_ppp *ppp)
2124 {
2125 if (ppp == NULL || ppp->ifidx < 0)
2126 return "(not binding)";
2127 return ppp_iface(ppp)->ifname;
2128 }
2129
2130 /** Is the interface usable? */
2131 int
npppd_ppp_iface_is_ready(npppd * _this,npppd_ppp * ppp)2132 npppd_ppp_iface_is_ready(npppd *_this, npppd_ppp *ppp)
2133 {
2134 return (npppd_iface_ip_is_ready(ppp_iface(ppp)) &&
2135 ppp_ipcp(ppp) != NULL)? 1 : 0;
2136 }
2137
2138 /** Select a suitable interface for {@link :npppd_ppp PPP} and bind them */
2139 int
npppd_ppp_bind_iface(npppd * _this,npppd_ppp * ppp)2140 npppd_ppp_bind_iface(npppd *_this, npppd_ppp *ppp)
2141 {
2142 int i, ifidx;
2143 struct confbind *bind;
2144 struct ipcpstat *ipcpstat;
2145
2146 NPPPD_ASSERT(_this != NULL);
2147 NPPPD_ASSERT(ppp != NULL);
2148
2149 if (ppp->ifidx >= 0)
2150 return 0;
2151
2152 TAILQ_FOREACH(bind, &_this->conf.confbinds, entry) {
2153 if (strcmp(bind->tunnconf->name, ppp->phy_label) != 0)
2154 continue;
2155 if (ppp->realm == NULL) {
2156 if (bind->authconf == NULL)
2157 break;
2158 } else if (strcmp(bind->authconf->name,
2159 npppd_auth_get_name(ppp->realm)) == 0)
2160 break;
2161 }
2162 if (bind == NULL)
2163 return 1;
2164
2165 /* Search a interface */
2166 ifidx = -1;
2167 for (i = 0; i < countof(_this->iface); i++) {
2168 if (_this->iface[i].initialized == 0)
2169 continue;
2170 if (strcmp(_this->iface[i].ifname, bind->iface->name) == 0)
2171 ifidx = i;
2172 }
2173 if (ifidx < 0)
2174 return 1;
2175
2176 ppp->ifidx = ifidx;
2177 NPPPD_ASSERT(ppp_ipcp(ppp) != NULL);
2178 ipcpstat = npppd_get_ipcp_stat(&_this->ipcpstats, ppp_ipcp(ppp)->name);
2179 if (ipcpstat == NULL) {
2180 ppp_log(ppp, LOG_WARNING, "Unknown IPCP %s",
2181 ppp_ipcp(ppp)->name);
2182 ppp->ifidx = -1; /* unbind interface */
2183 return 1;
2184 }
2185 if (ppp_ipcp(ppp)->max_session > 0 &&
2186 ipcpstat->nsession >= ppp_ipcp(ppp)->max_session) {
2187 ppp_log(ppp, LOG_WARNING,
2188 "Number of sessions per IPCP reaches out of the limit=%d",
2189 ppp_ipcp(ppp)->max_session);
2190 ppp->ifidx = -1; /* unbind interface */
2191 return 1;
2192 }
2193
2194 if (_this->conf.max_session > 0 &&
2195 _this->nsession >= _this->conf.max_session) {
2196 ppp_log(ppp, LOG_WARNING,
2197 "Number of sessions reaches out of the limit=%d",
2198 _this->conf.max_session);
2199 ppp->ifidx = -1; /* unbind interface */
2200 return 1;
2201 }
2202 _this->nsession++;
2203
2204 LIST_INSERT_HEAD(&ipcpstat->ppp, ppp, ipcpstat_entry);
2205 ppp->ipcpstat = ipcpstat;
2206 ipcpstat->nsession++;
2207
2208 return 0;
2209 }
2210
2211 /** Unbind the interface from the {@link ::npppd_ppp PPP} */
2212 void
npppd_ppp_unbind_iface(npppd * _this,npppd_ppp * ppp)2213 npppd_ppp_unbind_iface(npppd *_this, npppd_ppp *ppp)
2214 {
2215 if (ppp->ifidx >= 0) {
2216 _this->nsession--;
2217 if (ppp->ipcpstat!= NULL) {
2218 ppp->ipcpstat->nsession--;
2219 LIST_REMOVE(ppp, ipcpstat_entry);
2220 }
2221 }
2222 ppp->ifidx = -1;
2223 }
2224
2225 static int
npppd_rd_walktree_delete(struct radish_head * rh)2226 npppd_rd_walktree_delete(struct radish_head *rh)
2227 {
2228 void *dummy;
2229 struct radish *rd;
2230 slist list;
2231
2232 slist_init(&list);
2233 if (rd2slist(rh, &list) != 0)
2234 return 1;
2235 for (slist_itr_first(&list); slist_itr_has_next(&list);) {
2236 rd = slist_itr_next(&list);
2237 rd_delete(rd->rd_route, rd->rd_mask, rh, &dummy);
2238 }
2239 slist_fini(&list);
2240
2241 free(rh);
2242
2243 return 0;
2244 }
2245
2246 #ifdef USE_NPPPD_RADIUS
2247 /**
2248 * Return radius_req_setting for the given {@link ::npppd_ppp PPP}.
2249 * @return return NULL if no usable RADIUS setting.
2250 */
2251 void *
npppd_get_radius_auth_setting(npppd * _this,npppd_ppp * ppp)2252 npppd_get_radius_auth_setting(npppd *_this, npppd_ppp *ppp)
2253 {
2254 NPPPD_ASSERT(_this != NULL);
2255 NPPPD_ASSERT(ppp != NULL);
2256
2257 if (ppp->realm == NULL)
2258 return NULL;
2259 if (!npppd_ppp_is_realm_radius(_this, ppp))
2260 return NULL;
2261
2262 return npppd_auth_radius_get_radius_auth_setting(ppp->realm);
2263 }
2264 #endif
2265
2266 /** Finalize authentication realm */
2267 static void
npppd_auth_finalizer_periodic(npppd * _this)2268 npppd_auth_finalizer_periodic(npppd *_this)
2269 {
2270 int ndisposing = 0, refcnt;
2271 slist users;
2272 npppd_auth_base *auth_base;
2273 npppd_ppp *ppp;
2274
2275 /*
2276 * For the realms with disposing flag, if the realm has assigned PPPs,
2277 * disconnect them. If all PPPs are disconnected then free the realm.
2278 */
2279 NPPPD_DBG((DEBUG_LEVEL_2, "%s() called", __func__));
2280 slist_itr_first(&_this->realms);
2281 while (slist_itr_has_next(&_this->realms)) {
2282 auth_base = slist_itr_next(&_this->realms);
2283 if (!npppd_auth_is_disposing(auth_base))
2284 continue;
2285 refcnt = 0;
2286 if (ndisposing++ == 0) {
2287 slist_init(&users);
2288 if (npppd_get_all_users(_this, &users) != 0) {
2289 log_printf(LOG_WARNING,
2290 "npppd_get_all_users() failed in %s(): %m",
2291 __func__);
2292 break;
2293 }
2294 }
2295 slist_itr_first(&users);
2296 while (slist_itr_has_next(&users)) {
2297 ppp = slist_itr_next(&users);
2298 if (ppp->realm == auth_base) {
2299 refcnt++;
2300 ppp_stop(ppp, NULL);
2301 ppp_log(ppp, LOG_INFO,
2302 "Stop request by npppd. Binding "
2303 "authentication realm is disposing. "
2304 "realm=%s", npppd_auth_get_name(auth_base));
2305 slist_itr_remove(&users);
2306 }
2307 }
2308 if (refcnt == 0) {
2309 npppd_auth_destroy(auth_base);
2310 slist_itr_remove(&_this->realms);
2311 }
2312 }
2313 if (ndisposing > 0)
2314 slist_fini(&users);
2315 }
2316
2317 /** compare sockaddr_npppd. return 0 if matches */
2318 int
sockaddr_npppd_match(void * a0,void * b0)2319 sockaddr_npppd_match(void *a0, void *b0)
2320 {
2321 struct sockaddr_npppd *a, *b;
2322
2323 a = a0;
2324 b = b0;
2325
2326 return (a->snp_addr.s_addr == b->snp_addr.s_addr)? 1 : 0;
2327 }
2328
2329 /**
2330 * This function stores the username for authentication to the space specified
2331 * by username_buffer and returns it. username_buffer must have space more
2332 * than MAX_USERNAME_LENGTH.
2333 */
2334 const char *
npppd_ppp_get_username_for_auth(npppd * _this,npppd_ppp * ppp,const char * username,char * username_buffer)2335 npppd_ppp_get_username_for_auth(npppd *_this, npppd_ppp *ppp,
2336 const char *username, char *username_buffer)
2337 {
2338 NPPPD_ASSERT(_this != NULL);
2339 NPPPD_ASSERT(ppp != NULL);
2340 NPPPD_ASSERT(ppp->realm != NULL);
2341
2342 return npppd_auth_username_for_auth(ppp->realm, username,
2343 username_buffer);
2344 }
2345
2346 const char *
npppd_tunnel_protocol_name(int tunn_protocol)2347 npppd_tunnel_protocol_name(int tunn_protocol)
2348 {
2349 switch (tunn_protocol) {
2350 case NPPPD_TUNNEL_NONE:
2351 return "None";
2352 case NPPPD_TUNNEL_L2TP:
2353 return "L2TP";
2354 case NPPPD_TUNNEL_PPTP:
2355 return "PPTP";
2356 case NPPPD_TUNNEL_PPPOE:
2357 return "PPPoE";
2358 case NPPPD_TUNNEL_SSTP:
2359 return "SSTP";
2360 }
2361
2362 return "Error";
2363 }
2364
2365 const char *
npppd_ppp_tunnel_protocol_name(npppd * _this,npppd_ppp * ppp)2366 npppd_ppp_tunnel_protocol_name(npppd *_this, npppd_ppp *ppp)
2367 {
2368 return npppd_tunnel_protocol_name(ppp->tunnel_type);
2369 }
2370
2371 struct tunnconf *
npppd_get_tunnconf(npppd * _this,const char * name)2372 npppd_get_tunnconf(npppd *_this, const char *name)
2373 {
2374 struct tunnconf *conf;
2375
2376 TAILQ_FOREACH(conf, &_this->conf.tunnconfs, entry) {
2377 if (strcmp(conf->name, name) == 0)
2378 return conf;
2379 }
2380
2381 return NULL;
2382 }
2383
2384 void
npppd_on_ppp_start(npppd * _this,npppd_ppp * ppp)2385 npppd_on_ppp_start(npppd *_this, npppd_ppp *ppp)
2386 {
2387 struct ctl_conn *c;
2388
2389 TAILQ_FOREACH(c, &ctl_conns, entry) {
2390 if (npppd_ctl_add_started_ppp_id(c->ctx, ppp->id) == 0) {
2391 npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf);
2392 imsg_event_add(&c->iev);
2393 }
2394 }
2395 }
2396
2397 void
npppd_on_ppp_stop(npppd * _this,npppd_ppp * ppp)2398 npppd_on_ppp_stop(npppd *_this, npppd_ppp *ppp)
2399 {
2400 struct ctl_conn *c;
2401
2402 TAILQ_FOREACH(c, &ctl_conns, entry) {
2403 if (npppd_ctl_add_stopped_ppp(c->ctx, ppp) == 0) {
2404 npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf);
2405 imsg_event_add(&c->iev);
2406 }
2407 }
2408 }
2409
2410 void
imsg_event_add(struct imsgev * iev)2411 imsg_event_add(struct imsgev *iev)
2412 {
2413 iev->events = EV_READ;
2414 if (iev->ibuf.w.queued)
2415 iev->events |= EV_WRITE;
2416
2417 event_del(&iev->ev);
2418 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
2419 event_add(&iev->ev, NULL);
2420 }
2421