From c450bdccc0e204223543b305c862e85db572411e Mon Sep 17 00:00:00 2001 From: Michael Chapman Date: Tue, 11 Oct 2005 02:27:40 +0000 Subject: [PATCH 1/1] Fix RADIUS authentication on DAE responses. --- Changes | 3 ++- THANKS | 1 + l2tpns.spec | 2 +- radius.c | 72 ++++++++++++++++++++--------------------------------- 4 files changed, 31 insertions(+), 47 deletions(-) diff --git a/Changes b/Changes index e2f237f..9d913cc 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ -* Fri Sep 30 2005 Brendan O'Dea 2.1.9 +* Tue Oct 11 2005 Michael Chapman 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 2.1.8 - Move code from signal handlers into mainloop, avoiding a race diff --git a/THANKS b/THANKS index 08ca6e2..ffe0aa7 100644 --- a/THANKS +++ b/THANKS @@ -20,3 +20,4 @@ Alex Kiernan Dominique Rousseau Tim Devries Slobodan Tomic +Michael Chapman diff --git a/l2tpns.spec b/l2tpns.spec index 1eab27c..3f4e076 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Fri Sep 30 2005 Brendan O'Dea 2.1.9-1 +* Tue Oct 11 2005 Michael Chapman 2.1.9-1 - 2.1.9 release, see /usr/share/doc/l2tpns-2.1.9/Changes diff --git a/radius.c b/radius.c index cf22ffe..61cbfd4 100644 --- a/radius.c +++ b/radius.c @@ -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 #include @@ -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) { @@ -343,18 +357,9 @@ void radiussend(uint16_t r, uint8_t state) *(uint16_t *) (b + 2) = htons(p - b); 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); + // Build auth for accounting packet + 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); -- 2.20.1