xref: /openbsd/usr.sbin/npppd/pptp/pptpd.c (revision 891d7ab6)
1 /* $OpenBSD: pptpd.c,v 1.8 2011/01/20 23:12:33 jasper Exp $	*/
2 
3 /*-
4  * Copyright (c) 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 /* $Id: pptpd.c,v 1.8 2011/01/20 23:12:33 jasper Exp $ */
29 
30 /**@file
31  * This file provides a implementation of PPTP daemon.  Currently it
32  * provides functions for PAC (PPTP Access Concentrator) only.
33  * $Id: pptpd.c,v 1.8 2011/01/20 23:12:33 jasper Exp $
34  */
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/socket.h>
38 #include <net/if.h>
39 #include <netinet/in.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/ip.h>
42 #include <arpa/inet.h>
43 #include <netdb.h>
44 #include <stdio.h>
45 #include <stdarg.h>
46 #include <signal.h>
47 #include <syslog.h>
48 #include <fcntl.h>
49 #include <unistd.h>
50 #include <stdlib.h>
51 #include <errno.h>
52 #include <string.h>
53 #include <string.h>
54 #include <event.h>
55 #include <ifaddrs.h>
56 
57 #ifdef USE_LIBSOCKUTIL
58 #include <seil/sockfromto.h>
59 #endif
60 
61 #include "net_utils.h"
62 #include "bytebuf.h"
63 #include "debugutil.h"
64 #include "hash.h"
65 #include "slist.h"
66 #include "addr_range.h"
67 #include "properties.h"
68 #include "config_helper.h"
69 
70 #include "pptp.h"
71 #include "pptp_local.h"
72 #include "privsep.h"
73 
74 static int pptpd_seqno = 0;
75 
76 #ifdef	PPTPD_DEBUG
77 #define	PPTPD_ASSERT(x)	ASSERT(x)
78 #define	PPTPD_DBG(x)	pptpd_log x
79 #else
80 #define	PPTPD_ASSERT(x)
81 #define	PPTPD_DBG(x)
82 #endif
83 
84 static void      pptpd_log (pptpd *, int, const char *, ...) __printflike(3,4);
85 static void      pptpd_close_gre (pptpd *);
86 static void      pptpd_close_1723 (pptpd *);
87 static void      pptpd_io_event (int, short, void *);
88 static void      pptpd_gre_io_event (int, short, void *);
89 static void      pptpd_gre_input (pptpd_listener *, struct sockaddr *, u_char *, int);
90 static void      pptp_ctrl_start_by_pptpd (pptpd *, int, int, struct sockaddr *);
91 static int       pptp_call_cmp (const void *, const void *);
92 static uint32_t  pptp_call_hash (const void *, int);
93 static void      pptp_gre_header_string (struct pptp_gre_header *, char *, int);
94 
95 #define	PPTPD_SHUFFLE_MARK	-1
96 
97 /* initialize pptp daemon */
98 int
99 pptpd_init(pptpd *_this)
100 {
101 	int i, m;
102 	struct sockaddr_in sin0;
103 	uint16_t call0, call[UINT16_MAX - 1];
104 
105 	memset(_this, 0, sizeof(pptpd));
106 	_this->id = pptpd_seqno++;
107 
108 	slist_init(&_this->listener);
109 	memset(&sin0, 0, sizeof(sin0));
110 	sin0.sin_len = sizeof(sin0);
111 	sin0.sin_family = AF_INET;
112 	if (pptpd_add_listener(_this, 0, PPTPD_DEFAULT_LAYER2_LABEL,
113 	    (struct sockaddr *)&sin0) != 0) {
114 		return 1;
115 	}
116 
117 	_this->ip4_allow = NULL;
118 
119 	slist_init(&_this->ctrl_list);
120 	slist_init(&_this->call_free_list);
121 
122 	/* randomize call id */
123 	for (i = 0; i < countof(call) ; i++)
124 		call[i] = i + 1;
125 	for (i = countof(call); i > 1; i--) {
126 		m = random() % i;
127 		call0 = call[m];
128 		call[m] = call[i - 1];
129 		call[i - 1] = call0;
130 	}
131 
132 	for (i = 0; i < MIN(PPTP_MAX_CALL, countof(call)); i++)
133 		slist_add(&_this->call_free_list, (void *)(uintptr_t)call[i]);
134 	slist_add(&_this->call_free_list, (void *)PPTPD_SHUFFLE_MARK);
135 
136 	if (_this->call_id_map == NULL)
137 		_this->call_id_map = hash_create(pptp_call_cmp, pptp_call_hash,
138 		    0);
139 
140 	return 0;
141 }
142 
143 /* add a listner to pptpd daemon context */
144 int
145 pptpd_add_listener(pptpd *_this, int idx, const char *label,
146     struct sockaddr *bindaddr)
147 {
148 	int inaddr_any;
149 	pptpd_listener *plistener, *plstn;
150 
151 	plistener = NULL;
152 	if (idx == 0 && slist_length(&_this->listener) > 0) {
153 		slist_itr_first(&_this->listener);
154 		while (slist_itr_has_next(&_this->listener)) {
155 			slist_itr_next(&_this->listener);
156 			plstn = slist_itr_remove(&_this->listener);
157 			PPTPD_ASSERT(plstn != NULL);
158 			PPTPD_ASSERT(plstn->sock == -1);
159 			PPTPD_ASSERT(plstn->sock_gre == -1);
160 			free(plstn);
161 		}
162 	}
163 	PPTPD_ASSERT(slist_length(&_this->listener) == idx);
164 	if (slist_length(&_this->listener) != idx) {
165 		pptpd_log(_this, LOG_ERR,
166 		    "Invalid argument error on %s(): idx must be %d but %d",
167 		    __func__, slist_length(&_this->listener), idx);
168 		goto fail;
169 	}
170 	if ((plistener = malloc(sizeof(pptpd_listener))) == NULL) {
171 		pptpd_log(_this, LOG_ERR, "malloc() failed in %s: %m",
172 		    __func__);
173 		goto fail;
174 	}
175 	memset(plistener, 0, sizeof(pptpd_listener));
176 
177 	PPTPD_ASSERT(sizeof(plistener->bind_sin) >= bindaddr->sa_len);
178 	memcpy(&plistener->bind_sin, bindaddr, bindaddr->sa_len);
179 	memcpy(&plistener->bind_sin_gre, bindaddr, bindaddr->sa_len);
180 
181 	if (plistener->bind_sin.sin_port == 0)
182 		plistener->bind_sin.sin_port = htons(PPTPD_DEFAULT_TCP_PORT);
183 
184 	/* When a raw socket binds both of an INADDR_ANY and specific IP
185 	 * address sockets, packets will be received by those sockets
186 	 * simultaneously. To avoid this duplicate receives, not
187 	 * permit such kind of configuration */
188 	inaddr_any = 0;
189 	slist_itr_first(&_this->listener);
190 	while (slist_itr_has_next(&_this->listener)) {
191 		plstn = slist_itr_next(&_this->listener);
192 		if (plstn->bind_sin_gre.sin_addr.s_addr == INADDR_ANY)
193 			inaddr_any++;
194 	}
195 	if (plistener->bind_sin_gre.sin_addr.s_addr == INADDR_ANY)
196 		inaddr_any++;
197 	if (inaddr_any > 0 && idx > 0) {
198 		log_printf(LOG_ERR, "configuration error at pptpd.listener_in: "
199 		    "combination 0.0.0.0 and other address is not allowed.");
200 		goto fail;
201 	}
202 
203 	plistener->bind_sin_gre.sin_port = 0;
204 	plistener->sock = -1;
205 	plistener->sock_gre = -1;
206 	plistener->self = _this;
207 	plistener->index = idx;
208 	strlcpy(plistener->phy_label, label, sizeof(plistener->phy_label));
209 
210 	if (slist_add(&_this->listener, plistener) == NULL) {
211 		pptpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m",
212 		    __func__);
213 		goto fail;
214 	}
215 	return 0;
216 fail:
217 	if (plistener != NULL)
218 		free(plistener);
219 	return 1;
220 }
221 
222 void
223 pptpd_uninit(pptpd *_this)
224 {
225 	pptpd_listener *plstn;
226 
227 	slist_fini(&_this->ctrl_list);
228 	slist_fini(&_this->call_free_list);
229 
230 	slist_itr_first(&_this->listener);
231 	while (slist_itr_has_next(&_this->listener)) {
232 		plstn = slist_itr_next(&_this->listener);
233 		PPTPD_ASSERT(plstn != NULL);
234 		PPTPD_ASSERT(plstn->sock == -1);
235 		PPTPD_ASSERT(plstn->sock_gre == -1);
236 		free(plstn);
237 	}
238 	slist_fini(&_this->listener);
239 	if (_this->call_id_map != NULL) {
240 		hash_free(_this->call_id_map);
241 	}
242 	if (_this->ip4_allow != NULL)
243 		in_addr_range_list_remove_all(&_this->ip4_allow);
244 	_this->call_id_map = NULL;
245 	_this->config = NULL;
246 }
247 
248 #define	CALL_MAP_KEY(call)	\
249 	(void *)(call->id | (call->ctrl->listener_index << 16))
250 #define	CALL_ID(item)	((uint32_t)item & 0xffff)
251 
252 int
253 pptpd_assign_call(pptpd *_this, pptp_call *call)
254 {
255 	int shuffle_cnt = 0, call_id;
256 
257 	shuffle_cnt = 0;
258 	slist_itr_first(&_this->call_free_list);
259 	while (slist_length(&_this->call_free_list) > 1 &&
260 	    slist_itr_has_next(&_this->call_free_list)) {
261 		call_id = (int)slist_itr_next(&_this->call_free_list);
262 		if (call_id == 0)
263 			break;
264 		slist_itr_remove(&_this->call_free_list);
265 		if (call_id == PPTPD_SHUFFLE_MARK) {
266 			if (shuffle_cnt++ > 0)
267 				break;
268 			slist_shuffle(&_this->call_free_list);
269 			slist_add(&_this->call_free_list,
270 			    (void *)PPTPD_SHUFFLE_MARK);
271 			slist_itr_first(&_this->call_free_list);
272 			continue;
273 		}
274 		call->id = call_id;
275 		hash_insert(_this->call_id_map, CALL_MAP_KEY(call), call);
276 
277 		return 0;
278 	}
279 	errno = EBUSY;
280 	pptpd_log(_this, LOG_ERR, "call request reached limit=%d",
281 	    PPTP_MAX_CALL);
282 	return -1;
283 }
284 
285 void
286 pptpd_release_call(pptpd *_this, pptp_call *call)
287 {
288 	if (call->id != 0)
289 		slist_add(&_this->call_free_list, (void *)call->id);
290 	hash_delete(_this->call_id_map, CALL_MAP_KEY(call), 0);
291 	call->id = 0;
292 }
293 
294 static int
295 pptpd_listener_start(pptpd_listener *_this)
296 {
297 	int sock, ival, sock_gre;
298 	struct sockaddr_in bind_sin, bind_sin_gre;
299 	int wildcardbinding;
300 #ifdef NPPPD_FAKEBIND
301 	extern void set_faith(int, int);
302 #endif
303 
304 	wildcardbinding =
305 	    (_this->bind_sin.sin_addr.s_addr == INADDR_ANY)?  1 : 0;
306 	sock = -1;
307 	sock_gre = -1;
308 	memcpy(&bind_sin, &_this->bind_sin, sizeof(bind_sin));
309 	memcpy(&bind_sin_gre, &_this->bind_sin_gre, sizeof(bind_sin_gre));
310 
311 	if (_this->phy_label[0] == '\0')
312 		strlcpy(_this->phy_label, PPTPD_DEFAULT_LAYER2_LABEL,
313 		    sizeof(_this->phy_label));
314 	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
315 		pptpd_log(_this->self, LOG_ERR, "socket() failed at %s(): %m",
316 		    __func__);
317 		goto fail;
318 	}
319 	ival = 1;
320 	if(setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &ival, sizeof(ival)) < 0){
321 		pptpd_log(_this->self, LOG_WARNING,
322 		    "setsockopt(SO_REUSEPORT) failed at %s(): %m", __func__);
323 	}
324 #ifdef NPPPD_FAKEBIND
325 	if (!wildcardbinding)
326 		set_faith(sock, 1);
327 #endif
328 #if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF)
329 	ival = 1;
330 	if (setsockopt(sock, IPPROTO_IP, IP_STRICT_RCVIF, &ival, sizeof(ival))
331 	    != 0)
332 		pptpd_log(_this->self, LOG_WARNING,
333 		    "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__);
334 #endif
335 	if ((ival = fcntl(sock, F_GETFL, 0)) < 0) {
336 		pptpd_log(_this->self, LOG_ERR,
337 		    "fcntl(F_GET_FL) failed at %s(): %m", __func__);
338 		goto fail;
339 	} else if (fcntl(sock, F_SETFL, ival | O_NONBLOCK) < 0) {
340 		pptpd_log(_this->self, LOG_ERR,
341 		    "fcntl(F_SET_FL) failed at %s(): %m", __func__);
342 		goto fail;
343 	}
344 	if (bind(sock, (struct sockaddr *)&_this->bind_sin,
345 	    _this->bind_sin.sin_len) != 0) {
346 		pptpd_log(_this->self, LOG_ERR,
347 		    "bind(%s:%u) failed at %s(): %m",
348 		    inet_ntoa(_this->bind_sin.sin_addr),
349 		    ntohs(_this->bind_sin.sin_port), __func__);
350 		goto fail;
351 	}
352 	if (listen(sock, PPTP_BACKLOG) != 0) {
353 		pptpd_log(_this->self, LOG_ERR,
354 		    "listen(%s:%u) failed at %s(): %m",
355 		    inet_ntoa(_this->bind_sin.sin_addr),
356 		    ntohs(_this->bind_sin.sin_port), __func__);
357 		goto fail;
358 	}
359 #ifdef NPPPD_FAKEBIND
360 	if (!wildcardbinding)
361 		set_faith(sock, 0);
362 #endif
363 	pptpd_log(_this->self, LOG_INFO, "Listening %s:%u/tcp (PPTP PAC) [%s]",
364 	    inet_ntoa(_this->bind_sin.sin_addr),
365 	    ntohs(_this->bind_sin.sin_port), _this->phy_label);
366 
367 	/* GRE */
368 	bind_sin_gre.sin_port = 0;
369 	if ((sock_gre = priv_socket(AF_INET, SOCK_RAW, IPPROTO_GRE)) < 0) {
370 		pptpd_log(_this->self, LOG_ERR, "socket() failed at %s(): %m",
371 		    __func__);
372 		goto fail;
373 	}
374 #ifdef NPPPD_FAKEBIND
375 	if (!wildcardbinding)
376 		set_faith(sock_gre, 1);
377 #endif
378 #if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF)
379 	ival = 1;
380 	if (setsockopt(sock_gre, IPPROTO_IP, IP_STRICT_RCVIF, &ival,
381 	    sizeof(ival)) != 0)
382 		pptpd_log(_this->self, LOG_WARNING,
383 		    "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__);
384 #endif
385 #ifdef IP_PIPEX
386 	ival = 1;
387 	if (setsockopt(sock_gre, IPPROTO_IP, IP_PIPEX, &ival, sizeof(ival))
388 	    != 0)
389 		pptpd_log(_this->self, LOG_WARNING,
390 		    "%s(): setsockopt(IP_PIPEX) failed: %m", __func__);
391 #endif
392 	if ((ival = fcntl(sock_gre, F_GETFL, 0)) < 0) {
393 		pptpd_log(_this->self, LOG_ERR,
394 		    "fcntl(F_GET_FL) failed at %s(): %m", __func__);
395 		goto fail;
396 	} else if (fcntl(sock_gre, F_SETFL, ival | O_NONBLOCK) < 0) {
397 		pptpd_log(_this->self, LOG_ERR,
398 		    "fcntl(F_SET_FL) failed at %s(): %m", __func__);
399 		goto fail;
400 	}
401 	if (bind(sock_gre, (struct sockaddr *)&bind_sin_gre,
402 	    bind_sin_gre.sin_len) != 0) {
403 		pptpd_log(_this->self, LOG_ERR,
404 		    "bind(%s:%u) failed at %s(): %m",
405 		    inet_ntoa(bind_sin_gre.sin_addr),
406 		    ntohs(bind_sin_gre.sin_port), __func__);
407 		goto fail;
408 	}
409 #ifdef NPPPD_FAKEBIND
410 	if (!wildcardbinding)
411 		set_faith(sock_gre, 0);
412 #endif
413 	if (wildcardbinding) {
414 #ifdef USE_LIBSOCKUTIL
415 		if (setsockoptfromto(sock) != 0) {
416 			pptpd_log(_this->self, LOG_ERR,
417 			    "setsockoptfromto() failed in %s(): %m", __func__);
418 			goto fail;
419 		}
420 #else
421 		/* nothing to do */
422 #endif
423 	}
424 	pptpd_log(_this->self, LOG_INFO, "Listening %s:gre (PPTP PAC)",
425 	    inet_ntoa(bind_sin_gre.sin_addr));
426 
427 	_this->sock = sock;
428 	_this->sock_gre = sock_gre;
429 
430 	event_set(&_this->ev_sock, _this->sock, EV_READ | EV_PERSIST,
431 	    pptpd_io_event, _this);
432 	event_add(&_this->ev_sock, NULL);
433 
434 	event_set(&_this->ev_sock_gre, _this->sock_gre, EV_READ | EV_PERSIST,
435 	    pptpd_gre_io_event, _this);
436 	event_add(&_this->ev_sock_gre, NULL);
437 
438 	return 0;
439 fail:
440 	if (sock >= 0)
441 		close(sock);
442 	if (sock_gre >= 0)
443 		close(sock_gre);
444 
445 	_this->sock = -1;
446 	_this->sock_gre = -1;
447 
448 	return 1;
449 }
450 
451 int
452 pptpd_start(pptpd *_this)
453 {
454 	int rval = 0;
455 	pptpd_listener *plistener;
456 
457 	slist_itr_first(&_this->listener);
458 	while (slist_itr_has_next(&_this->listener)) {
459 		plistener = slist_itr_next(&_this->listener);
460 		PPTPD_ASSERT(plistener != NULL);
461 		rval |= pptpd_listener_start(plistener);
462 	}
463 	if (rval == 0)
464 		_this->state = PPTPD_STATE_RUNNING;
465 
466 	return rval;
467 }
468 
469 static void
470 pptpd_listener_close_gre(pptpd_listener *_this)
471 {
472 	if (_this->sock_gre >= 0) {
473 		event_del(&_this->ev_sock_gre);
474 		close(_this->sock_gre);
475 		pptpd_log(_this->self, LOG_INFO, "Shutdown %s/gre",
476 		    inet_ntoa(_this->bind_sin_gre.sin_addr));
477 	}
478 	_this->sock_gre = -1;
479 }
480 
481 static void
482 pptpd_close_gre(pptpd *_this)
483 {
484 	pptpd_listener *plistener;
485 
486 	slist_itr_first(&_this->listener);
487 	while (slist_itr_has_next(&_this->listener)) {
488 		plistener = slist_itr_next(&_this->listener);
489 		pptpd_listener_close_gre(plistener);
490 	}
491 }
492 
493 static void
494 pptpd_listener_close_1723(pptpd_listener *_this)
495 {
496 	if (_this->sock >= 0) {
497 		event_del(&_this->ev_sock);
498 		close(_this->sock);
499 		pptpd_log(_this->self, LOG_INFO, "Shutdown %s:%u/tcp",
500 		    inet_ntoa(_this->bind_sin.sin_addr),
501 		    ntohs(_this->bind_sin.sin_port));
502 	}
503 	_this->sock = -1;
504 }
505 
506 static void
507 pptpd_close_1723(pptpd *_this)
508 {
509 	pptpd_listener *plistener;
510 
511 	slist_itr_first(&_this->listener);
512 	while (slist_itr_has_next(&_this->listener)) {
513 		plistener = slist_itr_next(&_this->listener);
514 		pptpd_listener_close_1723(plistener);
515 	}
516 }
517 
518 void
519 pptpd_stop_immediatly(pptpd *_this)
520 {
521 	pptp_ctrl *ctrl;
522 
523 	if (event_initialized(&_this->ev_timer))
524 		evtimer_del(&_this->ev_timer);
525 	if (_this->state != PPTPD_STATE_STOPPED) {
526 		/* lock, to avoid multiple call from pptp_ctrl_stop() */
527 		_this->state = PPTPD_STATE_STOPPED;
528 
529 		pptpd_close_1723(_this);
530 		for (slist_itr_first(&_this->ctrl_list);
531 		    (ctrl = slist_itr_next(&_this->ctrl_list)) != NULL;) {
532 			pptp_ctrl_stop(ctrl, 0);
533 		}
534 		pptpd_close_gre(_this);
535 		slist_fini(&_this->ctrl_list);
536 		slist_fini(&_this->call_free_list);
537 		pptpd_log(_this, LOG_NOTICE, "Stopped");
538 	} else {
539 		PPTPD_DBG((_this, LOG_DEBUG, "(Already) Stopped"));
540 	}
541 }
542 
543 static void
544 pptpd_stop_timeout(int fd, short event, void *ctx)
545 {
546 	pptpd *_this;
547 
548 	_this = ctx;
549 	pptpd_stop_immediatly(_this);
550 }
551 
552 void
553 pptpd_stop(pptpd *_this)
554 {
555 	int nctrl;
556 	pptp_ctrl *ctrl;
557 	struct timeval tv;
558 
559 	if (event_initialized(&_this->ev_timer))
560 		evtimer_del(&_this->ev_timer);
561 	pptpd_close_1723(_this);
562 
563 	/* XXX: use common procedure with l2tpd_stop */
564 
565 	if (pptpd_is_stopped(_this))
566 		return;
567 	if (pptpd_is_shutting_down(_this)) {
568 		pptpd_stop_immediatly(_this);
569 		return;
570 	}
571 	_this->state = PPTPD_STATE_SHUTTING_DOWN;
572 	nctrl = 0;
573 	for (slist_itr_first(&_this->ctrl_list);
574 	    (ctrl = slist_itr_next(&_this->ctrl_list)) != NULL;) {
575 		pptp_ctrl_stop(ctrl, PPTP_CDN_RESULT_ADMIN_SHUTDOWN);
576 		nctrl++;
577 	}
578 	if (nctrl > 0) {
579 		tv.tv_sec = PPTPD_SHUTDOWN_TIMEOUT;
580 		tv.tv_usec = 0;
581 
582 		evtimer_set(&_this->ev_timer, pptpd_stop_timeout, _this);
583 		evtimer_add(&_this->ev_timer, &tv);
584 
585 		return;
586 	}
587 	pptpd_stop_immediatly(_this);
588 }
589 
590 /*
591  * PPTP Configuration
592  */
593 #define	CFG_KEY(p, s)	config_key_prefix((p), (s))
594 #define	VAL_SEP		" \t\r\n"
595 
596 CONFIG_FUNCTIONS(pptpd_config, pptpd, config);
597 PREFIXED_CONFIG_FUNCTIONS(pptp_ctrl_config, pptp_ctrl, pptpd->config,
598     phy_label);
599 int
600 pptpd_reload(pptpd *_this, struct properties *config, const char *name,
601     int default_enabled)
602 {
603 	int i, do_start, aierr;
604 	const char *val;
605 	char *tok, *cp, buf[PPTPD_CONFIG_BUFSIZ], *label;
606 	struct addrinfo *ai;
607 
608 	ASSERT(_this != NULL);
609 	ASSERT(config != NULL);
610 
611 	_this->config = config;
612 	do_start = 0;
613 	if (pptpd_config_str_equal(_this, CFG_KEY(name, "enabled"), "true",
614 	    default_enabled)) {
615 		/* avoid false-true flap */
616 		if (pptpd_is_shutting_down(_this))
617 			pptpd_stop_immediatly(_this);
618 		if (pptpd_is_stopped(_this))
619 			do_start = 1;
620 	} else {
621 		if (!pptpd_is_stopped(_this))
622 			pptpd_stop(_this);
623 		return 0;
624 	}
625 	if (do_start && pptpd_init(_this) != 0)
626 		return 1;
627 	/* set again as pptpd_init will reset it */
628 	_this->config = config;
629 
630 	_this->ctrl_in_pktdump = pptpd_config_str_equal(_this,
631 	    "log.pptp.ctrl.in.pktdump", "true", 0);
632 	_this->data_in_pktdump = pptpd_config_str_equal(_this,
633 	    "log.pptp.data.in.pktdump", "true", 0);
634 	_this->ctrl_out_pktdump = pptpd_config_str_equal(_this,
635 	    "log.pptp.ctrl.out.pktdump", "true", 0);
636 	_this->data_out_pktdump = pptpd_config_str_equal(_this,
637 	    "log.pptp.data.out.pktdump", "true", 0);
638 	_this->phy_label_with_ifname = pptpd_config_str_equal(_this,
639 	    CFG_KEY(name, "label_with_ifname"), "true", 0);
640 
641 	/* parse ip4_allow */
642 	in_addr_range_list_remove_all(&_this->ip4_allow);
643 	val = pptpd_config_str(_this, CFG_KEY(name, "ip4_allow"));
644 	if (val != NULL) {
645 		if (strlen(val) >= sizeof(buf)) {
646 			log_printf(LOG_ERR, "configuration error at "
647 			    "%s: too long", CFG_KEY(name, "ip4_allow"));
648 			return 1;
649 		}
650 		strlcpy(buf, val, sizeof(buf));
651 		for (cp = buf; (tok = strsep(&cp, VAL_SEP)) != NULL;) {
652 			if (*tok == '\0')
653 				continue;
654 			if (in_addr_range_list_add(&_this->ip4_allow, tok)
655 			    != 0) {
656 				pptpd_log(_this, LOG_ERR,
657 				    "configuration error at %s: %s",
658 				    CFG_KEY(name, "ip4_allow"), tok);
659 				return 1;
660 			}
661 		}
662 	}
663 
664 	if (do_start) {
665 		/* in the case of 1) cold-booted and 2) pptpd.enable
666 		 * toggled "false" to "true" do this, because we can
667 		 * assume that all pptpd listner are initialized. */
668 
669 		val = pptpd_config_str(_this, CFG_KEY(name, "listener_in"));
670 		if (val != NULL) {
671 			if (strlen(val) >= sizeof(buf)) {
672 				pptpd_log(_this, LOG_ERR,
673 				    "configuration error at "
674 				    "%s: too long", CFG_KEY(name, "listener"));
675 				return 1;
676 			}
677 			strlcpy(buf, val, sizeof(buf));
678 
679 			label = NULL;
680 			/* it can accept multple velues with tab/space
681 			 * separation */
682 			for (i = 0, cp = buf;
683 			    (tok = strsep(&cp, VAL_SEP)) != NULL;) {
684 				if (*tok == '\0')
685 					continue;
686 				if (label == NULL) {
687 					label = tok;
688 					continue;
689 				}
690 				if ((aierr = addrport_parse(tok, IPPROTO_TCP,
691 				    &ai)) != 0) {
692 					pptpd_log(_this, LOG_ERR,
693 					    "configuration error at "
694 					    "%s: %s: %s",
695 					    CFG_KEY(name, "listener_in"), tok,
696 					    gai_strerror(aierr));
697 					return 1;
698 				}
699 				PPTPD_ASSERT(ai != NULL &&
700 				    ai->ai_family == AF_INET);
701 				if (pptpd_add_listener(_this, i, label,
702 				    ai->ai_addr) != 0) {
703 					freeaddrinfo(ai);
704 					label = NULL;
705 					break;
706 				}
707 				freeaddrinfo(ai);
708 				label = NULL;
709 				i++;
710 			}
711 			if (label != NULL) {
712 				pptpd_log(_this, LOG_ERR,
713 				    "configuration error at %s: %s",
714 				    CFG_KEY(name, "listner_in"), label);
715 				return 1;
716 			}
717 		}
718 		if (pptpd_start(_this) != 0)
719 			return 1;
720 	}
721 
722 	return 0;
723 }
724 
725 /*
726  * I/O functions
727  */
728 static void
729 pptpd_log_access_deny(pptpd *_this, const char *reason, struct sockaddr *peer)
730 {
731 	char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV];
732 
733 	if (getnameinfo(peer, peer->sa_len, hostbuf, sizeof(hostbuf),
734 	    servbuf, sizeof(servbuf), NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
735 		pptpd_log(_this, LOG_ERR, "getnameinfo() failed at %s(): %m",
736 		    __func__);
737 		return;
738 	}
739 	pptpd_log(_this, LOG_ALERT, "denied a connection from %s:%s/tcp: %s",
740 	    hostbuf, servbuf, reason);
741 }
742 
743 /* I/O event handler of 1723/tcp */
744 static void
745 pptpd_io_event(int fd, short evmask, void *ctx)
746 {
747 	int newsock;
748 	const char *reason;
749 	socklen_t peerlen;
750 	struct sockaddr_storage peer;
751 	pptpd *_this;
752 	pptpd_listener *listener;
753 
754 	listener = ctx;
755 	PPTPD_ASSERT(listener != NULL);
756 	_this = listener->self;
757 	PPTPD_ASSERT(_this != NULL);
758 
759 	if ((evmask & EV_READ) != 0) {
760 		for (;;) { /* accept till EAGAIN occured */
761 			peerlen = sizeof(peer);
762 			if ((newsock = accept(listener->sock,
763 			    (struct sockaddr *)&peer, &peerlen)) < 0) {
764 				switch (errno) {
765 				case EAGAIN:
766 				case EINTR:
767 					break;
768 				case ECONNABORTED:
769 					pptpd_log(_this, LOG_WARNING,
770 					    "accept() failed at %s(): %m",
771 					    __func__);
772 					break;
773 				default:
774 					pptpd_log(_this, LOG_ERR,
775 					    "accept() failed at %s(): %m",
776 						__func__);
777 					pptpd_listener_close_1723(listener);
778 					pptpd_stop(_this);
779 				}
780 				break;
781 			}
782 		/* check peer */
783 			switch (peer.ss_family) {
784 			case AF_INET:
785 				if (!in_addr_range_list_includes(
786 				    &_this->ip4_allow,
787 				    &((struct sockaddr_in *)&peer)->sin_addr)) {
788 					reason = "not allowed by acl.";
789 					break;
790 				}
791 				goto accept;
792 			default:
793 				reason = "address family is not supported.";
794 				break;
795 			}
796 		/* not permitted */
797 			pptpd_log_access_deny(_this, reason,
798 			    (struct sockaddr *)&peer);
799 			close(newsock);
800 			continue;
801 			/* NOTREACHED */
802 accept:
803 		/* permitted, can accepted */
804 			pptp_ctrl_start_by_pptpd(_this, newsock,
805 			    listener->index, (struct sockaddr *)&peer);
806 		}
807 	}
808 }
809 
810 /* I/O event handeler of GRE */
811 static void
812 pptpd_gre_io_event(int fd, short evmask, void *ctx)
813 {
814 	int sz;
815 	u_char pkt[65535];
816 	socklen_t peerlen;
817 	struct sockaddr_storage peer;
818 	pptpd *_this;
819 	pptpd_listener *listener;
820 
821 	listener = ctx;
822 	PPTPD_ASSERT(listener != NULL);
823 	_this = listener->self;
824 	PPTPD_ASSERT(_this != NULL);
825 
826 	if (evmask & EV_READ) {
827 		for (;;) {
828 			/* read till bloked */
829 			peerlen = sizeof(peer);
830 			if ((sz = recvfrom(listener->sock_gre, pkt, sizeof(pkt),
831 			    0, (struct sockaddr *)&peer, &peerlen)) <= 0) {
832 				if (sz < 0 &&
833 				    (errno == EAGAIN || errno == EINTR))
834 					break;
835 				pptpd_log(_this, LOG_INFO,
836 				    "read(GRE) failed: %m");
837 				pptpd_stop(_this);
838 				return;
839 			}
840 			pptpd_gre_input(listener, (struct sockaddr *)&peer, pkt,
841 			    sz);
842 		}
843 	}
844 }
845 
846 /* receive GRE then route to pptp_call */
847 static void
848 pptpd_gre_input(pptpd_listener *listener, struct sockaddr *peer, u_char *pkt,
849     int lpkt)
850 {
851 	int hlen, input_flags;
852 	uint32_t seq, ack, call_id;
853 	struct ip *iphdr;
854 	struct pptp_gre_header *grehdr;
855 	char hbuf0[NI_MAXHOST], logbuf[512];
856 	const char *reason;
857 	pptp_call *call;
858 	hash_link *hl;
859 	pptpd *_this;
860 
861 	seq = 0;
862 	ack = 0;
863 	input_flags = 0;
864 	reason = "No error";
865 	_this = listener->self;
866 
867 	PPTPD_ASSERT(peer->sa_family == AF_INET);
868 
869 	strlcpy(hbuf0, "<unknown>", sizeof(hbuf0));
870 	if (getnameinfo(peer, peer->sa_len, hbuf0, sizeof(hbuf0), NULL, 0,
871 	    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
872 		pptpd_log(_this, LOG_ERR,
873 		    "getnameinfo() failed at %s(): %m", __func__);
874 		goto fail;
875 	}
876 	if (_this->data_in_pktdump != 0) {
877 		pptpd_log(_this, LOG_DEBUG, "PPTP Data input packet dump");
878 		show_hd(debug_get_debugfp(), pkt, lpkt);
879 	}
880 	if (peer->sa_family != AF_INET) {
881 		pptpd_log(_this, LOG_ERR,
882 		    "Received malformed GRE packet: address family is not "
883 		    "supported: peer=%s af=%d", hbuf0, peer->sa_family);
884 		goto fail;
885 	}
886 
887 	if (lpkt < sizeof(struct ip)) {
888 		pptpd_log(_this, LOG_ERR,
889 		    "Received a short length packet length=%d, from %s", lpkt,
890 			hbuf0);
891 		goto fail;
892 	}
893 	iphdr = (struct ip *)pkt;
894 
895 	iphdr->ip_len = ntohs(iphdr->ip_len);
896 	hlen = iphdr->ip_hl * 4;
897 
898 	if (iphdr->ip_len > lpkt ||
899 	    iphdr->ip_len < sizeof(struct pptp_gre_header)) {
900 		pptpd_log(_this, LOG_ERR,
901 		    "Received a broken packet: ip_hl=%d iplen=%d lpkt=%d", hlen,
902 			iphdr->ip_len, lpkt);
903 		show_hd(debug_get_debugfp(), pkt, lpkt);
904 		goto fail;
905 	}
906 	pkt += hlen;
907 	lpkt -= hlen;
908 	grehdr = (struct pptp_gre_header *)pkt;
909 	pkt += sizeof(struct pptp_gre_header);
910 	lpkt -= sizeof(struct pptp_gre_header);
911 
912 	grehdr->protocol_type = htons(grehdr->protocol_type);
913 	grehdr->payload_length = htons(grehdr->payload_length);
914 	grehdr->call_id = htons(grehdr->call_id);
915 
916 	if (!(grehdr->protocol_type == PPTP_GRE_PROTOCOL_TYPE &&
917 	    grehdr->C == 0 && grehdr->R == 0 && grehdr->K != 0 &&
918 	    grehdr->recur == 0 && grehdr->s == 0 && grehdr->flags == 0 &&
919 	    grehdr->ver == PPTP_GRE_VERSION)) {
920 		reason = "GRE header is broken";
921 		goto bad_gre;
922 	}
923 	if (grehdr->S != 0) {
924 		if (lpkt < 2) {
925 			reason = "No enough space for seq number";
926 			goto bad_gre;
927 		}
928 		input_flags |= PPTP_GRE_PKT_SEQ_PRESENT;
929 		seq = ntohl(*(uint32_t *)pkt);
930 		pkt += 4;
931 		lpkt -= 4;
932 	}
933 
934 	if (grehdr->A != 0) {
935 		if (lpkt < 2) {
936 			reason = "No enough space for ack number";
937 			goto bad_gre;
938 		}
939 		input_flags |= PPTP_GRE_PKT_ACK_PRESENT;
940 		ack = ntohl(*(uint32_t *)pkt);
941 		pkt += 4;
942 		lpkt -= 4;
943 	}
944 
945 	if (grehdr->payload_length > lpkt) {
946 		reason = "'Payload Length' is mismatch from actual length";
947 		goto bad_gre;
948 	}
949 
950 
951 	/* route to pptp_call */
952 	call_id = grehdr->call_id;
953 
954 	hl = hash_lookup(_this->call_id_map,
955 	    (void *)(call_id | (listener->index << 16)));
956 	if (hl == NULL) {
957 		reason = "Received GRE packet has unknown call_id";
958 		goto bad_gre;
959 	}
960 	call = hl->item;
961 	pptp_call_gre_input(call, seq, ack, input_flags, pkt, lpkt);
962 
963 	return;
964 bad_gre:
965 	pptp_gre_header_string(grehdr, logbuf, sizeof(logbuf));
966 	pptpd_log(_this, LOG_INFO,
967 	    "Received malformed GRE packet: %s: peer=%s sock=%s %s seq=%u: "
968 	    "ack=%u ifidx=%d", reason, hbuf0, inet_ntoa(iphdr->ip_dst), logbuf,
969 	    seq, ack, listener->index);
970 fail:
971 	return;
972 }
973 
974 /* start PPTP control, when new connection is established */
975 static void
976 pptp_ctrl_start_by_pptpd(pptpd *_this, int sock, int listener_index,
977     struct sockaddr *peer)
978 {
979 	int ival;
980 	pptp_ctrl *ctrl;
981 	socklen_t sslen;
982 	char ifname[IF_NAMESIZE], msgbuf[128];
983 
984 	ctrl = NULL;
985 	if ((ctrl = pptp_ctrl_create()) == NULL)
986 		goto fail;
987 	if (pptp_ctrl_init(ctrl) != 0)
988 		goto fail;
989 
990 	memset(&ctrl->peer, 0, sizeof(ctrl->peer));
991 	memcpy(&ctrl->peer, peer, peer->sa_len);
992 	ctrl->pptpd = _this;
993 	ctrl->sock = sock;
994 	ctrl->listener_index = listener_index;
995 
996 	sslen = sizeof(ctrl->our);
997 	if (getsockname(ctrl->sock, (struct sockaddr *)&ctrl->our,
998 	    &sslen) != 0) {
999 		pptpd_log(_this, LOG_WARNING,
1000 		    "getsockname() failed at %s(): %m", __func__);
1001 		goto fail;
1002 	}
1003 
1004 	/* change with interface name, ex) "L2TP%em0.mru" */
1005 	if (_this->phy_label_with_ifname != 0) {
1006 		if (get_ifname_by_sockaddr((struct sockaddr *)&ctrl->our,
1007 		    ifname) == NULL) {
1008 			pptpd_log_access_deny(_this,
1009 			    "could not get interface informations", peer);
1010 			goto fail;
1011 		}
1012 		if (pptpd_config_str_equal(_this,
1013 		    config_key_prefix("pptpd.interface", ifname), "accept", 0)){
1014 			snprintf(ctrl->phy_label, sizeof(ctrl->phy_label),
1015 			    "%s%%%s", PPTP_CTRL_LISTENER_LABEL(ctrl), ifname);
1016 		} else if (pptpd_config_str_equal(_this,
1017 		    config_key_prefix("pptpd.interface", "any"), "accept", 0)){
1018 			snprintf(ctrl->phy_label, sizeof(ctrl->phy_label),
1019 			    "%s", PPTP_CTRL_LISTENER_LABEL(ctrl));
1020 		} else {
1021 			/* the interface is not permitted */
1022 			snprintf(msgbuf, sizeof(msgbuf),
1023 			    "'%s' is not allowed by config.", ifname);
1024 			pptpd_log_access_deny(_this, msgbuf, peer);
1025 			goto fail;
1026 		}
1027 	} else
1028 		strlcpy(ctrl->phy_label, PPTP_CTRL_LISTENER_LABEL(ctrl),
1029 		    sizeof(ctrl->phy_label));
1030 
1031 	if ((ival = pptp_ctrl_config_int(ctrl, "pptp.echo_interval", 0)) != 0)
1032 		ctrl->echo_interval = ival;
1033 
1034 	if ((ival = pptp_ctrl_config_int(ctrl, "pptp.echo_timeout", 0)) != 0)
1035 		ctrl->echo_timeout = ival;
1036 
1037 	if (pptp_ctrl_start(ctrl) != 0)
1038 		goto fail;
1039 
1040 	slist_add(&_this->ctrl_list, ctrl);
1041 
1042 	return;
1043 fail:
1044 	close(sock);
1045 	pptp_ctrl_destroy(ctrl);
1046 	return;
1047 }
1048 
1049 void
1050 pptpd_ctrl_finished_notify(pptpd *_this, pptp_ctrl *ctrl)
1051 {
1052 	pptp_ctrl *ctrl1;
1053 	int i, nctrl;
1054 
1055 	PPTPD_ASSERT(_this != NULL);
1056 	PPTPD_ASSERT(ctrl != NULL);
1057 
1058 	nctrl = 0;
1059 	for (i = 0; i < slist_length(&_this->ctrl_list); i++) {
1060 		ctrl1 = slist_get(&_this->ctrl_list, i);
1061 		if (ctrl1 == ctrl) {
1062 			slist_remove(&_this->ctrl_list, i);
1063 			break;
1064 		}
1065 	}
1066 	pptp_ctrl_destroy(ctrl);
1067 
1068 	PPTPD_DBG((_this, LOG_DEBUG, "Remains %d ctrls", nctrl));
1069 	if (pptpd_is_shutting_down(_this) && nctrl == 0)
1070 		pptpd_stop_immediatly(_this);
1071 }
1072 
1073 /*
1074  * utility functions
1075  */
1076 
1077 /* logging with the this PPTP instance */
1078 static void
1079 pptpd_log(pptpd *_this, int prio, const char *fmt, ...)
1080 {
1081 	char logbuf[BUFSIZ];
1082 	va_list ap;
1083 
1084 	PPTPD_ASSERT(_this != NULL);
1085 	va_start(ap, fmt);
1086 #ifdef	PPTPD_MULITPLE
1087 	snprintf(logbuf, sizeof(logbuf), "pptpd id=%u %s", _this->id, fmt);
1088 #else
1089 	snprintf(logbuf, sizeof(logbuf), "pptpd %s", fmt);
1090 #endif
1091 	vlog_printf(prio, logbuf, ap);
1092 	va_end(ap);
1093 }
1094 
1095 static int
1096 pptp_call_cmp(const void *a0, const void *b0)
1097 {
1098 	return ((uint32_t)a0 - (uint32_t)b0);
1099 }
1100 
1101 static uint32_t
1102 pptp_call_hash(const void *ctx, int size)
1103 {
1104 	return (uint32_t)ctx % size;
1105 }
1106 
1107 /* convert GRE packet header to strings */
1108 static void
1109 pptp_gre_header_string(struct pptp_gre_header *grehdr, char *buf, int lbuf)
1110 {
1111 	snprintf(buf, lbuf,
1112 	    "[%s%s%s%s%s%s] ver=%d "
1113 	    "protocol_type=%04x payload_length=%d call_id=%d",
1114 	    (grehdr->C != 0)? "C" : "", (grehdr->R != 0)? "R" : "",
1115 	    (grehdr->K != 0)? "K" : "", (grehdr->S != 0)? "S" : "",
1116 	    (grehdr->s != 0)? "s" : "", (grehdr->A != 0)? "A" : "", grehdr->ver,
1117 	    grehdr->protocol_type, grehdr->payload_length, grehdr->call_id);
1118 }
1119