Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Dec 2002 16:50:29 +0100
From:      Michael Bretterklieber <mbretter@jawa.at>
To:        freebsd-net@freebsd.org
Cc:        Archie Cobbs <archie@dellroad.org>
Subject:   enhancements for libradius
Message-ID:  <3E0730C5.2090007@jawa.at>

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

Hi,

I made the radius integration for mpd. During this work I missed some 
functions in libradius.
I attached patches for libradius for adding this missing functions, 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

The rad_demangle_mppe_key function was taken from userland ppp.

I hope that someone with enough karma can make a short review and then 
commit this code.

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:   mbretter@inode.at
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


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

diff -u libradius/Makefile libradius_new/Makefile
--- libradius/Makefile	Mon Dec 23 16:07:51 2002
+++ libradius_new/Makefile	Mon Dec 23 16:02:46 2002
@@ -25,13 +25,13 @@
 #	$FreeBSD: src/lib/libradius/Makefile,v 1.3.2.2 2002/06/17 02:24:57 brian Exp $
 
 LIB=		radius
-SRCS=		radlib.c
+SRCS=		radlib.c radlib_vs.c
 INCS=		radlib.h radlib_vs.h
 CFLAGS+=	-Wall
 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	Mon Dec 23 16:08:01 2002
+++ libradius_new/radlib.c	Mon Dec 23 16:00:19 2002
@@ -45,8 +45,6 @@
 #include "radlib_private.h"
 
 static void	 clear_password(struct rad_handle *);
-static void	 generr(struct rad_handle *, const char *, ...)
-		    __printflike(2, 3);
 static void	 insert_scrambled_password(struct rad_handle *, int);
 static void	 insert_request_authenticator(struct rad_handle *, int);
 static int	 is_valid_response(struct rad_handle *, int,
@@ -67,7 +65,7 @@
 	h->pass_pos = 0;
 }
 
-static void
+void
 generr(struct rad_handle *h, const char *format, ...)
 {
 	va_list		 ap;
@@ -243,7 +241,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,8 +511,8 @@
 	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);
@@ -569,7 +567,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;
 	}
@@ -945,3 +943,51 @@
 	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;
+}
diff -u libradius/radlib.h libradius_new/radlib.h
--- libradius/radlib.h	Mon Dec 23 10:48:59 2002
+++ libradius_new/radlib.h	Mon Dec 23 16:00:58 2002
@@ -167,6 +167,8 @@
 struct timeval;
 
 __BEGIN_DECLS
+void			generr(struct rad_handle *, const char *, ...)
+			  __printflike(2, 3);
 struct rad_handle	*rad_acct_open(void);
 int			 rad_add_server(struct rad_handle *,
 			    const char *, int, const char *, int, int);
@@ -195,6 +197,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_ */
Only in libradius_new: radlib_vs.c
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_ */

--------------050902070303050401070002
Content-Type: text/plain;
 name="radlib_vs.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="radlib_vs.c"

/*-
 * Copyright 2002 Michael Bretterklieber <michael@bretterklieber.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	$FreeBSD$
 */
 
#include <sys/types.h>

#include <md5.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <netgraph/ng_mppc.h>

#include "radlib_private.h"
#include "radlib.h"
#include "radlib_vs.h"

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;
}

--------------050902070303050401070002--


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




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