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