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