1 /* $OpenBSD: pptp_ctrl.c,v 1.11 2016/04/16 18:32:29 krw 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.11 2016/04/16 18:32:29 krw 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 responce. */ 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 buf1[128], buf2[128], buf3[128]; 560 561 /* sanity check */ 562 strlcpy(buf1, scc->host_name, sizeof(buf1)); 563 strlcpy(buf2, scc->vendor_string, sizeof(buf2)); 564 565 if (scc->result_code != 0) 566 snprintf(buf3, sizeof(buf3), "result=%d error=%d ", 567 scc->result_code, scc->error_code); 568 else 569 buf3[0] = '\0'; 570 571 snprintf(buf, lbuf, 572 "protocol_version=%d.%d %sframing=%s bearer=%s max_channels=%d " 573 "firmware_revision=%d(0x%04x) host_name=\"%s\" " 574 "vendor_string=\"%s\"", 575 scc->protocol_version >> 8, scc->protocol_version & 0xff, buf3, 576 pptp_framing_string(scc->framing_caps), 577 pptp_bearer_string(scc->bearer_caps), scc->max_channels, 578 scc->firmware_revision, scc->firmware_revision, buf1, buf2); 579 } 580 581 /* receive Start-Control-Connection-Request */ 582 static int 583 pptp_ctrl_recv_SCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt) 584 { 585 char logbuf[512]; 586 struct pptp_scc *scc; 587 588 /* sanity check */ 589 if (lpkt < sizeof(struct pptp_scc)) { 590 pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: packet too " 591 "short: %d < %d", lpkt, (int)sizeof(struct pptp_scc)); 592 return 1; 593 } 594 scc = (struct pptp_scc *)pkt; 595 596 scc->protocol_version = ntohs(scc->protocol_version); 597 scc->framing_caps = htonl(scc->framing_caps); 598 scc->bearer_caps = htonl(scc->bearer_caps); 599 scc->max_channels = htons(scc->max_channels); 600 scc->firmware_revision = htons(scc->firmware_revision); 601 602 /* check protocol version */ 603 if (scc->protocol_version != PPTP_RFC_2637_VERSION) { 604 pptp_ctrl_log(_this, LOG_ERR, "Received bad SCCRQ: " 605 "unknown protocol version %d", scc->protocol_version); 606 return 1; 607 } 608 609 pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf)); 610 pptp_ctrl_log(_this, LOG_INFO, "RecvSCCRQ %s", logbuf); 611 612 return 0; 613 } 614 615 /* Receive Stop-Control-Connection-Reply */ 616 static int 617 pptp_ctrl_recv_StopCCRP(pptp_ctrl *_this, u_char *pkt, int lpkt) 618 { 619 struct pptp_stop_ccrp *stop_ccrp; 620 621 if (lpkt < sizeof(struct pptp_stop_ccrp)) { 622 pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRP: packet " 623 "too short: %d < %d", lpkt, 624 (int)sizeof(struct pptp_stop_ccrp)); 625 return 1; 626 } 627 stop_ccrp = (struct pptp_stop_ccrp *)pkt; 628 629 pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRP reason=%s(%u)", 630 pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result); 631 632 return 0; 633 } 634 635 static int 636 pptp_ctrl_send_StopCCRQ(pptp_ctrl *_this, int reason) 637 { 638 int lpkt; 639 struct pptp_stop_ccrq *stop_ccrq; 640 641 stop_ccrq = bytebuffer_pointer(_this->send_buf); 642 lpkt = bytebuffer_remaining(_this->send_buf); 643 if (lpkt < sizeof(struct pptp_stop_ccrq)) { 644 pptp_ctrl_log(_this, LOG_ERR, 645 "SendCCRP failed: No buffer space available"); 646 return -1; 647 } 648 memset(stop_ccrq, 0, sizeof(struct pptp_stop_ccrq)); 649 650 pptp_init_header(&stop_ccrq->header, sizeof(struct pptp_stop_ccrq), 651 PPTP_CTRL_MES_CODE_StopCCRQ); 652 653 stop_ccrq->reason = reason; 654 655 pptp_ctrl_log(_this, LOG_INFO, "SendStopCCRQ reason=%s(%u)", 656 pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason); 657 658 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrq)); 659 660 return 0; 661 } 662 663 /* Receive Stop-Control-Connection-Request */ 664 static int 665 pptp_ctrl_recv_StopCCRQ(pptp_ctrl *_this, u_char *pkt, int lpkt) 666 { 667 struct pptp_stop_ccrq *stop_ccrq; 668 669 if (lpkt < sizeof(struct pptp_stop_ccrq)) { 670 pptp_ctrl_log(_this, LOG_ERR, "Received bad StopCCRQ: packet " 671 "too short: %d < %d", lpkt, 672 (int)sizeof(struct pptp_stop_ccrq)); 673 return 1; 674 } 675 stop_ccrq = (struct pptp_stop_ccrq *)pkt; 676 677 pptp_ctrl_log(_this, LOG_INFO, "RecvStopCCRQ reason=%s(%u)", 678 pptp_StopCCRQ_reason_string(stop_ccrq->reason), stop_ccrq->reason); 679 680 return 0; 681 } 682 683 /* Send Stop-Control-Connection-Reply */ 684 static int 685 pptp_ctrl_send_StopCCRP(pptp_ctrl *_this, int result, int error) 686 { 687 int lpkt; 688 struct pptp_stop_ccrp *stop_ccrp; 689 690 stop_ccrp = bytebuffer_pointer(_this->send_buf); 691 692 lpkt = bytebuffer_remaining(_this->send_buf); 693 if (lpkt < sizeof(struct pptp_stop_ccrp)) { 694 pptp_ctrl_log(_this, LOG_ERR, 695 "SendCCRQ failed: No buffer space available"); 696 return -1; 697 } 698 memset(stop_ccrp, 0, sizeof(struct pptp_stop_ccrp)); 699 700 pptp_init_header(&stop_ccrp->header, sizeof(struct pptp_stop_ccrp), 701 PPTP_CTRL_MES_CODE_StopCCRP); 702 703 stop_ccrp->result = result; 704 stop_ccrp->error = error; 705 706 pptp_ctrl_log(_this, LOG_INFO, 707 "SendStopCCRP result=%s(%u) error=%s(%u)", 708 pptp_StopCCRP_result_string(stop_ccrp->result), stop_ccrp->result, 709 pptp_general_error_string(stop_ccrp->error), stop_ccrp->error); 710 711 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_stop_ccrp)); 712 713 return 0; 714 } 715 716 /* Send Start-Control-Connection-Reply */ 717 static int 718 pptp_ctrl_send_SCCRP(pptp_ctrl *_this, int result, int error) 719 { 720 int lpkt; 721 struct pptp_scc *scc; 722 char logbuf[512]; 723 const char *val; 724 725 scc = bytebuffer_pointer(_this->send_buf); 726 lpkt = bytebuffer_remaining(_this->send_buf); 727 if (lpkt < sizeof(struct pptp_scc)) { 728 pptp_ctrl_log(_this, LOG_ERR, 729 "SendSCCRP failed: No buffer space available"); 730 return -1; 731 } 732 memset(scc, 0, sizeof(struct pptp_scc)); 733 734 pptp_init_header(&scc->header, sizeof(struct pptp_scc), 735 PPTP_CTRL_MES_CODE_SCCRP); 736 737 scc->protocol_version = PPTP_RFC_2637_VERSION; 738 scc->result_code = result; 739 scc->error_code = error; 740 741 /* XXX only support sync frames */ 742 scc->framing_caps = PPTP_CTRL_FRAMING_SYNC; 743 scc->bearer_caps = PPTP_CTRL_BEARER_DIGITAL; 744 745 scc->max_channels = 4; /* XXX */ 746 scc->firmware_revision = MAJOR_VERSION << 8 | MINOR_VERSION; 747 748 /* this implementation only support these strings up to 749 * 63 character */ 750 /* host name */ 751 752 if ((val = PPTP_CTRL_CONF(_this)->hostname) == NULL) 753 val = ""; 754 strlcpy(scc->host_name, val, sizeof(scc->host_name)); 755 756 /* vender name */ 757 if (PPTP_CTRL_CONF(_this)->vendor_name == NULL) 758 val = PPTPD_DEFAULT_VENDOR_NAME; 759 strlcpy(scc->vendor_string, val, sizeof(scc->vendor_string)); 760 761 pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf)); 762 pptp_ctrl_log(_this, LOG_INFO, "SendSCCRP %s", logbuf); 763 764 scc->protocol_version = htons(scc->protocol_version); 765 scc->framing_caps = htonl(scc->framing_caps); 766 scc->bearer_caps = htonl(scc->bearer_caps); 767 scc->max_channels = htons(scc->max_channels); 768 scc->firmware_revision = htons(scc->firmware_revision); 769 770 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_scc)); 771 772 return 0; 773 } 774 775 /* receive ECHO and reply */ 776 static void 777 pptp_ctrl_process_echo_req(pptp_ctrl *_this, u_char *pkt, int lpkt) 778 { 779 struct pptp_echo_rq *echo_rq; 780 struct pptp_echo_rp *echo_rp; 781 782 if (lpkt < sizeof(struct pptp_echo_rq)) { 783 pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet " 784 "too short: %d < %d", lpkt, 785 (int)sizeof(struct pptp_echo_rq)); 786 return; 787 } 788 echo_rq = (struct pptp_echo_rq *)pkt; 789 790 PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReq")); 791 792 echo_rp = bytebuffer_pointer(_this->send_buf); 793 lpkt = bytebuffer_remaining(_this->send_buf); 794 if (echo_rp == NULL || lpkt < sizeof(struct pptp_echo_rp)) { 795 pptp_ctrl_log(_this, LOG_ERR, 796 "Failed to send EchoReq: No buffer space available"); 797 return; 798 } 799 memset(echo_rp, 0, sizeof(struct pptp_echo_rp)); 800 801 pptp_init_header(&echo_rp->header, sizeof(struct pptp_echo_rp), 802 PPTP_CTRL_MES_CODE_ECHO_RP); 803 804 echo_rp->identifier = echo_rq->identifier; 805 echo_rp->result_code = PPTP_ECHO_RP_RESULT_OK; 806 echo_rp->error_code = PPTP_ERROR_NONE; 807 echo_rp->reserved1 = htons(0); 808 809 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rp)); 810 PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReply")); 811 } 812 813 /* receiver Echo-Reply */ 814 static int 815 pptp_ctrl_recv_echo_rep(pptp_ctrl *_this, u_char *pkt, int lpkt) 816 { 817 struct pptp_echo_rp *echo_rp; 818 819 if (lpkt < sizeof(struct pptp_echo_rp)) { 820 pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReq: packet " 821 "too short: %d < %d", lpkt, 822 (int)sizeof(struct pptp_echo_rp)); 823 return 1; 824 } 825 echo_rp = (struct pptp_echo_rp *)pkt; 826 827 if (echo_rp->result_code != PPTP_ECHO_RP_RESULT_OK) { 828 pptp_ctrl_log(_this, LOG_ERR, "Received negative EchoReply: %s", 829 pptp_general_error_string(echo_rp->error_code)); 830 return 1; 831 } 832 if (_this->echo_seq != ntohl(echo_rp->identifier)) { 833 pptp_ctrl_log(_this, LOG_ERR, "Received bad EchoReply: " 834 "Identifier mismatch sent=%u recv=%u", 835 _this->echo_seq , ntohl(echo_rp->identifier)); 836 return 1; 837 } 838 PPTP_CTRL_DBG((_this, LOG_DEBUG, "RecvEchoReply")); 839 return 0; 840 } 841 842 /* send Echo-Request */ 843 static void 844 pptp_ctrl_send_echo_req(pptp_ctrl *_this) 845 { 846 int lpkt; 847 struct pptp_echo_rq *echo_rq; 848 849 echo_rq = (struct pptp_echo_rq *)bytebuffer_pointer(_this->send_buf); 850 lpkt = bytebuffer_remaining(_this->send_buf); 851 if (echo_rq == NULL || lpkt < sizeof(struct pptp_echo_rq)) { 852 pptp_ctrl_log(_this, LOG_ERR, 853 "SendEchoReq failed: No buffer space available"); 854 return; 855 } 856 memset(echo_rq, 0, sizeof(struct pptp_echo_rq)); 857 858 pptp_init_header(&echo_rq->header, sizeof(struct pptp_echo_rq), 859 PPTP_CTRL_MES_CODE_ECHO_RQ); 860 861 echo_rq->identifier = htonl(_this->echo_seq); 862 863 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_echo_rq)); 864 PPTP_CTRL_DBG((_this, LOG_DEBUG, "SendEchoReq")); 865 } 866 867 /* send Call-Disconnect-Notify */ 868 static void 869 pptp_ctrl_send_CDN(pptp_ctrl *_this, int result, int error, int cause, 870 const char *statistics) 871 { 872 int lpkt; 873 struct pptp_cdn *cdn; 874 875 cdn = bytebuffer_pointer(_this->send_buf); 876 lpkt = bytebuffer_remaining(_this->send_buf); 877 if (lpkt < sizeof(struct pptp_cdn)) { 878 pptp_ctrl_log(_this, LOG_ERR, 879 "SendCCR failed: No buffer space available"); 880 return; 881 } 882 memset(cdn, 0, sizeof(struct pptp_cdn)); 883 884 pptp_init_header(&cdn->header, sizeof(struct pptp_cdn), 885 PPTP_CTRL_MES_CODE_CDN); 886 887 cdn->call_id = _this->id; 888 cdn->result_code = result; 889 cdn->error_code = error; 890 cdn->cause_code = cause; 891 if (statistics != NULL) 892 strlcpy(cdn->statistics, statistics, sizeof(cdn->statistics)); 893 894 cdn->call_id = htons(cdn->call_id); 895 cdn->cause_code = htons(cdn->cause_code); 896 897 pptp_ctrl_output(_this, NULL, sizeof(struct pptp_cdn)); 898 } 899 900 /* receive Control-packet */ 901 static int 902 pptp_ctrl_input(pptp_ctrl *_this, u_char *pkt, int lpkt) 903 { 904 char errmes[256]; 905 time_t curr_time; 906 struct pptp_ctrl_header *hdr; 907 908 PPTP_CTRL_ASSERT(lpkt >= sizeof(struct pptp_ctrl_header)); 909 910 curr_time = get_monosec(); 911 hdr = (struct pptp_ctrl_header *)pkt; 912 913 hdr->length = ntohs(hdr->length); 914 hdr->pptp_message_type = ntohs(hdr->pptp_message_type); 915 hdr->magic_cookie = ntohl(hdr->magic_cookie); 916 hdr->control_message_type = ntohs(hdr->control_message_type); 917 hdr->reserved0 = ntohs(hdr->reserved0); 918 919 /* sanity check */ 920 PPTP_CTRL_ASSERT(hdr->length <= lpkt); 921 922 _this->last_rcv_ctrl = curr_time; 923 924 if (PPTP_CTRL_CONF(_this)->ctrl_in_pktdump != 0) { 925 pptp_ctrl_log(_this, LOG_DEBUG, 926 "PPTP Control input packet dump: mestype=%s(%d)", 927 pptp_ctrl_mes_type_string(hdr->control_message_type), 928 hdr->control_message_type); 929 show_hd(debug_get_debugfp(), pkt, lpkt); 930 } 931 932 /* inspect packet body */ 933 /* message type */ 934 if (hdr->pptp_message_type != PPTP_MES_TYPE_CTRL) { 935 snprintf(errmes, sizeof(errmes), "unknown message type %d", 936 hdr->pptp_message_type); 937 goto bad_packet; 938 } 939 /* magic cookie */ 940 if (hdr->magic_cookie != PPTP_MAGIC_COOKIE) { 941 snprintf(errmes, sizeof(errmes), "wrong magic %08x != %08x", 942 hdr->magic_cookie, PPTP_MAGIC_COOKIE); 943 goto bad_packet; 944 } 945 946 /* As there is possibility of state conflicts, 947 * ECHO Reply requiries special care. 948 */ 949 switch (hdr->control_message_type) { 950 case PPTP_CTRL_MES_CODE_ECHO_RP: 951 if (pptp_ctrl_recv_echo_rep(_this, pkt, lpkt) != 0) { 952 pptp_ctrl_fini(_this); 953 return 1; 954 } 955 return 0; 956 } 957 958 /* 959 * State machine 960 */ 961 switch (_this->state) { 962 case PPTP_CTRL_STATE_IDLE: 963 switch (hdr->control_message_type) { 964 case PPTP_CTRL_MES_CODE_SCCRQ: 965 if (pptp_ctrl_recv_SCCRQ(_this, pkt, lpkt) != 0) { 966 return 0; 967 } 968 if (pptp_ctrl_send_SCCRP(_this, 969 PPTP_SCCRP_RESULT_SUCCESS, PPTP_ERROR_NONE) != 0) { 970 return 0; 971 } 972 _this->state = PPTP_CTRL_STATE_ESTABLISHED; 973 return 0; 974 default: 975 break; 976 } 977 break; 978 case PPTP_CTRL_STATE_ESTABLISHED: 979 switch (hdr->control_message_type) { 980 case PPTP_CTRL_MES_CODE_ECHO_RQ: 981 pptp_ctrl_process_echo_req(_this, pkt, lpkt); 982 return 0; 983 /* dispatch to pptp_call_input() if it is call-related-packet */ 984 case PPTP_CTRL_MES_CODE_SLI: 985 case PPTP_CTRL_MES_CODE_ICRQ: 986 case PPTP_CTRL_MES_CODE_ICRP: 987 case PPTP_CTRL_MES_CODE_OCRQ: 988 case PPTP_CTRL_MES_CODE_OCRP: 989 case PPTP_CTRL_MES_CODE_ICCN: 990 case PPTP_CTRL_MES_CODE_CDN: 991 case PPTP_CTRL_MES_CODE_CCR: 992 return pptp_ctrl_call_input(_this, 993 hdr->control_message_type, pkt, lpkt); 994 case PPTP_CTRL_MES_CODE_StopCCRQ: 995 if (pptp_ctrl_recv_StopCCRQ(_this, pkt, lpkt) != 0) { 996 pptp_ctrl_stop(_this, 997 PPTP_StopCCRQ_REASON_STOP_PROTOCOL); 998 return 0; 999 } 1000 if (pptp_ctrl_send_StopCCRP(_this, 1001 PPTP_StopCCRP_RESULT_OK, PPTP_ERROR_NONE)!= 0) { 1002 return 0; 1003 } 1004 pptp_ctrl_fini(_this); 1005 return 1; 1006 default: 1007 break; 1008 } 1009 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 1010 switch (hdr->control_message_type) { 1011 case PPTP_CTRL_MES_CODE_StopCCRP: 1012 pptp_ctrl_recv_StopCCRP(_this, pkt, lpkt); 1013 pptp_ctrl_fini(_this); 1014 return 1; 1015 } 1016 break; 1017 case PPTP_CTRL_STATE_WAIT_CTRL_REPLY: 1018 /* XXX this implementation only support PAC mode */ 1019 break; 1020 } 1021 pptp_ctrl_log(_this, LOG_WARNING, 1022 "Unhandled control message type=%s(%d)", 1023 pptp_ctrl_mes_type_string(hdr->control_message_type), 1024 hdr->control_message_type); 1025 return 0; 1026 1027 bad_packet: 1028 pptp_ctrl_log(_this, LOG_ERR, "Received bad packet: %s", errmes); 1029 pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL); 1030 1031 return 0; 1032 } 1033 1034 /* receiver PPTP Call related messages */ 1035 static int 1036 pptp_ctrl_call_input(pptp_ctrl *_this, int mes_type, u_char *pkt, int lpkt) 1037 { 1038 int i, call_id, lpkt0; 1039 pptp_call *call; 1040 const char *reason; 1041 u_char *pkt0; 1042 1043 pkt0 = pkt; 1044 lpkt0 = lpkt; 1045 call_id = -1; 1046 pkt += sizeof(struct pptp_ctrl_header); 1047 lpkt -= sizeof(struct pptp_ctrl_header); 1048 reason = "(no reason)"; 1049 1050 /* sanity check */ 1051 if (lpkt < 4) { 1052 reason = "received packet is too short"; 1053 goto badpacket; 1054 } 1055 call = NULL; 1056 call_id = ntohs(*(uint16_t *)pkt); 1057 1058 switch (mes_type) { 1059 case PPTP_CTRL_MES_CODE_SLI: /* PNS <=> PAC */ 1060 /* only SLI contains Call-ID of this peer */ 1061 for (i = 0; i < slist_length(&_this->call_list); i++) { 1062 call = slist_get(&_this->call_list, i); 1063 if (call->id == call_id) 1064 break; 1065 call = NULL; 1066 } 1067 if (call == NULL) { 1068 reason = "Call Id is not associated by this control"; 1069 goto badpacket; 1070 } 1071 goto call_searched; 1072 case PPTP_CTRL_MES_CODE_ICRP: /* PNS => PAC */ 1073 /* 1074 * as this implementation never sent ICRQ, this case 1075 * should not happen. 1076 * But just to make sure, pptp_call.c can handle this 1077 * message. 1078 */ 1079 /* FALLTHROUGH */ 1080 case PPTP_CTRL_MES_CODE_OCRQ: /* PNS => PAC */ 1081 case PPTP_CTRL_MES_CODE_CCR: /* PNS => PAC */ 1082 /* liner-search will be enough */ 1083 for (i = 0; i < slist_length(&_this->call_list); i++) { 1084 call = slist_get(&_this->call_list, i); 1085 if (call->peers_call_id == call_id) 1086 break; 1087 call = NULL; 1088 } 1089 if (call == NULL && mes_type == PPTP_CTRL_MES_CODE_CCR) { 1090 pptp_ctrl_send_CDN(_this, PPTP_CDN_RESULT_GENRIC_ERROR, 1091 PPTP_ERROR_BAD_CALL, 0, NULL); 1092 goto call_searched; 1093 } 1094 if (mes_type == PPTP_CTRL_MES_CODE_OCRQ) { 1095 /* make new call */ 1096 if (call != NULL) { 1097 pptp_call_input(call, mes_type, pkt0, lpkt0); 1098 return 0; 1099 } 1100 if ((call = pptp_call_create()) == NULL) { 1101 pptp_ctrl_log(_this, LOG_ERR, 1102 "pptp_call_create() failed: %m"); 1103 goto fail; 1104 } 1105 if (pptp_call_init(call, _this) != 0) { 1106 pptp_ctrl_log(_this, LOG_ERR, 1107 "pptp_call_init() failed: %m"); 1108 pptp_call_destroy(call); 1109 goto fail; 1110 } 1111 slist_add(&_this->call_list, call); 1112 } 1113 call_searched: 1114 if (call == NULL) { 1115 reason = "Call Id is not associated by this control"; 1116 goto badpacket; 1117 } 1118 pptp_call_input(call, mes_type, pkt0, lpkt0); 1119 return 0; 1120 case PPTP_CTRL_MES_CODE_OCRP: /* PAC => PNS */ 1121 case PPTP_CTRL_MES_CODE_ICRQ: /* PAC => PNS */ 1122 case PPTP_CTRL_MES_CODE_ICCN: /* PAC => PNS */ 1123 case PPTP_CTRL_MES_CODE_CDN: /* PAC => PNS */ 1124 /* don't receive because above messages are only of PNS */ 1125 default: 1126 break; 1127 } 1128 reason = "Message type is unexpected."; 1129 /* FALLTHROUGH */ 1130 badpacket: 1131 pptp_ctrl_log(_this, LOG_INFO, 1132 "Received a bad %s(%d) call_id=%d: %s", 1133 pptp_ctrl_mes_type_string(mes_type), mes_type, call_id, reason); 1134 return 0; 1135 fail: 1136 pptp_ctrl_stop(_this, PPTP_StopCCRQ_REASON_STOP_PROTOCOL); 1137 return 0; 1138 } 1139 1140 1141 /* 1142 * utilities 1143 */ 1144 1145 /* logging with the label of the instance */ 1146 static void 1147 pptp_ctrl_log(pptp_ctrl *_this, int prio, const char *fmt, ...) 1148 { 1149 char logbuf[BUFSIZ]; 1150 va_list ap; 1151 1152 va_start(ap, fmt); 1153 #ifdef PPTPD_MULTIPLE 1154 snprintf(logbuf, sizeof(logbuf), "pptpd id=%u ctrl=%u %s", 1155 _this->pptpd->id, _this->id, fmt); 1156 #else 1157 snprintf(logbuf, sizeof(logbuf), "pptpd ctrl=%u %s", _this->id, fmt); 1158 #endif 1159 vlog_printf(prio, logbuf, ap); 1160 va_end(ap); 1161 } 1162 1163 static const char * 1164 pptp_ctrl_state_string(int state) 1165 { 1166 switch (state) { 1167 case PPTP_CTRL_STATE_IDLE: 1168 return "idle"; 1169 case PPTP_CTRL_STATE_WAIT_CTRL_REPLY: 1170 return "wait-ctrl-reply"; 1171 case PPTP_CTRL_STATE_ESTABLISHED: 1172 return "established"; 1173 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 1174 return "wait-stop-reply"; 1175 } 1176 return "unknown"; 1177 } 1178