1/* $OpenBSD: lcp.c,v 1.18 2019/02/27 04:52:19 denis Exp $ */ 2 3/*- 4 * Copyright (c) 2009 Internet Initiative Japan Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28/* $Id: lcp.c,v 1.18 2019/02/27 04:52:19 denis Exp $ */ 29/**@file 30 * This file provides LCP related functions. 31 *<pre> 32 * RFC1661: The Point-to-Point Protocol (PPP) 33 * RFC1570: PPP LCP Extensions 34 *</pre> 35 */ 36#include <sys/types.h> 37#include <sys/socket.h> 38#include <sys/time.h> 39#include <netinet/in.h> 40#include <net/if_dl.h> 41#include <stdlib.h> 42#include <stdio.h> 43#include <syslog.h> 44#include <string.h> 45#include <event.h> 46#include <ctype.h> 47 48#include "npppd.h" 49#include "ppp.h" 50#include "psm-opt.h" 51 52#define SPACE " \t\r\n" 53 54#include "debugutil.h" 55 56#ifdef LCP_DEBUG 57#define LCP_DBG(x) fsm_log x 58#define LCP_ASSERT(x) ASSERT(x) 59#else 60#define LCP_DBG(x) 61#define LCP_ASSERT(x) 62#endif 63 64#define PROTREJ 0x08 65#define ECHOREQ 0x09 66#define ECHOREP 0x0a 67#define IDENTIFICATION 0x0c 68 69static void lcp_resetci(fsm *); 70static void lcp_addci(fsm *, u_char *, int *); 71static int lcp_reqci(fsm *, u_char *, int *, int); 72static int lcp_ackci(fsm *, u_char *, int); 73static int lcp_nakci(fsm *, u_char *, int); 74static int lcp_rejci(fsm *, u_char *, int); 75static int lcp_cilen(fsm *); 76static void lcp_open(fsm *); 77static void lcp_down(fsm *); 78static void lcp_finished(fsm *); 79static int lcp_ext(fsm *, int, int, u_char *, int); 80static void lcp_timeout(void *); 81static void lcp_reset_timeout(void *); 82static int lcp_proxy_recv_ci(fsm *, u_char *, int); 83static int lcp_proxy_sent_ci(fsm *, u_char *, int); 84static void lcp_load_authconfig(fsm *f); 85 86static struct fsm_callbacks lcp_callbacks = { 87 lcp_resetci, /* Reset our Configuration Information */ 88 lcp_cilen, /* Length of our Configuration Information */ 89 lcp_addci, /* Add our Configuration Information */ 90 lcp_ackci, /* ACK our Configuration Information */ 91 lcp_nakci, /* NAK our Configuration Information */ 92 lcp_rejci, /* Reject our Configuration Information */ 93 lcp_reqci, /* Request peer's Configuration Information */ 94 lcp_open, /* Called when fsm reaches OPENED state */ 95 lcp_down, /* Called when fsm leaves OPENED state */ 96 NULL, /* Called when we want the lower layer up */ 97 lcp_finished, /* Called when we want the lower layer down */ 98 NULL, /* Called when Protocol-Reject received */ 99 NULL, /* Retransmission is necessary */ 100 lcp_ext, /* Called to handle LCP-specific codes */ 101 "lcp" /* String name of protocol */ 102}; 103#define NO_AUTH_AGREEABLE(lcp) \ 104 (!psm_opt_is_enabled(lcp, pap) || psm_opt_is_rejected(lcp, pap)) && \ 105 (!psm_opt_is_enabled(lcp, chap) || psm_opt_is_rejected(lcp, chap)) && \ 106 (!psm_opt_is_enabled(lcp, chapms) || psm_opt_is_rejected(lcp, chapms)) &&\ 107 (!psm_opt_is_enabled(lcp, chapms_v2) || psm_opt_is_rejected(lcp, chapms_v2)) && \ 108 (!psm_opt_is_enabled(lcp, eap) || psm_opt_is_rejected(lcp, eap)) 109 110 111/** initializing context for LCP. */ 112void 113lcp_init(lcp *_this, npppd_ppp *ppp) 114{ 115 struct tunnconf *conf; 116 117 fsm_init(&_this->fsm); 118 119 _this->fsm.ppp = ppp; 120 _this->fsm.callbacks = &lcp_callbacks; 121 _this->fsm.protocol = PPP_PROTO_LCP; 122 _this->fsm.flags |= OPT_SILENT; 123 _this->timerctx.ctx = _this; 124 125 _this->recv_ress = 0; 126 _this->recv_reqs = 0; 127 _this->magic_number = arc4random(); 128 129 conf = ppp_get_tunnconf(ppp); 130 PPP_FSM_CONFIG(&_this->fsm, timeouttime, conf->lcp_timeout); 131 PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits, 132 conf->lcp_max_configure); 133 PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits, 134 conf->lcp_max_terminate); 135 PPP_FSM_CONFIG(&_this->fsm, maxnakloops, 136 conf->lcp_max_nak_loop); 137 138 _this->echo_failures = 0; 139 if (!conf->lcp_keepalive) 140 _this->echo_interval = 0; 141 else { 142 _this->echo_interval = conf->lcp_keepalive_interval; 143 _this->echo_retry_interval = conf->lcp_keepalive_retry_interval; 144 _this->echo_max_retries = conf->lcp_keepalive_max_retries; 145 } 146 _this->auth_order[0] = -1; 147} 148 149 150/** 151 * This function is called when HDLC as LCP's lower layer is up. 152 */ 153void 154lcp_lowerup(lcp *_this) 155{ 156 fsm_lowerup(&_this->fsm); 157 fsm_open(&_this->fsm); 158 159 if (_this->dialin_proxy != 0 && 160 _this->dialin_proxy_lcp_renegotiation == 0) { 161 _this->fsm.state = OPENED; 162 lcp_open(&_this->fsm); 163 } 164} 165 166/** 167 * sending Protocol-Reject. 168 */ 169void 170lcp_send_protrej(lcp *_this, u_char *pktp, int lpktp) 171{ 172 LCP_ASSERT(_this != NULL); 173 LCP_ASSERT(pktp != NULL); 174 175 fsm_sdata(&_this->fsm, PROTREJ, _this->fsm.id++, pktp, lpktp); 176} 177 178static const char * 179lcp_auth_string(int auth) 180{ 181 switch (auth) { 182 case PPP_AUTH_PAP: return "PAP"; 183 case PPP_AUTH_CHAP_MD5: return "MD5-CHAP"; 184 case PPP_AUTH_CHAP_MS: return "MS-CHAP"; 185 case PPP_AUTH_CHAP_MS_V2: return "MS-CHAP-V2"; 186 case PPP_AUTH_EAP: return "EAP"; 187 case 0: return "none"; 188 default: return "ERROR"; 189 } 190} 191 192static void 193lcp_open(fsm *f) 194{ 195 lcp *_this; 196 int peer_auth = 0; 197 198 LCP_ASSERT(f != NULL); 199 _this = &f->ppp->lcp; 200 201 if (psm_opt_is_accepted(_this, pap)) 202 peer_auth = PPP_AUTH_PAP; 203 else if (psm_opt_is_accepted(_this, chap)) 204 peer_auth = PPP_AUTH_CHAP_MD5; 205 else if (psm_opt_is_accepted(_this, chapms)) 206 peer_auth = PPP_AUTH_CHAP_MS; 207 else if (psm_opt_is_accepted(_this, chapms_v2)) 208 peer_auth = PPP_AUTH_CHAP_MS_V2; 209 else if (psm_opt_is_accepted(_this, eap)) 210 peer_auth = PPP_AUTH_EAP; 211 else { 212 if (_this->auth_order[0] > 0) { 213 fsm_log(f, LOG_INFO, 214 "failed to negotiate a auth protocol."); 215 fsm_close(f, "Authentication is required"); 216 ppp_set_disconnect_cause(f->ppp, 217 PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE, 218 _this->auth_order[0] /* first one */, 219 1 /* peer refused */, NULL); 220 ppp_stop(f->ppp, "Authentication is required"); 221 return; 222 } 223 } 224 f->ppp->peer_auth = peer_auth; 225 226 if (_this->xxxmru > 0 && f->ppp->peer_mru <= 0) 227 f->ppp->peer_mru = _this->xxxmru; 228 if (f->ppp->peer_mru <= 0) 229 f->ppp->peer_mru = f->ppp->mru; 230 231 /* checking the size of ppp->peer_mru. */ 232 LCP_ASSERT(f->ppp->peer_mru > 500); 233 234 fsm_log(f, LOG_INFO, "logtype=Opened mru=%d/%d auth=%s magic=%08x/%08x" 235 , f->ppp->mru, f->ppp->peer_mru 236 , lcp_auth_string(peer_auth) 237 , f->ppp->lcp.magic_number, f->ppp->lcp.peer_magic_number 238 ); 239 lcp_reset_timeout(_this); 240 241 ppp_lcp_up(f->ppp); 242} 243 244static void 245lcp_down(fsm *f) 246{ 247 lcp *_this; 248 249 if (f->ppp->disconnect_code == PPP_DISCON_NO_INFORMATION) { 250 /* 251 * disconnect code is set when we are closing the lcp, so 252 * 'no info' means the lcp is going down by peer's termreq. 253 */ 254 ppp_set_disconnect_cause(f->ppp, PPP_DISCON_NORMAL, 0, 255 1 /* peer */, NULL); 256#ifdef USE_NPPPD_RADIUS 257 ppp_set_radius_terminate_cause(f->ppp, 258 RADIUS_TERMNATE_CAUSE_USER_REQUEST); 259#endif 260 } 261 262 _this = &f->ppp->lcp; 263 UNTIMEOUT(lcp_timeout, _this); 264} 265 266static void 267lcp_finished(fsm *f) 268{ 269 ppp_lcp_finished(f->ppp); 270} 271 272/** 273 * resetting ConfReq. 274 */ 275static void 276lcp_resetci(fsm *f) 277{ 278 LCP_ASSERT(f != NULL); 279 280 /* Unless doing dialin-proxy without re-negotiation */ 281 if (!(f->ppp->lcp.dialin_proxy != 0 && 282 f->ppp->lcp.dialin_proxy_lcp_renegotiation == 0)) { 283 284 /* Reset the LCP options' state */ 285 memset(&f->ppp->lcp.opt, 0, sizeof(f->ppp->lcp.opt)); 286 f->ppp->lcp.auth_order[0] = -1; 287 } 288} 289 290/** 291 * The length of ConfReq. 292 */ 293static int 294lcp_cilen(fsm *f) 295{ 296 LCP_ASSERT(f != NULL); 297 return f->ppp->mru; 298} 299 300/** 301 * selecting authentication protocols which is not rejected yet in order 302 * of auth_order, and adding Authentication-Protocol options in ConfReq 303 * packet area. 304 */ 305static int 306lcp_add_auth(fsm *f, u_char **ucpp) 307{ 308 int i; 309 u_char *ucp; 310 lcp *_this; 311 312 ucp = *ucpp; 313 _this = &f->ppp->lcp; 314 315 for (i = 0; _this->auth_order[i] > 0 && 316 i < countof(_this->auth_order); i++) { 317 switch (_this->auth_order[i]) { 318 case PPP_AUTH_PAP: 319 if (psm_opt_is_rejected(_this, pap)) 320 break; 321 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp); 322 PUTCHAR(4, ucp); 323 PUTSHORT(PPP_AUTH_PAP, ucp); 324 psm_opt_set_requested(_this, pap, 1); 325 _this->lastauth = PPP_AUTH_PAP; 326 goto end_loop; 327 case PPP_AUTH_CHAP_MD5: 328 if (psm_opt_is_rejected(_this, chap)) 329 break; 330 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp); 331 PUTCHAR(5, ucp); 332 PUTSHORT(PPP_AUTH_CHAP, ucp); 333 PUTCHAR(PPP_AUTH_CHAP_MD5, ucp); 334 psm_opt_set_requested(_this, chap, 1); 335 _this->lastauth = PPP_AUTH_CHAP_MD5; 336 goto end_loop; 337 case PPP_AUTH_CHAP_MS: 338 if (psm_opt_is_rejected(_this, chapms)) 339 break; 340 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp); 341 PUTCHAR(5, ucp); 342 PUTSHORT(PPP_AUTH_CHAP, ucp); 343 PUTCHAR(PPP_AUTH_CHAP_MS, ucp); 344 psm_opt_set_requested(_this, chapms, 1); 345 _this->lastauth = PPP_AUTH_CHAP_MS; 346 goto end_loop; 347 case PPP_AUTH_CHAP_MS_V2: 348 if (psm_opt_is_rejected(_this, chapms_v2)) 349 break; 350 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp); 351 PUTCHAR(5, ucp); 352 PUTSHORT(PPP_AUTH_CHAP, ucp); 353 PUTCHAR(PPP_AUTH_CHAP_MS_V2, ucp); 354 psm_opt_set_requested(_this, chapms_v2,1); 355 _this->lastauth = PPP_AUTH_CHAP_MS_V2; 356 goto end_loop; 357 case PPP_AUTH_EAP: 358 if (psm_opt_is_rejected(_this, eap)) 359 break; 360 PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp); 361 PUTCHAR(4, ucp); 362 PUTSHORT(PPP_AUTH_EAP, ucp); 363 psm_opt_set_requested(_this, eap, 1); 364 _this->lastauth = PPP_AUTH_EAP; 365 goto end_loop; 366 } 367 } 368 _this->lastauth = -1; 369 return -1; 370end_loop: 371 *ucpp = ucp; 372 373 return 0; 374} 375 376/** 377 * making ConfReq. 378 */ 379static void 380lcp_addci(fsm *f, u_char *ucp, int *lenp) 381{ 382 lcp *_this; 383 u_char *start_ucp = ucp; 384 385 LCP_ASSERT(f != NULL); 386 387 _this = &f->ppp->lcp; 388 if (!psm_opt_is_rejected(_this, mru)) { 389 PUTCHAR(PPP_LCP_MRU, ucp); 390 PUTCHAR(4, ucp); 391 392 if (_this->xxxmru > 0) { /* this value is got by Nak. */ 393 PUTSHORT(_this->xxxmru, ucp); 394 } else { 395 PUTSHORT(f->ppp->mru, ucp); 396 } 397 psm_opt_set_requested(_this, mru, 1); 398 } 399 if (f->ppp->has_acf == 1) { 400 if (!psm_opt_is_rejected(_this, pfc)) { 401 PUTCHAR(PPP_LCP_PFC, ucp); 402 PUTCHAR(2, ucp); 403 psm_opt_set_requested(_this, pfc, 1); 404 } 405 if (!psm_opt_is_rejected(_this, acfc)) { 406 PUTCHAR(PPP_LCP_ACFC, ucp); 407 PUTCHAR(2, ucp); 408 psm_opt_set_requested(_this, acfc, 1); 409 } 410 } 411 PUTCHAR(PPP_LCP_MAGICNUMBER, ucp); 412 PUTCHAR(6, ucp); 413 PUTLONG(_this->magic_number, ucp); 414 415 if (f->ppp->peer_auth != 0) { 416 _this->auth_order[0] = f->ppp->peer_auth; 417 _this->auth_order[1] = -1; 418 } else if (_this->auth_order[0] < 0) { 419 lcp_load_authconfig(f); 420 } 421 422 lcp_add_auth(f, &ucp); 423 *lenp = ucp - start_ucp; 424} 425 426static int 427lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) 428{ 429 uint32_t magic; 430 int type, len, rcode, mru, lrej; 431 u_char *inp0, *rejbuf, *nakbuf, *nakbuf0; 432 lcp *_this; 433 434 _this = &f->ppp->lcp; 435 rejbuf = NULL; 436 rcode = -1; 437 inp0 = inp; 438 lrej = 0; 439 440 if ((rejbuf = malloc(*lenp)) == NULL) 441 return -1; 442 if ((nakbuf0 = malloc(*lenp)) == NULL) { 443 free(rejbuf); 444 return -1; 445 } 446 nakbuf = nakbuf0; 447 448#define remlen() (*lenp - (inp - inp0)) 449#define LCP_OPT_PEER_ACCEPTED(opt) \ 450 psm_peer_opt_set_accepted(&f->ppp->lcp, opt, 1); 451 452 f->ppp->lcp.recv_reqs++; 453 454 while (remlen() >= 2) { 455 GETCHAR(type, inp); 456 GETCHAR(len, inp); 457 if (len <= 0 || remlen() + 2 < len) 458 goto fail; 459 460 switch (type) { 461 case PPP_LCP_MRU: 462 if (len != 4) 463 goto fail; 464 GETSHORT(mru, inp); 465 f->ppp->peer_mru = mru; 466 if (mru < NPPPD_MIN_MRU) { 467 if (reject_if_disagree) { 468 inp -= 2; 469 goto reject; 470 } 471 if (lrej > 0) { 472 /* if there is a reject, will send Rej, not send Nak. */ 473 } else { 474 inp -= 2; 475 memcpy(nakbuf, inp, len); 476 nakbuf += len; 477 inp += 2; 478 PUTSHORT(f->ppp->mru, nakbuf); 479 480 rcode = CONFNAK; 481 } 482 } else 483 LCP_OPT_PEER_ACCEPTED(mru); 484 break; 485 case PPP_LCP_MAGICNUMBER: 486 if (len != 6) 487 goto fail; 488 GETLONG(magic, inp); 489 if (magic == _this->magic_number) { 490 inp -= 4; 491 goto reject; 492 } 493 _this->peer_magic_number = magic; 494 break; 495 case PPP_LCP_PFC: 496 if (len != 2) 497 goto fail; 498 LCP_OPT_PEER_ACCEPTED(pfc); 499 break; 500 case PPP_LCP_ACFC: 501 if (len != 2) 502 goto fail; 503 LCP_OPT_PEER_ACCEPTED(acfc); 504 break; 505 case PPP_LCP_AUTH_PROTOCOL: 506 /* currently never authenticate. */ 507 case PPP_LCP_QUALITY_PROTOCOL: /* not used */ 508 default: 509reject: 510 inp -= 2; 511 memcpy(rejbuf + lrej, inp, len); 512 lrej += len; 513 inp += len; 514 rcode = CONFREJ; 515 } 516 continue; 517 } 518 if (rcode == -1) 519 rcode = CONFACK; 520fail: 521 switch (rcode) { 522 case CONFREJ: 523 memcpy(inp0, rejbuf, lrej); 524 *lenp = lrej; 525 break; 526 case CONFNAK: 527 memcpy(inp0, nakbuf0, nakbuf - nakbuf0); 528 *lenp = nakbuf - nakbuf0; 529 break; 530 } 531 if (rcode != CONFACK) { 532 psm_peer_opt_set_accepted(&f->ppp->lcp, mru, 0); 533 psm_peer_opt_set_accepted(&f->ppp->lcp, pfc, 0); 534 psm_peer_opt_set_accepted(&f->ppp->lcp, acfc, 0); 535 } 536 free(rejbuf); 537 free(nakbuf0); 538 539 return rcode; 540#undef remlen 541#undef LCP_OPT_PEER_ACCEPTED 542} 543 544/** receiving ConfAck. */ 545static int 546lcp_ackci(fsm *f, u_char *inp, int inlen) 547{ 548 int chapalg, authproto, type, len, mru, magic; 549 u_char *inp0; 550 551#define remlen() (inlen - (inp - inp0)) 552#define LCP_OPT_ACCEPTED(opt) \ 553 if (!psm_opt_is_requested(&f->ppp->lcp, opt)) \ 554 goto fail; \ 555 psm_opt_set_accepted(&f->ppp->lcp, opt, 1); 556 557 f->ppp->lcp.recv_ress++; 558 inp0 = inp; 559 while (remlen() >= 2) { 560 GETCHAR(type, inp); 561 GETCHAR(len, inp); 562 563 if (len <= 0 || remlen() + 2 < len) 564 goto fail; 565 566 switch (type) { 567 case PPP_LCP_MAGICNUMBER: 568 if (len != 6) 569 goto fail; 570 GETLONG(magic, inp); 571 if (f->ppp->lcp.magic_number != magic) 572 goto fail; 573 break; 574 case PPP_LCP_MRU: 575 if (len != 4) 576 goto fail; 577 LCP_OPT_ACCEPTED(mru); 578 GETSHORT(mru, inp); 579 break; 580 case PPP_LCP_AUTH_PROTOCOL: 581 if (len < 4) 582 goto fail; 583 GETSHORT(authproto, inp); 584 switch (authproto) { 585 case PPP_AUTH_PAP: 586 if (len != 4) 587 goto fail; 588 LCP_OPT_ACCEPTED(pap); 589 break; 590 case PPP_AUTH_CHAP: 591 if (len != 5) 592 goto fail; 593 GETCHAR(chapalg, inp); 594 switch (chapalg) { 595 case PPP_AUTH_CHAP_MD5: 596 LCP_OPT_ACCEPTED(chap); 597 break; 598 case PPP_AUTH_CHAP_MS: 599 LCP_OPT_ACCEPTED(chapms); 600 break; 601 case PPP_AUTH_CHAP_MS_V2: 602 LCP_OPT_ACCEPTED(chapms_v2); 603 break; 604 } 605 break; 606 case PPP_AUTH_EAP: 607 if (len != 4) 608 goto fail; 609 LCP_OPT_ACCEPTED(eap); 610 break; 611 } 612 break; 613 614 /* 615 * As RFC1661, ConfRej must be used for boolean options, but 616 * at least RouterTester uses ConfNak for them. 617 */ 618 case PPP_LCP_PFC: 619 if (len != 2) 620 goto fail; 621 LCP_OPT_ACCEPTED(pfc); 622 break; 623 case PPP_LCP_ACFC: 624 if (len != 2) 625 goto fail; 626 LCP_OPT_ACCEPTED(acfc); 627 break; 628 629 default: 630 goto fail; 631 } 632 } 633 return 1; 634fail: 635 fsm_log(f, LOG_ERR, "Received unexpected ConfAck."); 636 if (debug_get_debugfp() != NULL) 637 show_hd(debug_get_debugfp(), inp, remlen()); 638 return 0; 639#undef LCP_OPT_ACCEPTED 640} 641 642/** receiving ConfNak. */ 643static int 644lcp_nakci(fsm *f, u_char *inp, int inlen) 645{ 646 int chapalg, authproto, type, len, mru; 647 u_char *inp0; 648 lcp *_this; 649 const char *peer_auth = "unknown"; 650 651#define remlen() (inlen - (inp - inp0)) 652#define LCP_OPT_REJECTED(opt) \ 653 if (!psm_opt_is_requested(&f->ppp->lcp, opt)) \ 654 goto fail; \ 655 psm_opt_set_rejected(&f->ppp->lcp, opt, 1); 656 657 f->ppp->lcp.recv_ress++; 658 inp0 = inp; 659 _this = &f->ppp->lcp; 660 while (remlen() >= 2) { 661 GETCHAR(type, inp); 662 GETCHAR(len, inp); 663 664 if (len <= 0 || remlen() + 2 < len) 665 goto fail; 666 667 switch (type) { 668 case PPP_LCP_MRU: 669 if (len < 4) 670 goto fail; 671 GETSHORT(mru, inp); 672 fsm_log(f, LOG_NOTICE, 673 "ignored ConfNak from the peer: mru=%d", mru); 674 _this->xxxmru = mru; 675 break; 676 case PPP_LCP_AUTH_PROTOCOL: 677 if (len < 4) 678 goto fail; 679 switch (_this->lastauth) { 680 case PPP_AUTH_PAP: 681 psm_opt_set_rejected(_this, pap, 1); 682 break; 683 case PPP_AUTH_CHAP_MD5: 684 psm_opt_set_rejected(_this, chap, 1); 685 break; 686 case PPP_AUTH_CHAP_MS: 687 psm_opt_set_rejected(_this, chapms, 1); 688 break; 689 case PPP_AUTH_CHAP_MS_V2: 690 psm_opt_set_rejected(_this, chapms_v2, 1); 691 break; 692 case PPP_AUTH_EAP: 693 psm_opt_set_rejected(_this, eap, 1); 694 break; 695 } 696 GETSHORT(authproto, inp); 697 switch (authproto) { 698 case PPP_AUTH_PAP: 699 if (psm_opt_is_requested(_this, pap)) 700 psm_opt_set_accepted(_this, pap, 1); 701 peer_auth = "pap"; 702 break; 703 case PPP_AUTH_CHAP: 704 chapalg = 0; 705 if (len == 5) 706 GETCHAR(chapalg, inp); 707 switch (chapalg) { 708 case PPP_AUTH_CHAP_MD5: 709 if (psm_opt_is_requested(_this, chap)) 710 psm_opt_set_accepted(_this, 711 chap, 1); 712 peer_auth = "chap"; 713 break; 714 case PPP_AUTH_CHAP_MS: 715 if (psm_opt_is_requested(_this, chapms)) 716 psm_opt_set_accepted(_this, 717 chapms, 1); 718 peer_auth = "mschap"; 719 break; 720 case PPP_AUTH_CHAP_MS_V2: 721 if (psm_opt_is_requested(_this, 722 chapms_v2)) 723 psm_opt_set_accepted(_this, 724 chapms_v2, 1); 725 peer_auth = "mschap_v2"; 726 break; 727 default: 728 fsm_log(f, LOG_INFO, 729 "Nacked chap algorithm is " 730 "unknown(%d).", chapalg); 731 peer_auth = "unknown"; 732 break; 733 } 734 break; 735 case PPP_AUTH_EAP: 736 if (len != 4) 737 goto fail; 738 peer_auth = "eap"; 739 if (psm_opt_is_requested(_this, eap)) 740 psm_opt_set_accepted(_this, eap, 1); 741 break; 742 } 743 if (NO_AUTH_AGREEABLE(_this)) { 744 fsm_log(f, LOG_INFO, "No authentication " 745 "protocols are agreeable. peer's " 746 "auth proto=%s", 747 peer_auth); 748 ppp_set_disconnect_cause(f->ppp, 749 PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE, 750 authproto, 2 /* couldn't accept peer's */, 751 NULL); 752 ppp_stop(f->ppp, "Authentication is required"); 753 return 1; 754 } 755 break; 756 case PPP_LCP_PFC: 757 if (len != 2) 758 goto fail; 759 LCP_OPT_REJECTED(pfc); 760 break; 761 case PPP_LCP_ACFC: 762 if (len != 2) 763 goto fail; 764 LCP_OPT_REJECTED(acfc); 765 break; 766 default: 767 goto fail; 768 } 769 } 770 return 1; 771fail: 772 log_printf(LOG_ERR, "Received unexpected ConfNak."); 773 if (debug_get_debugfp() != NULL) 774 show_hd(debug_get_debugfp(), inp, inlen); 775 return 0; 776#undef remlen 777#undef LCP_OPT_REJECTED 778} 779 780/** 781 * receiving ConfRej. 782 */ 783static int 784lcp_rejci(fsm *f, u_char *inp, int inlen) 785{ 786 int chapalg, authproto, type, len, mru; 787 u_char *inp0; 788 lcp *_this; 789 790#define remlen() (inlen - (inp - inp0)) 791#define LCP_OPT_REJECTED(opt) \ 792 if (!psm_opt_is_requested(&f->ppp->lcp, opt)) \ 793 goto fail; \ 794 psm_opt_set_rejected(&f->ppp->lcp, opt, 1); 795 796 f->ppp->lcp.recv_ress++; 797 inp0 = inp; 798 _this = &f->ppp->lcp; 799 while (remlen() >= 2) { 800 GETCHAR(type, inp); 801 GETCHAR(len, inp); 802 803 if (len <= 0 || remlen() + 2 < len) 804 goto fail; 805 806 switch (type) { 807 case PPP_LCP_MAGICNUMBER: 808 if (f->ppp->lcp.echo_interval > 0) 809 goto fail; 810 inp += 4; 811 break; 812 case PPP_LCP_MRU: 813 LCP_OPT_REJECTED(mru); 814 GETSHORT(mru, inp); 815 break; 816 case PPP_LCP_AUTH_PROTOCOL: 817 if (len < 4) 818 goto fail; 819 GETSHORT(authproto, inp); 820 switch (authproto) { 821 case PPP_AUTH_PAP: 822 if (len != 4) 823 goto fail; 824 LCP_OPT_REJECTED(pap); 825 break; 826 case PPP_AUTH_CHAP: 827 chapalg = 0; 828 if (len == 5) 829 GETCHAR(chapalg, inp); 830 switch (chapalg) { 831 case PPP_AUTH_CHAP_MD5: 832 LCP_OPT_REJECTED(chap); 833 break; 834 case PPP_AUTH_CHAP_MS: 835 LCP_OPT_REJECTED(chapms); 836 break; 837 case PPP_AUTH_CHAP_MS_V2: 838 LCP_OPT_REJECTED(chapms_v2); 839 break; 840 default: 841 fsm_log(f, LOG_INFO, 842 "Rejected chap algorithm is " 843 "unknown(%d).", chapalg); 844 break; 845 } 846 break; 847 case PPP_AUTH_EAP: 848 if (len != 4) 849 goto fail; 850 LCP_OPT_REJECTED(eap); 851 break; 852 } 853 if (NO_AUTH_AGREEABLE(_this)) { 854 fsm_log(f, LOG_INFO, "No authentication " 855 "protocols are agreeable."); 856 ppp_set_disconnect_cause(f->ppp, 857 PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE, 858 authproto, 1 /* rejected by peer */, NULL); 859 ppp_stop(f->ppp, "Authentication is required"); 860 return 1; 861 } 862 break; 863 case PPP_LCP_PFC: 864 if (len != 2) 865 goto fail; 866 LCP_OPT_REJECTED(pfc); 867 break; 868 case PPP_LCP_ACFC: 869 if (len != 2) 870 goto fail; 871 LCP_OPT_REJECTED(acfc); 872 break; 873 default: 874 goto fail; 875 } 876 } 877 return 1; 878fail: 879 log_printf(LOG_ERR, "Received unexpected ConfRej."); 880 if (debug_get_debugfp() != NULL) 881 show_hd(debug_get_debugfp(), inp, inlen); 882 return 0; 883#undef remlen 884} 885 886static void 887lcp_rcoderej(fsm *f, u_char *inp, int inlen) 888{ 889 uint16_t proto; 890 fsm *rejfsm; 891 892 if (inlen < 2) { 893 fsm_log(f, LOG_WARNING, "Received short ProtRej packet."); 894 return; 895 } 896 GETSHORT(proto, inp); 897 898 rejfsm = NULL; 899 900 switch (proto) { 901 case PPP_PROTO_LCP: 902 rejfsm = &f->ppp->lcp.fsm; 903 break; 904 case PPP_PROTO_PAP: 905 fsm_log(f, LOG_WARNING, "our PAP packet is rejected"); 906 return; 907 case PPP_PROTO_CHAP: 908 fsm_log(f, LOG_WARNING, "our CHAP packet is rejected"); 909 return; 910 case PPP_PROTO_EAP: 911 fsm_log(f, LOG_ERR, "our EAP packet is rejected"); 912 ppp_stop(f->ppp, "Authentication Required"); 913 break; 914 case PPP_PROTO_NCP | NCP_IPCP: 915 rejfsm = &f->ppp->ipcp.fsm; 916 break; 917 case PPP_PROTO_NCP | NCP_CCP: 918 rejfsm = &f->ppp->ccp.fsm; 919 break; 920 } 921 if (rejfsm == NULL) { 922 fsm_log(f, LOG_WARNING, 923 "Received ProtRej packet for unknown protocol=(%d/%04x)", 924 proto, proto); 925 return; 926 } 927 fsm_protreject(rejfsm); 928 929 return; 930} 931 932static void 933lcp_reset_timeout(void *ctx) 934{ 935 lcp *_this; 936 937 _this = ctx; 938 939 if (_this->echo_interval > 0) { 940 if (_this->echo_failures == 0) { 941 TIMEOUT(lcp_timeout, _this, _this->echo_interval); 942 } else { 943 TIMEOUT(lcp_timeout, _this, _this->echo_retry_interval); 944 } 945 } else { 946 UNTIMEOUT(lcp_timeout, _this); 947 } 948} 949 950static void 951lcp_timeout(void *ctx) 952{ 953 lcp *_this; 954 u_char *cp, buf[32]; 955 956 _this = ctx; 957 if (_this->echo_failures >= _this->echo_max_retries) { 958 fsm_log(&_this->fsm, LOG_NOTICE, "keepalive failure."); 959 if (_this->fsm.ppp != NULL) { 960#ifdef USE_NPPPD_RADIUS 961 ppp_set_radius_terminate_cause(_this->fsm.ppp, 962 RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT); 963#endif 964 ppp_stop(_this->fsm.ppp, NULL); 965 } 966 return; 967 } 968 cp = buf; 969 PUTLONG(_this->magic_number, cp); 970 fsm_sdata(&_this->fsm, ECHOREQ, _this->fsm.id++, buf, 4); 971 _this->echo_failures++; 972 973 lcp_reset_timeout(_this); 974} 975 976static int 977lcp_rechoreq(fsm *f, int id, u_char *inp, int inlen) 978{ 979 u_char *inp0; 980 lcp *_this; 981 int len; 982 983 if (inlen < 4) 984 return 0; 985 986 _this = &f->ppp->lcp; 987 inp0 = inp; 988 PUTLONG(_this->magic_number, inp) 989 990 len = MINIMUM(inlen, f->ppp->peer_mru - 8); 991 fsm_sdata(f, ECHOREP, id, inp0, len); 992 993 return 1; 994} 995 996static int 997lcp_ext(fsm *f, int code, int id, u_char *inp, int inlen) 998{ 999 lcp *_this; 1000 uint32_t magic; 1001 char buf[256]; 1002 int i, len; 1003 1004 _this = &f->ppp->lcp; 1005 1006 switch (code) { 1007 case IDENTIFICATION: 1008 /* RFC 1570 */ 1009 if (inlen > 4) { 1010 GETLONG(magic, inp); 1011 inlen -= 4; 1012 memset(buf, 0, sizeof(buf)); 1013 len = MINIMUM(inlen, sizeof(buf) - 1); 1014 memcpy(buf, inp, len); 1015 buf[len] = '\0'; 1016 for (i = 0; i < len; i++) { 1017 if (!isprint((unsigned char)buf[i])) 1018 buf[i] = '.'; 1019 } 1020 fsm_log(f, LOG_INFO, 1021 "RecvId magic=%08x text=%s", magic, buf); 1022 } 1023 return 1; 1024 case PROTREJ: 1025 lcp_rcoderej(f, inp, inlen); 1026 return 1; 1027 case ECHOREP: 1028 if (f->state == OPENED) { 1029 if (inlen >= 4) { 1030 GETLONG(magic, inp); 1031 if (_this->peer_magic_number == magic) { 1032 _this->echo_failures = 0; 1033 lcp_reset_timeout(_this); 1034 } 1035 } 1036 } 1037 return 1; 1038 case ECHOREQ: 1039 if (f->state == OPENED) 1040 return lcp_rechoreq(f, id, inp, inlen); 1041 return 1; 1042 } 1043 1044 return 0; 1045} 1046 1047 1048/* 1049 * reading some authentication settings and storing ppp_order in 1050 * order of settings. 1051 */ 1052static void 1053lcp_load_authconfig(fsm *f) 1054{ 1055 int i; 1056 lcp *_this; 1057 struct tunnconf *conf; 1058 1059 i = 0; 1060 _this = &f->ppp->lcp; 1061 conf = ppp_get_tunnconf(f->ppp); 1062 if ((conf->auth_methods & NPPPD_AUTH_METHODS_MSCHAPV2) != 0) { 1063 _this->auth_order[i++] = PPP_AUTH_CHAP_MS_V2; 1064 psm_opt_set_enabled(_this,chapms_v2, 1); 1065 } 1066 if ((conf->auth_methods & NPPPD_AUTH_METHODS_CHAP) != 0) { 1067 _this->auth_order[i++] = PPP_AUTH_CHAP_MD5; 1068 psm_opt_set_enabled(_this, chap, 1); 1069 } 1070 if ((conf->auth_methods & NPPPD_AUTH_METHODS_PAP) != 0) { 1071 _this->auth_order[i++] = PPP_AUTH_PAP; 1072 psm_opt_set_enabled(_this, pap, 1); 1073 } 1074 1075 _this->auth_order[i] = -1; 1076} 1077 1078/*********************************************************************** 1079 * related functions of Dialin Proxy 1080 **********************************************************************/ 1081/** 1082 * This function set LCP status following dialin proxy information. 1083 * This returns non-zero value when LCP status is unacceptable. 1084 * 1085 */ 1086int 1087lcp_dialin_proxy(lcp *_this, dialin_proxy_info *dpi, int renegotiation, 1088 int force_renegotiation) 1089{ 1090 int i, authok; 1091 1092 _this->dialin_proxy = 1; 1093 lcp_load_authconfig(&_this->fsm); 1094 1095 /* whether authentication type is permitted by configuration or not. */ 1096 authok = 0; 1097 if (dpi->auth_type != 0) { 1098 for (i = 0; _this->auth_order[i] > 0; i++) { 1099 if (_this->auth_order[i] != dpi->auth_type) 1100 continue; 1101 authok = 1; 1102 break; 1103 } 1104 } 1105 if (!authok) { 1106 if (!renegotiation) { 1107 fsm_log(&_this->fsm, LOG_NOTICE, 1108 "dialin-proxy failed. auth-method=%s is " 1109 "not enabled. Try 'l2tp.dialin.lcp_renegotion'", 1110 lcp_auth_string(dpi->auth_type)); 1111 return 1; 1112 } 1113 _this->dialin_proxy_lcp_renegotiation = 1; 1114 } 1115 if (force_renegotiation) 1116 _this->dialin_proxy_lcp_renegotiation = 1; 1117 1118 if (_this->dialin_proxy_lcp_renegotiation == 0) { 1119 _this->fsm.ppp->peer_auth = dpi->auth_type; 1120 /* 1121 * Set the rejected flag to all options here for the moment, 1122 * the agreeed options will be handled in lcp_proxy_sent_ci(). 1123 */ 1124 psm_opt_set_rejected(_this, mru, 1); 1125 psm_opt_set_rejected(_this, pfc, 1); 1126 psm_opt_set_rejected(_this, acfc, 1); 1127 psm_opt_set_rejected(_this, pap, 1); 1128 psm_opt_set_rejected(_this, chap, 1); 1129 psm_opt_set_rejected(_this, chapms, 1); 1130 psm_opt_set_rejected(_this, chapms_v2, 1); 1131 psm_opt_set_rejected(_this, eap, 1); 1132 1133 } 1134 switch (dpi->auth_type) { 1135 case PPP_AUTH_PAP: 1136 pap_proxy_authen_prepare(&_this->fsm.ppp->pap, dpi); 1137 break; 1138 case PPP_AUTH_CHAP_MD5: 1139 chap_proxy_authen_prepare(&_this->fsm.ppp->chap, dpi); 1140 break; 1141 } 1142 if (lcp_proxy_sent_ci(&_this->fsm, dpi->last_sent_lcp.data, 1143 dpi->last_sent_lcp.ldata) != 0) { 1144 fsm_log(&_this->fsm, LOG_NOTICE, 1145 "dialin-proxy failed. couldn't use proxied lcp."); 1146 return 1; 1147 } 1148 if (lcp_proxy_recv_ci(&_this->fsm, dpi->last_recv_lcp.data, 1149 dpi->last_recv_lcp.ldata) != 0) { 1150 fsm_log(&_this->fsm, LOG_NOTICE, 1151 "dialin-proxy failed. couldn't use proxied lcp."); 1152 return 1; 1153 } 1154 1155 fsm_log(&_this->fsm, LOG_INFO, 1156 "dialin-proxy user=%s auth-type=%s renegotiate=%s", 1157 dpi->username, 1158 (dpi->auth_type == 0)? "none" : lcp_auth_string(dpi->auth_type), 1159 (_this->dialin_proxy_lcp_renegotiation != 0)? "yes" : "no"); 1160 1161 1162 if (_this->dialin_proxy_lcp_renegotiation == 0) 1163 _this->fsm.flags |= OPT_SILENT; /* It's ready to be "Opened" */ 1164 else 1165 _this->fsm.flags &= ~OPT_SILENT; 1166 1167 return 0; 1168} 1169 1170/* 1171 * This function copies from lcp_reqci. It only differs as follows: 1172 * - changes LCP_OPT_ACCEPTED. 1173 * - Magic Number and MRU. 1174 */ 1175static int 1176lcp_proxy_recv_ci(fsm *f, u_char *inp, int inlen) 1177{ 1178 int type, mru, len; 1179 uint32_t magic; 1180 u_char *inp0; 1181 lcp *_this; 1182 1183#define remlen() (inlen - (inp - inp0)) 1184#define LCP_OPT_PEER_ACCEPTED(opt) \ 1185 psm_peer_opt_set_rejected(&f->ppp->lcp, opt, 0); \ 1186 psm_peer_opt_set_requested(&f->ppp->lcp, opt, 1); \ 1187 psm_peer_opt_set_accepted(&f->ppp->lcp, opt, 1); 1188 1189 _this = &f->ppp->lcp; 1190 inp0 = inp; 1191 1192 while (remlen() >= 2) { 1193 GETCHAR(type, inp); 1194 GETCHAR(len, inp); 1195 if (len <= 0 || remlen() + 2 < len) 1196 goto fail; 1197 1198 switch (type) { 1199 case PPP_LCP_MRU: 1200 if (len != 4) 1201 goto fail; 1202 GETSHORT(mru, inp); 1203 f->ppp->peer_mru = mru; 1204 if (mru < NPPPD_MIN_MRU) 1205 goto fail; 1206 else 1207 LCP_OPT_PEER_ACCEPTED(mru); 1208 break; 1209 case PPP_LCP_MAGICNUMBER: 1210 if (len != 6) 1211 goto fail; 1212 GETLONG(magic, inp); 1213 if (magic == _this->magic_number) 1214 goto fail; 1215 _this->peer_magic_number = magic; 1216 break; 1217 case PPP_LCP_PFC: 1218 if (len != 2) 1219 goto fail; 1220 LCP_OPT_PEER_ACCEPTED(pfc); 1221 break; 1222 case PPP_LCP_ACFC: 1223 if (len != 2) 1224 goto fail; 1225 LCP_OPT_PEER_ACCEPTED(acfc); 1226 break; 1227 case PPP_LCP_ACCM: 1228 if (len != 6) 1229 goto fail; 1230 /* we don't use async framing. ignore this */ 1231 inp += (len - 2); 1232 break; 1233 default: 1234 goto fail; 1235 } 1236 } 1237 1238#undef remlen 1239#undef LCP_OPT_PEER_ACCEPTED 1240 return 0; 1241fail: 1242 return 1; 1243} 1244 1245/* 1246 * This function copies from lcp_ackci. It only differs as follows: 1247 * - Do not recv_reass++. 1248 * - changes LCP_OPT_ACCEPTED. 1249 * - Magic Number and MRU. 1250 */ 1251static int 1252lcp_proxy_sent_ci(fsm *f, u_char *inp, int inlen) 1253{ 1254 int chapalg, authproto, type, len, mru, magic; 1255 u_char *inp0; 1256 1257#define remlen() (inlen - (inp - inp0)) 1258#define LCP_OPT_ACCEPTED(opt) \ 1259 if (f->ppp->lcp.dialin_proxy_lcp_renegotiation == 0) { \ 1260 psm_opt_set_rejected(&f->ppp->lcp, opt, 0); \ 1261 psm_opt_set_requested(&f->ppp->lcp, opt, 1); \ 1262 psm_opt_set_accepted(&f->ppp->lcp, opt, 1); \ 1263 } 1264 1265 inp0 = inp; 1266 while (remlen() >= 2) { 1267 GETCHAR(type, inp); 1268 GETCHAR(len, inp); 1269 1270 if (len <= 0 || remlen() + 2 < len) 1271 goto fail; 1272 1273 switch (type) { 1274 case PPP_LCP_MAGICNUMBER: 1275 if (len != 6) 1276 goto fail; 1277 GETLONG(magic, inp); 1278 f->ppp->lcp.magic_number = magic; 1279 break; 1280 case PPP_LCP_MRU: 1281 if (len != 4) 1282 goto fail; 1283 LCP_OPT_ACCEPTED(mru); 1284 GETSHORT(mru, inp); 1285 f->ppp->lcp.xxxmru = mru; 1286 break; 1287 case PPP_LCP_AUTH_PROTOCOL: 1288 if (len < 4) 1289 goto fail; 1290 GETSHORT(authproto, inp); 1291 switch (authproto) { 1292 case PPP_AUTH_PAP: 1293 if (len != 4) 1294 goto fail; 1295 LCP_OPT_ACCEPTED(pap); 1296 break; 1297 case PPP_AUTH_CHAP: 1298 if (len != 5) 1299 goto fail; 1300 GETCHAR(chapalg, inp); 1301 switch (chapalg) { 1302 case PPP_AUTH_CHAP_MD5: 1303 LCP_OPT_ACCEPTED(chap); 1304 break; 1305 case PPP_AUTH_CHAP_MS: 1306 LCP_OPT_ACCEPTED(chapms); 1307 break; 1308 case PPP_AUTH_CHAP_MS_V2: 1309 LCP_OPT_ACCEPTED(chapms_v2); 1310 break; 1311 } 1312 break; 1313 case PPP_AUTH_EAP: 1314 if (len != 4) 1315 goto fail; 1316 LCP_OPT_ACCEPTED(eap); 1317 break; 1318 } 1319 break; 1320 case PPP_LCP_PFC: 1321 if (len != 2) 1322 goto fail; 1323 LCP_OPT_ACCEPTED(pfc); 1324 break; 1325 case PPP_LCP_ACFC: 1326 if (len != 2) 1327 goto fail; 1328 LCP_OPT_ACCEPTED(acfc); 1329 break; 1330 case PPP_LCP_ACCM: 1331 if (len != 6) 1332 goto fail; 1333 /* we don't use async framing. ignore this */ 1334 inp += (len - 2); 1335 break; 1336 default: 1337 goto fail; 1338 } 1339 } 1340 return 0; 1341fail: 1342 return 1; 1343#undef LCP_OPT_ACCEPTED 1344} 1345