]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/radius/radiusclient/lib/dict.c
Added RADIUS suppport.
[ppp.git] / pppd / plugins / radius / radiusclient / lib / dict.c
diff --git a/pppd/plugins/radius/radiusclient/lib/dict.c b/pppd/plugins/radius/radiusclient/lib/dict.c
new file mode 100644 (file)
index 0000000..95a0838
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * $Id: dict.c,v 1.1 2002/01/22 16:03:02 dfs Exp $
+ *
+ * Copyright (C) 2002 Roaring Penguin Software Inc.
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <config.h>
+#include <includes.h>
+#include <radiusclient.h>
+
+static DICT_ATTR *dictionary_attributes = NULL;
+static DICT_VALUE *dictionary_values = NULL;
+static VENDOR_DICT *vendor_dictionaries = NULL;
+
+/*
+ * Function: rc_read_dictionary
+ *
+ * Purpose: Initialize the dictionary.  Read all ATTRIBUTES into
+ *         the dictionary_attributes list.  Read all VALUES into
+ *         the dictionary_values list.  Construct VENDOR dictionaries
+ *          as required.
+ *
+ */
+
+int rc_read_dictionary (char *filename)
+{
+       FILE           *dictfd;
+       char            dummystr[AUTH_ID_LEN];
+       char            namestr[AUTH_ID_LEN];
+       char            valstr[AUTH_ID_LEN];
+       char            attrstr[AUTH_ID_LEN];
+       char            typestr[AUTH_ID_LEN];
+       char            vendorstr[AUTH_ID_LEN];
+       int             line_no;
+       DICT_ATTR      *attr;
+       DICT_VALUE     *dval;
+       VENDOR_DICT    *vdict;
+       char            buffer[256];
+       int             value;
+       int             type;
+       int             n;
+
+       if ((dictfd = fopen (filename, "r")) == (FILE *) NULL)
+       {
+               rc_log(LOG_ERR, "rc_read_dictionary: couldn't open dictionary %s: %s",
+                               filename, strerror(errno));
+               return (-1);
+       }
+
+       line_no = 0;
+       while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL)
+       {
+               line_no++;
+
+               /* Skip empty space */
+               if (*buffer == '#' || *buffer == '\0' || *buffer == '\n')
+               {
+                       continue;
+               }
+
+               if (strncmp (buffer, "VENDOR", 6) == 0) {
+                   /* Read the VENDOR line */
+                   if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) {
+                       rc_log(LOG_ERR, "rc_read_dictionary: invalid vendor on line %d of dictionary %s",
+                              line_no, filename);
+                       return (-1);
+                   }
+                   /* Validate entry */
+                   if (strlen (namestr) > NAME_LENGTH) {
+                       rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+                              line_no, filename);
+                       return (-1);
+                   }
+                   /* Create new vendor entry */
+                   vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT));
+                   if (!vdict) {
+                       rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+                       return (-1);
+                   }
+                   strcpy(vdict->vendorname, namestr);
+                   vdict->vendorcode = value;
+                   vdict->attributes = NULL;
+                   vdict->next = vendor_dictionaries;
+                   vendor_dictionaries = vdict;
+               }
+               else if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
+               {
+
+                       /* Read the ATTRIBUTE line.  It is one of:
+                        * ATTRIBUTE attr_name attr_val type         OR
+                        * ATTRIBUTE attr_name attr_val type vendor  */
+                       vendorstr[0] = 0;
+                       n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr);
+                       if (n != 4 && n != 5)
+                       {
+                               rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+
+                       /*
+                        * Validate all entries
+                        */
+                       if (strlen (namestr) > NAME_LENGTH)
+                       {
+                               rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+
+                       if (strlen (vendorstr) > NAME_LENGTH)
+                       {
+                               rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+
+                       if (!isdigit (*valstr))
+                       {
+                               rc_log(LOG_ERR,
+                                "rc_read_dictionary: invalid value on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+                       value = atoi (valstr);
+
+                       if (strcmp (typestr, "string") == 0)
+                       {
+                               type = PW_TYPE_STRING;
+                       }
+                       else if (strcmp (typestr, "integer") == 0)
+                       {
+                               type = PW_TYPE_INTEGER;
+                       }
+                       else if (strcmp (typestr, "ipaddr") == 0)
+                       {
+                               type = PW_TYPE_IPADDR;
+                       }
+                       else if (strcmp (typestr, "date") == 0)
+                       {
+                               type = PW_TYPE_DATE;
+                       }
+                       else
+                       {
+                               rc_log(LOG_ERR,
+                                 "rc_read_dictionary: invalid type on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+
+                       /* Search for vendor if supplied */
+                       if (*vendorstr) {
+                           vdict = rc_dict_findvendor(vendorstr);
+                           if (!vdict) {
+                               rc_log(LOG_ERR,
+                                      "rc_read_dictionary: unknown vendor on line %d of dictionary %s",
+                                      line_no, filename);
+                               return (-1);
+                           }
+                       } else {
+                           vdict = NULL;
+                       }
+                       /* Create a new attribute for the list */
+                       if ((attr =
+                               (DICT_ATTR *) malloc (sizeof (DICT_ATTR)))
+                                                       == (DICT_ATTR *) NULL)
+                       {
+                               rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+                               return (-1);
+                       }
+                       strcpy (attr->name, namestr);
+                       if (vdict) {
+                           attr->vendorcode = vdict->vendorcode;
+                       } else {
+                           attr->vendorcode = VENDOR_NONE;
+                       }
+                       attr->value = value;
+                       attr->type = type;
+
+                       /* Insert it into the list */
+                       if (vdict) {
+                           attr->next = vdict->attributes;
+                           vdict->attributes = attr;
+                       } else {
+                           attr->next = dictionary_attributes;
+                           dictionary_attributes = attr;
+                       }
+               }
+               else if (strncmp (buffer, "VALUE", 5) == 0)
+               {
+                       /* Read the VALUE line */
+                       if (sscanf (buffer, "%s%s%s%s", dummystr, attrstr,
+                                   namestr, valstr) != 4)
+                       {
+                               rc_log(LOG_ERR,
+                          "rc_read_dictionary: invalid value entry on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+
+                       /*
+                        * Validate all entries
+                        */
+                       if (strlen (attrstr) > NAME_LENGTH)
+                       {
+                               rc_log(LOG_ERR,
+                     "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+
+                       if (strlen (namestr) > NAME_LENGTH)
+                       {
+                               rc_log(LOG_ERR,
+                          "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+
+                       if (!isdigit (*valstr))
+                       {
+                               rc_log(LOG_ERR,
+                                "rc_read_dictionary: invalid value on line %d of dictionary %s",
+                                        line_no, filename);
+                               return (-1);
+                       }
+                       value = atoi (valstr);
+
+                       /* Create a new VALUE entry for the list */
+                       if ((dval =
+                               (DICT_VALUE *) malloc (sizeof (DICT_VALUE)))
+                                                       == (DICT_VALUE *) NULL)
+                       {
+                               rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+                               return (-1);
+                       }
+                       strcpy (dval->attrname, attrstr);
+                       strcpy (dval->name, namestr);
+                       dval->value = value;
+
+                       /* Insert it into the list */
+                       dval->next = dictionary_values;
+                       dictionary_values = dval;
+               }
+       }
+       fclose (dictfd);
+       return (0);
+}
+
+/*
+ * Function: rc_dict_getattr
+ *
+ * Purpose: Return the full attribute structure based on the
+ *         attribute id number and vendor code.  If vendor code is VENDOR_NONE,
+ *          non-vendor-specific attributes are used
+ *
+ */
+
+DICT_ATTR *rc_dict_getattr (int attribute, int vendor)
+{
+       DICT_ATTR      *attr;
+       VENDOR_DICT    *dict;
+
+       if (vendor == VENDOR_NONE) {
+           attr = dictionary_attributes;
+           while (attr != (DICT_ATTR *) NULL) {
+               if (attr->value == attribute) {
+                   return (attr);
+               }
+               attr = attr->next;
+           }
+       } else {
+           dict = rc_dict_getvendor(vendor);
+           if (!dict) {
+               return NULL;
+           }
+           attr = dict->attributes;
+           while (attr) {
+               if (attr->value == attribute) {
+                   return attr;
+               }
+               attr = attr->next;
+           }
+       }
+       return NULL;
+}
+
+/*
+ * Function: rc_dict_findattr
+ *
+ * Purpose: Return the full attribute structure based on the
+ *         attribute name.
+ *
+ */
+
+DICT_ATTR *rc_dict_findattr (char *attrname)
+{
+       DICT_ATTR      *attr;
+       VENDOR_DICT    *dict;
+
+       attr = dictionary_attributes;
+       while (attr != (DICT_ATTR *) NULL)
+       {
+               if (strcasecmp (attr->name, attrname) == 0)
+               {
+                       return (attr);
+               }
+               attr = attr->next;
+       }
+
+       /* Search vendor-specific dictionaries */
+       dict = vendor_dictionaries;
+       while (dict) {
+           attr = dict->attributes;
+           while (attr) {
+               if (strcasecmp (attr->name, attrname) == 0) {
+                   return (attr);
+               }
+               attr = attr->next;
+           }
+           dict = dict->next;
+       }
+       return ((DICT_ATTR *) NULL);
+}
+
+
+/*
+ * Function: rc_dict_findval
+ *
+ * Purpose: Return the full value structure based on the
+ *         value name.
+ *
+ */
+
+DICT_VALUE *rc_dict_findval (char *valname)
+{
+       DICT_VALUE     *val;
+
+       val = dictionary_values;
+       while (val != (DICT_VALUE *) NULL)
+       {
+               if (strcasecmp (val->name, valname) == 0)
+               {
+                       return (val);
+               }
+               val = val->next;
+       }
+       return ((DICT_VALUE *) NULL);
+}
+
+/*
+ * Function: dict_getval
+ *
+ * Purpose: Return the full value structure based on the
+ *          actual value and the associated attribute name.
+ *
+ */
+
+DICT_VALUE * rc_dict_getval (UINT4 value, char *attrname)
+{
+       DICT_VALUE     *val;
+
+       val = dictionary_values;
+       while (val != (DICT_VALUE *) NULL)
+       {
+               if (strcmp (val->attrname, attrname) == 0 &&
+                               val->value == value)
+               {
+                       return (val);
+               }
+               val = val->next;
+       }
+       return ((DICT_VALUE *) NULL);
+}
+
+/*
+ * Function: rc_dict_findvendor
+ *
+ * Purpose: Return the vendor's dictionary given the vendor name.
+ *
+ */
+VENDOR_DICT * rc_dict_findvendor (char *vendorname)
+{
+    VENDOR_DICT *dict;
+
+    dict = vendor_dictionaries;
+    while (dict) {
+       if (!strcmp(vendorname, dict->vendorname)) {
+           return dict;
+       }
+       dict = dict->next;
+    }
+    return NULL;
+}
+
+/*
+ * Function: rc_dict_getvendor
+ *
+ * Purpose: Return the vendor's dictionary given the vendor ID
+ *
+ */
+VENDOR_DICT * rc_dict_getvendor (int id)
+{
+    VENDOR_DICT *dict;
+
+    dict = vendor_dictionaries;
+    while (dict) {
+       if (id == dict->vendorcode) {
+           return dict;
+       }
+       dict = dict->next;
+    }
+    return NULL;
+}