hackedteam/vector-ipa

View on GitHub
src/radius.c

Summary

Maintainability
Test Coverage
/*
    MODULE -- Module for radius parsing

    Copyright (C) Alberto Ornaghi

    $Id: radius.c 1149 2009-11-17 09:53:46Z alor $
*/

#include <main.h>
#include <inet.h>
#include <radius.h>

/* globals */

struct radius_attr_name {
   u_char attr;
   char *name;
   u_char type;
      #define ATTR_STRING  0
      #define ATTR_HEX     1
      #define ATTR_INTEGER 2
      #define ATTR_ADDRESS 3
};

static struct radius_attr_name attr_name_list[] = {
   {   1, "User-Name", ATTR_STRING},
   {   2, "User-Password", ATTR_STRING},
   {   3, "CHAP-Password", ATTR_STRING},
   {   4, "NAS-IP-Address", ATTR_ADDRESS},
   {   5, "NAS-Port", ATTR_INTEGER},
   {   6, "Service-Type", ATTR_INTEGER},
   {   7, "Framed-Protocol", ATTR_INTEGER},
   {   8, "Framed-IP-Address", ATTR_ADDRESS},
   {   9, "Framed-IP-Netmask", ATTR_ADDRESS},
   {  10, "Framed-Routing", ATTR_INTEGER},
   {  11, "Filter-Id", ATTR_HEX},
   {  12, "Framed-MTU", ATTR_INTEGER},
   {  13, "Framed-Compression", ATTR_INTEGER},
   {  14, "Login-IP-Host", ATTR_ADDRESS},
   {  15, "Login-Service", ATTR_INTEGER},
   {  16, "Login-TCP-Port", ATTR_INTEGER},
   /* 17 unused */
   {  18, "Reply-Message", ATTR_STRING},
   {  19, "Callback-Number", ATTR_STRING},
   {  20, "Callback-Id", ATTR_STRING},
   /* 21 unused */
   {  22, "Framed-Route", ATTR_STRING},
   {  23, "Framed-IPX-Network", ATTR_INTEGER},
   {  24, "State", ATTR_STRING},
   {  25, "Class", ATTR_STRING},
   {  26, "Vendor-Specific", ATTR_STRING},
   {  27, "Session-Timeout", ATTR_INTEGER},
   {  28, "Idle-Timeout", ATTR_INTEGER},
   {  29, "Termination-Action", ATTR_INTEGER},
   {  30, "Called-Station-Id", ATTR_STRING},
   {  31, "Calling-Station-Id", ATTR_STRING},
   {  32, "NAS-Identifier", ATTR_STRING},
   {  33, "Proxy-State", ATTR_STRING},
   {  34, "Login-LAT-Service", ATTR_STRING},
   {  35, "Login-LAT-Node", ATTR_STRING},
   {  36, "Login-LAT-Group", ATTR_STRING},
   {  37, "Framed-AppleTalk-Link", ATTR_INTEGER},
   {  38, "Framed-AppleTalk-Network", ATTR_INTEGER},
   {  39, "Framed-AppleTalk-Zone", ATTR_STRING},
   {  40, "Acct-Status-Type", ATTR_INTEGER},
   {  41, "Acct-Delay-Time", ATTR_INTEGER},
   {  42, "Acct-Input-Octets", ATTR_INTEGER},
   {  43, "Acct-Output-Octets", ATTR_INTEGER},
   {  44, "Acct-Session-Id", ATTR_STRING},
   {  45, "Acct-Authentic", ATTR_INTEGER},
   {  46, "Acct-Session-Time", ATTR_INTEGER},
   {  47, "Acct-Input-Packets", ATTR_INTEGER},
   {  48, "Acct-Output-Packets", ATTR_INTEGER},
   {  49, "Acct-Terminate-Cause", ATTR_INTEGER},
   {  50, "Acct-Multi-Session-Id", ATTR_STRING},
   {  51, "Acct-Link-Count", ATTR_INTEGER},
   {  52, "Acct-Input-Gigawords", ATTR_INTEGER},
   {  53, "Acct-Output-Gigawords", ATTR_INTEGER},
   /* 54 unused */
   {  55, "Event-Timestamp", ATTR_INTEGER},
   /* 56-59 unused */
   {  60, "CHAP-Challenge", ATTR_STRING},
   {  61, "NAS-Port-Type", ATTR_INTEGER},
   {  62, "Port-Limit", ATTR_INTEGER},
   {  63, "Login-LAT-Port", ATTR_HEX},
   {  64, "Tunnel-Type", ATTR_INTEGER},
   {  65, "Tunnel-Medium-Type", ATTR_INTEGER},
   {  66, "Tunnel-Client-Endpoint", ATTR_STRING},
   {  67, "Tunnel-Server-Endpoint", ATTR_STRING},
   {  68, "Tunnel-Connection", ATTR_STRING},
   {  69, "Tunnel-Password", ATTR_STRING},
   /* 70-74 ARAP */
   {  75, "Password-Retry", ATTR_INTEGER},
   {  76, "Prompt", ATTR_INTEGER},
   {  77, "Connect-Info", ATTR_STRING},
   {  78, "Configuration-Token", ATTR_STRING},
   {  79, "EAP-Message", ATTR_STRING},
   {  80, "Message-Authenticator", ATTR_STRING},
   {  81, "Tunnel-Private-Group-ID", ATTR_STRING},
   {  82, "Tunnel-Assignment-ID", ATTR_STRING},
   {  83, "Tunnel-Preference", ATTR_INTEGER},
   {  84, "ARAP-Challenge-Response", ATTR_STRING},
   {  85, "Acct-Interim-Interval", ATTR_INTEGER},
   {  86, "Tunnel-Packets Lost", ATTR_INTEGER},
   {  87, "NAS-Port-ID", ATTR_STRING},
   {  88, "Framed-Pool", ATTR_STRING},
   {  90, "Tunnel-Client-Auth-ID", ATTR_STRING},
   {  91, "Tunnel-Server-Auth-ID", ATTR_STRING},
   { 0x0, NULL, 0},
};

/* protos */

u_char * radius_get_attribute(u_int8 attr, u_int16 *attr_len, u_char *begin, u_char *end);
struct radius_attribute * radius_get_next_attribute(u_char **begin, const u_char *end);

/************************************************/

/*
 * find a radius attribute thru the list
 */
u_char * radius_get_attribute(u_int8 attr, u_int16 *attr_len, u_char *begin, u_char *end)
{
   /* the parameter has no lenght until found */
   *attr_len = 0;

   /* sanity check */
   if (begin == NULL || end == NULL)
      return NULL;

   if (begin > end)
      return NULL;

   DEBUG_MSG(D_VERBOSE, "radius_get_attribute: [%d]", attr);

   /* stop when the attribute list ends */
   while (begin < end) {

      /* get the len of the attribute and subtract the header len */
      *attr_len = *(begin + 1) - 2;

      /* we have found our attribute */
      if (*begin == attr) {
         /* return the pointer to the attribute value */
         return begin + 2;
      }

      /* move to the next attribute */
      if (*(begin + 1) > 0) {
         begin += *(begin + 1);
      } else {
         *attr_len = 0;
         return NULL;
      }
   }

   /* not found */
   *attr_len = 0;
   return NULL;
}


struct radius_attribute * radius_get_next_attribute(u_char **begin, const u_char *end)
{
   u_char *param;
   size_t len = 0, i, j;
   struct radius_attribute *ra;
   struct ip_addr ipa;
   char tmp[MAX_ASCII_ADDR_LEN];

   /* sanity check */
   if (*begin == NULL || end == NULL)
      return NULL;

   if (*begin > end)
      return NULL;

   /* get the attribute and the lenght */
   param = *begin;
   len = param[1];

   /* sanity check */
   if (len == 0 || len <= 2)
      return NULL;

   /* don't go beyond the end */
   if (param + len > end)
      return NULL;

   /* move the pointer for the next call */
   *begin = param + len;

   /* adjust the len to the real len of the attribute */
   len -= 2;

   DEBUG_MSG(D_DEBUG, "radius_get_next_attribute: [%d][%d]", param[0], len);

   SAFE_CALLOC(ra, 1, sizeof(struct radius_attribute));

   /* initialize the values */
   ra->name = "Unknown-Attribute";
   ra->value = NULL;

   /* search the attribute in the list */
   for (i = 0; attr_name_list[i].name != NULL; i++) {
      if (attr_name_list[i].attr == param[0]) {
         ra->name = attr_name_list[i].name;
         switch (attr_name_list[i].type) {

            case ATTR_HEX:
               /* hex string takes (len * 2) to store the values */
               SAFE_CALLOC(ra->value, (len + 1) * 2, sizeof(char));
               for (j = 0; j < len; j++)
                  sprintf(ra->value + (j * 2), "%02X", param[2+j]);
               break;

            case ATTR_STRING:
               SAFE_CALLOC(ra->value, len + 1, sizeof(char));
               strncpy(ra->value, (char *)param + 2, len);
               break;

            case ATTR_INTEGER:
               /* sanity check */
               if (len != 4)
                  goto bad;

               SAFE_CALLOC(ra->value, len * 2, sizeof(char));
               snprintf(ra->value, len * 2, "%d", pntol(param + 2));
               break;

            case ATTR_ADDRESS:
               /* sanity check */
               if (len != 4)
                  goto bad;

               ip_addr_init(&ipa, AF_INET, param + 2);
               SAFE_CALLOC(ra->value, 16, sizeof(char));
               snprintf(ra->value, 16, "%s", ip_addr_ntoa(&ipa, tmp));
               break;
         }
         break;
      }
   }

   /* the attribute was not found */
   if (ra->value == NULL) {
      SAFE_CALLOC(ra->value, 10, sizeof(char));
      snprintf(ra->value, 10, "%d - %d", param[0], (int)len);
   }

   return ra;

bad:
   ra->value = strdup("Corrupted");

   return ra;
}

/* EOF */

// vim:ts=3:expandtab