* RFC 2869:
* "RADIUS Extensions"
*
- * Alfredo Andres Omella (aandres@mfom.es) v0.1 2000/09/15
+ * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15
*
* TODO: Among other things to print ok MacIntosh and Vendor values
*/
#ifndef lint
static const char rcsid[] =
- "$Id: print-radius.c,v 1.1 2000-10-06 06:49:21 guy Exp $";
+ "$Id: print-radius.c,v 1.7 2001-06-18 09:16:28 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <string.h>
+
#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
#include <stdio.h>
#define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) )
-#define HEX(a) ((char)( (a) <= 9 ? (a) + '0' : ((a) - 10) + 'A'))
-
#define PRINT_HEX(bytes_len, ptr_data) \
while(bytes_len) \
{ \
- printf("%c%c", HEX( ((u_short)(*ptr_data)) >> 4 ), \
- HEX( ((u_short)(*ptr_data)) & 0x0F ) ); \
+ printf("%02X", *ptr_data ); \
ptr_data++; \
bytes_len--; \
}
static void print_attr_strange(register u_char *, u_int, u_short);
-struct radius_hdr { u_char code; /* Radius packet code */
- u_char id; /* Radius packet id */
- u_short len; /* Radius total length */
- u_char auth[16]; /* Authenticator */
+struct radius_hdr { u_int8_t code; /* Radius packet code */
+ u_int8_t id; /* Radius packet id */
+ u_int16_t len; /* Radius total length */
+ u_int8_t auth[16]; /* Authenticator */
};
+#define MIN_RADIUS_LEN 20
-struct radius_attr { u_char type; /* Attribute type */
- u_char len; /* Attribute length */
+struct radius_attr { u_int8_t type; /* Attribute type */
+ u_int8_t len; /* Attribute length */
};
static void
print_attr_num(register u_char *data, u_int length, u_short attr_code )
{
+ u_int8_t tag;
u_int32_t timeout;
+ if (length != 4)
+ {
+ printf("{length %u != 4}", length);
+ return;
+ }
+
TCHECK2(data[0],4);
/* This attribute has standard values */
if (attr_type[attr_code].siz_subtypes)
printf("{Tag[Unused]");
else
printf("{Tag[%d]", *data);
- data_value = EXTRACT_24BITS(++data);
+ data++;
+ data_value = EXTRACT_24BITS(data);
}
else
- data_value = EXTRACT_32BITS(++data);
+ {
+ data++;
+ data_value = EXTRACT_32BITS(data);
+ }
if ( data_value <= (attr_type[attr_code].siz_subtypes - 1 +
attr_type[attr_code].first_subtype) )
printf("{%s}",table[data_value]);
break;
case TUNNEL_PREFERENCE:
- if (!*data)
- printf("{Tag[Unused] %d}",EXTRACT_24BITS(++data) );
+ tag = *data;
+ data++;
+ if (tag == 0)
+ printf("{Tag[Unused] %d}",EXTRACT_24BITS(data) );
else
- printf("{Tag[%d] %d}", *data, EXTRACT_24BITS(++data) );
+ printf("{Tag[%d] %d}", tag, EXTRACT_24BITS(data) );
break;
default:
static void
print_attr_address(register u_char *data, u_int length, u_short attr_code )
{
+ if (length != 4)
+ {
+ printf("{length %u != 4}", length);
+ return;
+ }
+
TCHECK2(data[0],4);
switch(attr_code)
/*************************************/
static void print_attr_time(register u_char *data, u_int length, u_short attr_code)
{
+ time_t attr_time;
+ char string[26];
+
+ if (length != 4)
+ {
+ printf("{length %u != 4}", length);
+ return;
+ }
+
TCHECK2(data[0],4);
- printf("{%s}", ctime( ((const time_t *)EXTRACT_32BITS(data) )) );
+ attr_time = EXTRACT_32BITS(data);
+ strcpy(string, ctime(&attr_time));
+ /* Get rid of the newline */
+ string[24] = '\0';
+ printf("{%.24s}", string);
return;
trunc:
/***********************************/
static void print_attr_strange(register u_char *data, u_int length, u_short attr_code)
{
- u_short len_data = 8;
+ u_short len_data;
switch(attr_code)
{
case ARAP_PASS:
+ if (length != 16)
+ {
+ printf("{length %u != 16}", length);
+ return;
+ }
printf("{User_challenge[");
TCHECK2(data[0],8);
+ len_data = 8;
PRINT_HEX(len_data, data);
printf("] User_resp[");
TCHECK2(data[0],8);
+ len_data = 8;
PRINT_HEX(len_data, data);
printf("]}");
break;
case ARAP_FEATURES:
+ if (length != 14)
+ {
+ printf("{length %u != 14}", length);
+ return;
+ }
+ TCHECK2(data[0],1);
if (*data)
printf("{User_can_change_pass");
else
printf("{User_cant_change_pass");
- TCHECK2(data[0],1);
data++;
+ TCHECK2(data[0],1);
printf(" Min_pass_len[%d]",*data);
+ data++;
printf(" Pass_created_at[");
- TCHECK2(data[0],8);
+ TCHECK2(data[0],4);
+ len_data = 4;
PRINT_HEX(len_data, data);
printf("] Pass_expired_in[");
- TCHECK2(data[0],8);
+ TCHECK2(data[0],4);
+ len_data = 4;
PRINT_HEX(len_data, data);
printf("] Current_time[");
- TCHECK2(data[0],8);
+ len_data = 4;
+ TCHECK2(data[0],4);
PRINT_HEX(len_data, data);
printf("]}");
break;
case ARAP_CHALLENGE_RESP:
+ if (length < 8)
+ {
+ printf("{length %u != 8}", length);
+ return;
+ }
printf("{");
TCHECK2(data[0],8);
+ len_data = 8;
PRINT_HEX(len_data, data);
printf("}");
break;
static void
-radius_attr_print(register u_char *attr, u_int length)
+radius_attr_print(register const u_char *attr, u_int length)
{
register const struct radius_attr *rad_attr = (struct radius_attr *)attr;
printf(" Attr[ ");
while (length > 0)
{
+ if (rad_attr->len == 0)
+ {
+ printf("(zero-length attribute)");
+ return;
+ }
if ( rad_attr->len <= length )
{
if ( !rad_attr->type || (rad_attr->type > (TAM_SIZE(attr_type)-1)) )
{
printf(" %s",attr_type[rad_attr->type].name);
- if ( attr_type[rad_attr->type].print_func )
- (*attr_type[rad_attr->type].print_func)( ((char *)(rad_attr+1)),
+ if (rad_attr->len > 2)
+ {
+ if ( attr_type[rad_attr->type].print_func )
+ (*attr_type[rad_attr->type].print_func)(
+ ((u_char *)(rad_attr+1)),
rad_attr->len - 2, rad_attr->type);
+ }
}
}
else
{
register const struct radius_hdr *rad;
register int i;
+ int len;
- i = min(length, snapend - dat) - sizeof(*rad);
+ i = min(length, snapend - dat);
- if (i < 0)
+ if (i < MIN_RADIUS_LEN)
{
printf(" [|radius]");
return;
}
rad = (struct radius_hdr *)dat;
-
+ len = ntohs(rad->len);
+
+ if (len < MIN_RADIUS_LEN)
+ {
+ printf(" [|radius]");
+ return;
+ }
+
+ if (len < i)
+ i = len;
+
+ i -= MIN_RADIUS_LEN;
+
switch (rad->code)
{
case RADCMD_ACCESS_REQ:
printf(" [id %d]", rad->id);
if (i)
- radius_attr_print( ((char *)(rad+1)), i);
+ radius_attr_print( dat + MIN_RADIUS_LEN, i);
}