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 RADIUS authentication on DAE responses.
* Mon Sep 19 2005 Brendan O'Dea <bod@optus.net> 2.1.8
- 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>
Tim Devries <tdevries@northrock.bm>
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]/*
%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

View file

@ -1,6 +1,6 @@
// 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 <stdio.h>
@ -27,6 +27,20 @@ extern configt *config;
extern int *radfds;
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
void initrad(void)
{
@ -344,17 +358,8 @@ void radiussend(uint16_t r, uint8_t state)
if (state != RADIUSAUTH)
{
// Build auth for accounting packet
uint8_t z[16] = {0};
uint8_t hash[16] = {0};
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);
calc_auth(b, p - b, zero, b + 4);
memcpy(radius[r].auth, b + 4, 16);
}
memset(&addr, 0, sizeof(addr));
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)
{
uint8_t b[MAXETHER];
MD5_CTX ctx;
uint16_t r;
sessionidt s;
tunnelidt t = 0;
@ -454,12 +458,7 @@ void processrad(uint8_t *buf, int len, char socket_index)
return;
}
t = session[s].tunnel;
MD5_Init(&ctx);
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);
calc_auth(buf, len, radius[r].auth, hash);
do {
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)
{
int i, r_code, r_id, length, attribute_length;
uint8_t vector[16], hash[16], *packet, attribute;
MD5_CTX ctx;
uint8_t *packet, attribute;
hasht hash;
char username[MAXUSER] = "";
in_addr_t nas = 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);
// check authenticator
memcpy(vector, buf + 4, 16);
memset(buf + 4, 0, 16);
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)
calc_auth(buf, len, zero, hash);
if (memcmp(hash, buf + 4, 16) != 0)
{
LOG(1, 0, 0, "Incorrect vector in DAE request (wrong secret in radius config?)\n");
return;
@ -1024,10 +1014,9 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen)
packet = buf;
*packet++ = r_code;
*packet++ = r_id;
packet += 2;
memset(packet, 0, 16);
packet += 16;
len = 20;
// skip len + auth
packet += 2 + 16;
len = packet - buf;
// add attributes
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);
// make vector
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);
memcpy(buf + 4, hash, 16);
calc_auth(buf, len, hash, buf + 4);
LOG(3, 0, 0, "Sending DAE %s, id=%d\n", radius_code(r_code), r_id);