From 06f88b85361a193390cca0f04779538ade984e49 Mon Sep 17 00:00:00 2001 From: brian Date: Mon, 17 Jun 2002 01:14:09 +0000 Subject: Compensate for dodgy Win98/WinME MSCHAPv2 responses later in the code path... after we've talked to any RADIUS servers involved, so that we haven't touched the data before it gets to the server. --- usr.sbin/ppp/ppp/chap.c | 34 ++++++++++++++++++---------------- usr.sbin/ppp/ppp/chap.h | 9 ++++++++- usr.sbin/ppp/ppp/pap.c | 4 ++-- usr.sbin/ppp/ppp/radius.c | 22 +++++++++------------- usr.sbin/ppp/ppp/radius.h | 4 ++-- 5 files changed, 39 insertions(+), 34 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/ppp/ppp/chap.c b/usr.sbin/ppp/ppp/chap.c index 5701a431aa2..7558cdf2440 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.35 2002/06/15 08:02:00 brian Exp $ + * $OpenBSD: chap.c,v 1.36 2002/06/17 01:14:08 brian Exp $ */ #include @@ -761,19 +761,13 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) m_freem(bp); return NULL; } - if ((ans = malloc(alen + 2)) == NULL) { + if ((ans = malloc(alen + 1)) == NULL) { log_Printf(LogERROR, "Chap Input: Out of memory !\n"); m_freem(bp); return NULL; } *ans = chap->auth.id; bp = mbuf_Read(bp, ans + 1, alen); - if (p->link.lcp.want_authtype == 0x81 && ans[alen] != '\0') { - log_Printf(LogWARN, "%s: Compensating for corrupt (Win98/WinME?) " - "CHAP81 RESPONSE\n", l->name); - ans[alen] = '\0'; - } - ans[alen+1] = '\0'; bp = auth_ReadName(&chap->auth, bp, len); #ifndef NODES lanman = p->link.lcp.want_authtype == 0x80 && @@ -847,8 +841,11 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) nlen = strlen(name); #ifndef NODES if (p->link.lcp.want_authtype == 0x81) { - chap->challenge.peer[0] = CHAP81_CHALLENGE_LEN; - memcpy(chap->challenge.peer + 1, ans + 1, CHAP81_CHALLENGE_LEN); + struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1); + + chap->challenge.peer[0] = sizeof resp->PeerChallenge; + memcpy(chap->challenge.peer + 1, resp->PeerChallenge, + sizeof resp->PeerChallenge); } #endif @@ -857,16 +854,21 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (!radius_Authenticate(&bundle->radius, &chap->auth, chap->auth.in.name, ans, alen + 1, chap->challenge.local + 1, - *chap->challenge.local, - chap->challenge.peer + 1, - *chap->challenge.peer)) + *chap->challenge.local)) chap_Failure(&chap->auth); } else #endif { + if (p->link.lcp.want_authtype == 0x81 && ans[alen] != '\0' && + alen == sizeof(struct MSCHAPv2_resp)) { + struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1); + + log_Printf(LogWARN, "%s: Compensating for corrupt (Win98/WinME?) " + "CHAP81 RESPONSE\n", l->name); + resp->Flags = '\0'; /* rfc2759 says it *MUST* be zero */ + } key = auth_GetSecret(bundle, name, nlen, p); if (key) { - char *myans; #ifndef NODES if (p->link.lcp.want_authtype == 0x80 && lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) { @@ -887,8 +889,8 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) } else #endif { - myans = chap_BuildAnswer(name, key, chap->auth.id, - chap->challenge.local, + char *myans = chap_BuildAnswer(name, key, chap->auth.id, + chap->challenge.local, p->link.lcp.want_authtype #ifndef NODES , chap->challenge.peer, diff --git a/usr.sbin/ppp/ppp/chap.h b/usr.sbin/ppp/ppp/chap.h index 35abb29b81b..2288210700b 100644 --- a/usr.sbin/ppp/ppp/chap.h +++ b/usr.sbin/ppp/ppp/chap.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: chap.h,v 1.12 2002/03/31 02:38:49 brian Exp $ + * $OpenBSD: chap.h,v 1.13 2002/06/17 01:14:08 brian Exp $ */ struct mbuf; @@ -63,6 +63,13 @@ struct chap { #define auth2chap(a) \ ((struct chap *)((char *)a - (int)&((struct chap *)0)->auth)) +struct MSCHAPv2_resp { /* rfc2759 */ + char PeerChallenge[16]; + char Reserved[8]; + char NTResponse[24]; + char Flags; +}; + extern void chap_Init(struct chap *, struct physical *); extern void chap_ReInit(struct chap *); extern struct mbuf *chap_Input(struct bundle *, struct link *, struct mbuf *); diff --git a/usr.sbin/ppp/ppp/pap.c b/usr.sbin/ppp/ppp/pap.c index 145b5912dcc..aff29c34a73 100644 --- a/usr.sbin/ppp/ppp/pap.c +++ b/usr.sbin/ppp/ppp/pap.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: pap.c,v 1.19 2002/05/16 14:27:21 brian Exp $ + * $OpenBSD: pap.c,v 1.20 2002/06/17 01:14:08 brian Exp $ */ #include @@ -266,7 +266,7 @@ pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) #ifndef NORADIUS if (*bundle->radius.cfg.file) { if (!radius_Authenticate(&bundle->radius, authp, authp->in.name, - key, strlen(key), NULL, 0, NULL, 0)) + key, strlen(key), NULL, 0)) pap_Failure(authp); } else #endif diff --git a/usr.sbin/ppp/ppp/radius.c b/usr.sbin/ppp/ppp/radius.c index 29dab0c440b..bf27a3e0daa 100644 --- a/usr.sbin/ppp/ppp/radius.c +++ b/usr.sbin/ppp/ppp/radius.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radius.c,v 1.19 2002/06/15 08:02:01 brian Exp $ + * $OpenBSD: radius.c,v 1.20 2002/06/17 01:14:08 brian Exp $ * */ @@ -700,7 +700,7 @@ radius_put_physical_details(struct rad_handle *rad, struct physical *p) int radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, const char *key, int klen, const char *nchallenge, - int nclen, const char *pchallenge, int pclen) + int nclen) { struct timeval tv; int got; @@ -712,6 +712,7 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, #ifndef NODES struct mschap_response msresp; struct mschap2_response msresp2; + const struct MSCHAPv2_resp *keyv2; #endif if (!*r->cfg.file) @@ -794,26 +795,21 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, break; case 0x81: - if (klen != 50) { + if (klen != sizeof(*keyv2) + 1) { log_Printf(LogERROR, "CHAP81: Unrecognised key length %d\n", klen); rad_close(r->cx.rad); return 0; } - if (pclen != sizeof msresp2.pchallenge) { - log_Printf(LogERROR, "CHAP81: Unrecognised peer challenge length %d\n", - pclen); - rad_close(r->cx.rad); - return 0; - } - + keyv2 = (const struct MSCHAPv2_resp *)(key + 1); rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen); msresp2.ident = *key; - msresp2.flags = 0x00; - memcpy(msresp2.response, key + 25, 24); + msresp2.flags = keyv2->Flags; + memcpy(msresp2.response, keyv2->NTResponse, sizeof msresp2.response); memset(msresp2.reserved, '\0', sizeof msresp2.reserved); - memcpy(msresp2.pchallenge, pchallenge, pclen); + memcpy(msresp2.pchallenge, keyv2->PeerChallenge, + sizeof msresp2.pchallenge); rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP2_RESPONSE, &msresp2, sizeof msresp2); diff --git a/usr.sbin/ppp/ppp/radius.h b/usr.sbin/ppp/ppp/radius.h index 8fd1390694f..a59a8308d41 100644 --- a/usr.sbin/ppp/ppp/radius.h +++ b/usr.sbin/ppp/ppp/radius.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radius.h,v 1.10 2002/06/15 08:02:01 brian Exp $ + * $OpenBSD: radius.h,v 1.11 2002/06/17 01:14:08 brian Exp $ */ #define MPPE_POLICY_ALLOWED 1 @@ -85,7 +85,7 @@ extern void radius_Destroy(struct radius *); extern void radius_Show(struct radius *, struct prompt *); extern int radius_Authenticate(struct radius *, struct authinfo *, const char *, const char *, int, - const char *, int, const char *, int); + const char *, int); extern void radius_Account(struct radius *, struct radacct *, struct datalink *, int, struct in_addr *, struct in_addr *, struct pppThroughput *); -- cgit v1.2.3