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