]> git.ozlabs.org Git - ppp.git/blob - pppd/plugins/radius/dict.c
Makefile.am: Add explicit openssl directory to pppd include path
[ppp.git] / pppd / plugins / radius / dict.c
1 /*
2  * $Id: dict.c,v 1.1 2004/11/14 07:26:26 paulus Exp $
3  *
4  * Copyright (C) 2002 Roaring Penguin Software Inc.
5  *
6  * Copyright (C) 1995,1996,1997 Lars Fenneberg
7  *
8  * Copyright 1992 Livingston Enterprises, Inc.
9  *
10  * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
11  * and Merit Network, Inc. All Rights Reserved
12  *
13  * See the file COPYRIGHT for the respective terms and conditions.
14  * If the file is missing contact me at lf@elemental.net
15  * and I'll send you a copy.
16  *
17  */
18
19 #include <includes.h>
20 #include <radiusclient.h>
21
22 static DICT_ATTR *dictionary_attributes = NULL;
23 static DICT_VALUE *dictionary_values = NULL;
24 static VENDOR_DICT *vendor_dictionaries = NULL;
25
26 /*
27  * Function: rc_read_dictionary
28  *
29  * Purpose: Initialize the dictionary.  Read all ATTRIBUTES into
30  *          the dictionary_attributes list.  Read all VALUES into
31  *          the dictionary_values list.  Construct VENDOR dictionaries
32  *          as required.
33  *
34  */
35
36 int rc_read_dictionary (char *filename)
37 {
38         FILE           *dictfd;
39         char            dummystr[AUTH_ID_LEN];
40         char            namestr[AUTH_ID_LEN];
41         char            valstr[AUTH_ID_LEN];
42         char            attrstr[AUTH_ID_LEN];
43         char            typestr[AUTH_ID_LEN];
44         char            vendorstr[AUTH_ID_LEN];
45         int             line_no;
46         DICT_ATTR      *attr;
47         DICT_VALUE     *dval;
48         VENDOR_DICT    *vdict;
49         char            buffer[256];
50         int             value;
51         int             type;
52         int             n;
53         int             retcode;
54         if ((dictfd = fopen (filename, "r")) == (FILE *) NULL)
55         {
56                 error( "rc_read_dictionary: couldn't open dictionary %s: %s",
57                                 filename, strerror(errno));
58                 return (-1);
59         }
60
61         line_no = 0;
62         retcode = 0;
63         while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL)
64         {
65                 line_no++;
66
67                 /* Skip empty space */
68                 if (*buffer == '#' || *buffer == '\0' || *buffer == '\n')
69                 {
70                         continue;
71                 }
72
73                 if (strncmp (buffer, "VENDOR", 6) == 0) {
74                     /* Read the VENDOR line */
75                     if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) {
76                         error("rc_read_dictionary: invalid vendor on line %d of dictionary %s",
77                               line_no, filename);
78                         retcode = -1;
79                         break;
80                     }
81                     /* Validate entry */
82                     if (strlen (namestr) > NAME_LENGTH) {
83                         error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
84                               line_no, filename);
85                         retcode = -1;
86                         break;
87                     }
88                     /* Create new vendor entry */
89                     vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT));
90                     if (!vdict) {
91                         novm("rc_read_dictionary");
92                         retcode = -1;
93                         break;
94                     }
95                     strcpy(vdict->vendorname, namestr);
96                     vdict->vendorcode = value;
97                     vdict->attributes = NULL;
98                     vdict->next = vendor_dictionaries;
99                     vendor_dictionaries = vdict;
100                 }
101                 else if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
102                 {
103
104                         /* Read the ATTRIBUTE line.  It is one of:
105                          * ATTRIBUTE attr_name attr_val type         OR
106                          * ATTRIBUTE attr_name attr_val type vendor  */
107                         vendorstr[0] = 0;
108                         n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr);
109                         if (n != 4 && n != 5)
110                         {
111                                 error("rc_read_dictionary: invalid attribute on line %d of dictionary %s",
112                                       line_no, filename);
113                                 retcode = -1;
114                                 break;
115                         }
116
117                         /*
118                          * Validate all entries
119                          */
120                         if (strlen (namestr) > NAME_LENGTH)
121                         {
122                                 error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
123                                       line_no, filename);
124                                 retcode = -1;
125                                 break;
126                         }
127
128                         if (strlen (vendorstr) > NAME_LENGTH)
129                         {
130                                 error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
131                                       line_no, filename);
132                                 retcode = -1;
133                                 break;
134                         }
135
136                         if (!isdigit (*valstr))
137                         {
138                                 error("rc_read_dictionary: invalid value on line %d of dictionary %s",
139                                       line_no, filename);
140                                 retcode = -1;
141                                 break;
142                         }
143                         value = atoi (valstr);
144
145                         if (strcmp (typestr, "string") == 0)
146                         {
147                                 type = PW_TYPE_STRING;
148                         }
149                         else if (strcmp (typestr, "integer") == 0)
150                         {
151                                 type = PW_TYPE_INTEGER;
152                         }
153                         else if (strcmp (typestr, "ipaddr") == 0 || strcmp (typestr, "ipv4addr") == 0)
154                         {
155                                 type = PW_TYPE_IPADDR;
156                         }
157                         else if (strcmp (typestr, "date") == 0)
158                         {
159                                 type = PW_TYPE_DATE;
160                         }
161                         else if (strcmp (typestr, "ifid") == 0)
162                         {
163                                 type = PW_TYPE_IFID;
164                         }
165                         else if (strcmp (typestr, "ipv6addr") == 0)
166                         {
167                                 type = PW_TYPE_IPV6ADDR;
168                         }
169                         else if (strcmp (typestr, "ipv6prefix") == 0)
170                         {
171                                 type = PW_TYPE_IPV6PREFIX;
172                         }
173                         else
174                         {
175                                 error("rc_read_dictionary: invalid type on line %d of dictionary %s",
176                                       line_no, filename);
177                                 retcode = -1;
178                                 break;
179                         }
180
181                         /* Search for vendor if supplied */
182                         if (*vendorstr) {
183                             vdict = rc_dict_findvendor(vendorstr);
184                             if (!vdict) {
185                                     error("rc_read_dictionary: unknown vendor on line %d of dictionary %s",
186                                           line_no, filename);
187                                     retcode = -1;
188                                     break;
189                             }
190                         } else {
191                             vdict = NULL;
192                         }
193                         /* Create a new attribute for the list */
194                         if ((attr =
195                                 (DICT_ATTR *) malloc (sizeof (DICT_ATTR)))
196                                                         == (DICT_ATTR *) NULL)
197                         {
198                                 novm("rc_read_dictionary");
199                                 retcode = -1;
200                                 break;
201                         }
202                         strcpy (attr->name, namestr);
203                         if (vdict) {
204                             attr->vendorcode = vdict->vendorcode;
205                         } else {
206                             attr->vendorcode = VENDOR_NONE;
207                         }
208                         attr->value = value;
209                         attr->type = type;
210
211                         /* Insert it into the list */
212                         if (vdict) {
213                             attr->next = vdict->attributes;
214                             vdict->attributes = attr;
215                         } else {
216                             attr->next = dictionary_attributes;
217                             dictionary_attributes = attr;
218                         }
219                 }
220                 else if (strncmp (buffer, "VALUE", 5) == 0)
221                 {
222                         /* Read the VALUE line */
223                         if (sscanf (buffer, "%s%s%s%s", dummystr, attrstr,
224                                     namestr, valstr) != 4)
225                         {
226                                 error("rc_read_dictionary: invalid value entry on line %d of dictionary %s",
227                                       line_no, filename);
228                                 retcode = -1;
229                                 break;
230                         }
231
232                         /*
233                          * Validate all entries
234                          */
235                         if (strlen (attrstr) > NAME_LENGTH)
236                         {
237                                 error("rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
238                                       line_no, filename);
239                                 retcode = -1;
240                                 break;
241                         }
242
243                         if (strlen (namestr) > NAME_LENGTH)
244                         {
245                                 error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
246                                       line_no, filename);
247                                 retcode = -1;
248                                 break;
249                         }
250
251                         if (!isdigit (*valstr))
252                         {
253                                 error("rc_read_dictionary: invalid value on line %d of dictionary %s",
254                                       line_no, filename);
255                                 retcode = -1;
256                                 break;
257                         }
258                         value = atoi (valstr);
259
260                         /* Create a new VALUE entry for the list */
261                         if ((dval =
262                                 (DICT_VALUE *) malloc (sizeof (DICT_VALUE)))
263                                                         == (DICT_VALUE *) NULL)
264                         {
265                                 novm("rc_read_dictionary");
266                                 retcode = -1;
267                                 break;
268                         }
269                         strcpy (dval->attrname, attrstr);
270                         strcpy (dval->name, namestr);
271                         dval->value = value;
272
273                         /* Insert it into the list */
274                         dval->next = dictionary_values;
275                         dictionary_values = dval;
276                 }
277                 else if (strncmp (buffer, "INCLUDE", 7) == 0)
278                 {
279                         /* Read the INCLUDE line */
280                         if (sscanf (buffer, "%s%s", dummystr, namestr) != 2)
281                         {
282                                 error("rc_read_dictionary: invalid include entry on line %d of dictionary %s",
283                                       line_no, filename);
284                                 retcode = -1;
285                                 break;
286                         }
287                         if (rc_read_dictionary(namestr) == -1)
288                         {
289                                 retcode = -1;
290                                 break;
291                         }
292                 }
293         }
294         fclose (dictfd);
295         return retcode;
296 }
297
298 /*
299  * Function: rc_dict_getattr
300  *
301  * Purpose: Return the full attribute structure based on the
302  *          attribute id number and vendor code.  If vendor code is VENDOR_NONE,
303  *          non-vendor-specific attributes are used
304  *
305  */
306
307 DICT_ATTR *rc_dict_getattr (int attribute, int vendor)
308 {
309         DICT_ATTR      *attr;
310         VENDOR_DICT    *dict;
311
312         if (vendor == VENDOR_NONE) {
313             attr = dictionary_attributes;
314             while (attr != (DICT_ATTR *) NULL) {
315                 if (attr->value == attribute) {
316                     return (attr);
317                 }
318                 attr = attr->next;
319             }
320         } else {
321             dict = rc_dict_getvendor(vendor);
322             if (!dict) {
323                 return NULL;
324             }
325             attr = dict->attributes;
326             while (attr) {
327                 if (attr->value == attribute) {
328                     return attr;
329                 }
330                 attr = attr->next;
331             }
332         }
333         return NULL;
334 }
335
336 /*
337  * Function: rc_dict_findattr
338  *
339  * Purpose: Return the full attribute structure based on the
340  *          attribute name.
341  *
342  */
343
344 DICT_ATTR *rc_dict_findattr (char *attrname)
345 {
346         DICT_ATTR      *attr;
347         VENDOR_DICT    *dict;
348
349         attr = dictionary_attributes;
350         while (attr != (DICT_ATTR *) NULL)
351         {
352                 if (strcasecmp (attr->name, attrname) == 0)
353                 {
354                         return (attr);
355                 }
356                 attr = attr->next;
357         }
358
359         /* Search vendor-specific dictionaries */
360         dict = vendor_dictionaries;
361         while (dict) {
362             attr = dict->attributes;
363             while (attr) {
364                 if (strcasecmp (attr->name, attrname) == 0) {
365                     return (attr);
366                 }
367                 attr = attr->next;
368             }
369             dict = dict->next;
370         }
371         return ((DICT_ATTR *) NULL);
372 }
373
374
375 /*
376  * Function: rc_dict_findval
377  *
378  * Purpose: Return the full value structure based on the
379  *         value name.
380  *
381  */
382
383 DICT_VALUE *rc_dict_findval (char *valname)
384 {
385         DICT_VALUE     *val;
386
387         val = dictionary_values;
388         while (val != (DICT_VALUE *) NULL)
389         {
390                 if (strcasecmp (val->name, valname) == 0)
391                 {
392                         return (val);
393                 }
394                 val = val->next;
395         }
396         return ((DICT_VALUE *) NULL);
397 }
398
399 /*
400  * Function: dict_getval
401  *
402  * Purpose: Return the full value structure based on the
403  *          actual value and the associated attribute name.
404  *
405  */
406
407 DICT_VALUE * rc_dict_getval (UINT4 value, char *attrname)
408 {
409         DICT_VALUE     *val;
410
411         val = dictionary_values;
412         while (val != (DICT_VALUE *) NULL)
413         {
414                 if (strcmp (val->attrname, attrname) == 0 &&
415                                 val->value == value)
416                 {
417                         return (val);
418                 }
419                 val = val->next;
420         }
421         return ((DICT_VALUE *) NULL);
422 }
423
424 /*
425  * Function: rc_dict_findvendor
426  *
427  * Purpose: Return the vendor's dictionary given the vendor name.
428  *
429  */
430 VENDOR_DICT * rc_dict_findvendor (char *vendorname)
431 {
432     VENDOR_DICT *dict;
433
434     dict = vendor_dictionaries;
435     while (dict) {
436         if (!strcmp(vendorname, dict->vendorname)) {
437             return dict;
438         }
439         dict = dict->next;
440     }
441     return NULL;
442 }
443
444 /*
445  * Function: rc_dict_getvendor
446  *
447  * Purpose: Return the vendor's dictionary given the vendor ID
448  *
449  */
450 VENDOR_DICT * rc_dict_getvendor (int id)
451 {
452     VENDOR_DICT *dict;
453
454     dict = vendor_dictionaries;
455     while (dict) {
456         if (id == dict->vendorcode) {
457             return dict;
458         }
459         dict = dict->next;
460     }
461     return NULL;
462 }