1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2000 Semen Ustimenko <semenu@FreeBSD.org> 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 * $FreeBSD$ 29 */ 30 31 #include <sys/param.h> 32 33 #include <sys/socket.h> 34 #include <netinet/in_systm.h> 35 #include <netinet/in.h> 36 #include <netinet/ip.h> 37 #include <sys/un.h> 38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <termios.h> 43 #include <openssl/rc4.h> 44 45 #include "defs.h" 46 #include "mbuf.h" 47 #include "log.h" 48 #include "timer.h" 49 #include "fsm.h" 50 #include "lqr.h" 51 #include "hdlc.h" 52 #include "lcp.h" 53 #include "ccp.h" 54 #include "throughput.h" 55 #include "layer.h" 56 #include "link.h" 57 #include "chap_ms.h" 58 #include "proto.h" 59 #include "mppe.h" 60 #include "ua.h" 61 #include "descriptor.h" 62 #ifndef NORADIUS 63 #include "radius.h" 64 #endif 65 #include "ncpaddr.h" 66 #include "iplist.h" 67 #include "slcompress.h" 68 #include "ipcp.h" 69 #include "ipv6cp.h" 70 #include "filter.h" 71 #include "mp.h" 72 #include "ncp.h" 73 #include "bundle.h" 74 75 /* 76 * Documentation: 77 * 78 * draft-ietf-pppext-mppe-04.txt 79 * draft-ietf-pppext-mppe-keys-02.txt 80 */ 81 82 #define MPPE_OPT_STATELESS 0x1000000 83 #define MPPE_OPT_COMPRESSED 0x01 84 #define MPPE_OPT_40BIT 0x20 85 #define MPPE_OPT_56BIT 0x80 86 #define MPPE_OPT_128BIT 0x40 87 #define MPPE_OPT_BITMASK 0xe0 88 #define MPPE_OPT_MASK (MPPE_OPT_STATELESS | MPPE_OPT_BITMASK) 89 90 #define MPPE_FLUSHED 0x8000 91 #define MPPE_ENCRYPTED 0x1000 92 #define MPPE_HEADER_BITMASK 0xf000 93 #define MPPE_HEADER_FLAG 0x00ff 94 #define MPPE_HEADER_FLAGMASK 0x00ff 95 #define MPPE_HEADER_FLAGSHIFT 8 96 #define MPPE_HEADER_STATEFUL_KEYCHANGES 16 97 98 struct mppe_state { 99 unsigned stateless : 1; 100 unsigned flushnext : 1; 101 unsigned flushrequired : 1; 102 int cohnum; 103 unsigned keylen; /* 8 or 16 bytes */ 104 int keybits; /* 40, 56 or 128 bits */ 105 char sesskey[MPPE_KEY_LEN]; 106 char mastkey[MPPE_KEY_LEN]; 107 RC4_KEY rc4key; 108 }; 109 110 int MPPE_MasterKeyValid = 0; 111 int MPPE_IsServer = 0; 112 char MPPE_MasterKey[MPPE_KEY_LEN]; 113 114 /* 115 * The peer has missed a packet. Mark the next output frame to be FLUSHED 116 */ 117 static int 118 MPPEResetOutput(void *v) 119 { 120 struct mppe_state *mop = (struct mppe_state *)v; 121 122 if (mop->stateless) 123 log_Printf(LogCCP, "MPPE: Unexpected output channel reset\n"); 124 else { 125 log_Printf(LogCCP, "MPPE: Output channel reset\n"); 126 mop->flushnext = 1; 127 } 128 129 return 0; /* Ask FSM not to ACK */ 130 } 131 132 static void 133 MPPEReduceSessionKey(struct mppe_state *mp) 134 { 135 switch(mp->keybits) { 136 case 40: 137 mp->sesskey[2] = 0x9e; 138 mp->sesskey[1] = 0x26; 139 case 56: 140 mp->sesskey[0] = 0xd1; 141 case 128: 142 break; 143 } 144 } 145 146 static void 147 MPPEKeyChange(struct mppe_state *mp) 148 { 149 char InterimKey[MPPE_KEY_LEN]; 150 RC4_KEY RC4Key; 151 152 GetNewKeyFromSHA(mp->mastkey, mp->sesskey, mp->keylen, InterimKey); 153 RC4_set_key(&RC4Key, mp->keylen, InterimKey); 154 RC4(&RC4Key, mp->keylen, InterimKey, mp->sesskey); 155 156 MPPEReduceSessionKey(mp); 157 } 158 159 static struct mbuf * 160 MPPEOutput(void *v, struct ccp *ccp, struct link *l __unused, int pri __unused, 161 u_short *proto, struct mbuf *mp) 162 { 163 struct mppe_state *mop = (struct mppe_state *)v; 164 struct mbuf *mo; 165 u_short nproto, prefix; 166 int dictinit, ilen, len; 167 char *rp; 168 169 ilen = m_length(mp); 170 dictinit = 0; 171 172 log_Printf(LogDEBUG, "MPPE: Output: Proto %02x (%d bytes)\n", *proto, ilen); 173 if (*proto < 0x21 || *proto > 0xFA) { 174 log_Printf(LogDEBUG, "MPPE: Output: Not encrypting\n"); 175 ccp->compout += ilen; 176 ccp->uncompout += ilen; 177 return mp; 178 } 179 180 log_DumpBp(LogDEBUG, "MPPE: Output: Encrypt packet:", mp); 181 182 /* Get mbuf for prefixes */ 183 mo = m_get(4, MB_CCPOUT); 184 mo->m_next = mp; 185 186 rp = MBUF_CTOP(mo); 187 prefix = MPPE_ENCRYPTED | mop->cohnum; 188 189 if (mop->stateless || 190 (mop->cohnum & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) { 191 /* Change our key */ 192 log_Printf(LogDEBUG, "MPPEOutput: Key changed [%d]\n", mop->cohnum); 193 MPPEKeyChange(mop); 194 dictinit = 1; 195 } 196 197 if (mop->stateless || mop->flushnext) { 198 prefix |= MPPE_FLUSHED; 199 dictinit = 1; 200 mop->flushnext = 0; 201 } 202 203 if (dictinit) { 204 /* Initialise our dictionary */ 205 log_Printf(LogDEBUG, "MPPEOutput: Dictionary initialised [%d]\n", 206 mop->cohnum); 207 RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey); 208 } 209 210 /* Set MPPE packet prefix */ 211 ua_htons(&prefix, rp); 212 213 /* Save encrypted protocol number */ 214 nproto = htons(*proto); 215 RC4(&mop->rc4key, 2, (char *)&nproto, rp + 2); 216 217 /* Encrypt main packet */ 218 rp = MBUF_CTOP(mp); 219 RC4(&mop->rc4key, ilen, rp, rp); 220 221 mop->cohnum++; 222 mop->cohnum &= ~MPPE_HEADER_BITMASK; 223 224 /* Set the protocol number */ 225 *proto = ccp_Proto(ccp); 226 len = m_length(mo); 227 ccp->uncompout += ilen; 228 ccp->compout += len; 229 230 log_Printf(LogDEBUG, "MPPE: Output: Encrypted: Proto %02x (%d bytes)\n", 231 *proto, len); 232 233 return mo; 234 } 235 236 static void 237 MPPEResetInput(void *v __unused) 238 { 239 log_Printf(LogCCP, "MPPE: Unexpected input channel ack\n"); 240 } 241 242 static struct mbuf * 243 MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp) 244 { 245 struct mppe_state *mip = (struct mppe_state *)v; 246 u_short prefix; 247 char *rp; 248 int dictinit, flushed, ilen, len, n; 249 250 ilen = m_length(mp); 251 dictinit = 0; 252 ccp->compin += ilen; 253 254 log_Printf(LogDEBUG, "MPPE: Input: Proto %02x (%d bytes)\n", *proto, ilen); 255 log_DumpBp(LogDEBUG, "MPPE: Input: Packet:", mp); 256 257 mp = mbuf_Read(mp, &prefix, 2); 258 prefix = ntohs(prefix); 259 flushed = prefix & MPPE_FLUSHED; 260 prefix &= ~flushed; 261 if ((prefix & MPPE_HEADER_BITMASK) != MPPE_ENCRYPTED) { 262 log_Printf(LogERROR, "MPPE: Input: Invalid packet (flags = 0x%x)\n", 263 (prefix & MPPE_HEADER_BITMASK) | flushed); 264 m_freem(mp); 265 return NULL; 266 } 267 268 prefix &= ~MPPE_HEADER_BITMASK; 269 270 if (!flushed && mip->stateless) { 271 log_Printf(LogCCP, "MPPEInput: Packet without MPPE_FLUSHED set" 272 " in stateless mode\n"); 273 flushed = MPPE_FLUSHED; 274 /* Should we really continue ? */ 275 } 276 277 if (mip->stateless) { 278 /* Change our key for each missed packet in stateless mode */ 279 while (prefix != mip->cohnum) { 280 log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix); 281 MPPEKeyChange(mip); 282 /* 283 * mip->cohnum contains what we received last time in stateless 284 * mode. 285 */ 286 mip->cohnum++; 287 mip->cohnum &= ~MPPE_HEADER_BITMASK; 288 } 289 dictinit = 1; 290 } else { 291 if (flushed) { 292 /* 293 * We can always process a flushed packet. 294 * Catch up on any outstanding key changes. 295 */ 296 n = (prefix >> MPPE_HEADER_FLAGSHIFT) - 297 (mip->cohnum >> MPPE_HEADER_FLAGSHIFT); 298 if (n < 0) 299 n += MPPE_HEADER_STATEFUL_KEYCHANGES; 300 while (n--) { 301 log_Printf(LogDEBUG, "MPPEInput: Key changed during catchup [%u]\n", 302 prefix); 303 MPPEKeyChange(mip); 304 } 305 mip->flushrequired = 0; 306 mip->cohnum = prefix; 307 dictinit = 1; 308 } 309 310 if (mip->flushrequired) { 311 /* 312 * Perhaps we should be lenient if 313 * (prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG 314 * The spec says that we shouldn't be though.... 315 */ 316 log_Printf(LogDEBUG, "MPPE: Not flushed - discarded\n"); 317 fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0, 318 MB_CCPOUT); 319 m_freem(mp); 320 return NULL; 321 } 322 323 if (prefix != mip->cohnum) { 324 /* 325 * We're in stateful mode and didn't receive the expected 326 * packet. Send a reset request, but don't tell the CCP layer 327 * about it as we don't expect to receive a Reset ACK ! 328 * Guess what... M$ invented this ! 329 */ 330 log_Printf(LogCCP, "MPPE: Input: Got seq %u, not %u\n", 331 prefix, mip->cohnum); 332 fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0, 333 MB_CCPOUT); 334 mip->flushrequired = 1; 335 m_freem(mp); 336 return NULL; 337 } 338 339 if ((prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) { 340 log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix); 341 MPPEKeyChange(mip); 342 dictinit = 1; 343 } else if (flushed) 344 dictinit = 1; 345 346 /* 347 * mip->cohnum contains what we expect to receive next time in stateful 348 * mode. 349 */ 350 mip->cohnum++; 351 mip->cohnum &= ~MPPE_HEADER_BITMASK; 352 } 353 354 if (dictinit) { 355 log_Printf(LogDEBUG, "MPPEInput: Dictionary initialised [%u]\n", prefix); 356 RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey); 357 } 358 359 mp = mbuf_Read(mp, proto, 2); 360 RC4(&mip->rc4key, 2, (char *)proto, (char *)proto); 361 *proto = ntohs(*proto); 362 363 rp = MBUF_CTOP(mp); 364 len = m_length(mp); 365 RC4(&mip->rc4key, len, rp, rp); 366 367 log_Printf(LogDEBUG, "MPPEInput: Decrypted: Proto %02x (%d bytes)\n", 368 *proto, len); 369 log_DumpBp(LogDEBUG, "MPPEInput: Decrypted: Packet:", mp); 370 371 ccp->uncompin += len; 372 373 return mp; 374 } 375 376 static void 377 MPPEDictSetup(void *v __unused, struct ccp *ccp __unused, 378 u_short proto __unused, struct mbuf *mp __unused) 379 { 380 /* Nothing to see here */ 381 } 382 383 static const char * 384 MPPEDispOpts(struct fsm_opt *o) 385 { 386 static char buf[70]; 387 u_int32_t val; 388 char ch; 389 int len, n; 390 391 ua_ntohl(o->data, &val); 392 len = 0; 393 if ((n = snprintf(buf, sizeof buf, "value 0x%08x ", (unsigned)val)) > 0) 394 len += n; 395 if (!(val & MPPE_OPT_BITMASK)) { 396 if ((n = snprintf(buf + len, sizeof buf - len, "(0")) > 0) 397 len += n; 398 } else { 399 ch = '('; 400 if (val & MPPE_OPT_128BIT) { 401 if ((n = snprintf(buf + len, sizeof buf - len, "%c128", ch)) > 0) 402 len += n; 403 ch = '/'; 404 } 405 if (val & MPPE_OPT_56BIT) { 406 if ((n = snprintf(buf + len, sizeof buf - len, "%c56", ch)) > 0) 407 len += n; 408 ch = '/'; 409 } 410 if (val & MPPE_OPT_40BIT) { 411 if ((n = snprintf(buf + len, sizeof buf - len, "%c40", ch)) > 0) 412 len += n; 413 ch = '/'; 414 } 415 } 416 417 if ((n = snprintf(buf + len, sizeof buf - len, " bits, state%s", 418 (val & MPPE_OPT_STATELESS) ? "less" : "ful")) > 0) 419 len += n; 420 421 if (val & MPPE_OPT_COMPRESSED) { 422 if ((n = snprintf(buf + len, sizeof buf - len, ", compressed")) > 0) 423 len += n; 424 } 425 426 snprintf(buf + len, sizeof buf - len, ")"); 427 428 return buf; 429 } 430 431 static int 432 MPPEUsable(struct fsm *fp) 433 { 434 int ok; 435 #ifndef NORADIUS 436 struct radius *r = &fp->bundle->radius; 437 438 /* 439 * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES, 440 * use that instead of our configuration value. 441 */ 442 if (*r->cfg.file) { 443 ok = r->mppe.sendkeylen && r->mppe.recvkeylen; 444 if (!ok) 445 log_Printf(LogCCP, "MPPE: Not permitted by RADIUS server\n"); 446 } else 447 #endif 448 { 449 struct lcp *lcp = &fp->link->lcp; 450 ok = (lcp->want_auth == PROTO_CHAP && lcp->want_authtype == 0x81) || 451 (lcp->his_auth == PROTO_CHAP && lcp->his_authtype == 0x81); 452 if (!ok) 453 log_Printf(LogCCP, "MPPE: Not usable without CHAP81\n"); 454 } 455 456 return ok; 457 } 458 459 static int 460 MPPERequired(struct fsm *fp) 461 { 462 #ifndef NORADIUS 463 /* 464 * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY, 465 * use that instead of our configuration value. 466 */ 467 if (*fp->bundle->radius.cfg.file && fp->bundle->radius.mppe.policy) 468 return fp->bundle->radius.mppe.policy == MPPE_POLICY_REQUIRED ? 1 : 0; 469 #endif 470 471 return fp->link->ccp.cfg.mppe.required; 472 } 473 474 static u_int32_t 475 MPPE_ConfigVal(struct bundle *bundle __unused, const struct ccp_config *cfg) 476 { 477 u_int32_t val; 478 479 val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0; 480 #ifndef NORADIUS 481 /* 482 * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES, 483 * use that instead of our configuration value. 484 */ 485 if (*bundle->radius.cfg.file && bundle->radius.mppe.types) { 486 if (bundle->radius.mppe.types & MPPE_TYPE_40BIT) 487 val |= MPPE_OPT_40BIT; 488 if (bundle->radius.mppe.types & MPPE_TYPE_128BIT) 489 val |= MPPE_OPT_128BIT; 490 } else 491 #endif 492 switch(cfg->mppe.keybits) { 493 case 128: 494 val |= MPPE_OPT_128BIT; 495 break; 496 case 56: 497 val |= MPPE_OPT_56BIT; 498 break; 499 case 40: 500 val |= MPPE_OPT_40BIT; 501 break; 502 case 0: 503 val |= MPPE_OPT_128BIT | MPPE_OPT_56BIT | MPPE_OPT_40BIT; 504 break; 505 } 506 507 return val; 508 } 509 510 /* 511 * What options should we use for our first configure request 512 */ 513 static void 514 MPPEInitOptsOutput(struct bundle *bundle, struct fsm_opt *o, 515 const struct ccp_config *cfg) 516 { 517 u_int32_t mval; 518 519 o->hdr.len = 6; 520 521 if (!MPPE_MasterKeyValid) { 522 log_Printf(LogCCP, "MPPE: MasterKey is invalid," 523 " MPPE is available only with CHAP81 authentication\n"); 524 mval = 0; 525 ua_htonl(&mval, o->data); 526 return; 527 } 528 529 530 mval = MPPE_ConfigVal(bundle, cfg); 531 ua_htonl(&mval, o->data); 532 } 533 534 /* 535 * Our CCP request was NAK'd with the given options 536 */ 537 static int 538 MPPESetOptsOutput(struct bundle *bundle, struct fsm_opt *o, 539 const struct ccp_config *cfg) 540 { 541 u_int32_t mval, peer; 542 543 ua_ntohl(o->data, &peer); 544 545 if (!MPPE_MasterKeyValid) 546 /* Treat their NAK as a REJ */ 547 return MODE_NAK; 548 549 mval = MPPE_ConfigVal(bundle, cfg); 550 551 /* 552 * If we haven't been configured with a specific number of keybits, allow 553 * whatever the peer asks for. 554 */ 555 if (!cfg->mppe.keybits) { 556 mval &= ~MPPE_OPT_BITMASK; 557 mval |= (peer & MPPE_OPT_BITMASK); 558 if (!(mval & MPPE_OPT_BITMASK)) 559 mval |= MPPE_OPT_128BIT; 560 } 561 562 /* Adjust our statelessness */ 563 if (cfg->mppe.state == MPPE_ANYSTATE) { 564 mval &= ~MPPE_OPT_STATELESS; 565 mval |= (peer & MPPE_OPT_STATELESS); 566 } 567 568 ua_htonl(&mval, o->data); 569 570 return MODE_ACK; 571 } 572 573 /* 574 * The peer has requested the given options 575 */ 576 static int 577 MPPESetOptsInput(struct bundle *bundle, struct fsm_opt *o, 578 const struct ccp_config *cfg) 579 { 580 u_int32_t mval, peer; 581 int res = MODE_ACK; 582 583 ua_ntohl(o->data, &peer); 584 if (!MPPE_MasterKeyValid) { 585 if (peer != 0) { 586 peer = 0; 587 ua_htonl(&peer, o->data); 588 return MODE_NAK; 589 } else 590 return MODE_ACK; 591 } 592 593 mval = MPPE_ConfigVal(bundle, cfg); 594 595 if (peer & ~MPPE_OPT_MASK) 596 /* He's asking for bits we don't know about */ 597 res = MODE_NAK; 598 599 if (peer & MPPE_OPT_STATELESS) { 600 if (cfg->mppe.state == MPPE_STATEFUL) 601 /* Peer can't have stateless */ 602 res = MODE_NAK; 603 else 604 /* Peer wants stateless, that's ok */ 605 mval |= MPPE_OPT_STATELESS; 606 } else { 607 if (cfg->mppe.state == MPPE_STATELESS) 608 /* Peer must have stateless */ 609 res = MODE_NAK; 610 else 611 /* Peer doesn't want stateless, that's ok */ 612 mval &= ~MPPE_OPT_STATELESS; 613 } 614 615 /* If we've got a configured number of keybits - the peer must use that */ 616 if (cfg->mppe.keybits) { 617 ua_htonl(&mval, o->data); 618 return peer == mval ? res : MODE_NAK; 619 } 620 621 /* If a specific number of bits hasn't been requested, we'll need to NAK */ 622 switch (peer & MPPE_OPT_BITMASK) { 623 case MPPE_OPT_128BIT: 624 case MPPE_OPT_56BIT: 625 case MPPE_OPT_40BIT: 626 break; 627 default: 628 res = MODE_NAK; 629 } 630 631 /* Suggest the best number of bits */ 632 mval &= ~MPPE_OPT_BITMASK; 633 if (peer & MPPE_OPT_128BIT) 634 mval |= MPPE_OPT_128BIT; 635 else if (peer & MPPE_OPT_56BIT) 636 mval |= MPPE_OPT_56BIT; 637 else if (peer & MPPE_OPT_40BIT) 638 mval |= MPPE_OPT_40BIT; 639 else 640 mval |= MPPE_OPT_128BIT; 641 ua_htonl(&mval, o->data); 642 643 return res; 644 } 645 646 static struct mppe_state * 647 MPPE_InitState(struct fsm_opt *o) 648 { 649 struct mppe_state *mp; 650 u_int32_t val; 651 652 if ((mp = calloc(1, sizeof *mp)) != NULL) { 653 ua_ntohl(o->data, &val); 654 655 switch (val & MPPE_OPT_BITMASK) { 656 case MPPE_OPT_128BIT: 657 mp->keylen = 16; 658 mp->keybits = 128; 659 break; 660 case MPPE_OPT_56BIT: 661 mp->keylen = 8; 662 mp->keybits = 56; 663 break; 664 case MPPE_OPT_40BIT: 665 mp->keylen = 8; 666 mp->keybits = 40; 667 break; 668 default: 669 log_Printf(LogWARN, "Unexpected MPPE options 0x%08x\n", val); 670 free(mp); 671 return NULL; 672 } 673 674 mp->stateless = !!(val & MPPE_OPT_STATELESS); 675 } 676 677 return mp; 678 } 679 680 static void * 681 MPPEInitInput(struct bundle *bundle __unused, struct fsm_opt *o) 682 { 683 struct mppe_state *mip; 684 685 if (!MPPE_MasterKeyValid) { 686 log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n"); 687 return NULL; 688 } 689 690 if ((mip = MPPE_InitState(o)) == NULL) { 691 log_Printf(LogWARN, "MPPEInput: Cannot initialise - unexpected options\n"); 692 return NULL; 693 } 694 695 log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits); 696 697 #ifndef NORADIUS 698 if (*bundle->radius.cfg.file && bundle->radius.mppe.recvkey) { 699 if (mip->keylen > bundle->radius.mppe.recvkeylen) 700 mip->keylen = bundle->radius.mppe.recvkeylen; 701 if (mip->keylen > sizeof mip->mastkey) 702 mip->keylen = sizeof mip->mastkey; 703 memcpy(mip->mastkey, bundle->radius.mppe.recvkey, mip->keylen); 704 } else 705 #endif 706 GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0, 707 MPPE_IsServer); 708 709 GetNewKeyFromSHA(mip->mastkey, mip->mastkey, mip->keylen, mip->sesskey); 710 711 MPPEReduceSessionKey(mip); 712 713 log_Printf(LogCCP, "MPPE: Input channel initiated\n"); 714 715 if (!mip->stateless) { 716 /* 717 * We need to initialise our dictionary here as the first packet we 718 * receive is unlikely to have the FLUSHED bit set. 719 */ 720 log_Printf(LogDEBUG, "MPPEInitInput: Dictionary initialised [%d]\n", 721 mip->cohnum); 722 RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey); 723 } else { 724 /* 725 * We do the first key change here as the first packet is expected 726 * to have a sequence number of 0 and we'll therefore not expect 727 * to have to change the key at that point. 728 */ 729 log_Printf(LogDEBUG, "MPPEInitInput: Key changed [%d]\n", mip->cohnum); 730 MPPEKeyChange(mip); 731 } 732 733 return mip; 734 } 735 736 static void * 737 MPPEInitOutput(struct bundle *bundle __unused, struct fsm_opt *o) 738 { 739 struct mppe_state *mop; 740 741 if (!MPPE_MasterKeyValid) { 742 log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n"); 743 return NULL; 744 } 745 746 if ((mop = MPPE_InitState(o)) == NULL) { 747 log_Printf(LogWARN, "MPPEOutput: Cannot initialise - unexpected options\n"); 748 return NULL; 749 } 750 751 log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits); 752 753 #ifndef NORADIUS 754 if (*bundle->radius.cfg.file && bundle->radius.mppe.sendkey) { 755 if (mop->keylen > bundle->radius.mppe.sendkeylen) 756 mop->keylen = bundle->radius.mppe.sendkeylen; 757 if (mop->keylen > sizeof mop->mastkey) 758 mop->keylen = sizeof mop->mastkey; 759 memcpy(mop->mastkey, bundle->radius.mppe.sendkey, mop->keylen); 760 } else 761 #endif 762 GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1, 763 MPPE_IsServer); 764 765 GetNewKeyFromSHA(mop->mastkey, mop->mastkey, mop->keylen, mop->sesskey); 766 767 MPPEReduceSessionKey(mop); 768 769 log_Printf(LogCCP, "MPPE: Output channel initiated\n"); 770 771 if (!mop->stateless) { 772 /* 773 * We need to initialise our dictionary now as the first packet we 774 * send won't have the FLUSHED bit set. 775 */ 776 log_Printf(LogDEBUG, "MPPEInitOutput: Dictionary initialised [%d]\n", 777 mop->cohnum); 778 RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey); 779 } 780 781 return mop; 782 } 783 784 static void 785 MPPETermInput(void *v) 786 { 787 free(v); 788 } 789 790 static void 791 MPPETermOutput(void *v) 792 { 793 free(v); 794 } 795 796 const struct ccp_algorithm MPPEAlgorithm = { 797 TY_MPPE, 798 CCP_NEG_MPPE, 799 MPPEDispOpts, 800 MPPEUsable, 801 MPPERequired, 802 { 803 MPPESetOptsInput, 804 MPPEInitInput, 805 MPPETermInput, 806 MPPEResetInput, 807 MPPEInput, 808 MPPEDictSetup 809 }, 810 { 811 2, 812 MPPEInitOptsOutput, 813 MPPESetOptsOutput, 814 MPPEInitOutput, 815 MPPETermOutput, 816 MPPEResetOutput, 817 MPPEOutput 818 }, 819 }; 820