From 64df5969679c3ad7b7f9452c2dcaee6a0621e26a Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 12 Jun 2002 00:33:17 +0000 Subject: Understand the following Microsoft Vendor Specific RADIUS attributes: RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES RAD_MICROSOFT_MS_MPPE_RECV_KEY RAD_MICROSOFT_MS_MPPE_SEND_KEY These attributes may be supplied by a RADIUS server when MSCHAPv2 is used to authenticate. It *should* now be possible to build ppp with -DNODES and still support CHAP/MSCHAP/MSCHAPv2/MPPE via a RADIUS server, but the code isn't yet smart enough to do that (building with -DNODES just looses these facilities). Sponsored by: Monzoon --- usr.sbin/ppp/ccp.c | 13 ++-- usr.sbin/ppp/ccp.h | 11 ++-- usr.sbin/ppp/deflate.c | 13 ++-- usr.sbin/ppp/mppe.c | 118 +++++++++++++++++++++++++++--------- usr.sbin/ppp/ppp.8.m4 | 44 +++++++++++++- usr.sbin/ppp/pred.c | 10 +-- usr.sbin/ppp/radius.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++- usr.sbin/ppp/radius.h | 14 +++++ 8 files changed, 329 insertions(+), 55 deletions(-) diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c index a0f6490..aef3a51 100644 --- a/usr.sbin/ppp/ccp.c +++ b/usr.sbin/ppp/ccp.c @@ -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/ccp.h b/usr.sbin/ppp/ccp.h index 46c96db..bc867b6 100644 --- a/usr.sbin/ppp/ccp.h +++ b/usr.sbin/ppp/ccp.h @@ -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/deflate.c b/usr.sbin/ppp/deflate.c index f629c5b..3e6198d 100644 --- a/usr.sbin/ppp/deflate.c +++ b/usr.sbin/ppp/deflate.c @@ -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/mppe.c b/usr.sbin/ppp/mppe.c index 908d427..f3d8254 100644 --- a/usr.sbin/ppp/mppe.c +++ b/usr.sbin/ppp/mppe.c @@ -26,11 +26,13 @@ * $FreeBSD$ */ -#include +#include -#ifdef __FreeBSD__ +#include +#include #include -#endif +#include +#include #include #include @@ -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.8.m4 b/usr.sbin/ppp/ppp.8.m4 index 9b59275..bec41d6 100644 --- a/usr.sbin/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp.8.m4 @@ -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 @@ -5342,7 +5343,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/pred.c b/usr.sbin/ppp/pred.c index d286a97..2a81381 100644 --- a/usr.sbin/ppp/pred.c +++ b/usr.sbin/ppp/pred.c @@ -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/radius.c b/usr.sbin/ppp/radius.c index 87d5375..1f43db2 100644 --- a/usr.sbin/ppp/radius.c +++ b/usr.sbin/ppp/radius.c @@ -28,6 +28,7 @@ */ #include + #include #include #include @@ -45,6 +46,9 @@ #endif #include +#ifndef NODES +#include +#endif #include #include #include @@ -104,6 +108,112 @@ 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); +log_Printf(LogWARN, "demangled %d bytes\n", *len); +} #endif /* @@ -304,6 +414,7 @@ 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) { @@ -328,6 +439,30 @@ radius_Process(struct radius *r, int got) 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 +599,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 +627,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 +697,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 +870,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 +883,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 +1012,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/radius.h b/usr.sbin/ppp/radius.h index 0ea6edd..0b01b23 100644 --- a/usr.sbin/ppp/radius.h +++ b/usr.sbin/ppp/radius.h @@ -26,6 +26,12 @@ * $FreeBSD$ */ +#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; }; -- cgit v1.1