summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/mppe.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ppp/mppe.c')
-rw-r--r--usr.sbin/ppp/mppe.c817
1 files changed, 0 insertions, 817 deletions
diff --git a/usr.sbin/ppp/mppe.c b/usr.sbin/ppp/mppe.c
deleted file mode 100644
index 141574f..0000000
--- a/usr.sbin/ppp/mppe.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/*-
- * Copyright (c) 2000 Semen Ustimenko <semenu@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-
-#include <sys/socket.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <sys/un.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <openssl/rc4.h>
-
-#include "defs.h"
-#include "mbuf.h"
-#include "log.h"
-#include "timer.h"
-#include "fsm.h"
-#include "lqr.h"
-#include "hdlc.h"
-#include "lcp.h"
-#include "ccp.h"
-#include "throughput.h"
-#include "layer.h"
-#include "link.h"
-#include "chap_ms.h"
-#include "proto.h"
-#include "mppe.h"
-#include "ua.h"
-#include "descriptor.h"
-#ifndef NORADIUS
-#include "radius.h"
-#endif
-#include "ncpaddr.h"
-#include "iplist.h"
-#include "slcompress.h"
-#include "ipcp.h"
-#include "ipv6cp.h"
-#include "filter.h"
-#include "mp.h"
-#include "ncp.h"
-#include "bundle.h"
-
-/*
- * Documentation:
- *
- * draft-ietf-pppext-mppe-04.txt
- * draft-ietf-pppext-mppe-keys-02.txt
- */
-
-#define MPPE_OPT_STATELESS 0x1000000
-#define MPPE_OPT_COMPRESSED 0x01
-#define MPPE_OPT_40BIT 0x20
-#define MPPE_OPT_56BIT 0x80
-#define MPPE_OPT_128BIT 0x40
-#define MPPE_OPT_BITMASK 0xe0
-#define MPPE_OPT_MASK (MPPE_OPT_STATELESS | MPPE_OPT_BITMASK)
-
-#define MPPE_FLUSHED 0x8000
-#define MPPE_ENCRYPTED 0x1000
-#define MPPE_HEADER_BITMASK 0xf000
-#define MPPE_HEADER_FLAG 0x00ff
-#define MPPE_HEADER_FLAGMASK 0x00ff
-#define MPPE_HEADER_FLAGSHIFT 8
-#define MPPE_HEADER_STATEFUL_KEYCHANGES 16
-
-struct mppe_state {
- unsigned stateless : 1;
- unsigned flushnext : 1;
- unsigned flushrequired : 1;
- int cohnum;
- unsigned keylen; /* 8 or 16 bytes */
- int keybits; /* 40, 56 or 128 bits */
- char sesskey[MPPE_KEY_LEN];
- char mastkey[MPPE_KEY_LEN];
- RC4_KEY rc4key;
-};
-
-int MPPE_MasterKeyValid = 0;
-int MPPE_IsServer = 0;
-char MPPE_MasterKey[MPPE_KEY_LEN];
-
-/*
- * The peer has missed a packet. Mark the next output frame to be FLUSHED
- */
-static int
-MPPEResetOutput(void *v)
-{
- struct mppe_state *mop = (struct mppe_state *)v;
-
- if (mop->stateless)
- log_Printf(LogCCP, "MPPE: Unexpected output channel reset\n");
- else {
- log_Printf(LogCCP, "MPPE: Output channel reset\n");
- mop->flushnext = 1;
- }
-
- return 0; /* Ask FSM not to ACK */
-}
-
-static void
-MPPEReduceSessionKey(struct mppe_state *mp)
-{
- switch(mp->keybits) {
- case 40:
- mp->sesskey[2] = 0x9e;
- mp->sesskey[1] = 0x26;
- case 56:
- mp->sesskey[0] = 0xd1;
- case 128:
- break;
- }
-}
-
-static void
-MPPEKeyChange(struct mppe_state *mp)
-{
- char InterimKey[MPPE_KEY_LEN];
- RC4_KEY RC4Key;
-
- GetNewKeyFromSHA(mp->mastkey, mp->sesskey, mp->keylen, InterimKey);
- RC4_set_key(&RC4Key, mp->keylen, InterimKey);
- RC4(&RC4Key, mp->keylen, InterimKey, mp->sesskey);
-
- MPPEReduceSessionKey(mp);
-}
-
-static struct mbuf *
-MPPEOutput(void *v, struct ccp *ccp, struct link *l __unused, int pri __unused,
- u_short *proto, struct mbuf *mp)
-{
- struct mppe_state *mop = (struct mppe_state *)v;
- struct mbuf *mo;
- u_short nproto, prefix;
- int dictinit, ilen, len;
- char *rp;
-
- ilen = m_length(mp);
- dictinit = 0;
-
- log_Printf(LogDEBUG, "MPPE: Output: Proto %02x (%d bytes)\n", *proto, ilen);
- if (*proto < 0x21 && *proto > 0xFA) {
- log_Printf(LogDEBUG, "MPPE: Output: Not encrypting\n");
- ccp->compout += ilen;
- ccp->uncompout += ilen;
- return mp;
- }
-
- log_DumpBp(LogDEBUG, "MPPE: Output: Encrypt packet:", mp);
-
- /* Get mbuf for prefixes */
- mo = m_get(4, MB_CCPOUT);
- mo->m_next = mp;
-
- rp = MBUF_CTOP(mo);
- prefix = MPPE_ENCRYPTED | mop->cohnum;
-
- if (mop->stateless ||
- (mop->cohnum & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
- /* Change our key */
- log_Printf(LogDEBUG, "MPPEOutput: Key changed [%d]\n", mop->cohnum);
- MPPEKeyChange(mop);
- dictinit = 1;
- }
-
- if (mop->stateless || mop->flushnext) {
- prefix |= MPPE_FLUSHED;
- dictinit = 1;
- mop->flushnext = 0;
- }
-
- if (dictinit) {
- /* Initialise our dictionary */
- log_Printf(LogDEBUG, "MPPEOutput: Dictionary initialised [%d]\n",
- mop->cohnum);
- RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
- }
-
- /* Set MPPE packet prefix */
- ua_htons(&prefix, rp);
-
- /* Save encrypted protocol number */
- nproto = htons(*proto);
- RC4(&mop->rc4key, 2, (char *)&nproto, rp + 2);
-
- /* Encrypt main packet */
- rp = MBUF_CTOP(mp);
- RC4(&mop->rc4key, ilen, rp, rp);
-
- mop->cohnum++;
- mop->cohnum &= ~MPPE_HEADER_BITMASK;
-
- /* Set the protocol number */
- *proto = ccp_Proto(ccp);
- len = m_length(mo);
- ccp->uncompout += ilen;
- ccp->compout += len;
-
- log_Printf(LogDEBUG, "MPPE: Output: Encrypted: Proto %02x (%d bytes)\n",
- *proto, len);
-
- return mo;
-}
-
-static void
-MPPEResetInput(void *v __unused)
-{
- log_Printf(LogCCP, "MPPE: Unexpected input channel ack\n");
-}
-
-static struct mbuf *
-MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp)
-{
- struct mppe_state *mip = (struct mppe_state *)v;
- u_short prefix;
- char *rp;
- int dictinit, flushed, ilen, len, n;
-
- ilen = m_length(mp);
- dictinit = 0;
- ccp->compin += ilen;
-
- log_Printf(LogDEBUG, "MPPE: Input: Proto %02x (%d bytes)\n", *proto, ilen);
- log_DumpBp(LogDEBUG, "MPPE: Input: Packet:", mp);
-
- mp = mbuf_Read(mp, &prefix, 2);
- prefix = ntohs(prefix);
- flushed = prefix & MPPE_FLUSHED;
- prefix &= ~flushed;
- if ((prefix & MPPE_HEADER_BITMASK) != MPPE_ENCRYPTED) {
- log_Printf(LogERROR, "MPPE: Input: Invalid packet (flags = 0x%x)\n",
- (prefix & MPPE_HEADER_BITMASK) | flushed);
- m_freem(mp);
- return NULL;
- }
-
- prefix &= ~MPPE_HEADER_BITMASK;
-
- if (!flushed && mip->stateless) {
- log_Printf(LogCCP, "MPPEInput: Packet without MPPE_FLUSHED set"
- " in stateless mode\n");
- flushed = MPPE_FLUSHED;
- /* Should we really continue ? */
- }
-
- if (mip->stateless) {
- /* Change our key for each missed packet in stateless mode */
- while (prefix != mip->cohnum) {
- log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
- MPPEKeyChange(mip);
- /*
- * mip->cohnum contains what we received last time in stateless
- * mode.
- */
- mip->cohnum++;
- mip->cohnum &= ~MPPE_HEADER_BITMASK;
- }
- dictinit = 1;
- } else {
- if (flushed) {
- /*
- * We can always process a flushed packet.
- * Catch up on any outstanding key changes.
- */
- n = (prefix >> MPPE_HEADER_FLAGSHIFT) -
- (mip->cohnum >> MPPE_HEADER_FLAGSHIFT);
- if (n < 0)
- n += MPPE_HEADER_STATEFUL_KEYCHANGES;
- while (n--) {
- log_Printf(LogDEBUG, "MPPEInput: Key changed during catchup [%u]\n",
- prefix);
- MPPEKeyChange(mip);
- }
- mip->flushrequired = 0;
- mip->cohnum = prefix;
- dictinit = 1;
- }
-
- if (mip->flushrequired) {
- /*
- * Perhaps we should be lenient if
- * (prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG
- * The spec says that we shouldn't be though....
- */
- log_Printf(LogDEBUG, "MPPE: Not flushed - discarded\n");
- fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0,
- MB_CCPOUT);
- m_freem(mp);
- return NULL;
- }
-
- if (prefix != mip->cohnum) {
- /*
- * We're in stateful mode and didn't receive the expected
- * packet. Send a reset request, but don't tell the CCP layer
- * about it as we don't expect to receive a Reset ACK !
- * Guess what... M$ invented this !
- */
- log_Printf(LogCCP, "MPPE: Input: Got seq %u, not %u\n",
- prefix, mip->cohnum);
- fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0,
- MB_CCPOUT);
- mip->flushrequired = 1;
- m_freem(mp);
- return NULL;
- }
-
- if ((prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
- log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
- MPPEKeyChange(mip);
- dictinit = 1;
- } else if (flushed)
- dictinit = 1;
-
- /*
- * mip->cohnum contains what we expect to receive next time in stateful
- * mode.
- */
- mip->cohnum++;
- mip->cohnum &= ~MPPE_HEADER_BITMASK;
- }
-
- if (dictinit) {
- log_Printf(LogDEBUG, "MPPEInput: Dictionary initialised [%u]\n", prefix);
- RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
- }
-
- mp = mbuf_Read(mp, proto, 2);
- RC4(&mip->rc4key, 2, (char *)proto, (char *)proto);
- *proto = ntohs(*proto);
-
- rp = MBUF_CTOP(mp);
- len = m_length(mp);
- RC4(&mip->rc4key, len, rp, rp);
-
- log_Printf(LogDEBUG, "MPPEInput: Decrypted: Proto %02x (%d bytes)\n",
- *proto, len);
- log_DumpBp(LogDEBUG, "MPPEInput: Decrypted: Packet:", mp);
-
- ccp->uncompin += len;
-
- return mp;
-}
-
-static void
-MPPEDictSetup(void *v __unused, struct ccp *ccp __unused,
- u_short proto __unused, struct mbuf *mp __unused)
-{
- /* Nothing to see here */
-}
-
-static const char *
-MPPEDispOpts(struct fsm_opt *o)
-{
- static char buf[70];
- u_int32_t val;
- char ch;
- int len, n;
-
- ua_ntohl(o->data, &val);
- len = 0;
- if ((n = snprintf(buf, sizeof buf, "value 0x%08x ", (unsigned)val)) > 0)
- len += n;
- if (!(val & MPPE_OPT_BITMASK)) {
- if ((n = snprintf(buf + len, sizeof buf - len, "(0")) > 0)
- len += n;
- } else {
- ch = '(';
- if (val & MPPE_OPT_128BIT) {
- if ((n = snprintf(buf + len, sizeof buf - len, "%c128", ch)) > 0)
- len += n;
- ch = '/';
- }
- if (val & MPPE_OPT_56BIT) {
- if ((n = snprintf(buf + len, sizeof buf - len, "%c56", ch)) > 0)
- len += n;
- ch = '/';
- }
- if (val & MPPE_OPT_40BIT) {
- if ((n = snprintf(buf + len, sizeof buf - len, "%c40", ch)) > 0)
- len += n;
- ch = '/';
- }
- }
-
- if ((n = snprintf(buf + len, sizeof buf - len, " bits, state%s",
- (val & MPPE_OPT_STATELESS) ? "less" : "ful")) > 0)
- len += n;
-
- if (val & MPPE_OPT_COMPRESSED) {
- if ((n = snprintf(buf + len, sizeof buf - len, ", compressed")) > 0)
- len += n;
- }
-
- snprintf(buf + len, sizeof buf - len, ")");
-
- return buf;
-}
-
-static int
-MPPEUsable(struct fsm *fp)
-{
- int ok;
-#ifndef NORADIUS
- struct radius *r = &fp->bundle->radius;
-
- /*
- * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES,
- * use that instead of our configuration value.
- */
- if (*r->cfg.file) {
- ok = r->mppe.sendkeylen && r->mppe.recvkeylen;
- if (!ok)
- log_Printf(LogCCP, "MPPE: Not permitted by RADIUS server\n");
- } else
-#endif
- {
- struct lcp *lcp = &fp->link->lcp;
- ok = (lcp->want_auth == PROTO_CHAP && lcp->want_authtype == 0x81) ||
- (lcp->his_auth == PROTO_CHAP && lcp->his_authtype == 0x81);
- if (!ok)
- log_Printf(LogCCP, "MPPE: Not usable without CHAP81\n");
- }
-
- return ok;
-}
-
-static int
-MPPERequired(struct fsm *fp)
-{
-#ifndef NORADIUS
- /*
- * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY,
- * use that instead of our configuration value.
- */
- if (*fp->bundle->radius.cfg.file && fp->bundle->radius.mppe.policy)
- return fp->bundle->radius.mppe.policy == MPPE_POLICY_REQUIRED ? 1 : 0;
-#endif
-
- return fp->link->ccp.cfg.mppe.required;
-}
-
-static u_int32_t
-MPPE_ConfigVal(struct bundle *bundle __unused, const struct ccp_config *cfg)
-{
- u_int32_t val;
-
- val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0;
-#ifndef NORADIUS
- /*
- * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES,
- * use that instead of our configuration value.
- */
- if (*bundle->radius.cfg.file && bundle->radius.mppe.types) {
- if (bundle->radius.mppe.types & MPPE_TYPE_40BIT)
- val |= MPPE_OPT_40BIT;
- if (bundle->radius.mppe.types & MPPE_TYPE_128BIT)
- val |= MPPE_OPT_128BIT;
- } else
-#endif
- switch(cfg->mppe.keybits) {
- case 128:
- val |= MPPE_OPT_128BIT;
- break;
- case 56:
- val |= MPPE_OPT_56BIT;
- break;
- case 40:
- val |= MPPE_OPT_40BIT;
- break;
- case 0:
- val |= MPPE_OPT_128BIT | MPPE_OPT_56BIT | MPPE_OPT_40BIT;
- break;
- }
-
- return val;
-}
-
-/*
- * What options should we use for our first configure request
- */
-static void
-MPPEInitOptsOutput(struct bundle *bundle, struct fsm_opt *o,
- const struct ccp_config *cfg)
-{
- u_int32_t mval;
-
- o->hdr.len = 6;
-
- if (!MPPE_MasterKeyValid) {
- log_Printf(LogCCP, "MPPE: MasterKey is invalid,"
- " MPPE is available only with CHAP81 authentication\n");
- mval = 0;
- ua_htonl(&mval, o->data);
- return;
- }
-
-
- mval = MPPE_ConfigVal(bundle, cfg);
- ua_htonl(&mval, o->data);
-}
-
-/*
- * Our CCP request was NAK'd with the given options
- */
-static int
-MPPESetOptsOutput(struct bundle *bundle, struct fsm_opt *o,
- const struct ccp_config *cfg)
-{
- u_int32_t mval, peer;
-
- ua_ntohl(o->data, &peer);
-
- if (!MPPE_MasterKeyValid)
- /* Treat their NAK as a REJ */
- return MODE_NAK;
-
- mval = MPPE_ConfigVal(bundle, cfg);
-
- /*
- * If we haven't been configured with a specific number of keybits, allow
- * whatever the peer asks for.
- */
- if (!cfg->mppe.keybits) {
- mval &= ~MPPE_OPT_BITMASK;
- mval |= (peer & MPPE_OPT_BITMASK);
- if (!(mval & MPPE_OPT_BITMASK))
- mval |= MPPE_OPT_128BIT;
- }
-
- /* Adjust our statelessness */
- if (cfg->mppe.state == MPPE_ANYSTATE) {
- mval &= ~MPPE_OPT_STATELESS;
- mval |= (peer & MPPE_OPT_STATELESS);
- }
-
- ua_htonl(&mval, o->data);
-
- return MODE_ACK;
-}
-
-/*
- * The peer has requested the given options
- */
-static int
-MPPESetOptsInput(struct bundle *bundle, struct fsm_opt *o,
- const struct ccp_config *cfg)
-{
- u_int32_t mval, peer;
- int res = MODE_ACK;
-
- ua_ntohl(o->data, &peer);
- if (!MPPE_MasterKeyValid) {
- if (peer != 0) {
- peer = 0;
- ua_htonl(&peer, o->data);
- return MODE_NAK;
- } else
- return MODE_ACK;
- }
-
- mval = MPPE_ConfigVal(bundle, cfg);
-
- if (peer & ~MPPE_OPT_MASK)
- /* He's asking for bits we don't know about */
- res = MODE_NAK;
-
- if (peer & MPPE_OPT_STATELESS) {
- if (cfg->mppe.state == MPPE_STATEFUL)
- /* Peer can't have stateless */
- res = MODE_NAK;
- else
- /* Peer wants stateless, that's ok */
- mval |= MPPE_OPT_STATELESS;
- } else {
- if (cfg->mppe.state == MPPE_STATELESS)
- /* Peer must have stateless */
- res = MODE_NAK;
- else
- /* Peer doesn't want stateless, that's ok */
- mval &= ~MPPE_OPT_STATELESS;
- }
-
- /* If we've got a configured number of keybits - the peer must use that */
- if (cfg->mppe.keybits) {
- ua_htonl(&mval, o->data);
- return peer == mval ? res : MODE_NAK;
- }
-
- /* If a specific number of bits hasn't been requested, we'll need to NAK */
- switch (peer & MPPE_OPT_BITMASK) {
- case MPPE_OPT_128BIT:
- case MPPE_OPT_56BIT:
- case MPPE_OPT_40BIT:
- break;
- default:
- res = MODE_NAK;
- }
-
- /* Suggest the best number of bits */
- mval &= ~MPPE_OPT_BITMASK;
- if (peer & MPPE_OPT_128BIT)
- mval |= MPPE_OPT_128BIT;
- else if (peer & MPPE_OPT_56BIT)
- mval |= MPPE_OPT_56BIT;
- else if (peer & MPPE_OPT_40BIT)
- mval |= MPPE_OPT_40BIT;
- else
- mval |= MPPE_OPT_128BIT;
- ua_htonl(&mval, o->data);
-
- return res;
-}
-
-static struct mppe_state *
-MPPE_InitState(struct fsm_opt *o)
-{
- struct mppe_state *mp;
- u_int32_t val;
-
- if ((mp = calloc(1, sizeof *mp)) != NULL) {
- ua_ntohl(o->data, &val);
-
- switch (val & MPPE_OPT_BITMASK) {
- case MPPE_OPT_128BIT:
- mp->keylen = 16;
- mp->keybits = 128;
- break;
- case MPPE_OPT_56BIT:
- mp->keylen = 8;
- mp->keybits = 56;
- break;
- case MPPE_OPT_40BIT:
- mp->keylen = 8;
- mp->keybits = 40;
- break;
- default:
- log_Printf(LogWARN, "Unexpected MPPE options 0x%08x\n", val);
- free(mp);
- return NULL;
- }
-
- mp->stateless = !!(val & MPPE_OPT_STATELESS);
- }
-
- return mp;
-}
-
-static void *
-MPPEInitInput(struct bundle *bundle __unused, struct fsm_opt *o)
-{
- struct mppe_state *mip;
-
- if (!MPPE_MasterKeyValid) {
- log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
- return NULL;
- }
-
- if ((mip = MPPE_InitState(o)) == NULL) {
- log_Printf(LogWARN, "MPPEInput: Cannot initialise - unexpected options\n");
- return NULL;
- }
-
- log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits);
-
-#ifndef NORADIUS
- if (*bundle->radius.cfg.file && bundle->radius.mppe.recvkey) {
- if (mip->keylen > bundle->radius.mppe.recvkeylen)
- mip->keylen = bundle->radius.mppe.recvkeylen;
- if (mip->keylen > sizeof mip->mastkey)
- mip->keylen = sizeof mip->mastkey;
- memcpy(mip->mastkey, bundle->radius.mppe.recvkey, mip->keylen);
- } else
-#endif
- GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0,
- MPPE_IsServer);
-
- GetNewKeyFromSHA(mip->mastkey, mip->mastkey, mip->keylen, mip->sesskey);
-
- MPPEReduceSessionKey(mip);
-
- log_Printf(LogCCP, "MPPE: Input channel initiated\n");
-
- if (!mip->stateless) {
- /*
- * We need to initialise our dictionary here as the first packet we
- * receive is unlikely to have the FLUSHED bit set.
- */
- log_Printf(LogDEBUG, "MPPEInitInput: Dictionary initialised [%d]\n",
- mip->cohnum);
- RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
- } else {
- /*
- * We do the first key change here as the first packet is expected
- * to have a sequence number of 0 and we'll therefore not expect
- * to have to change the key at that point.
- */
- log_Printf(LogDEBUG, "MPPEInitInput: Key changed [%d]\n", mip->cohnum);
- MPPEKeyChange(mip);
- }
-
- return mip;
-}
-
-static void *
-MPPEInitOutput(struct bundle *bundle __unused, struct fsm_opt *o)
-{
- struct mppe_state *mop;
-
- if (!MPPE_MasterKeyValid) {
- log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
- return NULL;
- }
-
- if ((mop = MPPE_InitState(o)) == NULL) {
- log_Printf(LogWARN, "MPPEOutput: Cannot initialise - unexpected options\n");
- return NULL;
- }
-
- log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits);
-
-#ifndef NORADIUS
- if (*bundle->radius.cfg.file && bundle->radius.mppe.sendkey) {
- if (mop->keylen > bundle->radius.mppe.sendkeylen)
- mop->keylen = bundle->radius.mppe.sendkeylen;
- if (mop->keylen > sizeof mop->mastkey)
- mop->keylen = sizeof mop->mastkey;
- memcpy(mop->mastkey, bundle->radius.mppe.sendkey, mop->keylen);
- } else
-#endif
- GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1,
- MPPE_IsServer);
-
- GetNewKeyFromSHA(mop->mastkey, mop->mastkey, mop->keylen, mop->sesskey);
-
- MPPEReduceSessionKey(mop);
-
- log_Printf(LogCCP, "MPPE: Output channel initiated\n");
-
- if (!mop->stateless) {
- /*
- * We need to initialise our dictionary now as the first packet we
- * send won't have the FLUSHED bit set.
- */
- log_Printf(LogDEBUG, "MPPEInitOutput: Dictionary initialised [%d]\n",
- mop->cohnum);
- RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
- }
-
- return mop;
-}
-
-static void
-MPPETermInput(void *v)
-{
- free(v);
-}
-
-static void
-MPPETermOutput(void *v)
-{
- free(v);
-}
-
-const struct ccp_algorithm MPPEAlgorithm = {
- TY_MPPE,
- CCP_NEG_MPPE,
- MPPEDispOpts,
- MPPEUsable,
- MPPERequired,
- {
- MPPESetOptsInput,
- MPPEInitInput,
- MPPETermInput,
- MPPEResetInput,
- MPPEInput,
- MPPEDictSetup
- },
- {
- 2,
- MPPEInitOptsOutput,
- MPPESetOptsOutput,
- MPPEInitOutput,
- MPPETermOutput,
- MPPEResetOutput,
- MPPEOutput
- },
-};
OpenPOWER on IntegriCloud