From 8ed456439d306257173fb0c74d77c4e3c472dfc6 Mon Sep 17 00:00:00 2001 From: "David F. Skoll" Date: Mon, 4 Mar 2002 14:59:52 +0000 Subject: [PATCH] Patch from Frank Cusack to make RADIUS plugin support MS-CHAP authentication. --- pppd/Makefile.linux | 4 +- pppd/chap.c | 10 +-- pppd/chap_ms.c | 6 +- pppd/chap_ms.h | 4 +- pppd/plugins/radius/Makefile.linux | 8 +++ pppd/plugins/radius/pppd-radius.8 | 6 +- pppd/plugins/radius/radius.c | 67 ++++++++++++++----- .../radiusclient/include/radiusclient.h | 11 ++- .../radius/radiusclient/lib/sendserver.c | 4 +- 9 files changed, 84 insertions(+), 36 deletions(-) diff --git a/pppd/Makefile.linux b/pppd/Makefile.linux index 5f2de1f..d16a71e 100644 --- a/pppd/Makefile.linux +++ b/pppd/Makefile.linux @@ -1,6 +1,6 @@ # # pppd makefile for Linux -# $Id: Makefile.linux,v 1.44 2002/01/14 14:26:31 dfs Exp $ +# $Id: Makefile.linux,v 1.45 2002/03/04 14:59:51 dfs Exp $ # # Default installation locations @@ -34,7 +34,7 @@ LIBS += -lcrypt endif # Uncomment the next 2 lines to include support for Microsoft's -# MS-CHAP authentication protocol. +# MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile. CHAPMS=y USE_CRYPT=y ifneq ($(wildcard /usr/lib/libcrypt.*),) diff --git a/pppd/chap.c b/pppd/chap.c index 25427e2..208a144 100644 --- a/pppd/chap.c +++ b/pppd/chap.c @@ -33,7 +33,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: chap.c,v 1.27 2002/03/01 14:39:18 dfs Exp $" +#define RCSID "$Id: chap.c,v 1.28 2002/03/04 14:59:51 dfs Exp $" /* * TODO: @@ -597,6 +597,7 @@ ChapReceiveResponse(cstate, inp, id, len) case CHAP_MICROSOFT: { int response_offset, response_size; + MS_ChapResponse *rmd = (MS_ChapResponse *) remmd; if (remmd_len != MS_CHAP_RESPONSE_LEN) break; /* not even the right length */ @@ -604,13 +605,12 @@ ChapReceiveResponse(cstate, inp, id, len) secret, secret_len); /* Determine which part of response to verify against */ - if ((u_char *) (remmd + offsetof(MS_ChapResponse, UseNT))) { + if (rmd->UseNT[0]) { response_offset = offsetof(MS_ChapResponse, NTResp); - response_size = sizeof(((MS_ChapResponse *) remmd)->NTResp); + response_size = sizeof(rmd->NTResp); } else { response_offset = offsetof(MS_ChapResponse, LANManResp); - response_size = - sizeof(((MS_ChapResponse *) remmd)->LANManResp); + response_size = sizeof(rmd->LANManResp); } /* compare MDs and send the appropriate status */ diff --git a/pppd/chap_ms.c b/pppd/chap_ms.c index 9a7002c..c4b7d20 100644 --- a/pppd/chap_ms.c +++ b/pppd/chap_ms.c @@ -31,7 +31,7 @@ * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 */ -#define RCSID "$Id: chap_ms.c,v 1.16 2002/03/01 14:39:18 dfs Exp $" +#define RCSID "$Id: chap_ms.c,v 1.17 2002/03/04 14:59:51 dfs Exp $" #ifdef CHAPMS @@ -318,9 +318,9 @@ ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len) ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response); /* prefered method is set by option */ - response.UseNT = !ms_lanman; + response.UseNT[0] = !ms_lanman; #else - response.UseNT = 1; + response.UseNT[0] = 1; #endif BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN); diff --git a/pppd/chap_ms.h b/pppd/chap_ms.h index e673f8a..4418c93 100644 --- a/pppd/chap_ms.h +++ b/pppd/chap_ms.h @@ -19,7 +19,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: chap_ms.h,v 1.3 2002/03/01 14:39:18 dfs Exp $ + * $Id: chap_ms.h,v 1.4 2002/03/04 14:59:51 dfs Exp $ */ #ifndef __CHAPMS_INCLUDE__ @@ -36,7 +36,7 @@ typedef struct { u_char LANManResp[24]; u_char NTResp[24]; - u_char UseNT; /* If 1, ignore the LANMan response field */ + u_char UseNT[1]; /* If 1, ignore the LANMan response field */ } MS_ChapResponse; void ChapMS __P((chap_state *, char *, int, char *, int)); diff --git a/pppd/plugins/radius/Makefile.linux b/pppd/plugins/radius/Makefile.linux index 1fa7ff9..30fcb7a 100644 --- a/pppd/plugins/radius/Makefile.linux +++ b/pppd/plugins/radius/Makefile.linux @@ -7,6 +7,14 @@ MANDIR=/usr/man PLUGIN=radius.so radattr.so CFLAGS=-I../.. -Iradiusclient/include -O2 +# Uncomment the next line to include support for Microsoft's +# MS-CHAP authentication protocol. +CHAPMS=y + +ifdef CHAPMS +CFLAGS += -DCHAPMS=1 +endif + all: $(PLUGIN) install: all diff --git a/pppd/plugins/radius/pppd-radius.8 b/pppd/plugins/radius/pppd-radius.8 index 4b9cddd..5e9bc1a 100644 --- a/pppd/plugins/radius/pppd-radius.8 +++ b/pppd/plugins/radius/pppd-radius.8 @@ -1,5 +1,5 @@ .\" manual page [] for RADIUS plugin for pppd 2.4 -.\" $Id: pppd-radius.8,v 1.1 2002/01/22 16:03:00 dfs Exp $ +.\" $Id: pppd-radius.8,v 1.2 2002/03/04 14:59:51 dfs Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph @@ -17,8 +17,8 @@ radius.so \- RADIUS authentication plugin for plugin radius.so .SH DESCRIPTION .LP -The RADIUS plugin for pppd permits pppd to perform CHAP and PAP authentication -against a RADIUS server instead of the usual +The RADIUS plugin for pppd permits pppd to perform PAP, CHAP, and MS-CHAP +authentication against a RADIUS server instead of the usual .I /etc/ppp/pap-secrets and .I /etc/ppp/chap-secrets diff --git a/pppd/plugins/radius/radius.c b/pppd/plugins/radius/radius.c index fa638d0..358fc95 100644 --- a/pppd/plugins/radius/radius.c +++ b/pppd/plugins/radius/radius.c @@ -2,8 +2,8 @@ * * radius.c * -* RADIUS plugin for pppd. Performs PAP and CHAP authentication using -* RADIUS. +* RADIUS plugin for pppd. Performs PAP, CHAP and MS-CHAP authentication +* using RADIUS. * * Copyright (C) 2002 Roaring Penguin Software Inc. * @@ -21,10 +21,13 @@ * ***********************************************************************/ static char const RCSID[] = -"$Id: radius.c,v 1.4 2002/03/01 15:16:51 dfs Exp $"; +"$Id: radius.c,v 1.5 2002/03/04 14:59:51 dfs Exp $"; #include "pppd.h" #include "chap.h" +#ifdef CHAPMS +#include "chap_ms.h" +#endif #include "radiusclient.h" #include "fsm.h" #include "ipcp.h" @@ -252,7 +255,7 @@ radius_pap_auth(char *user, * %RETURNS: * CHAP_SUCCESS if we can authenticate, CHAP_FAILURE if we cannot. * %DESCRIPTION: -* Performs CHAP authentication using RADIUS +* Performs CHAP and MS-CHAP authentication using RADIUS ***********************************************************************/ static int radius_chap_auth(char *user, @@ -264,7 +267,7 @@ radius_chap_auth(char *user, UINT4 av_type; static char radius_msg[BUF_LEN]; int result; - u_char cpassword[MD5_SIGNATURE_SIZE+1]; + u_char cpassword[MAX_RESPONSE_LENGTH + 1]; radius_msg[0] = 0; if (radius_init(radius_msg) < 0) { @@ -272,9 +275,13 @@ radius_chap_auth(char *user, return CHAP_FAILURE; } - /* we handle md5 digest at the moment */ - if (cstate->chal_type != CHAP_DIGEST_MD5) { - error("RADIUS: Challenge type not MD5"); + /* return error for types we can't handle */ + if ((cstate->chal_type != CHAP_DIGEST_MD5) +#ifdef CHAPMS + && (cstate->chal_type != CHAP_MICROSOFT) +#endif + ) { + error("RADIUS: Challenge type %u unsupported", cstate->chal_type); return CHAP_FAILURE; } @@ -300,16 +307,44 @@ radius_chap_auth(char *user, rc_avpair_add (&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE); /* - * add the CHAP-Password and CHAP-Challenge fields + * add the challenge and response fields */ + switch (cstate->chal_type) { + case CHAP_DIGEST_MD5: + /* CHAP-Challenge and CHAP-Password */ + cpassword[0] = cstate->chal_id; + memcpy(&cpassword[1], remmd, MD5_SIGNATURE_SIZE); + + rc_avpair_add(&send, PW_CHAP_CHALLENGE, + cstate->challenge, cstate->chal_len, VENDOR_NONE); + rc_avpair_add(&send, PW_CHAP_PASSWORD, + cpassword, MD5_SIGNATURE_SIZE + 1, VENDOR_NONE); + break; + +#ifdef CHAPMS + case CHAP_MICROSOFT: + { + /* MS-CHAP-Challenge and MS-CHAP-Response */ + MS_ChapResponse *rmd = remmd; + u_char *p = cpassword; + + *p++ = cstate->chal_id; + /* The idiots use a different field order in RADIUS than PPP */ + memcpy(p, rmd->UseNT, sizeof(rmd->UseNT)); + p += sizeof(rmd->UseNT); + memcpy(p, rmd->LANManResp, sizeof(rmd->LANManResp)); + p += sizeof(rmd->LANManResp); + memcpy(p, rmd->NTResp, sizeof(rmd->NTResp)); + + rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE, + cstate->challenge, cstate->chal_len, VENDOR_MICROSOFT); + rc_avpair_add(&send, PW_MS_CHAP_RESPONSE, + cpassword, MS_CHAP_RESPONSE_LEN + 1, VENDOR_MICROSOFT); + break; + } +#endif - cpassword[0] = cstate->chal_id; - - memcpy(&cpassword[1], remmd, MD5_SIGNATURE_SIZE); - - rc_avpair_add(&send, PW_CHAP_PASSWORD, cpassword, MD5_SIGNATURE_SIZE + 1, VENDOR_NONE); - - rc_avpair_add(&send, PW_CHAP_CHALLENGE, cstate->challenge, cstate->chal_len, VENDOR_NONE); + } /* * make authentication with RADIUS server diff --git a/pppd/plugins/radius/radiusclient/include/radiusclient.h b/pppd/plugins/radius/radiusclient/include/radiusclient.h index 5604987..141e690 100644 --- a/pppd/plugins/radius/radiusclient/include/radiusclient.h +++ b/pppd/plugins/radius/radiusclient/include/radiusclient.h @@ -1,5 +1,5 @@ /* - * $Id: radiusclient.h,v 1.3 2002/03/01 14:39:19 dfs Exp $ + * $Id: radiusclient.h,v 1.4 2002/03/04 14:59:52 dfs Exp $ * * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg * @@ -83,8 +83,8 @@ typedef struct pw_auth_hdr #define MAX_SECRET_LENGTH (3 * 16) /* MUST be multiple of 16 */ #define CHAP_VALUE_LENGTH 16 -#define PW_AUTH_UDP_PORT 1645 -#define PW_ACCT_UDP_PORT 1646 +#define PW_AUTH_UDP_PORT 1812 +#define PW_ACCT_UDP_PORT 1813 #define PW_TYPE_STRING 0 #define PW_TYPE_INTEGER 1 @@ -154,6 +154,10 @@ typedef struct pw_auth_hdr #define PW_PORT_LIMIT 62 /* integer */ #define PW_LOGIN_LAT_PORT 63 /* string */ +/* Vendor RADIUS attribute-value pairs */ +#define PW_MS_CHAP_CHALLENGE 11 /* string */ +#define PW_MS_CHAP_RESPONSE 1 /* string */ + /* Accounting */ #define PW_ACCT_STATUS_TYPE 40 /* integer */ @@ -277,6 +281,7 @@ typedef struct pw_auth_hdr /* Vendor codes */ #define VENDOR_NONE (-1) +#define VENDOR_MICROSOFT 311 /* Server data structures */ diff --git a/pppd/plugins/radius/radiusclient/lib/sendserver.c b/pppd/plugins/radius/radiusclient/lib/sendserver.c index 34c489c..23a0566 100644 --- a/pppd/plugins/radius/radiusclient/lib/sendserver.c +++ b/pppd/plugins/radius/radiusclient/lib/sendserver.c @@ -1,5 +1,5 @@ /* - * $Id: sendserver.c,v 1.1 2002/01/22 16:03:02 dfs Exp $ + * $Id: sendserver.c,v 1.2 2002/03/04 14:59:52 dfs Exp $ * * Copyright (C) 1995,1996,1997 Lars Fenneberg * @@ -177,8 +177,8 @@ static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth) } break; } - vp = vp->next; } + vp = vp->next; } return total_length; } -- 2.39.2