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>