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