1 /* $OpenBSD: pptp_ctrl.c,v 1.7 2012/09/18 13:14:08 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.7 2012/09/18 13:14:08 yasuoka Exp $ */ 33 #include <sys/types.h> 34 #include <sys/param.h> 35 #include <sys/socket.h> 36 #include <netinet/in.h> 37 #include <stdio.h> 38 #include <stdarg.h> 39 #include <stdlib.h> 40 #include <netdb.h> 41 #include <unistd.h> 42 #include <syslog.h> 43 #include <time.h> 44 #include <fcntl.h> 45 #include <errno.h> 46 #include <string.h> 47 #include <event.h> 48 49 #include "bytebuf.h" 50 #include "debugutil.h" 51 #include "hash.h" 52 #include "slist.h" 53 #include "time_utils.h" 54 55 #include "version.h" 56 57 #include "pptp.h" 58 #include "pptp_local.h" 59 #include "pptp_subr.h" 60 61 /* periods of pptp_ctrl_timeout */ 62 #define PPTP_CTRL_TIMEOUT_IVAL_SEC 2 63 64 #ifdef PPTP_CTRL_DEBUG 65 #define PPTP_CTRL_ASSERT(x) ASSERT(x) 66 #define PPTP_CTRL_DBG(x) pptp_ctrl_log x 67 #else 68 #define PPTP_CTRL_ASSERT(x) 69 #define PPTP_CTRL_DBG(x) 70 #endif 71 72 static unsigned pptp_ctrl_seqno = 0; 73 74 static void pptp_ctrl_log (pptp_ctrl *, int, const char *, ...) __printflike(3,4); 75 static void pptp_ctrl_timeout (int, short, void *); 76 static void pptp_ctrl_reset_timeout (pptp_ctrl *); 77 static void pptp_ctrl_io_event (int, short, void *); 78 static void pptp_ctrl_set_io_event (pptp_ctrl *); 79 static int pptp_ctrl_output_flush (pptp_ctrl *); 80 static void pptp_ctrl_SCCRx_string (struct pptp_scc *, u_char *, int); 81 static int pptp_ctrl_recv_SCCRQ (pptp_ctrl *, u_char *, int); 82 static int pptp_ctrl_recv_StopCCRP (pptp_ctrl *, u_char *, int); 83 static int pptp_ctrl_send_StopCCRQ (pptp_ctrl *, int); 84 static int pptp_ctrl_recv_StopCCRQ (pptp_ctrl *, u_char *, int); 85 static int pptp_ctrl_send_StopCCRP (pptp_ctrl *, int, int); 86 static int pptp_ctrl_send_SCCRP (pptp_ctrl *, int, int); 87 static void pptp_ctrl_send_CDN (pptp_ctrl *, int, int, int, const char *); 88 static void pptp_ctrl_process_echo_req (pptp_ctrl *, u_char *, int); 89 static int pptp_ctrl_recv_echo_rep (pptp_ctrl *, u_char *, int); 90 static void pptp_ctrl_send_echo_req (pptp_ctrl *); 91 static int pptp_ctrl_input (pptp_ctrl *, u_char *, int); 92 static int pptp_ctrl_call_input (pptp_ctrl *, int, u_char *, int); 93 static const char *pptp_ctrl_state_string (int); 94 static void pptp_ctrl_fini(pptp_ctrl *); 95 96 /* 97 * pptp_ctrl instance operation functions 98 */ 99 pptp_ctrl * 100 pptp_ctrl_create(void) 101 { 102 pptp_ctrl *_this; 103 104 if ((_this = malloc(sizeof(pptp_ctrl))) == NULL) 105 return NULL; 106 107 return _this; 108 } 109 110 int 111 pptp_ctrl_init(pptp_ctrl *_this) 112 { 113 time_t curr_time; 114 115 PPTP_CTRL_ASSERT(_this != NULL); 116 curr_time = get_monosec(); 117 memset(_this, 0, sizeof(pptp_ctrl)); 118 _this->id = pptp_ctrl_seqno++; 119 _this->sock = -1; 120 121 if ((_this->recv_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) { 122 pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at " 123 "%s(): %m", __func__); 124 goto fail; 125 } 126 if ((_this->send_buf = bytebuffer_create(PPTP_BUFSIZ)) == NULL) { 127 pptp_ctrl_log(_this, LOG_ERR, "bytebuffer_create() failed at " 128 "%s(): %m", __func__); 129 goto fail; 130 } 131 _this->last_rcv_ctrl = curr_time; 132 _this->last_snd_ctrl = curr_time; 133 _this->echo_seq = (random() << 16 )| (random() & 0xffff); 134 _this->echo_interval = PPTP_CTRL_DEFAULT_ECHO_INTERVAL; 135 _this->echo_timeout = PPTP_CTRL_DEFAULT_ECHO_TIMEOUT; 136 slist_init(&_this->call_list); 137 evtimer_set(&_this->ev_timer, pptp_ctrl_timeout, _this); 138 139 return 0; 140 fail: 141 return 1; 142 } 143 144 int 145 pptp_ctrl_start(pptp_ctrl *_this) 146 { 147 int ival; 148 char hbuf0[NI_MAXHOST], sbuf0[NI_MAXSERV]; 149 char hbuf1[NI_MAXHOST], sbuf1[NI_MAXSERV]; 150 struct sockaddr_storage sock; 151 socklen_t socklen; 152 153 PPTP_CTRL_ASSERT(_this != NULL); 154 PPTP_CTRL_ASSERT(_this->sock >= 0); 155 156 /* convert address to strings for logging */ 157 strlcpy(hbuf0, "<unknown>", sizeof(hbuf0)); 158 strlcpy(sbuf0, "<unknown>", sizeof(sbuf0)); 159 strlcpy(hbuf1, "<unknown>", sizeof(hbuf1)); 160 strlcpy(sbuf1, "<unknown>", sizeof(sbuf1)); 161 if (getnameinfo((struct sockaddr *)&_this->peer, _this->peer.ss_len, 162 hbuf0, sizeof(hbuf0), sbuf0, sizeof(sbuf0), 163 NI_NUMERICHOST | NI_NUMERICSERV) != 0) { 164 pptp_ctrl_log(_this, LOG_ERR, 165 "getnameinfo() failed at %s(): %m", __func__); 166 } 167 socklen = sizeof(sock); 168 if (getsockname(_this->sock, (struct sockaddr *)&sock, &socklen) != 0) { 169 pptp_ctrl_log(_this, LOG_ERR, 170 "getsockname() failed at %s(): %m", __func__); 171 goto fail; 172 } 173 if (getnameinfo((struct sockaddr *)&sock, sock.ss_len, hbuf1, 174 sizeof(hbuf1), sbuf1, sizeof(sbuf1), 175 NI_NUMERICHOST | NI_NUMERICSERV) != 0) { 176 pptp_ctrl_log(_this, LOG_ERR, 177 "getnameinfo() failed at %s(): %m", __func__); 178 } 179 pptp_ctrl_log(_this, LOG_INFO, "Starting peer=%s:%s/tcp " 180 "sock=%s:%s/tcp", hbuf0, sbuf0, hbuf1, sbuf1); 181 182 if ((ival = fcntl(_this->sock, F_GETFL, 0)) < 0) { 183 pptp_ctrl_log(_this, LOG_ERR, 184 "fcntl(F_GET_FL) failed at %s(): %m", __func__); 185 goto fail; 186 } else if (fcntl(_this->sock, F_SETFL, ival | O_NONBLOCK) < 0) { 187 pptp_ctrl_log(_this, LOG_ERR, 188 "fcntl(F_SET_FL) failed at %s(): %m", __func__); 189 goto fail; 190 } 191 pptp_ctrl_set_io_event(_this); 192 pptp_ctrl_reset_timeout(_this); 193 194 return 0; 195 fail: 196 return 1; 197 } 198 199 /* Timer */ 200 static void 201 pptp_ctrl_timeout(int fd, short event, void *ctx) 202 { 203 int i; 204 pptp_call *call; 205 pptp_ctrl *_this; 206 time_t last, curr_time; 207 208 _this = ctx; 209 curr_time = get_monosec(); 210 211 PPTP_CTRL_DBG((_this, DEBUG_LEVEL_3, "enter %s()", __func__)); 212 /* clean up call */ 213 i = 0; 214 while (i < slist_length(&_this->call_list)) { 215 call = slist_get(&_this->call_list, i); 216 if (call->state == PPTP_CALL_STATE_CLEANUP_WAIT && 217 curr_time - call->last_io > PPTP_CALL_CLEANUP_WAIT_TIME) { 218 pptp_call_stop(call); 219 pptp_call_destroy(call); 220 slist_remove(&_this->call_list, i); 221 } else 222 i++; 223 } 224 225 /* State machine: Timeout */ 226 switch (_this->state) { 227 default: 228 case PPTP_CTRL_STATE_WAIT_CTRL_REPLY: 229 case PPTP_CTRL_STATE_IDLE: 230 if (curr_time - _this->last_rcv_ctrl > PPTPD_IDLE_TIMEOUT) { 231 pptp_ctrl_log(_this, LOG_ERR, 232 "Timeout in state %s", 233 pptp_ctrl_state_string(_this->state)); 234 pptp_ctrl_fini(_this); 235 return; 236 } 237 break; 238 case PPTP_CTRL_STATE_ESTABLISHED: 239 last = MAX(_this->last_rcv_ctrl, _this->last_snd_ctrl); 240 241 if (curr_time - _this->last_rcv_ctrl 242 >= _this->echo_interval + _this->echo_timeout) { 243 pptp_ctrl_log(_this, LOG_INFO, 244 "Timeout waiting for echo reply"); 245 pptp_ctrl_fini(_this); 246 return; 247 } 248 if (curr_time - last >= _this->echo_interval) { 249 PPTP_CTRL_DBG((_this, LOG_DEBUG, "Echo")); 250 _this->echo_seq++; 251 pptp_ctrl_send_echo_req(_this); 252 } 253 break; 254 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 255 if (curr_time - _this->last_snd_ctrl > 256 PPTP_CTRL_StopCCRP_WAIT_TIME) { 257 pptp_ctrl_log(_this, LOG_WARNING, 258 "Timeout waiting for StopCCRP"); 259 pptp_ctrl_fini(_this); 260 return; 261 } 262 break; 263 case PPTP_CTRL_STATE_DISPOSING: 264 pptp_ctrl_fini(_this); 265 return; 266 } 267 pptp_ctrl_reset_timeout(_this); 268 } 269 270 static void 271 pptp_ctrl_reset_timeout(pptp_ctrl *_this) 272 { 273 struct timeval tv; 274 275 switch (_this->state) { 276 case PPTP_CTRL_STATE_DISPOSING: 277 /* call back immediately */ 278 timerclear(&tv); 279 break; 280 default: 281 tv.tv_sec = PPTP_CTRL_TIMEOUT_IVAL_SEC; 282 tv.tv_usec = 0; 283 break; 284 } 285 evtimer_add(&_this->ev_timer, &tv); 286 } 287 288 /** 289 * Terminate PPTP control connection 290 * @result The value for Stop-Control-Connection-Request(StopCCRQ) result. 291 This function will not sent StopCCRQ when the value == 0 and 292 the specification does not require to sent it. 293 * @see ::#PPTP_StopCCRQ_REASON_STOP_PROTOCOL 294 * @see ::#PPTP_StopCCRQ_REASON_STOP_LOCAL_SHUTDOWN 295 */ 296 void 297 pptp_ctrl_stop(pptp_ctrl *_this, int result) 298 { 299 int i; 300 pptp_call *call; 301 302 switch (_this->state) { 303 case PPTP_CTRL_STATE_WAIT_STOP_REPLY: 304 /* waiting responce. */ 305 /* this state will timeout by pptp_ctrl_timeout */ 306 break; 307 case PPTP_CTRL_STATE_ESTABLISHED: 308 if (result != 0) { 309 for (i = 0; i < slist_length(&_this->call_list); i++) { 310 call = slist_get(&_this->call_list, i); 311 pptp_call_disconnect(call, 312 PPTP_CDN_RESULT_ADMIN_SHUTDOWN, 0, NULL); 313 } 314 pptp_ctrl_send_StopCCRQ(_this, result); 315 _this->state = PPTP_CTRL_STATE_WAIT_STOP_REPLY; 316 break; 317 } 318 /* FALLTHROUGH */ 319 default: 320 pptp_ctrl_fini(_this); 321 } 322 return; 323 } 324 325 326 /* finish PPTP control */ 327 static void 328 pptp_ctrl_fini(pptp_ctrl *_this) 329 { 330 pptp_call *call; 331 332 PPTP_CTRL_ASSERT(_this != NULL); 333 334 if (_this->sock >= 0) { 335 event_del(&_this->ev_sock); 336 close(_this->sock); 337 _this->sock = -1; 338 } 339 for (slist_itr_first(&_this->call_list); 340 slist_itr_has_next(&_this->call_list);) { 341 call = slist_itr_next(&_this->call_list); 342 pptp_call_stop(call); 343 pptp_call_destroy(call); 344 slist_itr_remove(&_this->call_list); 345 } 346 347 if (_this->on_io_event != 0) { 348 /* 349 * as the complete terminate process needs complicated 350 * exception handling, do partially at here. 351 * rest of part will be handled by timer-event-handler. 352 */ 353 PPTP_CTRL_DBG((_this, LOG_DEBUG, "Disposing")); 354 _this->state = PPTP_CTRL_STATE_DISPOSING; 355 pptp_ctrl_reset_timeout(_this); 356 return; 357 } 358 359 evtimer_del(&_this->ev_timer); 360 slist_fini(&_this->call_list); 361 362 pptp_ctrl_log (_this, LOG_NOTICE, "logtype=Finished"); 363 364 /* disable _this */ 365 pptpd_ctrl_finished_notify(_this->pptpd, _this); 366 } 367 368 /* free PPTP control context */ 369 void 370 pptp_ctrl_destroy(pptp_ctrl *_this) 371 { 372 if (_this->send_buf != NULL) { 373 bytebuffer_destroy(_this->send_buf); 374 _this->send_buf = NULL; 375 } 376 if (_this->recv_buf != NULL) { 377 bytebuffer_destroy(_this->recv_buf); 378 _this->recv_buf = NULL; 379 } 380 free(_this); 381 } 382 383 /* 384 * network I/O 385 */ 386 /* I/O event dispather */ 387 static void 388 pptp_ctrl_io_event(int fd, short evmask, void *ctx) 389 { 390 int sz, lpkt, hdrlen; 391 u_char *pkt; 392 pptp_ctrl *_this; 393 394 _this = ctx; 395 PPTP_CTRL_ASSERT(_this != NULL); 396 397 _this->on_io_event = 1; 398 if ((evmask & EV_WRITE) != 0) { 399 if (pptp_ctrl_output_flush(_this) != 0 || 400 _this->state == PPTP_CTRL_STATE_DISPOSING) 401 goto fail; 402 _this->send_ready = 1; 403 } 404 if ((evmask & EV_READ) != 0) { 405 sz = read(_this->sock, bytebuffer_pointer(_this->recv_buf), 406 bytebuffer_remaining(_this->recv_buf)); 407 if (sz <= 0) { 408 if (sz == 0 || errno == ECONNRESET) { 409 pptp_ctrl_log(_this, LOG_INFO, 410 "Connection closed by foreign host"); 411 pptp_ctrl_fini(_this); 412 goto fail; 413 } else if (errno != EAGAIN && errno != EINTR) { 414 pptp_ctrl_log(_this, LOG_INFO, 415 "read() failed at %s(): %m", __func__); 416 pptp_ctrl_fini(_this); 417 goto fail; 418 } 419 } 420 bytebuffer_put(_this->recv_buf, BYTEBUFFER_PUT_DIRECT, sz); 421 bytebuffer_flip(_this->recv_buf); 422 423 for (;;) { 424 pkt = bytebuffer_pointer(_this->recv_buf); 425 lpkt = bytebuffer_remaining(_this->recv_buf); 426 if (pkt == NULL || 427 lpkt < sizeof(struct pptp_ctrl_header)) 428 break; /* read again */ 429 430 hdrlen = pkt[0] << 8 | pkt[1]; 431 if (lpkt < hdrlen) 432 break; /* read again */ 433 434 bytebuffer_get(_this->recv_buf, NULL, hdrlen); 435 if (pptp_ctrl_input(_this, pkt, hdrlen) != 0 || 436 _this->state == PPTP_CTRL_STATE_DISPOSING) { 437 bytebuffer_compact(_this->recv_buf); 438 goto fail; 439 } 440 } 441 bytebuffer_compact(_this->recv_buf); 442 } 443 if (pptp_ctrl_output_flush(_this) != 0) 444 goto fail; 445 pptp_ctrl_set_io_event(_this); 446 fail: 447 _this->on_io_event = 0; 448 } 449 450 451 /* set i/o event mask */ 452 static void 453 pptp_ctrl_set_io_event(pptp_ctrl *_this) 454 { 455 int evmask; 456 457 PPTP_CTRL_ASSERT(_this != NULL); 458 PPTP_CTRL_ASSERT(_this->sock >= 0); 459 460 evmask = 0; 461 if (bytebuffer_remaining(_this->recv_buf) > 128) 462 evmask |= EV_READ; 463 if (_this->send_ready == 0) 464 evmask |= EV_WRITE; 465 466 event_del(&_this->ev_sock); 467 if (evmask != 0) { 468 event_set(&_this->ev_sock, _this->sock, evmask, 469 pptp_ctrl_io_event, _this); 470 event_add(&_this->ev_sock, NULL); 471 } 472 } 473 474 /** 475 * Output PPTP control packet 476 * @param pkt pointer to packet buffer. 477 * when it was appended by _this-.send_buf using bytebuffer, 478 * specify NULL. 479 * @param lpkt packet length 480 */ 481 void 482 pptp_ctrl_output(pptp_ctrl *_this, u_char *pkt, int lpkt) 483 { 484 PPTP_CTRL_ASSERT(_this != NULL); 485 PPTP_CTRL_ASSERT(lpkt > 0); 486 487 /* just put the packet into the buffer now. send it later */ 488 bytebuffer_put(_this->send_buf, pkt, lpkt); 489 490 if (_this->on_io_event != 0) { 491 /* 492 * pptp_ctrl_output_flush() will be called by the end of 493 * the I/O event handler. 494 */ 495 } else { 496 /* 497 * When this function is called by other than I/O event handler, 498 * we need to call pptp_ctrl_output_flush(). However if we do 499 * it here, then we need to consider the situation 500 * 'flush => write failure => finalize'. The situation requires 501 * the caller function to handle the exception and causes 502 * complication. So we call pptp_ctrl_output_flush() by the 503 * the next send ready event. 504 */ 505 _this->send_ready = 0; /* clear 'send ready' */ 506 pptp_ctrl_set_io_event(_this); /* wait 'send ready */ 507 } 508 509 return; 510 } 511 512 /* Send Stop-Control-Connection-Request */ 513 514 /* flush output packet */ 515 static int 516 pptp_ctrl_output_flush(pptp_ctrl *_this) 517 { 518 int sz; 519 time_t curr_time; 520 521 curr_time = get_monosec(); 522 523 if (bytebuffer_position(_this->send_buf) <= 0) 524 return 0; /* nothing to write */ 525 if (_this->send_ready == 0) { 526 pptp_ctrl_set_io_event(_this); 527 return 0; /* not ready to write */ 528 } 529 530 bytebuffer_flip(_this->send_buf); 531 532 if (PPTP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) { 533 pptp_ctrl_log(_this, LOG_DEBUG, "PPTP Control output packet"); 534 show_hd(debug_get_debugfp(), 535 bytebuffer_pointer(_this->send_buf), 536 bytebuffer_remaining(_this->send_buf)); 537 } 538 if ((sz = write(_this->sock, bytebuffer_pointer(_this->send_buf), 539 bytebuffer_remaining(_this->send_buf))) < 0) { 540 pptp_ctrl_log(_this, LOG_ERR, "write to socket failed: %m"); 541 pptp_ctrl_fini(_this); 542 543 return 1; 544 } 545 _this->last_snd_ctrl = curr_time; 546 bytebuffer_get(_this->send_buf, NULL, sz); 547 bytebuffer_compact(_this->send_buf); 548 _this->send_ready = 0; 549 550 return 0; 551 } 552 553 /* convert Start-Control-Connection-{Request,Reply} packet to strings */ 554 static void 555 pptp_ctrl_SCCRx_string(struct pptp_scc *scc, u_char *buf, int lbuf) 556 { 557 char buf1[128], buf2[128], buf3[128]; 558 559 /* sanity check */ 560 strlcpy(buf1, scc->host_name, sizeof(buf1)); 561 strlcpy(buf2, scc->vendor_string, sizeof(buf2)); 562 563 if (scc->result_code != 0) 564 snprintf(buf3, sizeof(buf3), "result=%d error=%d ", 565 scc->result_code, scc->error_code); 566 else 567 buf3[0] = '\0'; 568 569 snprintf(buf, lbuf, 570 "protocol_version=%d.%d %sframing=%s bearer=%s max_channels=%d " 571 "firmware_revision=%d(0x%04x) host_name=\"%s\" " 572 "vendor_string=\"%s\"", 573 scc->protocol_version >> 8, scc->protocol_version & 0xff, buf3, 574 pptp_framing_string(scc->framing_caps), 575 pptp_bearer_string(scc->bearer_caps), scc->max_channels, 576 scc->firmware_revision, scc->firmware_revision, buf1, buf2); 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 (PPTP_CTRL_CONF(_this)->hostname == NULL) 751 val = ""; 752 strlcpy(scc->host_name, val, sizeof(scc->host_name)); 753 754 /* vender 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