543000fc051a0032d1d79ddc197ce927df160a42
[freeradius.git] / src / lib / valuepair.c
1 /*
2  * valuepair.c  Functions to handle VALUE_PAIRs
3  *
4  * Version:     $Id$
5  *
6  *   This library is free software; you can redistribute it and/or
7  *   modify it under the terms of the GNU Lesser General Public
8  *   License as published by the Free Software Foundation; either
9  *   version 2.1 of the License, or (at your option) any later version.
10  *
11  *   This library is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  *   Lesser General Public License for more details.
15  *
16  *   You should have received a copy of the GNU Lesser General Public
17  *   License along with this library; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006  The FreeRADIUS server project
21  */
22
23 #include <freeradius-devel/ident.h>
24 RCSID("$Id$")
25
26 #include        <freeradius-devel/libradius.h>
27
28 #include        <ctype.h>
29
30 #ifdef HAVE_MALLOC_H
31 #  include      <malloc.h>
32 #endif
33
34 #ifdef HAVE_REGEX_H
35 #  include      <regex.h>
36 #endif
37
38 static const char *months[] = {
39         "jan", "feb", "mar", "apr", "may", "jun",
40         "jul", "aug", "sep", "oct", "nov", "dec" };
41
42 /*
43  *      This padding is necessary only for attributes that are NOT
44  *      in the dictionary, and then only because the rest of the
45  *      code accesses vp->name directly, rather than through an
46  *      accessor function.
47  *
48  *      The name padding only has to large enough for:
49  *
50  *              Vendor-65535-Attr-65535
51  *
52  *      i.e. 23 characters, plus a zero.  We add another 8 bytes for
53  *      padding, because the VALUE_PAIR structure may be un-aligned.
54  *
55  *      The result is that for the normal case, the server uses a less
56  *      memory (36 bytes * number of VALUE_PAIRs).
57  */
58 #define FR_VP_NAME_PAD (32)
59 #define FR_VP_NAME_LEN (24)
60
61 VALUE_PAIR *pairalloc(DICT_ATTR *da)
62 {
63         size_t name_len = 0;
64         VALUE_PAIR *vp;
65
66         /*
67          *      Not in the dictionary: the name is allocated AFTER
68          *      the VALUE_PAIR struct.
69          */
70         if (!da) name_len = FR_VP_NAME_PAD;
71
72         vp = malloc(sizeof(*vp) + name_len);
73         if (!vp) return NULL;
74         memset(vp, 0, sizeof(*vp));
75
76         if (da) {
77                 vp->attribute = da->attr;
78                 vp->vendor = da->vendor;
79                 vp->type = da->type;
80                 vp->name = da->name;
81                 vp->flags = da->flags;
82         } else {
83                 vp->attribute = 0;
84                 vp->vendor = 0;
85                 vp->type = PW_TYPE_OCTETS;
86                 vp->name = NULL;
87                 memset(&vp->flags, 0, sizeof(vp->flags));
88                 vp->flags.unknown_attr = 1;
89         }
90
91         switch (vp->type) {
92                 case PW_TYPE_BYTE:
93                         vp->length = 1;
94                         break;
95
96                 case PW_TYPE_SHORT:
97                         vp->length = 2;
98                         break;
99
100                 case PW_TYPE_INTEGER:
101                 case PW_TYPE_IPADDR:
102                 case PW_TYPE_DATE:
103                 case PW_TYPE_SIGNED:
104                         vp->length = 4;
105                         break;
106
107                 case PW_TYPE_IFID:
108                         vp->length = sizeof(vp->vp_ifid);
109                         break;
110
111                 case PW_TYPE_IPV6ADDR:
112                         vp->length = sizeof(vp->vp_ipv6addr);
113                         break;
114
115                 case PW_TYPE_IPV6PREFIX:
116                         vp->length = sizeof(vp->vp_ipv6prefix);
117                         break;
118
119                 case PW_TYPE_ETHERNET:
120                         vp->length = sizeof(vp->vp_ether);
121                         break;
122
123                 case PW_TYPE_TLV:
124                         vp->vp_tlv = NULL;
125                         vp->length = 0;
126                         break;
127
128                 case PW_TYPE_COMBO_IP:
129                 default:
130                         vp->length = 0;
131                         break;
132         }
133
134         return vp;
135 }
136
137
138 /*
139  *      Create a new valuepair.
140  */
141 VALUE_PAIR *paircreate(int attr, int vendor, int type)
142 {
143         VALUE_PAIR      *vp;
144         DICT_ATTR       *da;
145
146         da = dict_attrbyvalue(attr, vendor);
147         if ((vp = pairalloc(da)) == NULL) {
148                 fr_strerror_printf("out of memory");
149                 return NULL;
150         }
151         vp->operator = T_OP_EQ;
152
153         /*
154          *      It isn't in the dictionary: update the name.
155          */
156         if (!da) {
157                 char *p = (char *) (vp + 1);
158                 
159                 vp->vendor = vendor;
160                 vp->attribute = attr;
161                 vp->name = p;
162                 vp->type = type; /* be forgiving */
163
164                 if (!vp_print_name(p, FR_VP_NAME_LEN, attr, vendor)) {
165                         free(vp);
166                         return NULL;
167                 }
168         }
169
170         return vp;
171 }
172
173 /*
174  *      release the memory used by a single attribute-value pair
175  *      just a wrapper around free() for now.
176  */
177 void pairbasicfree(VALUE_PAIR *pair)
178 {
179         if (pair->type == PW_TYPE_TLV) free(pair->vp_tlv);
180         /* clear the memory here */
181         memset(pair, 0, sizeof(*pair));
182         free(pair);
183 }
184
185 /*
186  *      Release the memory used by a list of attribute-value
187  *      pairs, and sets the pair pointer to NULL.
188  */
189 void pairfree(VALUE_PAIR **pair_ptr)
190 {
191         VALUE_PAIR      *next, *pair;
192
193         if (!pair_ptr) return;
194         pair = *pair_ptr;
195
196         while (pair != NULL) {
197                 next = pair->next;
198                 pairbasicfree(pair);
199                 pair = next;
200         }
201
202         *pair_ptr = NULL;
203 }
204
205
206 /*
207  *      Find the pair with the matching attribute
208  */
209 VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr, int vendor)
210 {
211         while (first) {
212                 if ((first->attribute == attr) && (first->vendor == vendor)) {
213                         return first;
214                 }
215                 first = first->next;
216         }
217
218         return NULL;
219 }
220
221
222 /*
223  *      Delete the pair(s) with the matching attribute
224  */
225 void pairdelete(VALUE_PAIR **first, int attr, int vendor)
226 {
227         VALUE_PAIR *i, *next;
228         VALUE_PAIR **last = first;
229
230         for(i = *first; i; i = next) {
231                 next = i->next;
232                 if ((i->attribute == attr) && (i->vendor == vendor)) {
233                         *last = next;
234                         pairbasicfree(i);
235                 } else {
236                         last = &i->next;
237                 }
238         }
239 }
240
241 /*
242  *      Add a pair at the end of a VALUE_PAIR list.
243  */
244 void pairadd(VALUE_PAIR **first, VALUE_PAIR *add)
245 {
246         VALUE_PAIR *i;
247
248         if (!add) return;
249
250         if (*first == NULL) {
251                 *first = add;
252                 return;
253         }
254         for(i = *first; i->next; i = i->next)
255                 ;
256         i->next = add;
257 }
258
259 /*
260  *      Add or replace a pair at the end of a VALUE_PAIR list.
261  */
262 void pairreplace(VALUE_PAIR **first, VALUE_PAIR *replace)
263 {
264         VALUE_PAIR *i, *next;
265         VALUE_PAIR **prev = first;
266
267         if (*first == NULL) {
268                 *first = replace;
269                 return;
270         }
271
272         /*
273          *      Not an empty list, so find item if it is there, and
274          *      replace it. Note, we always replace the first one, and
275          *      we ignore any others that might exist.
276          */
277         for(i = *first; i; i = next) {
278                 next = i->next;
279
280                 /*
281                  *      Found the first attribute, replace it,
282                  *      and return.
283                  */
284                 if ((i->attribute == replace->attribute) &&
285                     (i->vendor == replace->vendor)) {
286                         *prev = replace;
287
288                         /*
289                          *      Should really assert that replace->next == NULL
290                          */
291                         replace->next = next;
292                         pairbasicfree(i);
293                         return;
294                 }
295
296                 /*
297                  *      Point to where the attribute should go.
298                  */
299                 prev = &i->next;
300         }
301
302         /*
303          *      If we got here, we didn't find anything to replace, so
304          *      stopped at the last item, which we just append to.
305          */
306         *prev = replace;
307 }
308
309
310 /*
311  *      Copy just one VP.
312  */
313 VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp)
314 {
315         size_t name_len;
316         VALUE_PAIR *n;
317         
318         if (!vp->flags.unknown_attr) {
319                 name_len = 0;
320         } else {
321                 name_len = FR_VP_NAME_PAD;
322         }
323         
324         if ((n = malloc(sizeof(*n) + name_len)) == NULL) {
325                 fr_strerror_printf("out of memory");
326                 return NULL;
327         }
328         memcpy(n, vp, sizeof(*n) + name_len);
329         n->next = NULL;
330
331         if ((n->type == PW_TYPE_TLV) &&
332             (n->vp_tlv != NULL)) {
333                 n->vp_tlv = malloc(n->length);
334                 memcpy(n->vp_tlv, vp->vp_tlv, n->length);
335         }
336
337         return n;
338 }
339
340
341 /*
342  *      Copy just a certain type of pairs.
343  */
344 VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr, int vendor)
345 {
346         VALUE_PAIR      *first, *n, **last;
347
348         first = NULL;
349         last = &first;
350
351         while (vp) {
352                 if ((attr >= 0) &&
353                     !((vp->attribute == attr) && (vp->vendor == vendor))) {
354                         vp = vp->next;
355                         continue;
356                 }
357
358                 n = paircopyvp(vp);
359                 if (!n) return first;
360                 *last = n;
361                 last = &n->next;
362                 vp = vp->next;
363         }
364         return first;
365 }
366
367
368 /*
369  *      Copy a pairlist.
370  */
371 VALUE_PAIR *paircopy(VALUE_PAIR *vp)
372 {
373         return paircopy2(vp, -1, 0);
374 }
375
376
377 /*
378  *      Move attributes from one list to the other
379  *      if not already present.
380  */
381 void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
382 {
383         VALUE_PAIR **tailto, *i, *j, *next;
384         VALUE_PAIR *tailfrom = NULL;
385         VALUE_PAIR *found;
386         int has_password = 0;
387
388         /*
389          *      First, see if there are any passwords here, and
390          *      point "tailto" to the end of the "to" list.
391          */
392         tailto = to;
393         for(i = *to; i; i = i->next) {
394                 if (i->attribute == PW_USER_PASSWORD ||
395                     i->attribute == PW_CRYPT_PASSWORD)
396                         has_password = 1;
397                 tailto = &i->next;
398         }
399
400         /*
401          *      Loop over the "from" list.
402          */
403         for(i = *from; i; i = next) {
404                 next = i->next;
405
406                 /*
407                  *      If there was a password in the "to" list,
408                  *      do not move any other password from the
409                  *      "from" to the "to" list.
410                  */
411                 if (has_password &&
412                     (i->attribute == PW_USER_PASSWORD ||
413                      i->attribute == PW_CRYPT_PASSWORD)) {
414                         tailfrom = i;
415                         continue;
416                 }
417
418                 switch (i->operator) {
419                         /*
420                          *      These are COMPARISON attributes
421                          *      from a check list, and are not
422                          *      supposed to be copied!
423                          */
424                         case T_OP_NE:
425                         case T_OP_GE:
426                         case T_OP_GT:
427                         case T_OP_LE:
428                         case T_OP_LT:
429                         case T_OP_CMP_TRUE:
430                         case T_OP_CMP_FALSE:
431                         case T_OP_CMP_EQ:
432                                 tailfrom = i;
433                                 continue;
434
435                         default:
436                                 break;
437                 }
438
439                 /*
440                  *      If the attribute is already present in "to",
441                  *      do not move it from "from" to "to". We make
442                  *      an exception for "Hint" which can appear multiple
443                  *      times, and we never move "Fall-Through".
444                  */
445                 if (i->attribute == PW_FALL_THROUGH ||
446                     (i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) {
447
448                         found = pairfind(*to, i->attribute, i->vendor);
449                         switch (i->operator) {
450
451                           /*
452                            *    If matching attributes are found,
453                            *    delete them.
454                            */
455                         case T_OP_SUB:          /* -= */
456                                 if (found) {
457                                         if (!i->vp_strvalue[0] ||
458                                             (strcmp((char *)found->vp_strvalue,
459                                                     (char *)i->vp_strvalue) == 0)){
460                                                 pairdelete(to, found->attribute, found->vendor);
461
462                                                 /*
463                                                  *      'tailto' may have been
464                                                  *      deleted...
465                                                  */
466                                                 tailto = to;
467                                                 for(j = *to; j; j = j->next) {
468                                                         tailto = &j->next;
469                                                 }
470                                         }
471                                 }
472                                 tailfrom = i;
473                                 continue;
474                                 break;
475
476 /* really HAVE_REGEX_H */
477 #if 0
478                                 /*
479                                  *  Attr-Name =~ "s/find/replace/"
480                                  *
481                                  *  Very bad code.  Barely working,
482                                  *  if at all.
483                                  */
484
485                         case T_OP_REG_EQ:
486                           if (found &&
487                               (i->vp_strvalue[0] == 's')) {
488                             regex_t             reg;
489                             regmatch_t          match[1];
490
491                             char *str;
492                             char *p, *q;
493
494                             p = i->vp_strvalue + 1;
495                             q = strchr(p + 1, *p);
496                             if (!q || (q[strlen(q) - 1] != *p)) {
497                               tailfrom = i;
498                               continue;
499                             }
500                             str = strdup(i->vp_strvalue + 2);
501                             q = strchr(str, *p);
502                             *(q++) = '\0';
503                             q[strlen(q) - 1] = '\0';
504
505                             regcomp(&reg, str, 0);
506                             if (regexec(&reg, found->vp_strvalue,
507                                         1, match, 0) == 0) {
508                               fprintf(stderr, "\"%s\" will have %d to %d replaced with %s\n",
509                                       found->vp_strvalue, match[0].rm_so,
510                                       match[0].rm_eo, q);
511
512                             }
513                             regfree(&reg);
514                             free(str);
515                           }
516                           tailfrom = i; /* don't copy it over */
517                           continue;
518                           break;
519 #endif
520                         case T_OP_EQ:           /* = */
521                                 /*
522                                  *  FIXME: Tunnel attributes with
523                                  *  different tags are different
524                                  *  attributes.
525                                  */
526                                 if (found) {
527                                         tailfrom = i;
528                                         continue; /* with the loop */
529                                 }
530                                 break;
531
532                           /*
533                            *  If a similar attribute is found,
534                            *  replace it with the new one.  Otherwise,
535                            *  add the new one to the list.
536                            */
537                         case T_OP_SET:          /* := */
538                                 if (found) {
539                                         VALUE_PAIR *mynext = found->next;
540
541                                         /*
542                                          *      Do NOT call pairdelete()
543                                          *      here, due to issues with
544                                          *      re-writing "request->username".
545                                          *
546                                          *      Everybody calls pairmove,
547                                          *      and expects it to work.
548                                          *      We can't update request->username
549                                          *      here, so instead we over-write
550                                          *      the vp that it's pointing to.
551                                          */
552                                         memcpy(found, i, sizeof(*found));
553                                         found->next = mynext;
554
555                                         pairdelete(&found->next, found->attribute, found->vendor);
556
557                                         /*
558                                          *      'tailto' may have been
559                                          *      deleted...
560                                          */
561                                         for(j = found; j; j = j->next) {
562                                                 tailto = &j->next;
563                                         }
564                                         continue;
565                                 }
566                                 break;
567
568                           /*
569                            *  Add the new element to the list, even
570                            *  if similar ones already exist.
571                            */
572                         default:
573                         case T_OP_ADD: /* += */
574                                 break;
575                         }
576                 }
577                 if (tailfrom)
578                         tailfrom->next = next;
579                 else
580                         *from = next;
581
582                 /*
583                  *      If ALL of the 'to' attributes have been deleted,
584                  *      then ensure that the 'tail' is updated to point
585                  *      to the head.
586                  */
587                 if (!*to) {
588                         tailto = to;
589                 }
590                 *tailto = i;
591                 if (i) {
592                         i->next = NULL;
593                         tailto = &i->next;
594                 }
595         }
596 }
597
598 /*
599  *      Move one kind of attributes from one list to the other
600  */
601 void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr, int vendor)
602 {
603         VALUE_PAIR *to_tail, *i, *next;
604         VALUE_PAIR *iprev = NULL;
605
606         /*
607          *      Find the last pair in the "to" list and put it in "to_tail".
608          */
609         if (*to != NULL) {
610                 to_tail = *to;
611                 for(i = *to; i; i = i->next)
612                         to_tail = i;
613         } else
614                 to_tail = NULL;
615
616         for(i = *from; i; i = next) {
617                 next = i->next;
618
619                 /*
620                  *      vendor=0, attr = PW_VENDOR_SPECIFIC means
621                  *      "match any vendor attribute".  Otherwise, do
622                  *      an exact match
623                  */
624                 if (((vendor != 0) || (attr != PW_VENDOR_SPECIFIC)) &&
625                     (i->attribute != attr) && (i->vendor != vendor)) {
626                         iprev = i;
627                         continue;
628                 }
629
630                 /*
631                  *      If the attribute to move IS a VSA, then it ignores
632                  *      any non-VSA attribute.
633                  */
634                 if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC) &&
635                     (i->vendor == 0)) {
636                         iprev = i;
637                         continue;
638                 }
639
640                 /*
641                  *      Remove the attribute from the "from" list.
642                  */
643                 if (iprev)
644                         iprev->next = next;
645                 else
646                         *from = next;
647
648                 /*
649                  *      Add the attribute to the "to" list.
650                  */
651                 if (to_tail)
652                         to_tail->next = i;
653                 else
654                         *to = i;
655                 to_tail = i;
656                 i->next = NULL;
657         }
658 }
659
660
661 /*
662  *      Sort of strtok/strsep function.
663  */
664 static char *mystrtok(char **ptr, const char *sep)
665 {
666         char    *res;
667
668         if (**ptr == 0)
669                 return NULL;
670         while (**ptr && strchr(sep, **ptr))
671                 (*ptr)++;
672         if (**ptr == 0)
673                 return NULL;
674         res = *ptr;
675         while (**ptr && strchr(sep, **ptr) == NULL)
676                 (*ptr)++;
677         if (**ptr != 0)
678                 *(*ptr)++ = 0;
679         return res;
680 }
681
682 /*
683  *      Turn printable string into time_t
684  *      Returns -1 on error, 0 on OK.
685  */
686 static int gettime(const char *valstr, time_t *date)
687 {
688         int             i;
689         time_t          t;
690         struct tm       *tm, s_tm;
691         char            buf[64];
692         char            *p;
693         char            *f[4];
694         char            *tail = '\0';
695
696         /*
697          * Test for unix timestamp date
698          */
699         *date = strtoul(valstr, &tail, 10);
700         if (*tail == '\0') {
701                 return 0;
702         }
703
704         tm = &s_tm;
705         memset(tm, 0, sizeof(*tm));
706         tm->tm_isdst = -1;      /* don't know, and don't care about DST */
707
708         strlcpy(buf, valstr, sizeof(buf));
709
710         p = buf;
711         f[0] = mystrtok(&p, " \t");
712         f[1] = mystrtok(&p, " \t");
713         f[2] = mystrtok(&p, " \t");
714         f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
715         if (!f[0] || !f[1] || !f[2]) return -1;
716
717         /*
718          *      The time has a colon, where nothing else does.
719          *      So if we find it, bubble it to the back of the list.
720          */
721         if (f[3]) {
722                 for (i = 0; i < 3; i++) {
723                         if (strchr(f[i], ':')) {
724                                 p = f[3];
725                                 f[3] = f[i];
726                                 f[i] = p;
727                                 break;
728                         }
729                 }
730         }
731
732         /*
733          *  The month is text, which allows us to find it easily.
734          */
735         tm->tm_mon = 12;
736         for (i = 0; i < 3; i++) {
737                 if (isalpha( (int) *f[i])) {
738                         /*
739                          *  Bubble the month to the front of the list
740                          */
741                         p = f[0];
742                         f[0] = f[i];
743                         f[i] = p;
744
745                         for (i = 0; i < 12; i++) {
746                                 if (strncasecmp(months[i], f[0], 3) == 0) {
747                                         tm->tm_mon = i;
748                                         break;
749                                 }
750                         }
751                 }
752         }
753
754         /* month not found? */
755         if (tm->tm_mon == 12) return -1;
756
757         /*
758          *  The year may be in f[1], or in f[2]
759          */
760         tm->tm_year = atoi(f[1]);
761         tm->tm_mday = atoi(f[2]);
762
763         if (tm->tm_year >= 1900) {
764                 tm->tm_year -= 1900;
765
766         } else {
767                 /*
768                  *  We can't use 2-digit years any more, they make it
769                  *  impossible to tell what's the day, and what's the year.
770                  */
771                 if (tm->tm_mday < 1900) return -1;
772
773                 /*
774                  *  Swap the year and the day.
775                  */
776                 i = tm->tm_year;
777                 tm->tm_year = tm->tm_mday - 1900;
778                 tm->tm_mday = i;
779         }
780
781         /*
782          *  If the day is out of range, die.
783          */
784         if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
785                 return -1;
786         }
787
788         /*
789          *      There may be %H:%M:%S.  Parse it in a hacky way.
790          */
791         if (f[3]) {
792                 f[0] = f[3];    /* HH */
793                 f[1] = strchr(f[0], ':'); /* find : separator */
794                 if (!f[1]) return -1;
795
796                 *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
797
798                 f[2] = strchr(f[1], ':'); /* find : separator */
799                 if (f[2]) {
800                   *(f[2]++) = '\0';     /* nuke it, and point to SS */
801                 } else {
802                   strcpy(f[2], "0");    /* assignment would discard const */
803                 }
804
805                 tm->tm_hour = atoi(f[0]);
806                 tm->tm_min = atoi(f[1]);
807                 tm->tm_sec = atoi(f[2]);
808         }
809
810         /*
811          *  Returns -1 on error.
812          */
813         t = mktime(tm);
814         if (t == (time_t) -1) return -1;
815
816         *date = t;
817
818         return 0;
819 }
820
821 static const char *hextab = "0123456789abcdef";
822
823 /*
824  *  Parse a string value into a given VALUE_PAIR
825  *
826  *  FIXME: we probably want to fix this function to accept
827  *  octets as values for any type of attribute.  We should then
828  *  double-check the parsed value, to be sure it's legal for that
829  *  type (length, etc.)
830  */
831 static uint32_t getint(const char *value, char **end)
832 {
833         if ((value[0] == '0') && (value[1] == 'x')) {
834                 return strtoul(value, end, 16);
835         }
836
837         return strtoul(value, end, 10);
838 }
839
840 static int check_for_whitespace(const char *value)
841 {
842         while (*value) {
843                 if (!isspace((int) *value)) return 0;
844
845                 value++;
846         }
847
848         return 1;
849 }
850
851
852 VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
853 {
854         char            *p, *s=0;
855         const char      *cp, *cs;
856         int             x;
857         size_t          length;
858         DICT_VALUE      *dval;
859
860         if (!value) return NULL;
861
862         /*
863          *      Even for integers, dates and ip addresses we
864          *      keep the original string in vp->vp_strvalue.
865          */
866         if (vp->type != PW_TYPE_TLV) {
867                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
868                 vp->length = strlen(vp->vp_strvalue);
869         }
870
871         switch(vp->type) {
872                 case PW_TYPE_STRING:
873                         /*
874                          *      Do escaping here
875                          */
876                         p = vp->vp_strvalue;
877                         cp = value;
878                         length = 0;
879
880                         while (*cp && (length < (sizeof(vp->vp_strvalue) - 1))) {
881                                 char c = *cp++;
882
883                                 if (c == '\\') {
884                                         switch (*cp) {
885                                         case 'r':
886                                                 c = '\r';
887                                                 cp++;
888                                                 break;
889                                         case 'n':
890                                                 c = '\n';
891                                                 cp++;
892                                                 break;
893                                         case 't':
894                                                 c = '\t';
895                                                 cp++;
896                                                 break;
897                                         case '"':
898                                                 c = '"';
899                                                 cp++;
900                                                 break;
901                                         case '\'':
902                                                 c = '\'';
903                                                 cp++;
904                                                 break;
905                                         case '`':
906                                                 c = '`';
907                                                 cp++;
908                                                 break;
909                                         case '\0':
910                                                 c = '\\'; /* no cp++ */
911                                                 break;
912                                         default:
913                                                 if ((cp[0] >= '0') &&
914                                                     (cp[0] <= '9') &&
915                                                     (cp[1] >= '0') &&
916                                                     (cp[1] <= '9') &&
917                                                     (cp[2] >= '0') &&
918                                                     (cp[2] <= '9') &&
919                                                     (sscanf(cp, "%3o", &x) == 1)) {
920                                                         c = x;
921                                                         cp += 3;
922                                                 } /* else just do '\\' */
923                                         }
924                                 }
925                                 *p++ = c;
926                                 length++;
927                         }
928                         vp->length = length;
929                         break;
930
931                 case PW_TYPE_IPADDR:
932                         /*
933                          *      It's a comparison, not a real IP.
934                          */
935                         if ((vp->operator == T_OP_REG_EQ) ||
936                             (vp->operator == T_OP_REG_NE)) {
937                                 break;
938                         }
939
940                         /*
941                          *      FIXME: complain if hostname
942                          *      cannot be resolved, or resolve later!
943                          */
944                         s = NULL;
945                         if ((p = strrchr(value, '+')) != NULL && !p[1]) {
946                                 cs = s = strdup(value);
947                                 if (!s) return NULL;
948                                 p = strrchr(s, '+');
949                                 *p = 0;
950                                 vp->flags.addport = 1;
951                         } else {
952                                 p = NULL;
953                                 cs = value;
954                         }
955
956                         {
957                                 fr_ipaddr_t ipaddr;
958
959                                 if (ip_hton(cs, AF_INET, &ipaddr) < 0) {
960                                         free(s);
961                                         fr_strerror_printf("Failed to find IP address for %s", cs);
962                                         return NULL;
963                                 }
964
965                                 vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
966                         }
967                         free(s);
968                         vp->length = 4;
969                         break;
970
971                 case PW_TYPE_BYTE:
972                         vp->length = 1;
973
974                         /*
975                          *      Note that ALL integers are unsigned!
976                          */
977                         vp->vp_integer = getint(value, &p);
978                         if (!*p) {
979                                 if (vp->vp_integer > 255) {
980                                         fr_strerror_printf("Byte value \"%s\" is larger than 255", value);
981                                         return NULL;
982                                 }
983                                 break;
984                         }
985                         if (check_for_whitespace(p)) break;
986                         goto check_for_value;
987
988                 case PW_TYPE_SHORT:
989                         /*
990                          *      Note that ALL integers are unsigned!
991                          */
992                         vp->vp_integer = getint(value, &p);
993                         vp->length = 2;
994                         if (!*p) {
995                                 if (vp->vp_integer > 65535) {
996                                         fr_strerror_printf("Byte value \"%s\" is larger than 65535", value);
997                                         return NULL;
998                                 }
999                                 break;
1000                         }
1001                         if (check_for_whitespace(p)) break;
1002                         goto check_for_value;
1003
1004                 case PW_TYPE_INTEGER:
1005                         /*
1006                          *      Note that ALL integers are unsigned!
1007                          */
1008                         vp->vp_integer = getint(value, &p);
1009                         vp->length = 4;
1010                         if (!*p) break;
1011                         if (check_for_whitespace(p)) break;
1012
1013         check_for_value:
1014                         /*
1015                          *      Look for the named value for the given
1016                          *      attribute.
1017                          */
1018                         if ((dval = dict_valbyname(vp->attribute, vp->vendor, value)) == NULL) {
1019                                 fr_strerror_printf("Unknown value %s for attribute %s",
1020                                            value, vp->name);
1021                                 return NULL;
1022                         }
1023                         vp->vp_integer = dval->value;
1024                         break;
1025
1026                 case PW_TYPE_DATE:
1027                         {
1028                                 /*
1029                                  *      time_t may be 64 bits, whule vp_date
1030                                  *      MUST be 32-bits.  We need an
1031                                  *      intermediary variable to handle
1032                                  *      the conversions.
1033                                  */
1034                                 time_t date;
1035
1036                                 if (gettime(value, &date) < 0) {
1037                                         fr_strerror_printf("failed to parse time string "
1038                                                    "\"%s\"", value);
1039                                         return NULL;
1040                                 }
1041
1042                                 vp->vp_date = date;
1043                         }
1044                         vp->length = 4;
1045                         break;
1046
1047                 case PW_TYPE_ABINARY:
1048 #ifdef ASCEND_BINARY
1049                         if (strncasecmp(value, "0x", 2) == 0) {
1050                                 vp->type = PW_TYPE_OCTETS;
1051                                 goto do_octets;
1052                         }
1053
1054                         if (ascend_parse_filter(vp) < 0 ) {
1055                                 fr_strerror_printf("failed to parse Ascend binary attribute: %s",
1056                                            fr_strerror());
1057                                 return NULL;
1058                         }
1059                         break;
1060
1061                         /*
1062                          *      If Ascend binary is NOT defined,
1063                          *      then fall through to raw octets, so that
1064                          *      the user can at least make them by hand...
1065                          */
1066         do_octets:
1067 #endif
1068                         /* raw octets: 0x01020304... */
1069                 case PW_TYPE_OCTETS:
1070                         if (strncasecmp(value, "0x", 2) == 0) {
1071                                 uint8_t *us;
1072                                 cp = value + 2;
1073                                 us = vp->vp_octets;
1074                                 vp->length = 0;
1075
1076
1077                                 /*
1078                                  *      There is only one character,
1079                                  *      die.
1080                                  */
1081                                 if ((strlen(cp) & 0x01) != 0) {
1082                                         fr_strerror_printf("Hex string is not an even length string.");
1083                                         return NULL;
1084                                 }
1085
1086
1087                                 while (*cp &&
1088                                        (vp->length < MAX_STRING_LEN)) {
1089                                         unsigned int tmp;
1090
1091                                         if (sscanf(cp, "%02x", &tmp) != 1) {
1092                                                 fr_strerror_printf("Non-hex characters at %c%c", cp[0], cp[1]);
1093                                                 return NULL;
1094                                         }
1095
1096                                         cp += 2;
1097                                         *(us++) = tmp;
1098                                         vp->length++;
1099                                 }
1100                         }
1101                         break;
1102
1103                 case PW_TYPE_IFID:
1104                         if (ifid_aton(value, (void *) &vp->vp_ifid) == NULL) {
1105                                 fr_strerror_printf("failed to parse interface-id "
1106                                            "string \"%s\"", value);
1107                                 return NULL;
1108                         }
1109                         vp->length = 8;
1110                         break;
1111
1112                 case PW_TYPE_IPV6ADDR:
1113                         if (inet_pton(AF_INET6, value, &vp->vp_ipv6addr) <= 0) {
1114                                 fr_strerror_printf("failed to parse IPv6 address "
1115                                            "string \"%s\"", value);
1116                                 return NULL;
1117                         }
1118                         vp->length = 16; /* length of IPv6 address */
1119                         break;
1120
1121                 case PW_TYPE_IPV6PREFIX:
1122                         p = strchr(value, '/');
1123                         if (!p || ((p - value) >= 256)) {
1124                                 fr_strerror_printf("invalid IPv6 prefix "
1125                                            "string \"%s\"", value);
1126                                 return NULL;
1127                         } else {
1128                                 unsigned int prefix;
1129                                 char buffer[256], *eptr;
1130
1131                                 memcpy(buffer, value, p - value);
1132                                 buffer[p - value] = '\0';
1133
1134                                 if (inet_pton(AF_INET6, buffer, vp->vp_octets + 2) <= 0) {
1135                                         fr_strerror_printf("failed to parse IPv6 address "
1136                                                    "string \"%s\"", value);
1137                                         return NULL;
1138                                 }
1139
1140                                 prefix = strtoul(p + 1, &eptr, 10);
1141                                 if ((prefix > 128) || *eptr) {
1142                                         fr_strerror_printf("failed to parse IPv6 address "
1143                                                    "string \"%s\"", value);
1144                                         return NULL;
1145                                 }
1146                                 vp->vp_octets[1] = prefix;
1147                         }
1148                         vp->vp_octets[0] = '\0';
1149                         vp->length = 16 + 2;
1150                         break;
1151
1152                 case PW_TYPE_ETHERNET:
1153                         {
1154                                 const char *c1, *c2;
1155
1156                                 length = 0;
1157                                 cp = value;
1158                                 while (*cp) {
1159                                         if (cp[1] == ':') {
1160                                                 c1 = hextab;
1161                                                 c2 = memchr(hextab, tolower((int) cp[0]), 16);
1162                                                 cp += 2;
1163                                         } else if ((cp[1] != '\0') &&
1164                                                    ((cp[2] == ':') ||
1165                                                     (cp[2] == '\0'))) {
1166                                                    c1 = memchr(hextab, tolower((int) cp[0]), 16);
1167                                                    c2 = memchr(hextab, tolower((int) cp[1]), 16);
1168                                                    cp += 2;
1169                                                    if (*cp == ':') cp++;
1170                                         } else {
1171                                                 c1 = c2 = NULL;
1172                                         }
1173                                         if (!c1 || !c2 || (length >= sizeof(vp->vp_ether))) {
1174                                                 fr_strerror_printf("failed to parse Ethernet address \"%s\"", value);
1175                                                 return NULL;
1176                                         }
1177                                         vp->vp_ether[length] = ((c1-hextab)<<4) + (c2-hextab);
1178                                         length++;
1179                                 }
1180                         }
1181                         vp->length = 6;
1182                         break;
1183
1184                 case PW_TYPE_COMBO_IP:
1185                         if (inet_pton(AF_INET6, value, vp->vp_strvalue) > 0) {
1186                                 vp->type = PW_TYPE_IPV6ADDR;
1187                                 vp->length = 16; /* length of IPv6 address */
1188                                 vp->vp_strvalue[vp->length] = '\0';
1189
1190                         } else {
1191                                 fr_ipaddr_t ipaddr;
1192
1193                                 if (ip_hton(value, AF_INET, &ipaddr) < 0) {
1194                                         fr_strerror_printf("Failed to find IPv4 address for %s", value);
1195                                         return NULL;
1196                                 }
1197
1198                                 vp->type = PW_TYPE_IPADDR;
1199                                 vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
1200                                 vp->length = 4;
1201                         }
1202                         break;
1203
1204                 case PW_TYPE_SIGNED: /* Damned code for 1 WiMAX attribute */
1205                         vp->vp_signed = (int32_t) strtol(value, &p, 10);
1206                         vp->length = 4;
1207                         break;
1208
1209                 case PW_TYPE_TLV: /* don't use this! */
1210                         if (strncasecmp(value, "0x", 2) != 0) {
1211                                 fr_strerror_printf("Invalid TLV specification");
1212                                 return NULL;
1213                         }
1214                         length = strlen(value + 2) / 2;
1215                         if (vp->length < length) {
1216                                 free(vp->vp_tlv);
1217                                 vp->vp_tlv = NULL;
1218                         }
1219                         vp->vp_tlv = malloc(length);
1220                         if (!vp->vp_tlv) {
1221                                 fr_strerror_printf("No memory");
1222                                 return NULL;
1223                         }
1224                         if (fr_hex2bin(value + 2, vp->vp_tlv,
1225                                        length) != length) {
1226                                 fr_strerror_printf("Invalid hex data in TLV");
1227                                 return NULL;
1228                         }
1229                         vp->length = length;
1230                         break;
1231
1232                         /*
1233                          *  Anything else.
1234                          */
1235                 default:
1236                         fr_strerror_printf("unknown attribute type %d", vp->type);
1237                         return NULL;
1238         }
1239
1240         return vp;
1241 }
1242
1243 /*
1244  *      Create a VALUE_PAIR from an ASCII attribute and value,
1245  *      where the attribute name is in the form:
1246  *
1247  *      Attr-%d
1248  *      Vendor-%d-Attr-%d
1249  *      VendorName-Attr-%d
1250  */
1251 static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
1252                                 int operator)
1253 {
1254         int             attr, vendor;
1255         size_t          size;
1256         const char      *p = attribute;
1257         char            *q;
1258         VALUE_PAIR      *vp;
1259
1260         /*
1261          *      Unknown attributes MUST be of type 'octets'
1262          */
1263         if (value && (strncasecmp(value, "0x", 2) != 0)) {
1264                 fr_strerror_printf("Invalid octet string \"%s\" for attribute name \"%s\"", value, attribute);
1265                 return NULL;
1266         }
1267
1268         vendor = 0;
1269
1270         /*
1271          *      Pull off vendor prefix first.
1272          */
1273         if (strncasecmp(p, "Attr-", 5) != 0) {
1274                 if (strncasecmp(p, "Vendor-", 7) == 0) {
1275                         vendor = (int) strtol(p + 7, &q, 10);
1276                         if ((vendor == 0) || (vendor > FR_MAX_VENDOR)) {
1277                                 fr_strerror_printf("Invalid vendor value in attribute name \"%s\"", attribute);
1278                                 return NULL;
1279                         }
1280
1281                         p = q;
1282
1283                 } else {        /* must be vendor name */
1284                         char buffer[256];
1285
1286                         q = strchr(p, '-');
1287
1288                         if (!q) {
1289                                 fr_strerror_printf("Invalid vendor name in attribute name \"%s\"", attribute);
1290                                 return NULL;
1291                         }
1292
1293                         if ((size_t) (q - p) >= sizeof(buffer)) {
1294                                 fr_strerror_printf("Vendor name too long in attribute name \"%s\"", attribute);
1295                                 return NULL;
1296                         }
1297
1298                         memcpy(buffer, p, (q - p));
1299                         buffer[q - p] = '\0';
1300
1301                         vendor = dict_vendorbyname(buffer);
1302                         if (!vendor) {
1303                                 fr_strerror_printf("Unknown vendor name in attribute name \"%s\"", attribute);
1304                                 return NULL;
1305                         }
1306
1307                         p = q;
1308                 }
1309
1310                 if (*p != '-') {
1311                         fr_strerror_printf("Invalid text following vendor definition in attribute name \"%s\"", attribute);
1312                         return NULL;
1313                 }
1314                 p++;
1315         }
1316
1317         /*
1318          *      Attr-%d
1319          */
1320         if (strncasecmp(p, "Attr-", 5) != 0) {
1321                 fr_strerror_printf("Invalid format in attribute name \"%s\"", attribute);
1322                 return NULL;
1323         }
1324
1325         attr = strtol(p + 5, &q, 10);
1326
1327         /*
1328          *      Invalid, or trailing text after number.
1329          */
1330         if ((attr == 0) || *q) {
1331                 fr_strerror_printf("Invalid value in attribute name \"%s\"", attribute);
1332                 return NULL;
1333         }
1334
1335         /*
1336          *      Double-check the size of attr.
1337          */
1338         if (vendor) {
1339                 DICT_VENDOR *dv = dict_vendorbyvalue(vendor);
1340
1341                 if (!dv) {
1342                         if (attr > 255) {
1343                         attr_error:
1344                                 fr_strerror_printf("Invalid attribute number in attribute name \"%s\"", attribute);
1345                                 return NULL;
1346                         }
1347
1348                 } else switch (dv->type) {
1349                         case 1:
1350                                 if (attr > 255) goto attr_error;
1351                                 break;
1352
1353                         case 2:
1354                                 if (attr > 65535) goto attr_error;
1355                                 break;
1356
1357                         case 4:
1358                                 break;
1359
1360                         default:
1361                                 fr_strerror_printf("Internal sanity check failed");
1362                                 return NULL;
1363                 }
1364         }
1365
1366         /*
1367          *      We've now parsed the attribute properly, Let's create
1368          *      it.  This next stop also looks the attribute up in the
1369          *      dictionary, and creates the appropriate type for it.
1370          */
1371         if ((vp = paircreate(attr, vendor, PW_TYPE_OCTETS)) == NULL) {
1372                 fr_strerror_printf("out of memory");
1373                 return NULL;
1374         }
1375
1376         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1377         if (!value) return vp;
1378
1379         size = strlen(value + 2);
1380
1381         /*
1382          *      We may be reading something like Attr-5.  i.e.
1383          *      who-ever wrote the text didn't understand it, but we
1384          *      do.
1385          */
1386         switch (vp->type) {
1387         default:
1388                 if (size == (vp->length * 2)) break;
1389                 vp->type = PW_TYPE_OCTETS;
1390                 /* FALL-THROUGH */
1391                 
1392         case PW_TYPE_STRING:
1393         case PW_TYPE_OCTETS:
1394         case PW_TYPE_ABINARY:
1395                 vp->length = size >> 1;
1396                 break;
1397         }
1398
1399         if (fr_hex2bin(value + 2, vp->vp_octets, size) != vp->length) {
1400                 fr_strerror_printf("Invalid hex string");
1401                 free(vp);
1402                 return NULL;
1403         }
1404
1405         /*
1406          *      Move contents around based on type.  This is
1407          *      to work around the historical use of "lvalue".
1408          */
1409         switch (vp->type) {
1410         case PW_TYPE_DATE:
1411         case PW_TYPE_IPADDR:
1412         case PW_TYPE_INTEGER:
1413                 memcpy(&vp->lvalue, vp->vp_octets, sizeof(vp->lvalue));
1414                 vp->vp_strvalue[0] = '\0';
1415                 break;
1416                 
1417         default:
1418                 break;
1419         }
1420        
1421         return vp;
1422 }
1423
1424
1425 /*
1426  *      Create a VALUE_PAIR from an ASCII attribute and value.
1427  */
1428 VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
1429 {
1430         DICT_ATTR       *da;
1431         VALUE_PAIR      *vp;
1432         char            *tc, *ts;
1433         signed char     tag;
1434         int             found_tag;
1435         char            buffer[64];
1436         const char      *attrname = attribute;
1437
1438         /*
1439          *    Check for tags in 'Attribute:Tag' format.
1440          */
1441         found_tag = 0;
1442         tag = 0;
1443
1444         ts = strrchr(attribute, ':');
1445         if (ts && !ts[1]) {
1446                 fr_strerror_printf("Invalid tag for attribute %s", attribute);
1447                 return NULL;
1448         }
1449
1450         if (ts && ts[1]) {
1451                 strlcpy(buffer, attribute, sizeof(buffer));
1452                 attrname = buffer;
1453                 ts = strrchr(attrname, ':');
1454
1455                  /* Colon found with something behind it */
1456                  if (ts[1] == '*' && ts[2] == 0) {
1457                          /* Wildcard tag for check items */
1458                          tag = TAG_ANY;
1459                          *ts = 0;
1460                  } else if ((ts[1] >= '0') && (ts[1] <= '9')) {
1461                          /* It's not a wild card tag */
1462                          tag = strtol(ts + 1, &tc, 0);
1463                          if (tc && !*tc && TAG_VALID_ZERO(tag))
1464                                  *ts = 0;
1465                          else tag = 0;
1466                  } else {
1467                          fr_strerror_printf("Invalid tag for attribute %s", attribute);
1468                          return NULL;
1469                  }
1470                  found_tag = 1;
1471         }
1472
1473         /*
1474          *      It's not found in the dictionary, so we use
1475          *      another method to create the attribute.
1476          */
1477         if ((da = dict_attrbyname(attrname)) == NULL) {
1478                 return pairmake_any(attrname, value, operator);
1479         }
1480
1481         if ((vp = pairalloc(da)) == NULL) {
1482                 fr_strerror_printf("out of memory");
1483                 return NULL;
1484         }
1485         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1486
1487         /*      Check for a tag in the 'Merit' format of:
1488          *      :Tag:Value.  Print an error if we already found
1489          *      a tag in the Attribute.
1490          */
1491
1492         if (value && (*value == ':' && da->flags.has_tag)) {
1493                 /* If we already found a tag, this is invalid */
1494                 if(found_tag) {
1495                         fr_strerror_printf("Duplicate tag %s for attribute %s",
1496                                    value, vp->name);
1497                         DEBUG("Duplicate tag %s for attribute %s\n",
1498                                    value, vp->name);
1499                         pairbasicfree(vp);
1500                         return NULL;
1501                 }
1502                 /* Colon found and attribute allows a tag */
1503                 if (value[1] == '*' && value[2] == ':') {
1504                        /* Wildcard tag for check items */
1505                        tag = TAG_ANY;
1506                        value += 3;
1507                 } else {
1508                        /* Real tag */
1509                        tag = strtol(value + 1, &tc, 0);
1510                        if (tc && *tc==':' && TAG_VALID_ZERO(tag))
1511                             value = tc + 1;
1512                        else tag = 0;
1513                 }
1514                 found_tag = 1;
1515         }
1516
1517         if (found_tag) {
1518           vp->flags.tag = tag;
1519         }
1520
1521         switch (vp->operator) {
1522         default:
1523                 break;
1524
1525                 /*
1526                  *      For =* and !* operators, the value is irrelevant
1527                  *      so we return now.
1528                  */
1529         case T_OP_CMP_TRUE:
1530         case T_OP_CMP_FALSE:
1531                 vp->vp_strvalue[0] = '\0';
1532                 vp->length = 0;
1533                 return vp;
1534                 break;
1535
1536                 /*
1537                  *      Regular expression comparison of integer attributes
1538                  *      does a STRING comparison of the names of their
1539                  *      integer attributes.
1540                  */
1541         case T_OP_REG_EQ:       /* =~ */
1542         case T_OP_REG_NE:       /* !~ */
1543                 if (!value) {
1544                         fr_strerror_printf("No regular expression found in %s",
1545                                            vp->name);
1546                         pairbasicfree(vp);
1547                         return NULL;
1548                 }
1549           
1550                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1551                 vp->length = strlen(vp->vp_strvalue);
1552                 /*
1553                  *      If anything goes wrong, this is a run-time error,
1554                  *      not a compile-time error.
1555                  */
1556                 return vp;
1557
1558         }
1559
1560         /*
1561          *      FIXME: if (strcasecmp(attribute, vp->name) != 0)
1562          *      then the user MAY have typed in the attribute name
1563          *      as Vendor-%d-Attr-%d, and the value MAY be octets.
1564          *
1565          *      We probably want to fix pairparsevalue to accept
1566          *      octets as values for any attribute.
1567          */
1568         if (value && (pairparsevalue(vp, value) == NULL)) {
1569                 pairbasicfree(vp);
1570                 return NULL;
1571         }
1572
1573         return vp;
1574 }
1575
1576
1577 /*
1578  *      [a-zA-Z0-9_-:]+
1579  */
1580 static const int valid_attr_name[256] = {
1581         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1582         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1583         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1584         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1585         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1586         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
1587         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1588         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1589         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1590         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1591         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1592         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1593         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1594         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1595         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1596         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1597 };
1598
1599 /*
1600  *      Read a valuepair from a buffer, and advance pointer.
1601  *      Sets *eol to T_EOL if end of line was encountered.
1602  */
1603 VALUE_PAIR *pairread(const char **ptr, FR_TOKEN *eol)
1604 {
1605         char            buf[64];
1606         char            attr[64];
1607         char            value[1024], *q;
1608         const char      *p;
1609         FR_TOKEN        token, t, xlat;
1610         VALUE_PAIR      *vp;
1611         size_t          len;
1612
1613         *eol = T_OP_INVALID;
1614
1615         p = *ptr;
1616         while ((*p == ' ') || (*p == '\t')) p++;
1617
1618         if (!*p) {
1619                 *eol = T_OP_INVALID;
1620                 fr_strerror_printf("No token read where we expected an attribute name");
1621                 return NULL;
1622         }
1623
1624         if (*p == '#') {
1625                 *eol = T_HASH;
1626                 fr_strerror_printf("Read a comment instead of a token");
1627                 return NULL;
1628         }
1629
1630         q = attr;
1631         for (len = 0; len < sizeof(attr); len++) {
1632                 if (valid_attr_name[(int)*p]) {
1633                         *q++ = *p++;
1634                         continue;
1635                 }
1636                 break;
1637         }
1638
1639         if (len == sizeof(attr)) {
1640                 *eol = T_OP_INVALID;
1641                 fr_strerror_printf("Attribute name is too long");
1642                 return NULL;
1643         }
1644
1645         /*
1646          *      We may have Foo-Bar:= stuff, so back up.
1647          */
1648         if ((len > 0) && (attr[len - 1] == ':')) {
1649                 p--;
1650                 len--;
1651         }
1652
1653         attr[len] = '\0';
1654         *ptr = p;
1655
1656         /* Now we should have an operator here. */
1657         token = gettoken(ptr, buf, sizeof(buf));
1658         if (token < T_EQSTART || token > T_EQEND) {
1659                 fr_strerror_printf("expecting operator");
1660                 return NULL;
1661         }
1662
1663         /* Read value.  Note that empty string values are allowed */
1664         xlat = gettoken(ptr, value, sizeof(value));
1665         if (xlat == T_EOL) {
1666                 fr_strerror_printf("failed to get value");
1667                 return NULL;
1668         }
1669
1670         /*
1671          *      Peek at the next token. Must be T_EOL, T_COMMA, or T_HASH
1672          */
1673         p = *ptr;
1674         t = gettoken(&p, buf, sizeof(buf));
1675         if (t != T_EOL && t != T_COMMA && t != T_HASH) {
1676                 fr_strerror_printf("Expected end of line or comma");
1677                 return NULL;
1678         }
1679
1680         *eol = t;
1681         if (t == T_COMMA) {
1682                 *ptr = p;
1683         }
1684
1685         vp = NULL;
1686         switch (xlat) {
1687                 /*
1688                  *      Make the full pair now.
1689                  */
1690         default:
1691                 vp = pairmake(attr, value, token);
1692                 break;
1693
1694                 /*
1695                  *      Perhaps do xlat's
1696                  */
1697         case T_DOUBLE_QUOTED_STRING:
1698                 p = strchr(value, '%');
1699                 if (p && (p[1] == '{')) {
1700                         if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1701                                 fr_strerror_printf("Value too long");
1702                                 return NULL;
1703                         }
1704                         vp = pairmake(attr, NULL, token);
1705                         if (!vp) {
1706                                 *eol = T_OP_INVALID;
1707                                 return NULL;
1708                         }
1709
1710                         strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1711                         vp->flags.do_xlat = 1;
1712                         vp->length = 0;
1713                 } else {
1714                         /*
1715                          *      Parse && escape it, as defined by the
1716                          *      data type.
1717                          */
1718                         vp = pairmake(attr, value, token);
1719                         if (!vp) {
1720                                 *eol = T_OP_INVALID;
1721                                 return NULL;
1722                         }
1723                 }
1724                 break;
1725
1726         case T_SINGLE_QUOTED_STRING:
1727                 vp = pairmake(attr, NULL, token);
1728                 if (!vp) {
1729                         *eol = T_OP_INVALID;
1730                         return NULL;
1731                 }
1732
1733                 /*
1734                  *      String and octet types get copied verbatim.
1735                  */
1736                 if ((vp->type == PW_TYPE_STRING) ||
1737                     (vp->type == PW_TYPE_OCTETS)) {
1738                         strlcpy(vp->vp_strvalue, value,
1739                                 sizeof(vp->vp_strvalue));
1740                         vp->length = strlen(vp->vp_strvalue);
1741
1742                         /*
1743                          *      Everything else gets parsed: it's
1744                          *      DATA, not a string!
1745                          */
1746                 } else if (!pairparsevalue(vp, value)) {
1747                         pairfree(&vp);
1748                         *eol = T_OP_INVALID;
1749                         return NULL;
1750                 }
1751                 break;
1752
1753                 /*
1754                  *      Mark the pair to be allocated later.
1755                  */
1756         case T_BACK_QUOTED_STRING:
1757                 if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1758                         fr_strerror_printf("Value too long");
1759                         return NULL;
1760                 }
1761
1762                 vp = pairmake(attr, NULL, token);
1763                 if (!vp) {
1764                         *eol = T_OP_INVALID;
1765                         return NULL;
1766                 }
1767
1768                 vp->flags.do_xlat = 1;
1769                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1770                 vp->length = 0;
1771                 break;
1772         }
1773
1774         /*
1775          *      If we didn't make a pair, return an error.
1776          */
1777         if (!vp) {
1778                 *eol = T_OP_INVALID;
1779                 return NULL;
1780         }
1781
1782         return vp;
1783 }
1784
1785 /*
1786  *      Read one line of attribute/value pairs. This might contain
1787  *      multiple pairs seperated by comma's.
1788  */
1789 FR_TOKEN userparse(const char *buffer, VALUE_PAIR **first_pair)
1790 {
1791         VALUE_PAIR      *vp;
1792         const char      *p;
1793         FR_TOKEN        last_token = T_OP_INVALID;
1794         FR_TOKEN        previous_token;
1795
1796         /*
1797          *      We allow an empty line.
1798          */
1799         if (buffer[0] == 0)
1800                 return T_EOL;
1801
1802         p = buffer;
1803         do {
1804                 previous_token = last_token;
1805                 if ((vp = pairread(&p, &last_token)) == NULL) {
1806                         return last_token;
1807                 }
1808                 pairadd(first_pair, vp);
1809         } while (*p && (last_token == T_COMMA));
1810
1811         /*
1812          *      Don't tell the caller that there was a comment.
1813          */
1814         if (last_token == T_HASH) {
1815                 return previous_token;
1816         }
1817
1818         /*
1819          *      And return the last token which we read.
1820          */
1821         return last_token;
1822 }
1823
1824 /*
1825  *      Read valuepairs from the fp up to End-Of-File.
1826  *
1827  *      Hmm... this function is only used by radclient..
1828  */
1829 VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix)
1830 {
1831         char buf[8192];
1832         FR_TOKEN last_token = T_EOL;
1833         VALUE_PAIR *vp;
1834         VALUE_PAIR *list;
1835         int error = 0;
1836
1837         list = NULL;
1838
1839         while (!error && fgets(buf, sizeof(buf), fp) != NULL) {
1840                 /*
1841                  *      If we get a '\n' by itself, we assume that's
1842                  *      the end of that VP
1843                  */
1844                 if ((buf[0] == '\n') && (list)) {
1845                         return list;
1846                 }
1847                 if ((buf[0] == '\n') && (!list)) {
1848                         continue;
1849                 }
1850
1851                 /*
1852                  *      Comments get ignored
1853                  */
1854                 if (buf[0] == '#') continue;
1855
1856                 /*
1857                  *      Read all of the attributes on the current line.
1858                  */
1859                 vp = NULL;
1860                 last_token = userparse(buf, &vp);
1861                 if (!vp) {
1862                         if (last_token != T_EOL) {
1863                                 fr_perror("%s", errprefix);
1864                                 error = 1;
1865                                 break;
1866                         }
1867                         break;
1868                 }
1869
1870                 pairadd(&list, vp);
1871                 buf[0] = '\0';
1872         }
1873
1874         if (error) pairfree(&list);
1875
1876         *pfiledone = 1;
1877
1878         return error ? NULL: list;
1879 }
1880
1881
1882
1883 /*
1884  *      Compare two pairs, using the operator from "one".
1885  *
1886  *      i.e. given two attributes, it does:
1887  *
1888  *      (two->data) (one->operator) (one->data)
1889  *
1890  *      e.g. "foo" != "bar"
1891  *
1892  *      Returns true (comparison is true), or false (comparison is not true);
1893  *
1894  *      FIXME: Ignores tags!
1895  */
1896 int paircmp(VALUE_PAIR *one, VALUE_PAIR *two)
1897 {
1898         int compare;
1899
1900         switch (one->operator) {
1901         case T_OP_CMP_TRUE:
1902                 return (two != NULL);
1903
1904         case T_OP_CMP_FALSE:
1905                 return (two == NULL);
1906
1907                 /*
1908                  *      One is a regex, compile it, print two to a string,
1909                  *      and then do string comparisons.
1910                  */
1911         case T_OP_REG_EQ:
1912         case T_OP_REG_NE:
1913 #ifndef HAVE_REGEX_H
1914                 return -1;
1915 #else
1916                 {
1917                         regex_t reg;
1918                         char buffer[MAX_STRING_LEN * 4 + 1];
1919
1920                         compare = regcomp(&reg, one->vp_strvalue,
1921                                           REG_EXTENDED);
1922                         if (compare != 0) {
1923                                 regerror(compare, &reg, buffer, sizeof(buffer));
1924                                 fr_strerror_printf("Illegal regular expression in attribute: %s: %s",
1925                                            one->name, buffer);
1926                                 return -1;
1927                         }
1928
1929                         vp_prints_value(buffer, sizeof(buffer), two, 0);
1930
1931                         /*
1932                          *      Don't care about substring matches,
1933                          *      oh well...
1934                          */
1935                         compare = regexec(&reg, buffer, 0, NULL, 0);
1936
1937                         regfree(&reg);
1938                         if (one->operator == T_OP_REG_EQ) return (compare == 0);
1939                         return (compare != 0);
1940                 }
1941 #endif
1942
1943         default:                /* we're OK */
1944                 break;
1945         }
1946
1947         /*
1948          *      After doing the previous check for special comparisons,
1949          *      do the per-type comparison here.
1950          */
1951         switch (one->type) {
1952         case PW_TYPE_ABINARY:
1953         case PW_TYPE_OCTETS:
1954         {
1955                 size_t length;
1956
1957                 if (one->length < two->length) {
1958                         length = one->length;
1959                 } else {
1960                         length = two->length;
1961                 }
1962
1963                 if (length) {
1964                         compare = memcmp(two->vp_octets, one->vp_octets,
1965                                          length);
1966                         if (compare != 0) break;
1967                 }
1968
1969                 /*
1970                  *      Contents are the same.  The return code
1971                  *      is therefore the difference in lengths.
1972                  *
1973                  *      i.e. "0x00" is smaller than "0x0000"
1974                  */
1975                 compare = two->length - one->length;
1976         }
1977                 break;
1978
1979         case PW_TYPE_STRING:
1980                 compare = strcmp(two->vp_strvalue, one->vp_strvalue);
1981                 break;
1982
1983         case PW_TYPE_BYTE:
1984         case PW_TYPE_SHORT:
1985         case PW_TYPE_INTEGER:
1986         case PW_TYPE_DATE:
1987                 compare = two->vp_integer - one->vp_integer;
1988                 break;
1989
1990         case PW_TYPE_IPADDR:
1991                 compare = ntohl(two->vp_ipaddr) - ntohl(one->vp_ipaddr);
1992                 break;
1993
1994         case PW_TYPE_IPV6ADDR:
1995                 compare = memcmp(&two->vp_ipv6addr, &one->vp_ipv6addr,
1996                                  sizeof(two->vp_ipv6addr));
1997                 break;
1998
1999         case PW_TYPE_IPV6PREFIX:
2000                 compare = memcmp(&two->vp_ipv6prefix, &one->vp_ipv6prefix,
2001                                  sizeof(two->vp_ipv6prefix));
2002                 break;
2003
2004         case PW_TYPE_IFID:
2005                 compare = memcmp(&two->vp_ifid, &one->vp_ifid,
2006                                  sizeof(two->vp_ifid));
2007                 break;
2008
2009         default:
2010                 return 0;       /* unknown type */
2011         }
2012
2013         /*
2014          *      Now do the operator comparison.
2015          */
2016         switch (one->operator) {
2017         case T_OP_CMP_EQ:
2018                 return (compare == 0);
2019
2020         case T_OP_NE:
2021                 return (compare != 0);
2022
2023         case T_OP_LT:
2024                 return (compare < 0);
2025
2026         case T_OP_GT:
2027                 return (compare > 0);
2028
2029         case T_OP_LE:
2030                 return (compare <= 0);
2031
2032         case T_OP_GE:
2033                 return (compare >= 0);
2034
2035         default:
2036                 return 0;
2037         }
2038
2039         return 0;
2040 }