1 /* $OpenBSD: pptp_ctrl.c,v 1.13 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 /**@file 29 * PPTP(RFC 2637) control connection implementation. 30 * currently it only support PAC part 31 */ 32 /* $Id: pptp_ctrl.c,v 1.13 2021/03/29 03:54:40 yasuoka Exp $ */ 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 #include <netinet/in.h> 36 #include <stdio.h> 37 #include <stdarg.h> 38 #include <stdlib.h> 39 #include <netdb.h> 40 #include <unistd.h> 41 #include <syslog.h> 42 #include <time.h> 43 #include <fcntl.h> 44 #include <errno.h> 45 #include <string.h> 46 #include <event.h> 47 48 #include "bytebuf.h" 49 #include "debugutil.h" 50 #include "hash.h" 51 #include "slist.h" 52 #include "time_utils.h" 53 54 #include "version.h" 55 56 #include "pptp.h" 57 #include "pptp_local.h" 58 #include "pptp_subr.h" 59 60 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 61 #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) 62 63 /* periods of pptp_ctrl_timeout */ 64 #define PPTP_CTRL_TIMEOUT_IVAL_SEC 2 65 66 #ifdef PPTP_CTRL_DEBUG 67 #define PPTP_CTRL_ASSERT(x) ASSERT(x) 68 #define PPTP_CTRL_DBG(x) pptp_ctrl_log x 69 #else 70 #define PPTP_CTRL_ASSERT(x) 71 #define PPTP_CTRL_DBG(x) 72 #endif 73 74 static unsigned pptp_ctrl_seqno = 0; 75 76 static void pptp_ctrl_log (pptp_ctrl *, int, const char *, ...) __printflike(3,4); 77 static void pptp_ctrl_timeout (int, short, void *); 78 static void pptp_ctrl_reset_timeout (pptp_ctrl *); 79 static void pptp_ctrl_io_event (int, short, void *); 80 static void pptp_ctrl_set_io_event (pptp_ctrl *); 81 static int pptp_ctrl_output_flush (pptp_ctrl *); 82 static void pptp_ctrl_SCCRx_string (struct pptp_scc *, u_char *, int); 83 static int pptp_ctrl_recv_SCCRQ (pptp_ctrl *, u_char *, int); 84 static int pptp_ctrl_recv_StopCCRP (pptp_ctrl *, u_char *, int); 85 static int pptp_ctrl_send_StopCCRQ (pptp_ctrl *, int); 86 static int pptp_ctrl_recv_StopCCRQ (pptp_ctrl *, u_char *, int); 87 static int pptp_ctrl_send_StopCCRP (pptp_ctrl *, int, int); 88 static int pptp_ctrl_send_SCCRP (pptp_ctrl *, int, int); 89 static void pptp_ctrl_send_CDN (pptp_ctrl *, int, int, int, const char *); 90 static void pptp_ctrl_process_echo_req (pptp_ctrl *, u_char *, int); 91 static int pptp_ctrl_recv_echo_rep (pptp_ctrl *, u_char *, int); 92 static void pptp_ctrl_send_echo_req (pptp_ctrl *); 93 static int pptp_ctrl_input (pptp_ctrl *, u_char *, int); 94 static int pptp_ctrl_call_input (pptp_ctrl *, int, u_char *, int); 95 static const char *pptp_ctrl_state_string (int); 96 static void pptp_ctrl_fini(pptp_ctrl *); 97 98 /* 99 * pptp_ctrl instance operation functions 100 */ 101 pptp_ctrl * 102 pptp_ctrl_create(void) 103 { 104 pptp_ctrl *_this; 105 106 if ((_this = malloc(sizeof(pptp_ctrl))) == NULL) 107 return NULL; 108 109 return _this; 110 } 111 112 int 113 pptp_ctrl_init(pptp_ctrl *_this) 114 { 115 time_t curr_time; 116 117 PPTP_CTRL_ASSERT(_this != NULL); 118 curr_time = get_monosec(); 119 memset(_this, 0, sizeof(pptp_ctrl)); 120 _this->id = pptp_ctrl_seqno++; 121 _this->sock = -1; 122 123 if ((_this->recv_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) { 124 pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at " 125 "%s(): %m", __func__); 126 goto fail; 127 } 128 if ((_this->send_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) { 129 pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at " 130 "%s(): %m", __func__); 131 goto fail; 132 } 133 _this->last_rcv_ctrl = curr_time; 134 _this->last_snd_ctrl = curr_time; 135 _this->echo_seq = arc4random(); 136 _this->echo_interval = PPTP_CTRL_DEFAULT_ECHO_INTERVAL; 137 _this->echo_timeout = PPTP_CTRL_DEFAULT_ECHO_TIMEOUT; 138 slist_init(&_this->call_list); 139 evtimer_set(&_this->ev_timer, pptp_ctrl_timeout, _this); 140 141 return 0; 142 fail: 143 return 1; 144 } 145 146 int 147 pptp_ctrl_start(pptp_ctrl *_this) 148 { 149 int ival; 150 char hbuf0[NI_MAXHOST], sbuf0[NI_MAXSERV]; 151 char hbuf1[NI_MAXHOST], sbuf1[NI_MAXSERV]; 152 struct sockaddr_storage sock; 153 socklen_t socklen; 154 155 PPTP_CTRL_ASSERT(_this != NULL); 156 PPTP_CTRL_ASSERT(_this->sock >= 0); 157 158 /* convert address to strings for logging */ 159 strlcpy(hbuf0, "<unknown>", sizeof(hbuf0)); 160 strlcpy(sbuf0, "<unknown>", sizeof(sbuf0)); 161 strlcpy(hbuf1, "<unknown>", sizeof(hbuf1)); 162 strlcpy(sbuf1, "<unknown>", sizeof(sbuf1)); 163 if (getnameinfo((struct sockaddr *)&_this->peer, _this->peer.ss_len, 164 hbuf0, sizeof(hbuf0), sbuf0, sizeof(sbuf0), 165 NI_NUMERICHOST | NI_NUMERICSERV) != 0) { 166 pptp_ctrl_log(_this, LOG_ERR, 167 "getnameinfo() failed at %s(): %m", __func__); 168 } 169 socklen = sizeof(sock); 170 if (getsockname(_this->sock, (struct sockaddr *)&sock, &socklen) != 0) { 171 pptp_ctrl_log(_this, LOG_ERR, 172 "getsockname() failed at %s(): %m", __func__); 173 goto fail; 174 } 175 if (getnameinfo((struct sockaddr *)&sock, sock.ss_len, hbuf1, 176 sizeof(hbuf1), sbuf1, sizeof(sbuf1), 177 NI_NUMERICHOST | NI_NUMERICSERV) != 0) { 178 pptp_ctrl_log(_this, LOG_ERR, 179 "getnameinfo() failed at %s(): %m", __func__); 180 } 181 pptp_ctrl_log(_this, LOG_INFO, "Starting peer=%s:%s/tcp " 182 "sock=%s:%s/tcp", hbuf0, sbuf0, hbuf1, sbuf1); 183 184 if ((ival = fcntl(_this->sock, F_GETFL)) < 0) { 185 pptp_ctrl_log(_this, LOG_ERR, 186 "fcntl(F_GET_FL) failed at %s(): %m", __func__); 187 goto fail; 188 } else if (fcntl(_this->sock, F_SETFL, ival | O_NONBLOCK) < 0) { 189 pptp_ctrl_log(_this, LOG_ERR, 190 "fcntl(F_SET_FL) failed at %s(): %m", __func__); 191 goto fail; 192 } 193 pptp_ctrl_set_io_event(_this); 194 pptp_ctrl_reset_timeout(_this); 195 196 return 0; 197 fail: 198 return 1; 199 } 200 201 /* Timer */ 202 static void 203 pptp_ctrl_timeout(int fd, short event, void *ctx) 204 { 205 int i; 206 pptp_call *call; 207 pptp_ctrl *_this; 208 time_t last, curr_time; 209 210 _this = ctx; 211 curr_time = get_monosec(); 212 213 PPTP_CTRL_DBG((_this, DEBUG_LEVEL_3, "enter %s()", __func__)); 214 /* clean up call */ 215 i = 0; 216 while (i < slist_length(&_this->call_list)) { 217 call = slist_get(&_this->call_list, i); 218 if (call->state == PPTP_CALL_STATE_CLEANUP_WAIT && 219 curr_time - call->last_io > PPTP_CALL_CLEANUP_WAIT_TIME) { 220 pptp_call_stop(call); 221 pptp_call_destroy(call); 222 slist_remove(&_this->call_list, i); 223 } else 224 i++; 225 } 226 227 /* State machine: Timeout */ 228 switch (_this->state) { 229 default: 230 case PPTP_CTRL_STATE_WAIT_CTRL_REPLY: 231 case PPTP_CTRL_STATE_IDLE: 232 if (curr_time - _this->last_rcv_ctrl > PPTPD_IDLE_TIMEOUT) { 233 pptp_ctrl_log(_this, LOG_ERR, 234 "Timeout in state %s", 235 pptp_ctrl_state_string(_this->state)); 236 pptp_ctrl_fini(_this); 237 return; 238 } 239 break; 240 case PPTP_CTRL_STATE_ESTABLISHED: 241 last = MAXIMUM(_this->last_rcv_ctrl, _this->last_snd_ctrl); 242 243 if (curr_time - _this->last_rcv_ctrl 244 >= _this->echo_interval + _this->echo_timeout) { 245 pptp_ctrl_log(_this, LOG_INFO, 246 "Timeout waiting for echo reply"); 247 pptp_ctrl_fini(_this); 248 return; 249 } 250 if (curr_time - last >= _this->echo_interval) { 251 PPTP_CTRL_DBG((_this, LOG_DEBUG, "Echo")); 252 _this->echo_seq++; 253 pptp_ctrl_send_echo_req(_this); 254 } 255 break; 256 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 257 if (curr_time - _this->last_snd_ctrl > 258 PPTP_CTRL_StopCCRP_WAIT_TIME) { 259 pptp_ctrl_log(_this, LOG_WARNING, 260 "Timeout waiting for StopCCRP"); 261 pptp_ctrl_fini(_this); 262 return; 263 } 264 break; 265 case PPTP_CTRL_STATE_DISPOSING: 266 pptp_ctrl_fini(_this); 267 return; 268 } 269 pptp_ctrl_reset_timeout(_this); 270 } 271 272 static void 273 pptp_ctrl_reset_timeout(pptp_ctrl *_this) 274 { 275 struct timeval tv; 276 277 switch (_this->state) { 278 case PPTP_CTRL_STATE_DISPOSING: 279 /* call back immediately */ 280 timerclear(&tv); 281 break; 282 default: 283 tv.tv_sec = PPTP_CTRL_TIMEOUT_IVAL_SEC; 284 tv.tv_usec = 0; 285 break; 286 } 287 evtimer_add(&_this->ev_timer, &tv); 288 } 289 290 /** 291 * Terminate PPTP control connection 292 * @result The value for Stop-Control-Connection-Request(StopCCRQ) result. 293 This function will not sent StopCCRQ when the value == 0 and 294 the specification does not require to sent it. 295 * @see ::#PPTP_StopCCRQ_REASON_STOP_PROTOCOL 296 * @see ::#PPTP_StopCCRQ_REASON_STOP_LOCAL_SHUTDOWN 297 */ 298 void 299 pptp_ctrl_stop(pptp_ctrl *_this, int result) 300 { 301 int i; 302 pptp_call *call; 303 304 switch (_this->state) { 305 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 306 /* waiting response. */ 307 /* this state will timeout by pptp_ctrl_timeout */ 308 break; 309 case PPTP_CTRL_STATE_ESTABLISHED: 310 if (result != 0) { 311 for (i = 0; i < slist_length(&_this->call_list); i++) { 312 call = slist_get(&_this->call_list, i); 313 pptp_call_disconnect(call, 314 PPTP_CDN_RESULT_ADMIN_SHUTDOWN, 0, NULL); 315 } 316 pptp_ctrl_send_StopCCRQ(_this, result); 317 _this->state = PPTP_CTRL_STATE_WAIT_STOP_REPLY; 318 break; 319 } 320 /* FALLTHROUGH */ 321 default: 322 pptp_ctrl_fini(_this); 323 } 324 return; 325 } 326 327 328 /* finish PPTP control */ 329 static void 330 pptp_ctrl_fini(pptp_ctrl *_this) 331 { 332 pptp_call *call; 333 334 PPTP_CTRL_ASSERT(_this != NULL); 335 336 if (_this->sock >= 0) { 337 event_del(&_this->ev_sock); 338 close(_this->sock); 339 _this->sock = -1; 340 } 341 for (slist_itr_first(&_this->call_list); 342 slist_itr_has_next(&_this->call_list);) { 343 call = slist_itr_next(&_this->call_list); 344 pptp_call_stop(call); 345 pptp_call_destroy(call); 346 slist_itr_remove(&_this->call_list); 347 } 348 349 if (_this->on_io_event != 0) { 350 /* 351 * as the complete terminate process needs complicated 352 * exception handling, do partially at here. 353 * rest of part will be handled by timer-event-handler. 354 */ 355 PPTP_CTRL_DBG((_this, LOG_DEBUG, "Disposing")); 356 _this->state = PPTP_CTRL_STATE_DISPOSING; 357 pptp_ctrl_reset_timeout(_this); 358 return; 359 } 360 361 evtimer_del(&_this->ev_timer); 362 slist_fini(&_this->call_list); 363 364 pptp_ctrl_log (_this, LOG_NOTICE, "logtype=Finished"); 365 366 /* disable _this */ 367 pptpd_ctrl_finished_notify(_this->pptpd, _this); 368 } 369 370 /* free PPTP control context */ 371 void 372 pptp_ctrl_destroy(pptp_ctrl *_this) 373 { 374 if (_this->send_buf != NULL) { 375 bytebuffer_destroy(_this->send_buf); 376 _this->send_buf = NULL; 377 } 378 if (_this->recv_buf != NULL) { 379 bytebuffer_destroy(_this->recv_buf); 380 _this->recv_buf = NULL; 381 } 382 free(_this); 383 } 384 385 /* 386 * network I/O 387 */ 388 /* I/O event dispather */ 389 static void 390 pptp_ctrl_io_event(int fd, short evmask, void *ctx) 391 { 392 int sz, lpkt, hdrlen; 393 u_char *pkt; 394 pptp_ctrl *_this; 395 396 _this = ctx; 397 PPTP_CTRL_ASSERT(_this != NULL); 398 399 _this->on_io_event = 1; 400 if ((evmask & EV_WRITE) != 0) { 401 if (pptp_ctrl_output_flush(_this) != 0 || 402 _this->state == PPTP_CTRL_STATE_DISPOSING) 403 goto fail; 404 _this->send_ready = 1; 405 } 406 if ((evmask & EV_READ) != 0) { 407 sz = read(_this->sock, bytebuffer_pointer(_this->recv_buf), 408 bytebuffer_remaining(_this->recv_buf)); 409 if (sz <= 0) { 410 if (sz == 0 || errno == ECONNRESET) { 411 pptp_ctrl_log(_this, LOG_INFO, 412 "Connection closed by foreign host"); 413 pptp_ctrl_fini(_this); 414 goto fail; 415 } else if (errno != EAGAIN && errno != EINTR) { 416 pptp_ctrl_log(_this, LOG_INFO, 417 "read() failed at %s(): %m", __func__); 418 pptp_ctrl_fini(_this); 419 goto fail; 420 } 421 } 422 bytebuffer_put(_this->recv_buf, BYTEBUFFER_PUT_DIRECT, sz); 423 bytebuffer_flip(_this->recv_buf); 424 425 for (;;) { 426 pkt = bytebuffer_pointer(_this->recv_buf); 427 lpkt = bytebuffer_remaining(_this->recv_buf); 428 if (pkt == NULL || 429 lpkt < sizeof(struct pptp_ctrl_header)) 430 break; /* read again */ 431 432 hdrlen = pkt[0] << 8 | pkt[1]; 433 if (lpkt < hdrlen) 434 break; /* read again */ 435 436 bytebuffer_get(_this->recv_buf, NULL, hdrlen); 437 if (pptp_ctrl_input(_this, pkt, hdrlen) != 0 || 438 _this->state == PPTP_CTRL_STATE_DISPOSING) { 439 bytebuffer_compact(_this->recv_buf); 440 goto fail; 441 } 442 } 443 bytebuffer_compact(_this->recv_buf); 444 } 445 if (pptp_ctrl_output_flush(_this) != 0) 446 goto fail; 447 pptp_ctrl_set_io_event(_this); 448 fail: 449 _this->on_io_event = 0; 450 } 451 452 453 /* set i/o event mask */ 454 static void 455 pptp_ctrl_set_io_event(pptp_ctrl *_this) 456 { 457 int evmask; 458 459 PPTP_CTRL_ASSERT(_this != NULL); 460 PPTP_CTRL_ASSERT(_this->sock >= 0); 461 462 evmask = 0; 463 if (bytebuffer_remaining(_this->recv_buf) > 128) 464 evmask |= EV_READ; 465 if (_this->send_ready == 0) 466 evmask |= EV_WRITE; 467 468 event_del(&_this->ev_sock); 469 if (evmask != 0) { 470 event_set(&_this->ev_sock, _this->sock, evmask, 471 pptp_ctrl_io_event, _this); 472 event_add(&_this->ev_sock, NULL); 473 } 474 } 475 476 /** 477 * Output PPTP control packet 478 * @param pkt pointer to packet buffer. 479 * when it was appended by _this-.send_buf using bytebuffer, 480 * specify NULL. 481 * @param lpkt packet length 482 */ 483 void 484 pptp_ctrl_output(pptp_ctrl *_this, u_char *pkt, int lpkt) 485 { 486 PPTP_CTRL_ASSERT(_this != NULL); 487 PPTP_CTRL_ASSERT(lpkt > 0); 488 489 /* just put the packet into the buffer now. send it later */ 490 bytebuffer_put(_this->send_buf, pkt, lpkt); 491 492 if (_this->on_io_event != 0) { 493 /* 494 * pptp_ctrl_output_flush() will be called by the end of 495 * the I/O event handler. 496 */ 497 } else { 498 /* 499 * When this function is called by other than I/O event handler, 500 * we need to call pptp_ctrl_output_flush(). However if we do 501 * it here, then we need to consider the situation 502 * 'flush => write failure => finalize'. The situation requires 503 * the caller function to handle the exception and causes 504 * complication. So we call pptp_ctrl_output_flush() by the 505 * the next send ready event. 506 */ 507 _this->send_ready = 0; /* clear 'send ready' */ 508 pptp_ctrl_set_io_event(_this); /* wait 'send ready */ 509 } 510 511 return; 512 } 513 514 /* Send Stop-Control-Connection-Request */ 515 516 /* flush output packet */ 517 static int 518 pptp_ctrl_output_flush(pptp_ctrl *_this) 519 { 520 int sz; 521 time_t curr_time; 522 523 curr_time = get_monosec(); 524 525 if (bytebuffer_position(_this->send_buf) <= 0) 526 return 0; /* nothing to write */ 527 if (_this->send_ready == 0) { 528 pptp_ctrl_set_io_event(_this); 529 return 0; /* not ready to write */ 530 } 531 532 bytebuffer_flip(_this->send_buf); 533 534 if (PPTP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) { 535 pptp_ctrl_log(_this, LOG_DEBUG, "PPTP Control output packet"); 536 show_hd(debug_get_debugfp(), 537 bytebuffer_pointer(_this->send_buf), 538 bytebuffer_remaining(_this->send_buf)); 539 } 540 if ((sz = write(_this->sock, bytebuffer_pointer(_this->send_buf), 541 bytebuffer_remaining(_this->send_buf))) < 0) { 542 pptp_ctrl_log(_this, LOG_ERR, "write to socket failed: %m"); 543 pptp_ctrl_fini(_this); 544 545 return 1; 546 } 547 _this->last_snd_ctrl = curr_time; 548 bytebuffer_get(_this->send_buf, NULL, sz); 549 bytebuffer_compact(_this->send_buf); 550 _this->send_ready = 0; 551 552 return 0; 553 } 554 555 /* convert Start-Control-Connection-{Request,Reply} packet to strings */ 556 static void 557 pptp_ctrl_SCCRx_string(struct pptp_scc *scc, u_char *buf, int lbuf) 558 { 559 char results[128]; 560 561 if (scc->result_code != 0) 562 snprintf(results, sizeof(results), "result=%d error=%d ", 563 scc->result_code, scc->error_code); 564 else 565 results[0] = '\0'; 566 567 snprintf(buf, lbuf, 568 "protocol_version=%d.%d %sframing=%s bearer=%s max_channels=%d " 569 "firmware_revision=%d(0x%04x) host_name=\"%.*s\" " 570 "vendor_string=\"%.*s\"", 571 scc->protocol_version >> 8, scc->protocol_version & 0xff, results, 572 pptp_framing_string(scc->framing_caps), 573 pptp_bearer_string(scc->bearer_caps), scc->max_channels, 574 scc->firmware_revision, scc->firmware_revision, 575 (u_int)sizeof(scc->host_name), scc->host_name, 576 (u_int)sizeof(scc->vendor_string), scc->vendor_string); 577 } 578 579 /* receive Start-Control-Connection-Request */ 580 static int 581 pptp_ctrl_recv_SCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt) 582 { 583 char logbuf[512]; 584 struct pptp_scc *scc; 585 586 /* sanity check */ 587 if (lpkt < sizeof(struct pptp_scc)) { 588 pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: packet too " 589 "short: %d < %d", lpkt, (int)sizeof(struct pptp_scc)); 590 return 1; 591 } 592 scc = (struct pptp_scc *)pkt; 593 594 scc->protocol_version = ntohs(scc->protocol_version); 595 scc->framing_caps = htonl(scc->framing_caps); 596 scc->bearer_caps = htonl(scc->bearer_caps); 597 scc->max_channels = htons(scc->max_channels); 598 scc->firmware_revision = htons(scc->firmware_revision); 599 600 /* check protocol version */ 601 if (scc->protocol_version != PPTP_RFC_2637_VERSION) { 602 pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: " 603 "unknown protocol version %d", scc->protocol_version); 604 return 1; 605 } 606 607 pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf)); 608 pptp_ctrl_log(_this, LOG_INFO, "RecvSCCRQ %s", logbuf); 609 610 return 0; 611 } 612 613 /* Receive Stop-Control-Connection-Reply */ 614 static int 615 pptp_ctrl_recv_StopCCRP(pptp_ctrl *_this, u_char *pkt, int lpkt) 616 { 617 struct pptp_stop_ccrp *stop_ccrp; 618 619 if (lpkt < sizeof(struct pptp_stop_ccrp)) { 620 pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRP: packet " 621 "too short: %d < %d", lpkt, 622 (int)sizeof(struct pptp_stop_ccrp)); 623 return 1; 624 } 625 stop_ccrp = (struct pptp_stop_ccrp *)pkt; 626 627 pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRP reason=%s(%u)", 628 pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result); 629 630 return 0; 631 } 632 633 static int 634 pptp_ctrl_send_StopCCRQ(pptp_ctrl *_this, int reason) 635 { 636 int lpkt; 637 struct pptp_stop_ccrq *stop_ccrq; 638 639 stop_ccrq = bytebuffer_pointer(_this->send_buf); 640 lpkt = bytebuffer_remaining(_this->send_buf); 641 if (lpkt < sizeof(struct pptp_stop_ccrq)) { 642 pptp_ctrl_log(_this, LOG_ERR, 643 "SendCCRP failed: No buffer space available"); 644 return -1; 645 } 646 memset(stop_ccrq, 0, sizeof(struct pptp_stop_ccrq)); 647 648 pptp_init_header(&stop_ccrq->header, sizeof(struct pptp_stop_ccrq), 649 PPTP_CTRL_MES_CODE_StopCCRQ); 650 651 stop_ccrq->reason = reason; 652 653 pptp_ctrl_log(_this, LOG_INFO, "SendStopCCRQ reason=%s(%u)", 654 pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason); 655 656 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrq)); 657 658 return 0; 659 } 660 661 /* Receive Stop-Control-Connection-Request */ 662 static int 663 pptp_ctrl_recv_StopCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt) 664 { 665 struct pptp_stop_ccrq *stop_ccrq; 666 667 if (lpkt < sizeof(struct pptp_stop_ccrq)) { 668 pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRQ: packet " 669 "too short: %d < %d", lpkt, 670 (int)sizeof(struct pptp_stop_ccrq)); 671 return 1; 672 } 673 stop_ccrq = (struct pptp_stop_ccrq *)pkt; 674 675 pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRQ reason=%s(%u)", 676 pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason); 677 678 return 0; 679 } 680 681 /* Send Stop-Control-Connection-Reply */ 682 static int 683 pptp_ctrl_send_StopCCRP(pptp_ctrl *_this, int result, int error) 684 { 685 int lpkt; 686 struct pptp_stop_ccrp *stop_ccrp; 687 688 stop_ccrp = bytebuffer_pointer(_this->send_buf); 689 690 lpkt = bytebuffer_remaining(_this->send_buf); 691 if (lpkt < sizeof(struct pptp_stop_ccrp)) { 692 pptp_ctrl_log(_this, LOG_ERR, 693 "SendCCRQ failed: No buffer space available"); 694 return -1; 695 } 696 memset(stop_ccrp, 0, sizeof(struct pptp_stop_ccrp)); 697 698 pptp_init_header(&stop_ccrp->header, sizeof(struct pptp_stop_ccrp), 699 PPTP_CTRL_MES_CODE_StopCCRP); 700 701 stop_ccrp->result = result; 702 stop_ccrp->error = error; 703 704 pptp_ctrl_log(_this, LOG_INFO, 705 "SendStopCCRP result=%s(%u) error=%s(%u)", 706 pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result, 707 pptp_general_error_string(stop_ccrp->error), stop_ccrp->error); 708 709 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrp)); 710 711 return 0; 712 } 713 714 /* Send Start-Control-Connection-Reply */ 715 static int 716 pptp_ctrl_send_SCCRP(pptp_ctrl *_this, int result, int error) 717 { 718 int lpkt; 719 struct pptp_scc *scc; 720 char logbuf[512]; 721 const char *val; 722 723 scc = bytebuffer_pointer(_this->send_buf); 724 lpkt = bytebuffer_remaining(_this->send_buf); 725 if (lpkt < sizeof(struct pptp_scc)) { 726 pptp_ctrl_log(_this, LOG_ERR, 727 "SendSCCRP failed: No buffer space available"); 728 return -1; 729 } 730 memset(scc, 0, sizeof(struct pptp_scc)); 731 732 pptp_init_header(&scc->header, sizeof(struct pptp_scc), 733 PPTP_CTRL_MES_CODE_SCCRP); 734 735 scc->protocol_version = PPTP_RFC_2637_VERSION; 736 scc->result_code = result; 737 scc->error_code = error; 738 739 /* XXX only support sync frames */ 740 scc->framing_caps = PPTP_CTRL_FRAMING_SYNC; 741 scc->bearer_caps = PPTP_CTRL_BEARER_DIGITAL; 742 743 scc->max_channels = 4; /* XXX */ 744 scc->firmware_revision = MAJOR_VERSION << 8 | MINOR_VERSION; 745 746 /* this implementation only support these strings up to 747 * 63 character */ 748 /* host name */ 749 750 if ((val = PPTP_CTRL_CONF(_this)->hostname) == NULL) 751 val = ""; 752 strlcpy(scc->host_name, val, sizeof(scc->host_name)); 753 754 /* vendor name */ 755 if (PPTP_CTRL_CONF(_this)->vendor_name == NULL) 756 val = PPTPD_DEFAULT_VENDOR_NAME; 757 strlcpy(scc->vendor_string, val, sizeof(scc->vendor_string)); 758 759 pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf)); 760 pptp_ctrl_log(_this, LOG_INFO, "SendSCCRP %s", logbuf); 761 762 scc->protocol_version = htons(scc->protocol_version); 763 scc->framing_caps = htonl(scc->framing_caps); 764 scc->bearer_caps = htonl(scc->bearer_caps); 765 scc->max_channels = htons(scc->max_channels); 766 scc->firmware_revision = htons(scc->firmware_revision); 767 768 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_scc)); 769 770 return 0; 771 } 772 773 /* receive ECHO and reply */ 774 static void 775 pptp_ctrl_process_echo_req(pptp_ctrl *_this, u_char *pkt, int lpkt) 776 { 777 struct pptp_echo_rq *echo_rq; 778 struct pptp_echo_rp *echo_rp; 779 780 if (lpkt < sizeof(struct pptp_echo_rq)) { 781 pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet " 782 "too short: %d < %d", lpkt, 783 (int)sizeof(struct pptp_echo_rq)); 784 return; 785 } 786 echo_rq = (struct pptp_echo_rq *)pkt; 787 788 PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReq")); 789 790 echo_rp = bytebuffer_pointer(_this->send_buf); 791 lpkt = bytebuffer_remaining(_this->send_buf); 792 if (echo_rp == NULL || lpkt < sizeof(struct pptp_echo_rp)) { 793 pptp_ctrl_log(_this, LOG_ERR, 794 "Failed to send EchoReq: No buffer space available"); 795 return; 796 } 797 memset(echo_rp, 0, sizeof(struct pptp_echo_rp)); 798 799 pptp_init_header(&echo_rp->header, sizeof(struct pptp_echo_rp), 800 PPTP_CTRL_MES_CODE_ECHO_RP); 801 802 echo_rp->identifier = echo_rq->identifier; 803 echo_rp->result_code = PPTP_ECHO_RP_RESULT_OK; 804 echo_rp->error_code = PPTP_ERROR_NONE; 805 echo_rp->reserved1 = htons(0); 806 807 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rp)); 808 PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReply")); 809 } 810 811 /* receiver Echo-Reply */ 812 static int 813 pptp_ctrl_recv_echo_rep(pptp_ctrl *_this, u_char *pkt, int lpkt) 814 { 815 struct pptp_echo_rp *echo_rp; 816 817 if (lpkt < sizeof(struct pptp_echo_rp)) { 818 pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet " 819 "too short: %d < %d", lpkt, 820 (int)sizeof(struct pptp_echo_rp)); 821 return 1; 822 } 823 echo_rp = (struct pptp_echo_rp *)pkt; 824 825 if (echo_rp->result_code != PPTP_ECHO_RP_RESULT_OK) { 826 pptp_ctrl_log(_this, LOG_ERR, "Received negative EchoReply: %s", 827 pptp_general_error_string(echo_rp->error_code)); 828 return 1; 829 } 830 if (_this->echo_seq != ntohl(echo_rp->identifier)) { 831 pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReply: " 832 "Identifier mismatch sent=%u recv=%u", 833 _this->echo_seq , ntohl(echo_rp->identifier)); 834 return 1; 835 } 836 PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReply")); 837 return 0; 838 } 839 840 /* send Echo-Request */ 841 static void 842 pptp_ctrl_send_echo_req(pptp_ctrl *_this) 843 { 844 int lpkt; 845 struct pptp_echo_rq *echo_rq; 846 847 echo_rq = (struct pptp_echo_rq *)bytebuffer_pointer(_this->send_buf); 848 lpkt = bytebuffer_remaining(_this->send_buf); 849 if (echo_rq == NULL || lpkt < sizeof(struct pptp_echo_rq)) { 850 pptp_ctrl_log(_this, LOG_ERR, 851 "SendEchoReq failed: No buffer space available"); 852 return; 853 } 854 memset(echo_rq, 0, sizeof(struct pptp_echo_rq)); 855 856 pptp_init_header(&echo_rq->header, sizeof(struct pptp_echo_rq), 857 PPTP_CTRL_MES_CODE_ECHO_RQ); 858 859 echo_rq->identifier = htonl(_this->echo_seq); 860 861 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rq)); 862 PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReq")); 863 } 864 865 /* send Call-Disconnect-Notify */ 866 static void 867 pptp_ctrl_send_CDN(pptp_ctrl *_this, int result, int error, int cause, 868 const char *statistics) 869 { 870 int lpkt; 871 struct pptp_cdn *cdn; 872 873 cdn = bytebuffer_pointer(_this->send_buf); 874 lpkt = bytebuffer_remaining(_this->send_buf); 875 if (lpkt < sizeof(struct pptp_cdn)) { 876 pptp_ctrl_log(_this, LOG_ERR, 877 "SendCCR failed: No buffer space available"); 878 return; 879 } 880 memset(cdn, 0, sizeof(struct pptp_cdn)); 881 882 pptp_init_header(&cdn->header, sizeof(struct pptp_cdn), 883 PPTP_CTRL_MES_CODE_CDN); 884 885 cdn->call_id = _this->id; 886 cdn->result_code = result; 887 cdn->error_code = error; 888 cdn->cause_code = cause; 889 if (statistics != NULL) 890 strlcpy(cdn->statistics, statistics, sizeof(cdn->statistics)); 891 892 cdn->call_id = htons(cdn->call_id); 893 cdn->cause_code = htons(cdn->cause_code); 894 895 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_cdn)); 896 } 897 898 /* receive Control-packet */ 899 static int 900 pptp_ctrl_input(pptp_ctrl *_this, u_char *pkt, int lpkt) 901 { 902 char errmes[256]; 903 time_t curr_time; 904 struct pptp_ctrl_header *hdr; 905 906 PPTP_CTRL_ASSERT(lpkt >= sizeof(struct pptp_ctrl_header)); 907 908 curr_time = get_monosec(); 909 hdr = (struct pptp_ctrl_header *)pkt; 910 911 hdr->length = ntohs(hdr->length); 912 hdr->pptp_message_type = ntohs(hdr->pptp_message_type); 913 hdr->magic_cookie = ntohl(hdr->magic_cookie); 914 hdr->control_message_type = ntohs(hdr->control_message_type); 915 hdr->reserved0 = ntohs(hdr->reserved0); 916 917 /* sanity check */ 918 PPTP_CTRL_ASSERT(hdr->length <= lpkt); 919 920 _this->last_rcv_ctrl = curr_time; 921 922 if (PPTP_CTRL_CONF(_this)->ctrl_in_pktdump != 0) { 923 pptp_ctrl_log(_this, LOG_DEBUG, 924 "PPTP Control input packet dump: mestype=%s(%d)", 925 pptp_ctrl_mes_type_string(hdr->control_message_type), 926 hdr->control_message_type); 927 show_hd(debug_get_debugfp(), pkt, lpkt); 928 } 929 930 /* inspect packet body */ 931 /* message type */ 932 if (hdr->pptp_message_type != PPTP_MES_TYPE_CTRL) { 933 snprintf(errmes, sizeof(errmes), "unknown message type %d", 934 hdr->pptp_message_type); 935 goto bad_packet; 936 } 937 /* magic cookie */ 938 if (hdr->magic_cookie != PPTP_MAGIC_COOKIE) { 939 snprintf(errmes, sizeof(errmes), "wrong magic %08x != %08x", 940 hdr->magic_cookie, PPTP_MAGIC_COOKIE); 941 goto bad_packet; 942 } 943 944 /* As there is possibility of state conflicts, 945 * ECHO Reply requiries special care. 946 */ 947 switch (hdr->control_message_type) { 948 case PPTP_CTRL_MES_CODE_ECHO_RP: 949 if (pptp_ctrl_recv_echo_rep(_this, pkt, lpkt) != 0) { 950 pptp_ctrl_fini(_this); 951 return 1; 952 } 953 return 0; 954 } 955 956 /* 957 * State machine 958 */ 959 switch (_this->state) { 960 case PPTP_CTRL_STATE_IDLE: 961 switch (hdr->control_message_type) { 962 case PPTP_CTRL_MES_CODE_SCCRQ: 963 if (pptp_ctrl_recv_SCCRQ(_this, pkt, lpkt) != 0) { 964 return 0; 965 } 966 if (pptp_ctrl_send_SCCRP(_this, 967 PPTP_SCCRP_RESULT_SUCCESS, PPTP_ERROR_NONE) != 0) { 968 return 0; 969 } 970 _this->state = PPTP_CTRL_STATE_ESTABLISHED; 971 return 0; 972 default: 973 break; 974 } 975 break; 976 case PPTP_CTRL_STATE_ESTABLISHED: 977 switch (hdr->control_message_type) { 978 case PPTP_CTRL_MES_CODE_ECHO_RQ: 979 pptp_ctrl_process_echo_req(_this, pkt, lpkt); 980 return 0; 981 /* dispatch to pptp_call_input() if it is call-related-packet */ 982 case PPTP_CTRL_MES_CODE_SLI: 983 case PPTP_CTRL_MES_CODE_ICRQ: 984 case PPTP_CTRL_MES_CODE_ICRP: 985 case PPTP_CTRL_MES_CODE_OCRQ: 986 case PPTP_CTRL_MES_CODE_OCRP: 987 case PPTP_CTRL_MES_CODE_ICCN: 988 case PPTP_CTRL_MES_CODE_CDN: 989 case PPTP_CTRL_MES_CODE_CCR: 990 return pptp_ctrl_call_input(_this, 991 hdr->control_message_type, pkt, lpkt); 992 case PPTP_CTRL_MES_CODE_StopCCRQ: 993 if (pptp_ctrl_recv_StopCCRQ(_this, pkt, lpkt) != 0) { 994 pptp_ctrl_stop(_this, 995 PPTP_StopCCRQ_REASON_STOP_PROTOCOL); 996 return 0; 997 } 998 if (pptp_ctrl_send_StopCCRP(_this, 999 PPTP_StopCCRP_RESULT_OK, PPTP_ERROR_NONE)!= 0) { 1000 return 0; 1001 } 1002 pptp_ctrl_fini(_this); 1003 return 1; 1004 default: 1005 break; 1006 } 1007 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 1008 switch (hdr->control_message_type) { 1009 case PPTP_CTRL_MES_CODE_StopCCRP: 1010 pptp_ctrl_recv_StopCCRP(_this, pkt, lpkt); 1011 pptp_ctrl_fini(_this); 1012 return 1; 1013 } 1014 break; 1015 case PPTP_CTRL_STATE_WAIT_CTRL_REPLY: 1016 /* XXX this implementation only support PAC mode */ 1017 break; 1018 } 1019 pptp_ctrl_log(_this, LOG_WARNING, 1020 "Unhandled control message type=%s(%d)", 1021 pptp_ctrl_mes_type_string(hdr->control_message_type), 1022 hdr->control_message_type); 1023 return 0; 1024 1025 bad_packet: 1026 pptp_ctrl_log(_this, LOG_ERR, "Received bad packet: %s", errmes); 1027 pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL); 1028 1029 return 0; 1030 } 1031 1032 /* receiver PPTP Call related messages */ 1033 static int 1034 pptp_ctrl_call_input(pptp_ctrl *_this, int mes_type, u_char *pkt, int lpkt) 1035 { 1036 int i, call_id, lpkt0; 1037 pptp_call *call; 1038 const char *reason; 1039 u_char *pkt0; 1040 1041 pkt0 = pkt; 1042 lpkt0 = lpkt; 1043 call_id = -1; 1044 pkt += sizeof(struct pptp_ctrl_header); 1045 lpkt -= sizeof(struct pptp_ctrl_header); 1046 reason = "(no reason)"; 1047 1048 /* sanity check */ 1049 if (lpkt < 4) { 1050 reason = "received packet is too short"; 1051 goto badpacket; 1052 } 1053 call = NULL; 1054 call_id = ntohs(*(uint16_t *)pkt); 1055 1056 switch (mes_type) { 1057 case PPTP_CTRL_MES_CODE_SLI: /* PNS <=> PAC */ 1058 /* only SLI contains Call-ID of this peer */ 1059 for (i = 0; i < slist_length(&_this->call_list); i++) { 1060 call = slist_get(&_this->call_list, i); 1061 if (call->id == call_id) 1062 break; 1063 call = NULL; 1064 } 1065 if (call == NULL) { 1066 reason = "Call Id is not associated by this control"; 1067 goto badpacket; 1068 } 1069 goto call_searched; 1070 case PPTP_CTRL_MES_CODE_ICRP: /* PNS => PAC */ 1071 /* 1072 * as this implementation never sent ICRQ, this case 1073 * should not happen. 1074 * But just to make sure, pptp_call.c can handle this 1075 * message. 1076 */ 1077 /* FALLTHROUGH */ 1078 case PPTP_CTRL_MES_CODE_OCRQ: /* PNS => PAC */ 1079 case PPTP_CTRL_MES_CODE_CCR: /* PNS => PAC */ 1080 /* liner-search will be enough */ 1081 for (i = 0; i < slist_length(&_this->call_list); i++) { 1082 call = slist_get(&_this->call_list, i); 1083 if (call->peers_call_id == call_id) 1084 break; 1085 call = NULL; 1086 } 1087 if (call == NULL && mes_type == PPTP_CTRL_MES_CODE_CCR) { 1088 pptp_ctrl_send_CDN(_this, PPTP_CDN_RESULT_GENRIC_ERROR, 1089 PPTP_ERROR_BAD_CALL, 0, NULL); 1090 goto call_searched; 1091 } 1092 if (mes_type == PPTP_CTRL_MES_CODE_OCRQ) { 1093 /* make new call */ 1094 if (call != NULL) { 1095 pptp_call_input(call, mes_type, pkt0, lpkt0); 1096 return 0; 1097 } 1098 if ((call = pptp_call_create()) == NULL) { 1099 pptp_ctrl_log(_this, LOG_ERR, 1100 "pptp_call_create() failed: %m"); 1101 goto fail; 1102 } 1103 if (pptp_call_init(call, _this) != 0) { 1104 pptp_ctrl_log(_this, LOG_ERR, 1105 "pptp_call_init() failed: %m"); 1106 pptp_call_destroy(call); 1107 goto fail; 1108 } 1109 slist_add(&_this->call_list, call); 1110 } 1111 call_searched: 1112 if (call == NULL) { 1113 reason = "Call Id is not associated by this control"; 1114 goto badpacket; 1115 } 1116 pptp_call_input(call, mes_type, pkt0, lpkt0); 1117 return 0; 1118 case PPTP_CTRL_MES_CODE_OCRP: /* PAC => PNS */ 1119 case PPTP_CTRL_MES_CODE_ICRQ: /* PAC => PNS */ 1120 case PPTP_CTRL_MES_CODE_ICCN: /* PAC => PNS */ 1121 case PPTP_CTRL_MES_CODE_CDN: /* PAC => PNS */ 1122 /* don't receive because above messages are only of PNS */ 1123 default: 1124 break; 1125 } 1126 reason = "Message type is unexpected."; 1127 /* FALLTHROUGH */ 1128 badpacket: 1129 pptp_ctrl_log(_this, LOG_INFO, 1130 "Received a bad %s(%d) call_id=%d: %s", 1131 pptp_ctrl_mes_type_string(mes_type), mes_type, call_id, reason); 1132 return 0; 1133 fail: 1134 pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL); 1135 return 0; 1136 } 1137 1138 1139 /* 1140 * utilities 1141 */ 1142 1143 /* logging with the label of the instance */ 1144 static void 1145 pptp_ctrl_log(pptp_ctrl *_this, int prio, const char *fmt, ...) 1146 { 1147 char logbuf[BUFSIZ]; 1148 va_list ap; 1149 1150 va_start(ap, fmt); 1151 #ifdef PPTPD_MULTIPLE 1152 snprintf(logbuf, sizeof(logbuf), "pptpd id=%u ctrl=%u %s", 1153 _this->pptpd->id, _this->id, fmt); 1154 #else 1155 snprintf(logbuf, sizeof(logbuf), "pptpd ctrl=%u %s", _this->id, fmt); 1156 #endif 1157 vlog_printf(prio, logbuf, ap); 1158 va_end(ap); 1159 } 1160 1161 static const char * 1162 pptp_ctrl_state_string(int state) 1163 { 1164 switch (state) { 1165 case PPTP_CTRL_STATE_IDLE: 1166 return "idle"; 1167 case PPTP_CTRL_STATE_WAIT_CTRL_REPLY: 1168 return "wait-ctrl-reply"; 1169 case PPTP_CTRL_STATE_ESTABLISHED: 1170 return "established"; 1171 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 1172 return "wait-stop-reply"; 1173 } 1174 return "unknown"; 1175 } 1176