diff options
author | brian <brian@cvs.openbsd.org> | 2002-06-15 01:33:24 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 2002-06-15 01:33:24 +0000 |
commit | 60f1678facd1c144d43bf40470fb108b0f8d7bda (patch) | |
tree | 61a9c39c30ec9ca5e4dd7360ff16d27f453c8164 | |
parent | adbfac5ec41202fc30cb6cdbbd84d87460fd16e1 (diff) |
Understand MS-MPPE-Encryption-Policy, MS-MPPE-Encryption-Types,
MS-MPPE-Recv-Key and MS-MPPE-Send-Key RADIUS attributes, making
MPPE work properly with RADIUS & MSCHAPv2.
Do something with the Filter-Id RADIUS attribute.
Handle MS-CHAP-Error and MS-CHAP2-Success correctly rather than
bogusly including the Ident field in the text passed back to the
client.
Bump the max FSM option length to 52 (was 20)
Add some missing includes.
-rw-r--r-- | usr.sbin/ppp/ppp/ccp.c | 15 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ccp.h | 13 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/chap.c | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/command.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/deflate.c | 15 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/fsm.c | 6 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/fsm.h | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ipcp.c | 10 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/main.c | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/mppe.c | 120 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ppp.8.m4 | 63 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/pred.c | 12 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.c | 201 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.h | 16 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radlib.c | 19 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radlib.h | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/sig.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/timer.c | 4 |
18 files changed, 421 insertions, 98 deletions
diff --git a/usr.sbin/ppp/ppp/ccp.c b/usr.sbin/ppp/ppp/ccp.c index aabe4e31cfe..3899c9322e9 100644 --- a/usr.sbin/ppp/ppp/ccp.c +++ b/usr.sbin/ppp/ppp/ccp.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ccp.c,v 1.27 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: ccp.c,v 1.28 2002/06/15 01:33:23 brian Exp $ */ #include <sys/param.h> @@ -369,7 +369,7 @@ CcpSendConfigReq(struct fsm *fp) (*o)->val.hdr.len = 2; (*o)->next = NULL; (*o)->algorithm = f; - (*algorithm[f]->o.OptInit)(&(*o)->val, &ccp->cfg); + (*algorithm[f]->o.OptInit)(fp->bundle, &(*o)->val, &ccp->cfg); } if (cp + (*o)->val.hdr.len > buff + sizeof buff) { @@ -517,7 +517,8 @@ CcpLayerUp(struct fsm *fp) if (ccp->in.state == NULL && ccp->in.algorithm >= 0 && ccp->in.algorithm < NALGORITHMS) { - ccp->in.state = (*algorithm[ccp->in.algorithm]->i.Init)(&ccp->in.opt); + ccp->in.state = (*algorithm[ccp->in.algorithm]->i.Init) + (fp->bundle, &ccp->in.opt); if (ccp->in.state == NULL) { log_Printf(LogERROR, "%s: %s (in) initialisation failure\n", fp->link->name, protoname(ccp->his_proto)); @@ -534,7 +535,8 @@ CcpLayerUp(struct fsm *fp) if (ccp->out.state == NULL && ccp->out.algorithm >= 0 && ccp->out.algorithm < NALGORITHMS) { - ccp->out.state = (*algorithm[ccp->out.algorithm]->o.Init)(&(*o)->val); + ccp->out.state = (*algorithm[ccp->out.algorithm]->o.Init) + (fp->bundle, &(*o)->val); if (ccp->out.state == NULL) { log_Printf(LogERROR, "%s: %s (out) initialisation failure\n", fp->link->name, protoname(ccp->my_proto)); @@ -596,7 +598,7 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, (*algorithm[f]->Usable)(fp) && ccp->in.algorithm == -1) { memcpy(&ccp->in.opt, opt, opt->hdr.len); - switch ((*algorithm[f]->i.Set)(&ccp->in.opt, &ccp->cfg)) { + switch ((*algorithm[f]->i.Set)(fp->bundle, &ccp->in.opt, &ccp->cfg)) { case MODE_REJ: fsm_rej(dec, &ccp->in.opt); break; @@ -622,7 +624,8 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, " option\n", fp->link->name); else { memcpy(&o->val, opt, opt->hdr.len); - if ((*algorithm[f]->o.Set)(&o->val, &ccp->cfg) == MODE_ACK) + if ((*algorithm[f]->o.Set)(fp->bundle, &o->val, &ccp->cfg) == + MODE_ACK) ccp->my_proto = algorithm[f]->id; else { ccp->his_reject |= (1 << opt->hdr.id); diff --git a/usr.sbin/ppp/ppp/ccp.h b/usr.sbin/ppp/ppp/ccp.h index c04dbfe1bf3..70493e37c0a 100644 --- a/usr.sbin/ppp/ppp/ccp.h +++ b/usr.sbin/ppp/ppp/ccp.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ccp.h,v 1.13 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: ccp.h,v 1.14 2002/06/15 01:33:23 brian Exp $ */ #define CCP_MAXCODE CODE_RESETACK @@ -127,8 +127,8 @@ struct ccp_algorithm { int (*Usable)(struct fsm *); /* Ok to negotiate ? */ int (*Required)(struct fsm *); /* Must negotiate ? */ struct { - int (*Set)(struct fsm_opt *, const struct ccp_config *); - void *(*Init)(struct fsm_opt *); + int (*Set)(struct bundle *, struct fsm_opt *, const struct ccp_config *); + void *(*Init)(struct bundle *, struct fsm_opt *); void (*Term)(void *); void (*Reset)(void *); struct mbuf *(*Read)(void *, struct ccp *, u_short *, struct mbuf *); @@ -136,9 +136,10 @@ struct ccp_algorithm { } i; struct { int MTUOverhead; - void (*OptInit)(struct fsm_opt *, const struct ccp_config *); - int (*Set)(struct fsm_opt *, const struct ccp_config *); - void *(*Init)(struct fsm_opt *); + void (*OptInit)(struct bundle *, struct fsm_opt *, + const struct ccp_config *); + int (*Set)(struct bundle *, struct fsm_opt *, const struct ccp_config *); + void *(*Init)(struct bundle *, struct fsm_opt *); void (*Term)(void *); int (*Reset)(void *); struct mbuf *(*Write)(void *, struct ccp *, struct link *, int, u_short *, diff --git a/usr.sbin/ppp/ppp/chap.c b/usr.sbin/ppp/ppp/chap.c index 15f310e05bd..ce78843bed5 100644 --- a/usr.sbin/ppp/ppp/chap.c +++ b/usr.sbin/ppp/ppp/chap.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: chap.c,v 1.33 2002/05/16 14:27:21 brian Exp $ + * $OpenBSD: chap.c,v 1.34 2002/06/15 01:33:23 brian Exp $ */ #include <sys/param.h> @@ -926,8 +926,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (p->link.lcp.auth_ineed == 0) { #ifndef NODES if (p->link.lcp.his_authtype == 0x81) { - if (strncmp(ans, chap->authresponse, 42) && - (*ans != 1 || strncmp(ans + 1, chap->authresponse, 41))) { + if (strncmp(ans, chap->authresponse, 42)) { datalink_AuthNotOk(p->dl); log_Printf(LogWARN, "CHAP81: AuthenticatorResponse: (%.42s)" " != ans: (%.42s)\n", chap->authresponse, ans); diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index 91565cb6097..c5f7199762c 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: command.c,v 1.75 2002/05/27 23:19:38 brian Exp $ + * $OpenBSD: command.c,v 1.76 2002/06/15 01:33:23 brian Exp $ */ #include <sys/param.h> @@ -163,7 +163,7 @@ #define NEG_MPPE 54 #define NEG_CHAP81 55 -const char Version[] = "3.0.5"; +const char Version[] = "3.1"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); diff --git a/usr.sbin/ppp/ppp/deflate.c b/usr.sbin/ppp/ppp/deflate.c index 4d69280a25e..62a02a0c4c6 100644 --- a/usr.sbin/ppp/ppp/deflate.c +++ b/usr.sbin/ppp/ppp/deflate.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: deflate.c,v 1.14 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: deflate.c,v 1.15 2002/06/15 01:33:23 brian Exp $ */ #include <sys/types.h> @@ -440,7 +440,8 @@ DeflateDispOpts(struct fsm_opt *o) } static void -DeflateInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) +DeflateInitOptsOutput(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { o->hdr.len = 4; o->data[0] = ((cfg->deflate.out.winsize - 8) << 4) + 8; @@ -448,7 +449,8 @@ DeflateInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) } static int -DeflateSetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) +DeflateSetOptsOutput(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { if (o->hdr.len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0') return MODE_REJ; @@ -462,7 +464,8 @@ DeflateSetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) } static int -DeflateSetOptsInput(struct fsm_opt *o, const struct ccp_config *cfg) +DeflateSetOptsInput(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { int want; @@ -483,7 +486,7 @@ DeflateSetOptsInput(struct fsm_opt *o, const struct ccp_config *cfg) } static void * -DeflateInitInput(struct fsm_opt *o) +DeflateInitInput(struct bundle *bundle, struct fsm_opt *o) { struct deflate_state *state; @@ -506,7 +509,7 @@ DeflateInitInput(struct fsm_opt *o) } static void * -DeflateInitOutput(struct fsm_opt *o) +DeflateInitOutput(struct bundle *bundle, struct fsm_opt *o) { struct deflate_state *state; diff --git a/usr.sbin/ppp/ppp/fsm.c b/usr.sbin/ppp/ppp/fsm.c index f51bf405d2e..03e544070f3 100644 --- a/usr.sbin/ppp/ppp/fsm.c +++ b/usr.sbin/ppp/ppp/fsm.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: fsm.c,v 1.21 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: fsm.c,v 1.22 2002/06/15 01:33:23 brian Exp $ */ #include <sys/param.h> @@ -1144,9 +1144,9 @@ fsm_readopt(u_char **cp) *cp += o->hdr.len; if (o->hdr.len > sizeof(struct fsm_opt)) { + log_Printf(LogERROR, "Warning: Truncating option length from %d to %ld\n", + o->hdr.len, sizeof(struct fsm_opt)); o->hdr.len = sizeof(struct fsm_opt); - log_Printf(LogERROR, "Warning: Truncating option length to %d\n", - o->hdr.len); } return o; diff --git a/usr.sbin/ppp/ppp/fsm.h b/usr.sbin/ppp/ppp/fsm.h index 769bb7a2416..c183e0287a7 100644 --- a/usr.sbin/ppp/ppp/fsm.h +++ b/usr.sbin/ppp/ppp/fsm.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: fsm.h,v 1.9 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: fsm.h,v 1.10 2002/06/15 01:33:23 brian Exp $ */ /* @@ -166,7 +166,7 @@ struct fsm_opt_hdr { u_char len; }; -#define MAX_FSM_OPT_LEN 20 +#define MAX_FSM_OPT_LEN 52 struct fsm_opt { struct fsm_opt_hdr hdr; u_char data[MAX_FSM_OPT_LEN-2]; diff --git a/usr.sbin/ppp/ppp/ipcp.c b/usr.sbin/ppp/ppp/ipcp.c index 48627502ee2..ce7e8986fbd 100644 --- a/usr.sbin/ppp/ppp/ipcp.c +++ b/usr.sbin/ppp/ppp/ipcp.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ipcp.c,v 1.35 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: ipcp.c,v 1.36 2002/06/15 01:33:23 brian Exp $ */ #include <sys/param.h> @@ -873,6 +873,10 @@ IpcpLayerDown(struct fsm *fp) radius_Account(&fp->bundle->radius, &fp->bundle->radacct, fp->bundle->links, RAD_STOP, &ipcp->peer_ip, &ipcp->ifmask, &ipcp->throughput); + + if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, + NULL, NULL); #endif /* @@ -936,6 +940,10 @@ IpcpLayerUp(struct fsm *fp) #ifndef NORADIUS radius_Account(&fp->bundle->radius, &fp->bundle->radacct, fp->bundle->links, RAD_START, &ipcp->peer_ip, &ipcp->ifmask, &ipcp->throughput); + + if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + system_Select(fp->bundle, fp->bundle->radius.filterid, LINKUPFILE, + NULL, NULL); #endif /* diff --git a/usr.sbin/ppp/ppp/main.c b/usr.sbin/ppp/ppp/main.c index 50fba63e364..0df8d30b058 100644 --- a/usr.sbin/ppp/ppp/main.c +++ b/usr.sbin/ppp/ppp/main.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: main.c,v 1.32 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: main.c,v 1.33 2002/06/15 01:33:23 brian Exp $ */ #include <sys/param.h> @@ -43,6 +43,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/time.h> #include <termios.h> #include <unistd.h> #include <sys/stat.h> diff --git a/usr.sbin/ppp/ppp/mppe.c b/usr.sbin/ppp/ppp/mppe.c index 7a277501356..7d6f2f219db 100644 --- a/usr.sbin/ppp/ppp/mppe.c +++ b/usr.sbin/ppp/ppp/mppe.c @@ -23,14 +23,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: mppe.c,v 1.13 2002/05/17 00:43:46 brian Exp $ + * $OpenBSD: mppe.c,v 1.14 2002/06/15 01:33:23 brian Exp $ */ -#include <sys/types.h> +#include <sys/param.h> -#ifdef __FreeBSD__ +#include <sys/socket.h> +#include <netinet/in_systm.h> #include <netinet/in.h> -#endif +#include <netinet/ip.h> +#include <sys/un.h> #include <stdio.h> #include <stdlib.h> @@ -54,6 +56,19 @@ #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: @@ -427,29 +442,50 @@ MPPEUsable(struct fsm *fp) 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(const struct ccp_config *cfg) +MPPE_ConfigVal(struct bundle *bundle, const struct ccp_config *cfg) { u_int32_t val; val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0; - 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; - } +#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; } @@ -458,7 +494,8 @@ MPPE_ConfigVal(const struct ccp_config *cfg) * What options should we use for our first configure request */ static void -MPPEInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) +MPPEInitOptsOutput(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { u_int32_t mval; @@ -471,7 +508,8 @@ MPPEInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) return; } - mval = MPPE_ConfigVal(cfg); + + mval = MPPE_ConfigVal(bundle, cfg); ua_htonl(&mval, o->data); } @@ -479,7 +517,8 @@ MPPEInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) * Our CCP request was NAK'd with the given options */ static int -MPPESetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) +MPPESetOptsOutput(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { u_int32_t mval, peer; @@ -489,7 +528,7 @@ MPPESetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) /* Treat their NAK as a REJ */ return MODE_NAK; - mval = MPPE_ConfigVal(cfg); + mval = MPPE_ConfigVal(bundle, cfg); /* * If we haven't been configured with a specific number of keybits, allow @@ -517,7 +556,8 @@ MPPESetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) * The peer has requested the given options */ static int -MPPESetOptsInput(struct fsm_opt *o, const struct ccp_config *cfg) +MPPESetOptsInput(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { u_int32_t mval, peer; int res = MODE_ACK; @@ -532,7 +572,7 @@ MPPESetOptsInput(struct fsm_opt *o, const struct ccp_config *cfg) return MODE_ACK; } - mval = MPPE_ConfigVal(cfg); + mval = MPPE_ConfigVal(bundle, cfg); if (peer & ~MPPE_OPT_MASK) /* He's asking for bits we don't know about */ @@ -620,7 +660,7 @@ MPPE_InitState(struct fsm_opt *o) } static void * -MPPEInitInput(struct fsm_opt *o) +MPPEInitInput(struct bundle *bundle, struct fsm_opt *o) { struct mppe_state *mip; @@ -636,8 +676,17 @@ MPPEInitInput(struct fsm_opt *o) log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits); - GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0, - MPPE_IsServer); +#ifndef NORADIUS + if (*bundle->radius.cfg.file && bundle->radius.mppe.recvkey) { + 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); @@ -666,7 +715,7 @@ MPPEInitInput(struct fsm_opt *o) } static void * -MPPEInitOutput(struct fsm_opt *o) +MPPEInitOutput(struct bundle *bundle, struct fsm_opt *o) { struct mppe_state *mop; @@ -682,8 +731,17 @@ MPPEInitOutput(struct fsm_opt *o) log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits); - GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1, - MPPE_IsServer); +#ifndef NORADIUS + if (*bundle->radius.cfg.file && bundle->radius.mppe.sendkey) { + 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); diff --git a/usr.sbin/ppp/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp/ppp.8.m4 index 09385853526..959e136ec8f 100644 --- a/usr.sbin/ppp/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp/ppp.8.m4 @@ -25,7 +25,7 @@ changecom(,)dnl .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: ppp.8.m4,v 1.9 2002/06/14 21:35:01 todd Exp $ +.\" $OpenBSD: ppp.8.m4,v 1.10 2002/06/15 01:33:23 brian Exp $ .\" .Dd September 20, 1995 .Dt PPP 8 @@ -283,7 +283,7 @@ If the peer requests Microsoft CHAP authentication and .Nm is compiled with DES support, an appropriate MD4/DES response will be made. -.It Supports RADIUS (rfc 2138) authentication. +.It Supports RADIUS (rfc 2138 & 2548) authentication. An extension to PAP and CHAP, .Em \&R Ns No emote .Em \&A Ns No ccess @@ -1332,7 +1332,7 @@ It is .Em VITAL that either PAP or CHAP are enabled as above. If they are not, you are -allowing anybody to establish ppp session with your machine +allowing anybody to establish a ppp session with your machine .Em without a password, opening yourself up to all sorts of potential attacks. .Sh AUTHENTICATING INCOMING CONNECTIONS @@ -5081,7 +5081,8 @@ If any arguments are given, .Nm will .Em insist -on using MPPE and will close the link if it's rejected by the peer. +on using MPPE and will close the link if it's rejected by the peer (Note; +this behaviour can be overridden by a configured RADIUS server). .Pp The first argument specifies the number of bits that .Nm @@ -5243,7 +5244,7 @@ This command enables RADIUS support (if it's compiled in). .Ar config-file refers to the radius client configuration file as described in .Xr radius.conf 5 . -If PAP or CHAP are +If PAP, CHAP, MSCHAP or MSCHAPv2 are .Dq enable Ns No d , .Nm behaves as a @@ -5255,7 +5256,7 @@ authenticating from the .Pa ppp.secret file or from the passwd database. .Pp -If neither PAP or CHAP are enabled, +If none of PAP, CHAP, MSCHAP or MSCHAPv2 are enabled, .Dq set radius will do nothing. .Pp @@ -5279,7 +5280,18 @@ will request VJ compression during IPCP negotiations despite any .Dq disable vj configuration command. .It RAD_FILTER_ID -This attribute is stored but not yet used. +If this attribute is supplied, +.Nm +will attempt to use it as an additional label to load from the +.Pa ppp.linkup +and +.Pa ppp.linkdown +files. +The load will be attempted before (and in addition to) the normal +label search. +If the label doesn't exist, no action is taken and +.Nm +proceeds to the normal load using the current label. .It RAD_FRAMED_ROUTE The received string is expected to be in the format .Ar dest Ns Op / Ns Ar bits @@ -5342,7 +5354,44 @@ If this .Dv RAD_VENDOR_MICROSOFT vendor specific attribute is supplied and if MS-CHAPv2 authentication is being used, it is passed back to the peer as the authentication SUCCESS text. +.It RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY +If this +.Dv RAD_VENDOR_MICROSOFT +vendor specific attribute is supplied and has a value of 2 (Required), +.Nm +will insist that MPPE encryption is used (even if no +.Dq set mppe +configuration command has been given with arguments). +If it is supplied with a value of 1 (Allowed), encryption is made optional +(despite any +.Dq set mppe +configuration commands with arguments). +.It RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES +If this +.Dv RAD_VENDOR_MICROSOFT +vendor specific attribute is supplied, bits 1 and 2 are examined. +If either or both are set, 40 bit and/or 128 bit (respectively) encryption +options are set, overriding any given first argument to the +.Dq set mppe +command. +Note, it is not currently possible for the RADIUS server to specify 56 bit +encryption. +.It RAD_MICROSOFT_MS_MPPE_RECV_KEY +If this +.Dv RAD_VENDOR_MICROSOFT +vendor specific attribute is supplied, it's value is used as the master +key for decryption of incoming data. When clients are authenticated using +MSCHAPv2, the RADIUS server MUST provide this attribute if inbound MPPE is +to function. +.It RAD_MICROSOFT_MS_MPPE_SEND_KEY +If this +.Dv RAD_VENDOR_MICROSOFT +vendor specific attribute is supplied, it's value is used as the master +key for encryption of outgoing data. When clients are authenticated using +MSCHAPv2, the RADIUS server MUST provide this attribute if outbound MPPE is +to function. .El +.Pp Values received from the RADIUS server may be viewed using .Dq show bundle . .It set reconnect Ar timeout ntries diff --git a/usr.sbin/ppp/ppp/pred.c b/usr.sbin/ppp/ppp/pred.c index 85f87d45fdb..c47a4b169b8 100644 --- a/usr.sbin/ppp/ppp/pred.c +++ b/usr.sbin/ppp/ppp/pred.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: pred.c,v 1.13 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: pred.c,v 1.14 2002/06/15 01:33:23 brian Exp $ */ #include <sys/types.h> @@ -151,7 +151,7 @@ Pred1ResetOutput(void *v) } static void * -Pred1InitInput(struct fsm_opt *o) +Pred1InitInput(struct bundle *bundle, struct fsm_opt *o) { struct pred1_state *state; state = (struct pred1_state *)malloc(sizeof(struct pred1_state)); @@ -161,7 +161,7 @@ Pred1InitInput(struct fsm_opt *o) } static void * -Pred1InitOutput(struct fsm_opt *o) +Pred1InitOutput(struct bundle *bundle, struct fsm_opt *o) { struct pred1_state *state; state = (struct pred1_state *)malloc(sizeof(struct pred1_state)); @@ -300,13 +300,15 @@ Pred1DispOpts(struct fsm_opt *o) } static void -Pred1InitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) +Pred1InitOptsOutput(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { o->hdr.len = 2; } static int -Pred1SetOpts(struct fsm_opt *o, const struct ccp_config *cfg) +Pred1SetOpts(struct bundle *bundle, struct fsm_opt *o, + const struct ccp_config *cfg) { if (o->hdr.len != 2) { o->hdr.len = 2; diff --git a/usr.sbin/ppp/ppp/radius.c b/usr.sbin/ppp/ppp/radius.c index 63bdd9283cc..fb5c1b4670b 100644 --- a/usr.sbin/ppp/ppp/radius.c +++ b/usr.sbin/ppp/ppp/radius.c @@ -23,11 +23,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radius.c,v 1.17 2002/06/02 14:28:40 brian Exp $ + * $OpenBSD: radius.c,v 1.18 2002/06/15 01:33:23 brian Exp $ * */ #include <sys/param.h> + #include <sys/socket.h> #include <netinet/in_systm.h> #include <netinet/in.h> @@ -45,6 +46,9 @@ #endif #include <errno.h> +#ifndef NODES +#include <md5.h> +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -104,6 +108,111 @@ struct mschap2_response { u_char reserved[8]; u_char response[24]; }; + +#define AUTH_LEN 16 +#define SALT_LEN 2 +#endif + +static const char * +radius_policyname(int policy) +{ + switch(policy) { + case MPPE_POLICY_ALLOWED: + return "Allowed"; + case MPPE_POLICY_REQUIRED: + return "Required"; + } + return NumStr(policy, NULL, 0); +} + +static const char * +radius_typesname(int types) +{ + switch(types) { + case MPPE_TYPE_40BIT: + return "40 bit"; + case MPPE_TYPE_128BIT: + return "128 bit"; + case MPPE_TYPE_40BIT|MPPE_TYPE_128BIT: + return "40 or 128 bit"; + } + return NumStr(types, NULL, 0); +} + +#ifndef NODES +static void +demangle(struct radius *r, const void *mangled, size_t mlen, + char **buf, size_t *len) +{ + char R[AUTH_LEN]; /* variable names as per rfc2548 */ + const char *S; + u_char b[16]; + const u_char *A, *C; + MD5_CTX Context; + int Slen, i, Clen, Ppos; + u_char *P; + + if (mlen % 16 != SALT_LEN) { + log_Printf(LogWARN, "Cannot interpret mangled data of length %ld\n", + (u_long)mlen); + *buf = NULL; + *len = 0; + return; + } + + /* We need the RADIUS Request-Authenticator */ + if (rad_request_authenticator(r->cx.rad, R, sizeof R) != AUTH_LEN) { + log_Printf(LogWARN, "Cannot obtain the RADIUS request authenticator\n"); + *buf = NULL; + *len = 0; + return; + } + + A = (const u_char *)mangled; /* Salt comes first */ + C = (const u_char *)mangled + SALT_LEN; /* Then the ciphertext */ + Clen = mlen - SALT_LEN; + S = rad_server_secret(r->cx.rad); /* We need the RADIUS secret */ + Slen = strlen(S); + P = alloca(Clen); /* We derive our plaintext */ + + MD5Init(&Context); + MD5Update(&Context, S, Slen); + MD5Update(&Context, R, AUTH_LEN); + MD5Update(&Context, A, SALT_LEN); + MD5Final(b, &Context); + Ppos = 0; + + while (Clen) { + Clen -= 16; + + for (i = 0; i < 16; i++) + P[Ppos++] = C[i] ^ b[i]; + + if (Clen) { + MD5Init(&Context); + MD5Update(&Context, S, Slen); + MD5Update(&Context, C, 16); + MD5Final(b, &Context); + } + + C += 16; + } + + /* + * The resulting plain text consists of a one-byte length, the text and + * maybe some padding. + */ + *len = *P; + if (*len > mlen - 1) { + log_Printf(LogWARN, "Mangled data seems to be garbage\n"); + *buf = NULL; + *len = 0; + return; + } + + *buf = malloc(*len); + memcpy(*buf, P + 1, *len); +} #endif /* @@ -304,30 +413,66 @@ radius_Process(struct radius *r, int got) switch (vendor) { case RAD_VENDOR_MICROSOFT: switch (res) { +#ifndef NODES case RAD_MICROSOFT_MS_CHAP_ERROR: free(r->errstr); - if ((r->errstr = rad_cvt_string(data, len)) == NULL) { - log_Printf(LogERROR, "rad_cvt_string: %s\n", - rad_strerror(r->cx.rad)); - auth_Failure(r->cx.auth); - rad_close(r->cx.rad); - return; + if (len == 0) + r->errstr = NULL; + else { + if ((r->errstr = rad_cvt_string((const char *)data + 1, + len - 1)) == NULL) { + log_Printf(LogERROR, "rad_cvt_string: %s\n", + rad_strerror(r->cx.rad)); + auth_Failure(r->cx.auth); + rad_close(r->cx.rad); + return; + } + log_Printf(LogPHASE, " MS-CHAP-Error \"%s\"\n", r->errstr); } - log_Printf(LogPHASE, " MS-CHAP-Error \"%s\"\n", r->errstr); break; case RAD_MICROSOFT_MS_CHAP2_SUCCESS: free(r->msrepstr); - if ((r->msrepstr = rad_cvt_string(data, len)) == NULL) { - log_Printf(LogERROR, "rad_cvt_string: %s\n", - rad_strerror(r->cx.rad)); - auth_Failure(r->cx.auth); - rad_close(r->cx.rad); - return; + if (len == 0) + r->msrepstr = NULL; + else { + if ((r->msrepstr = rad_cvt_string((const char *)data + 1, + len - 1)) == NULL) { + log_Printf(LogERROR, "rad_cvt_string: %s\n", + rad_strerror(r->cx.rad)); + auth_Failure(r->cx.auth); + rad_close(r->cx.rad); + return; + } + log_Printf(LogPHASE, " MS-CHAP2-Success \"%s\"\n", + r->msrepstr); } - log_Printf(LogPHASE, " MS-CHAP2-Success \"%s\"\n", r->msrepstr); break; + case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY: + r->mppe.policy = rad_cvt_int(data); + log_Printf(LogPHASE, " MS-MPPE-Encryption-Policy %s\n", + radius_policyname(r->mppe.policy)); + break; + + case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES: + r->mppe.types = rad_cvt_int(data); + log_Printf(LogPHASE, " MS-MPPE-Encryption-Types %s\n", + radius_typesname(r->mppe.types)); + break; + + case RAD_MICROSOFT_MS_MPPE_RECV_KEY: + free(r->mppe.recvkey); + demangle(r, data, len, &r->mppe.recvkey, &r->mppe.recvkeylen); + log_Printf(LogPHASE, " MS-MPPE-Recv-Key ********\n"); + break; + + case RAD_MICROSOFT_MS_MPPE_SEND_KEY: + demangle(r, data, len, &r->mppe.sendkey, &r->mppe.sendkeylen); + log_Printf(LogPHASE, " MS-MPPE-Send-Key ********\n"); + break; +#endif + default: log_Printf(LogDEBUG, "Dropping MICROSOFT vendor specific " "RADIUS attribute %d\n", res); @@ -464,6 +609,12 @@ radius_Init(struct radius *r) r->msrepstr = NULL; r->repstr = NULL; r->errstr = NULL; + r->mppe.policy = 0; + r->mppe.types = 0; + r->mppe.recvkey = NULL; + r->mppe.recvkeylen = 0; + r->mppe.sendkey = NULL; + r->mppe.sendkeylen = 0; *r->cfg.file = '\0';; log_Printf(LogDEBUG, "Radius: radius_Init\n"); } @@ -486,6 +637,12 @@ radius_Destroy(struct radius *r) r->repstr = NULL; free(r->errstr); r->errstr = NULL; + free(r->mppe.recvkey); + r->mppe.recvkey = NULL; + r->mppe.recvkeylen = 0; + free(r->mppe.sendkey); + r->mppe.sendkey = NULL; + r->mppe.sendkeylen = 0; if (r->cx.fd != -1) { r->cx.fd = -1; rad_close(r->cx.rad); @@ -550,8 +707,8 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, char hostname[MAXHOSTNAMELEN]; #if 0 struct hostent *hp; -#endif struct in_addr hostaddr; +#endif #ifndef NODES struct mschap_response msresp; struct mschap2_response msresp2; @@ -723,8 +880,8 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, char hostname[MAXHOSTNAMELEN]; #if 0 struct hostent *hp; -#endif struct in_addr hostaddr; +#endif if (!*r->cfg.file) return; @@ -736,7 +893,7 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, */ return; - radius_Destroy(r); + timer_Stop(&r->cx.timer); if ((r->cx.rad = rad_acct_open()) == NULL) { log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); @@ -865,6 +1022,14 @@ radius_Show(struct radius *r, struct prompt *p) prompt_Printf(p, " MTU: %lu\n", r->mtu); prompt_Printf(p, " VJ: %sabled\n", r->vj ? "en" : "dis"); prompt_Printf(p, " Message: %s\n", r->repstr ? r->repstr : ""); + prompt_Printf(p, " MPPE Enc Policy: %s\n", + radius_policyname(r->mppe.policy)); + prompt_Printf(p, " MPPE Enc Types: %s\n", + radius_typesname(r->mppe.types)); + prompt_Printf(p, " MPPE Recv Key: %seceived\n", + r->mppe.recvkey ? "R" : "Not r"); + prompt_Printf(p, " MPPE Send Key: %seceived\n", + r->mppe.sendkey ? "R" : "Not r"); prompt_Printf(p, " MS-CHAP2-Response: %s\n", r->msrepstr ? r->msrepstr : ""); prompt_Printf(p, " Error Message: %s\n", r->errstr ? r->errstr : ""); diff --git a/usr.sbin/ppp/ppp/radius.h b/usr.sbin/ppp/ppp/radius.h index 9eafae49332..693ff6ebee2 100644 --- a/usr.sbin/ppp/ppp/radius.h +++ b/usr.sbin/ppp/ppp/radius.h @@ -23,9 +23,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radius.h,v 1.8 2002/05/16 14:27:21 brian Exp $ + * $OpenBSD: radius.h,v 1.9 2002/06/15 01:33:23 brian Exp $ */ +#define MPPE_POLICY_ALLOWED 1 +#define MPPE_POLICY_REQUIRED 2 + +#define MPPE_TYPE_40BIT 2 +#define MPPE_TYPE_128BIT 4 + struct radius { struct fdescriptor desc; /* We're a sort of (selectable) fdescriptor */ struct { @@ -46,6 +52,14 @@ struct radius { char *repstr; /* Reply-Message */ char *errstr; /* Error-Message */ struct { + int policy; /* MPPE_POLICY_* */ + int types; /* MPPE_TYPE_*BIT bitmask */ + char *recvkey; + size_t recvkeylen; + char *sendkey; + size_t sendkeylen; + } mppe; + struct { char file[PATH_MAX]; /* Radius config file */ } cfg; }; diff --git a/usr.sbin/ppp/ppp/radlib.c b/usr.sbin/ppp/ppp/radlib.c index 197aeaaab18..dea9e7adb40 100644 --- a/usr.sbin/ppp/ppp/radlib.c +++ b/usr.sbin/ppp/ppp/radlib.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radlib.c,v 1.6 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: radlib.c,v 1.7 2002/06/15 01:33:23 brian Exp $ */ #include <sys/types.h> @@ -928,3 +928,20 @@ rad_put_vendor_string(struct rad_handle *h, int vendor, int type, { return (rad_put_vendor_attr(h, vendor, type, str, strlen(str))); } + +ssize_t +rad_request_authenticator(struct rad_handle *h, char *buf, size_t len) +{ + if (len < LEN_AUTH) + return (-1); + memcpy(buf, h->request + POS_AUTH, LEN_AUTH); + if (len > LEN_AUTH) + buf[LEN_AUTH] = '\0'; + return (LEN_AUTH); +} + +const char * +rad_server_secret(struct rad_handle *h) +{ + return (h->servers[h->srv].secret); +} diff --git a/usr.sbin/ppp/ppp/radlib.h b/usr.sbin/ppp/ppp/radlib.h index cdd4d236518..657cee1792f 100644 --- a/usr.sbin/ppp/ppp/radlib.h +++ b/usr.sbin/ppp/ppp/radlib.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radlib.h,v 1.3 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: radlib.h,v 1.4 2002/06/15 01:33:23 brian Exp $ */ #ifndef _RADLIB_H_ @@ -190,7 +190,10 @@ int rad_put_attr(struct rad_handle *, int, int rad_put_int(struct rad_handle *, int, u_int32_t); int rad_put_string(struct rad_handle *, int, const char *); +ssize_t rad_request_authenticator(struct rad_handle *, char *, + size_t); int rad_send_request(struct rad_handle *); +const char *rad_server_secret(struct rad_handle *); const char *rad_strerror(struct rad_handle *); __END_DECLS diff --git a/usr.sbin/ppp/ppp/sig.c b/usr.sbin/ppp/ppp/sig.c index c69f6632574..faa647a1e8d 100644 --- a/usr.sbin/ppp/ppp/sig.c +++ b/usr.sbin/ppp/ppp/sig.c @@ -23,9 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: sig.c,v 1.6 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: sig.c,v 1.7 2002/06/15 01:33:23 brian Exp $ */ +#include <sys/types.h> + #include <signal.h> #include "log.h" diff --git a/usr.sbin/ppp/ppp/timer.c b/usr.sbin/ppp/ppp/timer.c index 53e713b3894..657999e9033 100644 --- a/usr.sbin/ppp/ppp/timer.c +++ b/usr.sbin/ppp/ppp/timer.c @@ -25,16 +25,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: timer.c,v 1.11 2002/05/16 01:13:39 brian Exp $ + * $OpenBSD: timer.c,v 1.12 2002/06/15 01:33:23 brian Exp $ */ #include <errno.h> #include <signal.h> #include <stdio.h> #include <string.h> -#ifdef __NetBSD__ #include <sys/time.h> -#endif #include <termios.h> #include "log.h" |