1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2000 Semen Ustimenko <[email protected]>
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
MPPEResetOutput(void * v)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
MPPEReduceSessionKey(struct mppe_state * mp)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
MPPEKeyChange(struct mppe_state * mp)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 *
MPPEOutput(void * v,struct ccp * ccp,struct link * l __unused,int pri __unused,u_short * proto,struct mbuf * mp)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
MPPEResetInput(void * v __unused)237 MPPEResetInput(void *v __unused)
238 {
239 log_Printf(LogCCP, "MPPE: Unexpected input channel ack\n");
240 }
241
242 static struct mbuf *
MPPEInput(void * v,struct ccp * ccp,u_short * proto,struct mbuf * mp)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
MPPEDictSetup(void * v __unused,struct ccp * ccp __unused,u_short proto __unused,struct mbuf * mp __unused)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 *
MPPEDispOpts(struct fsm_opt * o)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
MPPEUsable(struct fsm * fp)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
MPPERequired(struct fsm * fp)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
MPPE_ConfigVal(struct bundle * bundle __unused,const struct ccp_config * cfg)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
MPPEInitOptsOutput(struct bundle * bundle,struct fsm_opt * o,const struct ccp_config * cfg)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
MPPESetOptsOutput(struct bundle * bundle,struct fsm_opt * o,const struct ccp_config * cfg)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
MPPESetOptsInput(struct bundle * bundle,struct fsm_opt * o,const struct ccp_config * cfg)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 *
MPPE_InitState(struct fsm_opt * o)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 *
MPPEInitInput(struct bundle * bundle __unused,struct fsm_opt * o)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 *
MPPEInitOutput(struct bundle * bundle __unused,struct fsm_opt * o)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
MPPETermInput(void * v)785 MPPETermInput(void *v)
786 {
787 free(v);
788 }
789
790 static void
MPPETermOutput(void * v)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