summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid F. Skoll <dfs@roaringpenguin.com>2002-03-04 14:59:52 +0000
committerDavid F. Skoll <dfs@roaringpenguin.com>2002-03-04 14:59:52 +0000
commit8ed456439d306257173fb0c74d77c4e3c472dfc6 (patch)
treeb353e6600e5b3f3fd376246f73b9012d561c83bd
parent8832e3ba208085ae3f15c0d48c2bb7a02bc9ae79 (diff)
downloadppp-8ed456439d306257173fb0c74d77c4e3c472dfc6.tar.gz
Patch from Frank Cusack to make RADIUS plugin support MS-CHAP authentication.
-rw-r--r--pppd/Makefile.linux4
-rw-r--r--pppd/chap.c10
-rw-r--r--pppd/chap_ms.c6
-rw-r--r--pppd/chap_ms.h4
-rw-r--r--pppd/plugins/radius/Makefile.linux8
-rw-r--r--pppd/plugins/radius/pppd-radius.86
-rw-r--r--pppd/plugins/radius/radius.c67
-rw-r--r--pppd/plugins/radius/radiusclient/include/radiusclient.h11
-rw-r--r--pppd/plugins/radius/radiusclient/lib/sendserver.c4
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;
}