1 /* $OpenBSD: pptpd.c,v 1.33 2021/03/29 03:54:40 yasuoka 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.33 2021/03/29 03:54:40 yasuoka 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.33 2021/03/29 03:54:40 yasuoka Exp $ 34 */ 35 #include <sys/types.h> 36 #include <sys/socket.h> 37 #include <sys/sysctl.h> 38 #include <net/if.h> 39 #include <netinet/in.h> 40 #include <netinet/ip.h> 41 #include <netinet/ip_gre.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 <event.h> 54 55 #ifdef USE_LIBSOCKUTIL 56 #include <seil/sockfromto.h> 57 #endif 58 59 #include "net_utils.h" 60 #include "bytebuf.h" 61 #include "debugutil.h" 62 #include "hash.h" 63 #include "slist.h" 64 #include "addr_range.h" 65 66 #include "pptp.h" 67 #include "pptp_local.h" 68 #include "privsep.h" 69 #include "accept.h" 70 71 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 72 73 static int pptpd_seqno = 0; 74 75 #ifdef PPTPD_DEBUG 76 #define PPTPD_ASSERT(x) ASSERT(x) 77 #define PPTPD_DBG(x) pptpd_log x 78 #else 79 #define PPTPD_ASSERT(x) 80 #define PPTPD_DBG(x) 81 #endif 82 83 static void pptpd_log (pptpd *, int, const char *, ...) __printflike(3,4); 84 static void pptpd_close_gre (pptpd *); 85 static void pptpd_close_1723 (pptpd *); 86 static void pptpd_io_event (int, short, void *); 87 static void pptpd_gre_io_event (int, short, void *); 88 static void pptpd_gre_input (pptpd_listener *, struct sockaddr *, u_char *, int); 89 static void pptp_ctrl_start_by_pptpd (pptpd *, int, int, struct sockaddr *); 90 static int pptp_call_cmp (const void *, const void *); 91 static uint32_t pptp_call_hash (const void *, int); 92 static void pptp_gre_header_string (struct pptp_gre_header *, char *, int); 93 94 #define PPTPD_SHUFFLE_MARK -1 95 96 /* initialize pptp daemon */ 97 int 98 pptpd_init(pptpd *_this) 99 { 100 int i, m; 101 uint16_t call0, call[UINT16_MAX - 1]; 102 103 int mib[] = { CTL_NET, PF_INET, IPPROTO_GRE, GRECTL_ALLOW }; 104 int value; 105 size_t size; 106 size = sizeof(value); 107 108 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size, NULL, 0) == 0) { 109 if(value == 0) { 110 pptpd_log(_this, LOG_WARNING, "GRE protocol not allowed"); 111 } 112 } 113 114 memset(_this, 0, sizeof(pptpd)); 115 _this->id = pptpd_seqno++; 116 117 slist_init(&_this->ctrl_list); 118 slist_init(&_this->call_free_list); 119 120 /* randomize call id */ 121 for (i = 0; i < countof(call) ; i++) 122 call[i] = i + 1; 123 for (i = countof(call); i > 1; i--) { 124 m = arc4random_uniform(i); 125 call0 = call[m]; 126 call[m] = call[i - 1]; 127 call[i - 1] = call0; 128 } 129 130 for (i = 0; i < MINIMUM(PPTP_MAX_CALL, countof(call)); i++) 131 slist_add(&_this->call_free_list, (void *)(uintptr_t)call[i]); 132 slist_add(&_this->call_free_list, (void *)PPTPD_SHUFFLE_MARK); 133 134 if (_this->call_id_map == NULL) 135 _this->call_id_map = hash_create(pptp_call_cmp, pptp_call_hash, 136 0); 137 138 return 0; 139 } 140 141 /* add a listener to pptpd daemon context */ 142 int 143 pptpd_add_listener(pptpd *_this, int idx, struct pptp_conf *conf, 144 struct sockaddr *addr) 145 { 146 int inaddr_any; 147 pptpd_listener *plistener, *plstn; 148 149 plistener = NULL; 150 if (idx == 0 && slist_length(&_this->listener) > 0) { 151 slist_itr_first(&_this->listener); 152 while (slist_itr_has_next(&_this->listener)) { 153 slist_itr_next(&_this->listener); 154 plstn = slist_itr_remove(&_this->listener); 155 PPTPD_ASSERT(plstn != NULL); 156 PPTPD_ASSERT(plstn->sock == -1); 157 PPTPD_ASSERT(plstn->sock_gre == -1); 158 free(plstn); 159 } 160 } 161 PPTPD_ASSERT(slist_length(&_this->listener) == idx); 162 if (slist_length(&_this->listener) != idx) { 163 pptpd_log(_this, LOG_ERR, 164 "Invalid argument error on %s(): idx must be %d but %d", 165 __func__, slist_length(&_this->listener), idx); 166 goto fail; 167 } 168 if ((plistener = calloc(1, sizeof(pptpd_listener))) == NULL) { 169 pptpd_log(_this, LOG_ERR, "calloc() failed in %s: %m", 170 __func__); 171 goto fail; 172 } 173 174 PPTPD_ASSERT(sizeof(plistener->bind_sin) >= addr->sa_len); 175 memcpy(&plistener->bind_sin, addr, addr->sa_len); 176 memcpy(&plistener->bind_sin_gre, addr, addr->sa_len); 177 178 if (plistener->bind_sin.sin_port == 0) 179 plistener->bind_sin.sin_port = htons(PPTPD_DEFAULT_TCP_PORT); 180 181 /* When a raw socket binds both of an INADDR_ANY and specific IP 182 * address sockets, packets will be received by those sockets 183 * simultaneously. To avoid this duplicate receives, not 184 * permit such kind of configuration */ 185 inaddr_any = 0; 186 slist_itr_first(&_this->listener); 187 while (slist_itr_has_next(&_this->listener)) { 188 plstn = slist_itr_next(&_this->listener); 189 if (plstn->bind_sin_gre.sin_addr.s_addr == INADDR_ANY) 190 inaddr_any++; 191 } 192 if (plistener->bind_sin_gre.sin_addr.s_addr == INADDR_ANY) 193 inaddr_any++; 194 if (inaddr_any > 0 && idx > 0) { 195 log_printf(LOG_ERR, "configuration error at pptpd.listener_in: " 196 "combination 0.0.0.0 and other address is not allowed."); 197 goto fail; 198 } 199 200 plistener->bind_sin_gre.sin_port = 0; 201 plistener->sock = -1; 202 plistener->sock_gre = -1; 203 plistener->self = _this; 204 plistener->index = idx; 205 plistener->conf = conf; 206 strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name)); 207 208 if (slist_add(&_this->listener, plistener) == NULL) { 209 pptpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m", 210 __func__); 211 goto fail; 212 } 213 return 0; 214 fail: 215 free(plistener); 216 return 1; 217 } 218 219 void 220 pptpd_uninit(pptpd *_this) 221 { 222 pptpd_listener *plstn; 223 224 slist_fini(&_this->ctrl_list); 225 slist_fini(&_this->call_free_list); 226 227 slist_itr_first(&_this->listener); 228 while (slist_itr_has_next(&_this->listener)) { 229 plstn = slist_itr_next(&_this->listener); 230 PPTPD_ASSERT(plstn != NULL); 231 PPTPD_ASSERT(plstn->sock == -1); 232 PPTPD_ASSERT(plstn->sock_gre == -1); 233 free(plstn); 234 } 235 slist_fini(&_this->listener); 236 if (_this->call_id_map != NULL) 237 hash_free(_this->call_id_map); 238 _this->call_id_map = NULL; 239 } 240 241 #define CALL_ID_KEY(call_id, listener_idx) \ 242 ((void *)((uintptr_t)(call_id) | (listener_idx) << 16)) 243 #define CALL_KEY(call) \ 244 CALL_ID_KEY((call)->id, (call)->ctrl->listener_index) 245 int 246 pptpd_assign_call(pptpd *_this, pptp_call *call) 247 { 248 int shuffle_cnt = 0; 249 u_int call_id; 250 251 shuffle_cnt = 0; 252 slist_itr_first(&_this->call_free_list); 253 while (slist_length(&_this->call_free_list) > 1 && 254 slist_itr_has_next(&_this->call_free_list)) { 255 call_id = (uintptr_t)slist_itr_next(&_this->call_free_list); 256 if (call_id == 0) 257 break; 258 slist_itr_remove(&_this->call_free_list); 259 if (call_id == PPTPD_SHUFFLE_MARK) { 260 if (shuffle_cnt++ > 0) 261 break; 262 slist_shuffle(&_this->call_free_list); 263 slist_add(&_this->call_free_list, 264 (void *)PPTPD_SHUFFLE_MARK); 265 slist_itr_first(&_this->call_free_list); 266 continue; 267 } 268 call->id = call_id; 269 hash_insert(_this->call_id_map, CALL_KEY(call), call); 270 271 return 0; 272 } 273 errno = EBUSY; 274 pptpd_log(_this, LOG_ERR, "call request reached limit=%d", 275 PPTP_MAX_CALL); 276 return -1; 277 } 278 279 void 280 pptpd_release_call(pptpd *_this, pptp_call *call) 281 { 282 if (call->id != 0) 283 slist_add(&_this->call_free_list, (void *)(uintptr_t)call->id); 284 hash_delete(_this->call_id_map, CALL_KEY(call), 0); 285 call->id = 0; 286 } 287 288 static int 289 pptpd_listener_start(pptpd_listener *_this) 290 { 291 int sock, ival, sock_gre; 292 struct sockaddr_in bind_sin, bind_sin_gre; 293 int wildcardbinding; 294 295 wildcardbinding = 296 (_this->bind_sin.sin_addr.s_addr == INADDR_ANY)? 1 : 0; 297 sock = -1; 298 sock_gre = -1; 299 memcpy(&bind_sin, &_this->bind_sin, sizeof(bind_sin)); 300 memcpy(&bind_sin_gre, &_this->bind_sin_gre, sizeof(bind_sin_gre)); 301 302 if ((sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)) 303 < 0) { 304 pptpd_log(_this->self, LOG_ERR, "socket() failed at %s(): %m", 305 __func__); 306 goto fail; 307 } 308 ival = 1; 309 if(setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &ival, sizeof(ival)) < 0){ 310 pptpd_log(_this->self, LOG_WARNING, 311 "setsockopt(SO_REUSEPORT) failed at %s(): %m", __func__); 312 } 313 #if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF) 314 ival = 1; 315 if (setsockopt(sock, IPPROTO_IP, IP_STRICT_RCVIF, &ival, sizeof(ival)) 316 != 0) 317 pptpd_log(_this->self, LOG_WARNING, 318 "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__); 319 #endif 320 if (bind(sock, (struct sockaddr *)&_this->bind_sin, 321 _this->bind_sin.sin_len) != 0) { 322 pptpd_log(_this->self, LOG_ERR, 323 "bind(%s:%u) failed at %s(): %m", 324 inet_ntoa(_this->bind_sin.sin_addr), 325 ntohs(_this->bind_sin.sin_port), __func__); 326 goto fail; 327 } 328 if (listen(sock, PPTP_BACKLOG) != 0) { 329 pptpd_log(_this->self, LOG_ERR, 330 "listen(%s:%u) failed at %s(): %m", 331 inet_ntoa(_this->bind_sin.sin_addr), 332 ntohs(_this->bind_sin.sin_port), __func__); 333 goto fail; 334 } 335 pptpd_log(_this->self, LOG_INFO, "Listening %s:%u/tcp (PPTP PAC) [%s]", 336 inet_ntoa(_this->bind_sin.sin_addr), 337 ntohs(_this->bind_sin.sin_port), _this->tun_name); 338 339 /* GRE */ 340 bind_sin_gre.sin_port = 0; 341 if ((sock_gre = priv_socket(AF_INET, SOCK_RAW, IPPROTO_GRE)) < 0) { 342 pptpd_log(_this->self, LOG_ERR, "socket() failed at %s(): %m", 343 __func__); 344 goto fail; 345 } 346 #if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF) 347 ival = 1; 348 if (setsockopt(sock_gre, IPPROTO_IP, IP_STRICT_RCVIF, &ival, 349 sizeof(ival)) != 0) 350 pptpd_log(_this->self, LOG_WARNING, 351 "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__); 352 #endif 353 #ifdef IP_PIPEX 354 ival = 1; 355 if (setsockopt(sock_gre, IPPROTO_IP, IP_PIPEX, &ival, sizeof(ival)) 356 != 0) 357 pptpd_log(_this->self, LOG_WARNING, 358 "%s(): setsockopt(IP_PIPEX) failed: %m", __func__); 359 #endif 360 if ((ival = fcntl(sock_gre, F_GETFL)) < 0) { 361 pptpd_log(_this->self, LOG_ERR, 362 "fcntl(F_GET_FL) failed at %s(): %m", __func__); 363 goto fail; 364 } else if (fcntl(sock_gre, F_SETFL, ival | O_NONBLOCK) < 0) { 365 pptpd_log(_this->self, LOG_ERR, 366 "fcntl(F_SET_FL) failed at %s(): %m", __func__); 367 goto fail; 368 } 369 if (bind(sock_gre, (struct sockaddr *)&bind_sin_gre, 370 bind_sin_gre.sin_len) != 0) { 371 pptpd_log(_this->self, LOG_ERR, 372 "bind(%s:%u) failed at %s(): %m", 373 inet_ntoa(bind_sin_gre.sin_addr), 374 ntohs(bind_sin_gre.sin_port), __func__); 375 goto fail; 376 } 377 if (wildcardbinding) { 378 #ifdef USE_LIBSOCKUTIL 379 if (setsockoptfromto(sock) != 0) { 380 pptpd_log(_this->self, LOG_ERR, 381 "setsockoptfromto() failed in %s(): %m", __func__); 382 goto fail; 383 } 384 #else 385 /* nothing to do */ 386 #endif 387 } 388 pptpd_log(_this->self, LOG_INFO, "Listening %s:gre (PPTP PAC)", 389 inet_ntoa(bind_sin_gre.sin_addr)); 390 391 _this->sock = sock; 392 _this->sock_gre = sock_gre; 393 394 if (accept_add(_this->sock, pptpd_io_event, _this) != 0) { 395 pptpd_log(_this->self, LOG_ERR, 396 "accept_add() failed in %s(): %m", __func__); 397 goto fail; 398 } 399 400 event_set(&_this->ev_sock_gre, _this->sock_gre, EV_READ | EV_PERSIST, 401 pptpd_gre_io_event, _this); 402 event_add(&_this->ev_sock_gre, NULL); 403 404 return 0; 405 fail: 406 if (sock >= 0) 407 close(sock); 408 if (sock_gre >= 0) 409 close(sock_gre); 410 411 _this->sock = -1; 412 _this->sock_gre = -1; 413 414 return 1; 415 } 416 417 int 418 pptpd_start(pptpd *_this) 419 { 420 int rval = 0; 421 pptpd_listener *plistener; 422 423 slist_itr_first(&_this->listener); 424 while (slist_itr_has_next(&_this->listener)) { 425 plistener = slist_itr_next(&_this->listener); 426 PPTPD_ASSERT(plistener != NULL); 427 rval |= pptpd_listener_start(plistener); 428 } 429 if (rval == 0) 430 _this->state = PPTPD_STATE_RUNNING; 431 432 return rval; 433 } 434 435 static void 436 pptpd_listener_close_gre(pptpd_listener *_this) 437 { 438 if (_this->sock_gre >= 0) { 439 event_del(&_this->ev_sock_gre); 440 close(_this->sock_gre); 441 pptpd_log(_this->self, LOG_INFO, "Shutdown %s/gre", 442 inet_ntoa(_this->bind_sin_gre.sin_addr)); 443 } 444 _this->sock_gre = -1; 445 } 446 447 static void 448 pptpd_close_gre(pptpd *_this) 449 { 450 pptpd_listener *plistener; 451 452 slist_itr_first(&_this->listener); 453 while (slist_itr_has_next(&_this->listener)) { 454 plistener = slist_itr_next(&_this->listener); 455 pptpd_listener_close_gre(plistener); 456 } 457 } 458 459 static void 460 pptpd_listener_close_1723(pptpd_listener *_this) 461 { 462 if (_this->sock >= 0) { 463 accept_del(_this->sock); 464 close(_this->sock); 465 pptpd_log(_this->self, LOG_INFO, "Shutdown %s:%u/tcp", 466 inet_ntoa(_this->bind_sin.sin_addr), 467 ntohs(_this->bind_sin.sin_port)); 468 } 469 _this->sock = -1; 470 } 471 472 static void 473 pptpd_close_1723(pptpd *_this) 474 { 475 pptpd_listener *plistener; 476 477 slist_itr_first(&_this->listener); 478 while (slist_itr_has_next(&_this->listener)) { 479 plistener = slist_itr_next(&_this->listener); 480 pptpd_listener_close_1723(plistener); 481 } 482 } 483 484 void 485 pptpd_stop_immediatly(pptpd *_this) 486 { 487 pptp_ctrl *ctrl; 488 489 if (event_initialized(&_this->ev_timer)) 490 evtimer_del(&_this->ev_timer); 491 if (_this->state != PPTPD_STATE_STOPPED) { 492 /* lock, to avoid multiple call from pptp_ctrl_stop() */ 493 _this->state = PPTPD_STATE_STOPPED; 494 495 pptpd_close_1723(_this); 496 for (slist_itr_first(&_this->ctrl_list); 497 (ctrl = slist_itr_next(&_this->ctrl_list)) != NULL;) { 498 pptp_ctrl_stop(ctrl, 0); 499 } 500 pptpd_close_gre(_this); 501 slist_fini(&_this->ctrl_list); 502 slist_fini(&_this->call_free_list); 503 PPTPD_DBG((_this, LOG_DEBUG, "Stopped")); 504 } else { 505 PPTPD_DBG((_this, LOG_DEBUG, "(Already) Stopped")); 506 } 507 } 508 509 static void 510 pptpd_stop_timeout(int fd, short event, void *ctx) 511 { 512 pptpd *_this; 513 514 _this = ctx; 515 pptpd_stop_immediatly(_this); 516 } 517 518 void 519 pptpd_stop(pptpd *_this) 520 { 521 int nctrl; 522 pptp_ctrl *ctrl; 523 struct timeval tv; 524 525 if (event_initialized(&_this->ev_timer)) 526 evtimer_del(&_this->ev_timer); 527 pptpd_close_1723(_this); 528 529 /* XXX: use common procedure with l2tpd_stop */ 530 531 if (pptpd_is_stopped(_this)) 532 return; 533 if (pptpd_is_shutting_down(_this)) { 534 pptpd_stop_immediatly(_this); 535 return; 536 } 537 _this->state = PPTPD_STATE_SHUTTING_DOWN; 538 nctrl = 0; 539 for (slist_itr_first(&_this->ctrl_list); 540 (ctrl = slist_itr_next(&_this->ctrl_list)) != NULL;) { 541 pptp_ctrl_stop(ctrl, PPTP_CDN_RESULT_ADMIN_SHUTDOWN); 542 nctrl++; 543 } 544 if (nctrl > 0) { 545 tv.tv_sec = PPTPD_SHUTDOWN_TIMEOUT; 546 tv.tv_usec = 0; 547 548 evtimer_set(&_this->ev_timer, pptpd_stop_timeout, _this); 549 evtimer_add(&_this->ev_timer, &tv); 550 551 return; 552 } 553 pptpd_stop_immediatly(_this); 554 } 555 556 /* 557 * PPTP Configuration 558 */ 559 int 560 pptpd_reload(pptpd *_this, struct pptp_confs *pptp_conf) 561 { 562 int i; 563 struct pptp_conf *conf; 564 pptpd_listener *listener; 565 struct pptp_listen_addr *addr; 566 567 if (slist_length(&_this->listener) > 0) { 568 /* 569 * TODO: add / remove / restart listener. 570 */ 571 slist_itr_first(&_this->listener); 572 while (slist_itr_has_next(&_this->listener)) { 573 listener = slist_itr_next(&_this->listener); 574 TAILQ_FOREACH(conf, pptp_conf, entry) { 575 if (strcmp(listener->tun_name, 576 conf->name) == 0) { 577 listener->conf = conf; 578 break; 579 } 580 } 581 } 582 583 return 0; 584 } 585 586 i = 0; 587 TAILQ_FOREACH(conf, pptp_conf, entry) { 588 TAILQ_FOREACH(addr, &conf->listen, entry) 589 pptpd_add_listener(_this, i++, conf, 590 (struct sockaddr *)&addr->addr); 591 } 592 if (pptpd_start(_this) != 0) 593 return -1; 594 595 return 0; 596 } 597 598 /* 599 * I/O functions 600 */ 601 /* I/O event handler of 1723/tcp */ 602 static void 603 pptpd_io_event(int fd, short evmask, void *ctx) 604 { 605 int newsock; 606 const char *reason; 607 socklen_t peerlen; 608 struct sockaddr_storage peer; 609 pptpd *_this; 610 pptpd_listener *listener; 611 612 listener = ctx; 613 PPTPD_ASSERT(listener != NULL); 614 _this = listener->self; 615 PPTPD_ASSERT(_this != NULL); 616 617 if ((evmask & EV_READ) != 0) { 618 for (;;) { /* accept till EAGAIN occurred */ 619 peerlen = sizeof(peer); 620 if ((newsock = accept(listener->sock, 621 (struct sockaddr *)&peer, &peerlen)) < 0) { 622 if (errno != EAGAIN && errno == EINTR && 623 errno != ECONNABORTED) { 624 if (errno == EMFILE || errno == ENFILE) 625 accept_pause(); 626 pptpd_log(_this, LOG_ERR, 627 "accept() failed at %s(): %m", 628 __func__); 629 } 630 break; 631 } 632 /* check peer */ 633 switch (peer.ss_family) { 634 case AF_INET: 635 pptp_ctrl_start_by_pptpd(_this, newsock, 636 listener->index, (struct sockaddr *)&peer); 637 break; 638 default: 639 reason = "address family is not supported."; 640 break; 641 } 642 } 643 } 644 } 645 646 /* I/O event handler of GRE */ 647 static void 648 pptpd_gre_io_event(int fd, short evmask, void *ctx) 649 { 650 int sz; 651 u_char pkt[65535]; 652 socklen_t peerlen; 653 struct sockaddr_storage peer; 654 pptpd *_this; 655 pptpd_listener *listener; 656 657 listener = ctx; 658 PPTPD_ASSERT(listener != NULL); 659 _this = listener->self; 660 PPTPD_ASSERT(_this != NULL); 661 662 if (evmask & EV_READ) { 663 for (;;) { 664 /* read till bloked */ 665 peerlen = sizeof(peer); 666 if ((sz = recvfrom(listener->sock_gre, pkt, sizeof(pkt), 667 0, (struct sockaddr *)&peer, &peerlen)) == -1) { 668 if (errno == EAGAIN || errno == EINTR) 669 break; 670 pptpd_log(_this, LOG_INFO, 671 "read(GRE) failed: %m"); 672 pptpd_stop(_this); 673 return; 674 } 675 pptpd_gre_input(listener, (struct sockaddr *)&peer, pkt, 676 sz); 677 } 678 } 679 } 680 681 /* receive GRE then route to pptp_call */ 682 static void 683 pptpd_gre_input(pptpd_listener *listener, struct sockaddr *peer, u_char *pkt, 684 int lpkt) 685 { 686 int hlen, input_flags; 687 uint32_t seq, ack, call_id; 688 struct ip *iphdr; 689 struct pptp_gre_header *grehdr; 690 char hbuf0[NI_MAXHOST], logbuf[512]; 691 const char *reason; 692 pptp_call *call; 693 hash_link *hl; 694 pptpd *_this; 695 696 seq = 0; 697 ack = 0; 698 input_flags = 0; 699 reason = "No error"; 700 _this = listener->self; 701 702 PPTPD_ASSERT(peer->sa_family == AF_INET); 703 704 strlcpy(hbuf0, "<unknown>", sizeof(hbuf0)); 705 if (getnameinfo(peer, peer->sa_len, hbuf0, sizeof(hbuf0), NULL, 0, 706 NI_NUMERICHOST | NI_NUMERICSERV) != 0) { 707 pptpd_log(_this, LOG_ERR, 708 "getnameinfo() failed at %s(): %m", __func__); 709 goto fail; 710 } 711 if (listener->conf->data_in_pktdump != 0) { 712 pptpd_log(_this, LOG_DEBUG, "PPTP Data input packet dump"); 713 show_hd(debug_get_debugfp(), pkt, lpkt); 714 } 715 if (peer->sa_family != AF_INET) { 716 pptpd_log(_this, LOG_ERR, 717 "Received malformed GRE packet: address family is not " 718 "supported: peer=%s af=%d", hbuf0, peer->sa_family); 719 goto fail; 720 } 721 722 if (lpkt < sizeof(struct ip)) { 723 pptpd_log(_this, LOG_ERR, 724 "Received a short length packet length=%d, from %s", lpkt, 725 hbuf0); 726 goto fail; 727 } 728 iphdr = (struct ip *)pkt; 729 730 iphdr->ip_len = ntohs(iphdr->ip_len); 731 hlen = iphdr->ip_hl * 4; 732 733 if (iphdr->ip_len > lpkt || 734 iphdr->ip_len < hlen + sizeof(struct pptp_gre_header)) { 735 pptpd_log(_this, LOG_ERR, 736 "Received a broken packet: ip_hl=%d iplen=%d lpkt=%d", hlen, 737 iphdr->ip_len, lpkt); 738 show_hd(debug_get_debugfp(), pkt, lpkt); 739 goto fail; 740 } 741 pkt += hlen; 742 lpkt -= hlen; 743 grehdr = (struct pptp_gre_header *)pkt; 744 pkt += sizeof(struct pptp_gre_header); 745 lpkt -= sizeof(struct pptp_gre_header); 746 747 grehdr->protocol_type = htons(grehdr->protocol_type); 748 grehdr->payload_length = htons(grehdr->payload_length); 749 grehdr->call_id = htons(grehdr->call_id); 750 751 if (!(grehdr->protocol_type == PPTP_GRE_PROTOCOL_TYPE && 752 grehdr->C == 0 && grehdr->R == 0 && grehdr->K != 0 && 753 grehdr->recur == 0 && grehdr->s == 0 && grehdr->flags == 0 && 754 grehdr->ver == PPTP_GRE_VERSION)) { 755 reason = "GRE header is broken"; 756 goto bad_gre; 757 } 758 if (grehdr->S != 0) { 759 if (lpkt < 2) { 760 reason = "No enough space for seq number"; 761 goto bad_gre; 762 } 763 input_flags |= PPTP_GRE_PKT_SEQ_PRESENT; 764 seq = ntohl(*(uint32_t *)pkt); 765 pkt += 4; 766 lpkt -= 4; 767 } 768 769 if (grehdr->A != 0) { 770 if (lpkt < 2) { 771 reason = "No enough space for ack number"; 772 goto bad_gre; 773 } 774 input_flags |= PPTP_GRE_PKT_ACK_PRESENT; 775 ack = ntohl(*(uint32_t *)pkt); 776 pkt += 4; 777 lpkt -= 4; 778 } 779 780 if (grehdr->payload_length > lpkt) { 781 reason = "'Payload Length' is mismatch from actual length"; 782 goto bad_gre; 783 } 784 785 786 /* route to pptp_call */ 787 call_id = grehdr->call_id; 788 789 hl = hash_lookup(_this->call_id_map, CALL_ID_KEY(call_id, listener->index)); 790 if (hl == NULL) { 791 reason = "Received GRE packet has unknown call_id"; 792 goto bad_gre; 793 } 794 call = hl->item; 795 pptp_call_gre_input(call, seq, ack, input_flags, pkt, lpkt); 796 797 return; 798 bad_gre: 799 pptp_gre_header_string(grehdr, logbuf, sizeof(logbuf)); 800 pptpd_log(_this, LOG_INFO, 801 "Received malformed GRE packet: %s: peer=%s sock=%s %s seq=%u: " 802 "ack=%u ifidx=%d", reason, hbuf0, inet_ntoa(iphdr->ip_dst), logbuf, 803 seq, ack, listener->index); 804 fail: 805 return; 806 } 807 808 /* start PPTP control, when new connection is established */ 809 static void 810 pptp_ctrl_start_by_pptpd(pptpd *_this, int sock, int listener_index, 811 struct sockaddr *peer) 812 { 813 pptp_ctrl *ctrl; 814 socklen_t sslen; 815 816 ctrl = NULL; 817 if ((ctrl = pptp_ctrl_create()) == NULL) 818 goto fail; 819 if (pptp_ctrl_init(ctrl) != 0) 820 goto fail; 821 822 memset(&ctrl->peer, 0, sizeof(ctrl->peer)); 823 memcpy(&ctrl->peer, peer, peer->sa_len); 824 ctrl->pptpd = _this; 825 ctrl->sock = sock; 826 ctrl->listener_index = listener_index; 827 828 sslen = sizeof(ctrl->our); 829 if (getsockname(ctrl->sock, (struct sockaddr *)&ctrl->our, 830 &sslen) != 0) { 831 pptpd_log(_this, LOG_WARNING, 832 "getsockname() failed at %s(): %m", __func__); 833 goto fail; 834 } 835 836 if (PPTP_CTRL_CONF(ctrl)->echo_interval != 0) 837 ctrl->echo_interval = PPTP_CTRL_CONF(ctrl)->echo_interval; 838 if (PPTP_CTRL_CONF(ctrl)->echo_timeout != 0) 839 ctrl->echo_timeout = PPTP_CTRL_CONF(ctrl)->echo_timeout; 840 841 if (pptp_ctrl_start(ctrl) != 0) 842 goto fail; 843 844 slist_add(&_this->ctrl_list, ctrl); 845 846 return; 847 fail: 848 close(sock); 849 pptp_ctrl_destroy(ctrl); 850 return; 851 } 852 853 void 854 pptpd_ctrl_finished_notify(pptpd *_this, pptp_ctrl *ctrl) 855 { 856 pptp_ctrl *ctrl1; 857 int i, nctrl; 858 859 PPTPD_ASSERT(_this != NULL); 860 PPTPD_ASSERT(ctrl != NULL); 861 862 accept_unpause(); 863 864 nctrl = 0; 865 for (i = 0; i < slist_length(&_this->ctrl_list); i++) { 866 ctrl1 = slist_get(&_this->ctrl_list, i); 867 if (ctrl1 == ctrl) { 868 slist_remove(&_this->ctrl_list, i); 869 break; 870 } 871 } 872 pptp_ctrl_destroy(ctrl); 873 874 PPTPD_DBG((_this, LOG_DEBUG, "Remains %d ctrls", nctrl)); 875 if (pptpd_is_shutting_down(_this) && nctrl == 0) 876 pptpd_stop_immediatly(_this); 877 } 878 879 /* 880 * utility functions 881 */ 882 883 /* logging with the this PPTP instance */ 884 static void 885 pptpd_log(pptpd *_this, int prio, const char *fmt, ...) 886 { 887 char logbuf[BUFSIZ]; 888 va_list ap; 889 890 PPTPD_ASSERT(_this != NULL); 891 va_start(ap, fmt); 892 #ifdef PPTPD_MULTIPLE 893 snprintf(logbuf, sizeof(logbuf), "pptpd id=%u %s", _this->id, fmt); 894 #else 895 snprintf(logbuf, sizeof(logbuf), "pptpd %s", fmt); 896 #endif 897 vlog_printf(prio, logbuf, ap); 898 va_end(ap); 899 } 900 901 static int 902 pptp_call_cmp(const void *a0, const void *b0) 903 { 904 return ((intptr_t)a0 - (intptr_t)b0); 905 } 906 907 static uint32_t 908 pptp_call_hash(const void *ctx, int size) 909 { 910 return (uintptr_t)ctx % size; 911 } 912 913 /* convert GRE packet header to strings */ 914 static void 915 pptp_gre_header_string(struct pptp_gre_header *grehdr, char *buf, int lbuf) 916 { 917 snprintf(buf, lbuf, 918 "[%s%s%s%s%s%s] ver=%d " 919 "protocol_type=%04x payload_length=%d call_id=%d", 920 (grehdr->C != 0)? "C" : "", (grehdr->R != 0)? "R" : "", 921 (grehdr->K != 0)? "K" : "", (grehdr->S != 0)? "S" : "", 922 (grehdr->s != 0)? "s" : "", (grehdr->A != 0)? "A" : "", grehdr->ver, 923 grehdr->protocol_type, grehdr->payload_length, grehdr->call_id); 924 } 925