Fix RADIUS authentication on DAE responses.

This commit is contained in:
Michael Chapman 2005-10-11 02:27:40 +00:00
parent d266f5fc93
commit c450bdccc0
4 changed files with 31 additions and 47 deletions

View file

@ -1,5 +1,6 @@
* Fri Sep 30 2005 Brendan O'Dea <bod@optus.net> 2.1.9 * Tue Oct 11 2005 Michael Chapman <mike.chapman@optus.net> 2.1.9
- Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic). - Fix Calling-Station-Id in RADIUS accounting records (Slobodan Tomic).
- Fix RADIUS authentication on DAE responses.
* Mon Sep 19 2005 Brendan O'Dea <bod@optus.net> 2.1.8 * Mon Sep 19 2005 Brendan O'Dea <bod@optus.net> 2.1.8
- Move code from signal handlers into mainloop, avoiding a race - Move code from signal handlers into mainloop, avoiding a race

1
THANKS
View file

@ -20,3 +20,4 @@ Alex Kiernan <alex.kiernan@gmail.com>
Dominique Rousseau <d.rousseau@nnx.com> Dominique Rousseau <d.rousseau@nnx.com>
Tim Devries <tdevries@northrock.bm> Tim Devries <tdevries@northrock.bm>
Slobodan Tomic <stomic@loznica.com> Slobodan Tomic <stomic@loznica.com>
Michael Chapman <mike.chapman@optus.net>

View file

@ -43,5 +43,5 @@ rm -rf %{buildroot}
%attr(644,root,root) /usr/share/man/man[58]/* %attr(644,root,root) /usr/share/man/man[58]/*
%changelog %changelog
* Fri Sep 30 2005 Brendan O'Dea <bod@optus.net> 2.1.9-1 * Tue Oct 11 2005 Michael Chapman <mike.chapman@optus.net> 2.1.9-1
- 2.1.9 release, see /usr/share/doc/l2tpns-2.1.9/Changes - 2.1.9 release, see /usr/share/doc/l2tpns-2.1.9/Changes

View file

@ -1,6 +1,6 @@
// L2TPNS Radius Stuff // L2TPNS Radius Stuff
char const *cvs_id_radius = "$Id: radius.c,v 1.42 2005-09-30 13:13:26 bodea Exp $"; char const *cvs_id_radius = "$Id: radius.c,v 1.43 2005-10-11 02:27:40 foonly Exp $";
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
@ -27,6 +27,20 @@ extern configt *config;
extern int *radfds; extern int *radfds;
extern ip_filtert *ip_filters; extern ip_filtert *ip_filters;
static const hasht zero;
static void calc_auth(const void *buf, size_t len, const uint8_t *in, uint8_t *out)
{
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, (void *)buf, 4); // code, id, length
MD5_Update(&ctx, (void *)in, 16); // auth
MD5_Update(&ctx, (void *)(buf + 20), len - 20);
MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret));
MD5_Final(out, &ctx);
}
// Set up socket for radius requests // Set up socket for radius requests
void initrad(void) void initrad(void)
{ {
@ -343,18 +357,9 @@ void radiussend(uint16_t r, uint8_t state)
*(uint16_t *) (b + 2) = htons(p - b); *(uint16_t *) (b + 2) = htons(p - b);
if (state != RADIUSAUTH) if (state != RADIUSAUTH)
{ {
// Build auth for accounting packet // Build auth for accounting packet
uint8_t z[16] = {0}; calc_auth(b, p - b, zero, b + 4);
uint8_t hash[16] = {0}; memcpy(radius[r].auth, b + 4, 16);
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, b, 4);
MD5_Update(&ctx, z, 16);
MD5_Update(&ctx, b + 20, (p - b) - 20);
MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret));
MD5_Final(hash, &ctx);
memcpy(b + 4, hash, 16);
memcpy(radius[r].auth, hash, 16);
} }
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
@ -415,7 +420,6 @@ static void handle_avpair(sessionidt s, uint8_t *avp, int len)
void processrad(uint8_t *buf, int len, char socket_index) void processrad(uint8_t *buf, int len, char socket_index)
{ {
uint8_t b[MAXETHER]; uint8_t b[MAXETHER];
MD5_CTX ctx;
uint16_t r; uint16_t r;
sessionidt s; sessionidt s;
tunnelidt t = 0; tunnelidt t = 0;
@ -454,12 +458,7 @@ void processrad(uint8_t *buf, int len, char socket_index)
return; return;
} }
t = session[s].tunnel; t = session[s].tunnel;
MD5_Init(&ctx); calc_auth(buf, len, radius[r].auth, hash);
MD5_Update(&ctx, buf, 4);
MD5_Update(&ctx, radius[r].auth, 16);
MD5_Update(&ctx, buf + 20, len - 20);
MD5_Update(&ctx, config->radiussecret, strlen(config->radiussecret));
MD5_Final(hash, &ctx);
do { do {
if (memcmp(hash, buf + 4, 16)) if (memcmp(hash, buf + 4, 16))
{ {
@ -762,8 +761,8 @@ extern int daefd;
void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen) void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
{ {
int i, r_code, r_id, length, attribute_length; int i, r_code, r_id, length, attribute_length;
uint8_t vector[16], hash[16], *packet, attribute; uint8_t *packet, attribute;
MD5_CTX ctx; hasht hash;
char username[MAXUSER] = ""; char username[MAXUSER] = "";
in_addr_t nas = 0; in_addr_t nas = 0;
in_addr_t ip = 0; in_addr_t ip = 0;
@ -808,17 +807,8 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
LOG(3, 0, 0, "Received DAE %s, id %d\n", radius_code(r_code), r_id); LOG(3, 0, 0, "Received DAE %s, id %d\n", radius_code(r_code), r_id);
// check authenticator // check authenticator
memcpy(vector, buf + 4, 16); calc_auth(buf, len, zero, hash);
memset(buf + 4, 0, 16); if (memcmp(hash, buf + 4, 16) != 0)
i = strlen(config->radiussecret);
if (i > 16) i = 16;
MD5_Init(&ctx);
MD5_Update(&ctx, buf, len);
MD5_Update(&ctx, config->radiussecret, i);
MD5_Final(hash, &ctx);
if (memcmp(hash, vector, 16) != 0)
{ {
LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n"); LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n");
return; return;
@ -1024,10 +1014,9 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
packet = buf; packet = buf;
*packet++ = r_code; *packet++ = r_code;
*packet++ = r_id; *packet++ = r_id;
packet += 2; // skip len + auth
memset(packet, 0, 16); packet += 2 + 16;
packet += 16; len = packet - buf;
len = 20;
// add attributes // add attributes
if (error) if (error)
@ -1042,14 +1031,7 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
*((uint16_t *)(buf + 2)) = htons(len); *((uint16_t *)(buf + 2)) = htons(len);
// make vector // make vector
i = strlen(config->radiussecret); calc_auth(buf, len, hash, buf + 4);
if (i > 16) i = 16;
MD5_Init(&ctx);
MD5_Update(&ctx, buf, len);
MD5_Update(&ctx, config->radiussecret, i);
MD5_Final(hash, &ctx);
memcpy(buf + 4, hash, 16);
LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code), r_id); LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code), r_id);