Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Feb 2003 20:17:18 +0100
From:      Michael Bretterklieber <mbretter@jawa.at>
To:        freebsd-current@FreeBSD.ORG
Subject:   enhancements for libradius - commiter wanted
Message-ID:  <3E4FE3BE.1060308@jawa.at>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------000902020409040009090101
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

I already tried some weeks ago to find (at net@freebsd.org) someone who 
can review and commit  this code, but nobody replied, so I try it again:

I made the radius integration for mpd. During this work I missed some
functions in libradius.

Here is a short changelog:
- added rad_demangle for demangling user-passwords (needed for MS-CHAPv1
MPPE-keys).
- added rad_demangle_mppe_key for demangling mppe-keys (needed for
MS-CHAPv2 MPPE-keys).
- added some typecasts to avoid compilation warnings
- if the programmer has not called rad_create_request() but rad_put_*,
then a weird error message was returned => fixed.

The rad_demangle_mppe_key function was taken from userland ppp.

I also opened a pr:
http://www.freebsd.org/cgi/query-pr.cgi?pr=46555

bye,
-- 
------------------------------- -------------------------------------
Michael Bretterklieber        - Michael.Bretterklieber@jawa.at
JAWA Management Software GmbH - http://www.jawa.at
Liebenauer Hauptstr. 200        -------------- privat ---------------
A-8041 GRAZ                     GSM: ++43-(0)676-93 96 698
Tel: ++43-(0)316-403274-12      E-mail:   michael@bretterklieber.com
Fax: ++43-(0)316-403274-10      http://www.bretterklieber.com
------------------------------- -------------------------------------
"...the number of UNIX installations has grown to 10, with more
expected..." - Dennis Ritchie and Ken Thompson, June 1972


--------------000902020409040009090101
Content-Type: text/plain;
 name="libradius.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="libradius.diff"

diff -u libradius/Makefile libradius_new/Makefile
--- libradius/Makefile	Mon Dec 23 16:07:51 2002
+++ libradius_new/Makefile	Sat Jan  4 23:25:13 2003
@@ -31,7 +31,7 @@
 DPADD+=		${LIBMD}
 LDADD+=		-lmd
 SHLIB_MAJOR=	1
-SHLIB_MINOR=	0
+SHLIB_MINOR=	1
 MAN=		libradius.3 radius.conf.5
 
 .include <bsd.lib.mk>
diff -u libradius/radlib.c libradius_new/radlib.c
--- libradius/radlib.c	Sat Jan  4 23:26:58 2003
+++ libradius_new/radlib.c	Sat Jan  4 23:24:46 2003
@@ -31,6 +31,7 @@
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netgraph/ng_mppc.h>
 
 #include <errno.h>
 #include <md5.h>
@@ -243,7 +244,7 @@
 		    sizeof srvp->addr.sin_addr);
 	}
 	if (port != 0)
-		srvp->addr.sin_port = htons(port);
+		srvp->addr.sin_port = htons((u_short)port);
 	else {
 		struct servent *sent;
 
@@ -513,11 +514,12 @@
 	for (i = 0;  i < LEN_AUTH;  i += 2) {
 		long r;
 		r = random();
-		h->request[POS_AUTH+i] = r;
-		h->request[POS_AUTH+i+1] = r >> 8;
+		h->request[POS_AUTH+i] = (u_char)r;
+		h->request[POS_AUTH+i+1] = (u_char)(r >> 8);
 	}
 	h->req_len = POS_ATTRS;
 	clear_password(h);
+	h->request_created = 1;
 	return 0;
 }
 
@@ -569,7 +571,7 @@
 	}
 	type = h->response[h->resp_pos++];
 	*len = h->response[h->resp_pos++] - 2;
-	if (h->resp_pos + *len > h->resp_len) {
+	if (h->resp_pos + (int)*len > h->resp_len) {
 		generr(h, "Malformed attribute in response");
 		return -1;
 	}
@@ -671,6 +673,7 @@
 		h->pass_pos = 0;
 		h->chap_pass = 0;
 		h->type = RADIUS_AUTH;
+                h->request_created = 0;
 	}
 	return h;
 }
@@ -703,6 +706,11 @@
 {
 	int result;
 
+	if (!h->request_created) {
+		generr(h, "Please call rad_create_request()");
+		return -1;
+        }
+
 	if (type == RAD_USER_PASSWORD)
 		result = put_password_attr(h, type, value, len);
 	else {
@@ -892,6 +900,11 @@
 	struct vendor_attribute *attr;
 	int res;
 
+	if (!h->request_created) {
+		generr(h, "Please call rad_create_request()");
+		return -1;
+        }
+
 	if ((attr = malloc(len + 6)) == NULL) {
 		generr(h, "malloc failure (%d bytes)", len + 6);
 		return -1;
@@ -945,3 +958,122 @@
 	return (h->servers[h->srv].secret);
 }
 
+int
+rad_demangle(struct rad_handle *h, const void *mangled, size_t mlen, u_char *demangled) 
+{
+	char R[LEN_AUTH];
+	const char *S;
+	int i, Ppos;
+	MD5_CTX Context;
+	u_char b[16], *C;
+
+	if ((mlen % 16 != 0) || (mlen > 128)) {
+		generr(h, "Cannot interpret mangled data of length %ld", (u_long)mlen);
+		return -1;
+	}
+
+	C = (u_char *)mangled;
+
+	/* We need the shared secret as Salt */
+	S = rad_server_secret(h);
+
+	/* We need the request authenticator */
+	if (rad_request_authenticator(h, R, sizeof R) != LEN_AUTH) {
+		generr(h, "Cannot obtain the RADIUS request authenticator");
+                return -1;
+	}
+
+	MD5Init(&Context);
+	MD5Update(&Context, S, strlen(S));
+	MD5Update(&Context, R, LEN_AUTH);
+	MD5Final(b, &Context);
+	Ppos = 0;
+	while (mlen) {
+
+		mlen -= 16;
+		for (i = 0; i < 16; i++)
+			demangled[Ppos++] = C[i] ^ b[i];
+
+		if (mlen) {
+			MD5Init(&Context);
+			MD5Update(&Context, S, strlen(S));
+			MD5Update(&Context, C, 16);
+			MD5Final(b, &Context);
+		}
+
+		C += 16;
+	}
+
+	return 0;
+}
+
+int
+rad_demangle_mppe_key(struct rad_handle *h, const void *mangled, size_t mlen, u_char *demangled, size_t *len)
+{
+	char R[LEN_AUTH];    /* 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) {
+		generr(h, "Cannot interpret mangled data of length %ld", (u_long)mlen);
+		return -1;
+	}
+
+	/* We need the RADIUS Request-Authenticator */
+	if (rad_request_authenticator(h, R, sizeof R) != LEN_AUTH) {
+		generr(h, "Cannot obtain the RADIUS request authenticator");
+		return -1;
+	}
+
+	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(h);    /* We need the RADIUS secret */
+	Slen = strlen(S);
+	P = alloca(Clen);        /* We derive our plaintext */
+
+	MD5Init(&Context);
+	MD5Update(&Context, S, Slen);
+	MD5Update(&Context, R, LEN_AUTH);
+	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) {
+		generr(h, "Mangled data seems to be garbage %d %d", *len, mlen-1);        
+		return -1;
+	}
+
+	if (*len > MPPE_KEY_LEN) {
+		generr(h, "Key to long (%d) for me max. %d", *len, MPPE_KEY_LEN);        
+		return -1;
+	}
+
+	memcpy(demangled, P + 1, *len);
+	return 0;
+}
diff -u libradius/radlib.h libradius_new/radlib.h
--- libradius/radlib.h	Mon Dec 23 10:48:59 2002
+++ libradius_new/radlib.h	Sat Jan  4 23:22:42 2003
@@ -195,6 +195,9 @@
 int			 rad_send_request(struct rad_handle *);
 const char		*rad_server_secret(struct rad_handle *);
 const char		*rad_strerror(struct rad_handle *);
+int			 rad_demangle(struct rad_handle *,
+			    const void *, size_t, u_char *);
+
 __END_DECLS
 
 #endif /* _RADLIB_H_ */
diff -u libradius/radlib_private.h libradius_new/radlib_private.h
--- libradius/radlib_private.h	Mon Sep  9 18:36:48 2002
+++ libradius_new/radlib_private.h	Sat Jan  4 23:15:41 2003
@@ -76,6 +76,7 @@
 	int		 ident;		/* Current identifier value */
 	char		 errmsg[ERRSIZE];	/* Most recent error message */
 	unsigned char	 request[MSGSIZE];	/* Request to send */
+	char	 	 request_created;	/* rad_create_request() called? */
 	int		 req_len;	/* Length of request */
 	char		 pass[PASSSIZE];	/* Cleartext password */
 	int		 pass_len;	/* Length of cleartext password */
diff -u libradius/radlib_vs.h libradius_new/radlib_vs.h
--- libradius/radlib_vs.h	Mon Dec 23 16:09:07 2002
+++ libradius_new/radlib_vs.h	Mon Dec 23 16:02:02 2002
@@ -66,6 +66,8 @@
 	#define	RAD_MICROSOFT_MS_SECONDARY_NBNS_SERVER		31
 	#define	RAD_MICROSOFT_MS_ARAP_CHALLENGE			33
 
+#define SALT_LEN    2
+
 struct rad_handle;
 
 __BEGIN_DECLS
@@ -75,6 +77,7 @@
 	    size_t);
 int	rad_put_vendor_int(struct rad_handle *, int, int, u_int32_t);
 int	rad_put_vendor_string(struct rad_handle *, int, int, const char *);
+int	rad_demangle_mppe_key(struct rad_handle *, const void *, size_t, u_char *, size_t *);
 __END_DECLS
 
 #endif /* _RADLIB_VS_H_ */


--------------000902020409040009090101--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3E4FE3BE.1060308>