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 - [EMAIL PROTECTED] 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: [EMAIL PROTECTED]
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

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_ */
/*-
 * Copyright 2002 Michael Bretterklieber <[EMAIL PROTECTED]>
 * 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;
}

Reply via email to