Fixed comparisons to be correct
[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 > 65535)) {
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: /* Internal limitations! */
1358                                 if (attr > 65535) goto attr_error;
1359                                 break;
1360
1361                         default:
1362                                 fr_strerror_printf("Internal sanity check failed");
1363                                 return NULL;
1364                 }
1365         }
1366
1367         /*
1368          *      We've now parsed the attribute properly, Let's create
1369          *      it.  This next stop also looks the attribute up in the
1370          *      dictionary, and creates the appropriate type for it.
1371          */
1372         if ((vp = paircreate(attr, vendor, PW_TYPE_OCTETS)) == NULL) {
1373                 fr_strerror_printf("out of memory");
1374                 return NULL;
1375         }
1376
1377         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1378         if (!value) return vp;
1379
1380         size = strlen(value + 2);
1381
1382         /*
1383          *      We may be reading something like Attr-5.  i.e.
1384          *      who-ever wrote the text didn't understand it, but we
1385          *      do.
1386          */
1387         switch (vp->type) {
1388         default:
1389                 if (size == (vp->length * 2)) break;
1390                 vp->type = PW_TYPE_OCTETS;
1391                 /* FALL-THROUGH */
1392                 
1393         case PW_TYPE_STRING:
1394         case PW_TYPE_OCTETS:
1395         case PW_TYPE_ABINARY:
1396                 vp->length = size >> 1;
1397                 break;
1398         }
1399
1400         if (fr_hex2bin(value + 2, vp->vp_octets, size) != vp->length) {
1401                 fr_strerror_printf("Invalid hex string");
1402                 free(vp);
1403                 return NULL;
1404         }
1405
1406         /*
1407          *      Move contents around based on type.  This is
1408          *      to work around the historical use of "lvalue".
1409          */
1410         switch (vp->type) {
1411         case PW_TYPE_DATE:
1412         case PW_TYPE_IPADDR:
1413         case PW_TYPE_INTEGER:
1414                 memcpy(&vp->lvalue, vp->vp_octets, sizeof(vp->lvalue));
1415                 vp->vp_strvalue[0] = '\0';
1416                 break;
1417                 
1418         default:
1419                 break;
1420         }
1421        
1422         return vp;
1423 }
1424
1425
1426 /*
1427  *      Create a VALUE_PAIR from an ASCII attribute and value.
1428  */
1429 VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
1430 {
1431         DICT_ATTR       *da;
1432         VALUE_PAIR      *vp;
1433         char            *tc, *ts;
1434         signed char     tag;
1435         int             found_tag;
1436         char            buffer[64];
1437         const char      *attrname = attribute;
1438
1439         /*
1440          *    Check for tags in 'Attribute:Tag' format.
1441          */
1442         found_tag = 0;
1443         tag = 0;
1444
1445         ts = strrchr(attribute, ':');
1446         if (ts && !ts[1]) {
1447                 fr_strerror_printf("Invalid tag for attribute %s", attribute);
1448                 return NULL;
1449         }
1450
1451         if (ts && ts[1]) {
1452                 strlcpy(buffer, attribute, sizeof(buffer));
1453                 attrname = buffer;
1454                 ts = strrchr(attrname, ':');
1455
1456                  /* Colon found with something behind it */
1457                  if (ts[1] == '*' && ts[2] == 0) {
1458                          /* Wildcard tag for check items */
1459                          tag = TAG_ANY;
1460                          *ts = 0;
1461                  } else if ((ts[1] >= '0') && (ts[1] <= '9')) {
1462                          /* It's not a wild card tag */
1463                          tag = strtol(ts + 1, &tc, 0);
1464                          if (tc && !*tc && TAG_VALID_ZERO(tag))
1465                                  *ts = 0;
1466                          else tag = 0;
1467                  } else {
1468                          fr_strerror_printf("Invalid tag for attribute %s", attribute);
1469                          return NULL;
1470                  }
1471                  found_tag = 1;
1472         }
1473
1474         /*
1475          *      It's not found in the dictionary, so we use
1476          *      another method to create the attribute.
1477          */
1478         if ((da = dict_attrbyname(attrname)) == NULL) {
1479                 return pairmake_any(attrname, value, operator);
1480         }
1481
1482         if ((vp = pairalloc(da)) == NULL) {
1483                 fr_strerror_printf("out of memory");
1484                 return NULL;
1485         }
1486         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1487
1488         /*      Check for a tag in the 'Merit' format of:
1489          *      :Tag:Value.  Print an error if we already found
1490          *      a tag in the Attribute.
1491          */
1492
1493         if (value && (*value == ':' && da->flags.has_tag)) {
1494                 /* If we already found a tag, this is invalid */
1495                 if(found_tag) {
1496                         fr_strerror_printf("Duplicate tag %s for attribute %s",
1497                                    value, vp->name);
1498                         DEBUG("Duplicate tag %s for attribute %s\n",
1499                                    value, vp->name);
1500                         pairbasicfree(vp);
1501                         return NULL;
1502                 }
1503                 /* Colon found and attribute allows a tag */
1504                 if (value[1] == '*' && value[2] == ':') {
1505                        /* Wildcard tag for check items */
1506                        tag = TAG_ANY;
1507                        value += 3;
1508                 } else {
1509                        /* Real tag */
1510                        tag = strtol(value + 1, &tc, 0);
1511                        if (tc && *tc==':' && TAG_VALID_ZERO(tag))
1512                             value = tc + 1;
1513                        else tag = 0;
1514                 }
1515                 found_tag = 1;
1516         }
1517
1518         if (found_tag) {
1519           vp->flags.tag = tag;
1520         }
1521
1522         switch (vp->operator) {
1523         default:
1524                 break;
1525
1526                 /*
1527                  *      For =* and !* operators, the value is irrelevant
1528                  *      so we return now.
1529                  */
1530         case T_OP_CMP_TRUE:
1531         case T_OP_CMP_FALSE:
1532                 vp->vp_strvalue[0] = '\0';
1533                 vp->length = 0;
1534                 return vp;
1535                 break;
1536
1537                 /*
1538                  *      Regular expression comparison of integer attributes
1539                  *      does a STRING comparison of the names of their
1540                  *      integer attributes.
1541                  */
1542         case T_OP_REG_EQ:       /* =~ */
1543         case T_OP_REG_NE:       /* !~ */
1544                 if (!value) {
1545                         fr_strerror_printf("No regular expression found in %s",
1546                                            vp->name);
1547                         pairbasicfree(vp);
1548                         return NULL;
1549                 }
1550           
1551                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1552                 vp->length = strlen(vp->vp_strvalue);
1553                 /*
1554                  *      If anything goes wrong, this is a run-time error,
1555                  *      not a compile-time error.
1556                  */
1557                 return vp;
1558
1559         }
1560
1561         /*
1562          *      FIXME: if (strcasecmp(attribute, vp->name) != 0)
1563          *      then the user MAY have typed in the attribute name
1564          *      as Vendor-%d-Attr-%d, and the value MAY be octets.
1565          *
1566          *      We probably want to fix pairparsevalue to accept
1567          *      octets as values for any attribute.
1568          */
1569         if (value && (pairparsevalue(vp, value) == NULL)) {
1570                 pairbasicfree(vp);
1571                 return NULL;
1572         }
1573
1574         return vp;
1575 }
1576
1577
1578 /*
1579  *      [a-zA-Z0-9_-:]+
1580  */
1581 static const int valid_attr_name[256] = {
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, 0, 0, 0,
1584         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1585         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1586         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1587         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
1588         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1589         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1598 };
1599
1600 /*
1601  *      Read a valuepair from a buffer, and advance pointer.
1602  *      Sets *eol to T_EOL if end of line was encountered.
1603  */
1604 VALUE_PAIR *pairread(const char **ptr, FR_TOKEN *eol)
1605 {
1606         char            buf[64];
1607         char            attr[64];
1608         char            value[1024], *q;
1609         const char      *p;
1610         FR_TOKEN        token, t, xlat;
1611         VALUE_PAIR      *vp;
1612         size_t          len;
1613
1614         *eol = T_OP_INVALID;
1615
1616         p = *ptr;
1617         while ((*p == ' ') || (*p == '\t')) p++;
1618
1619         if (!*p) {
1620                 *eol = T_OP_INVALID;
1621                 fr_strerror_printf("No token read where we expected an attribute name");
1622                 return NULL;
1623         }
1624
1625         if (*p == '#') {
1626                 *eol = T_HASH;
1627                 fr_strerror_printf("Read a comment instead of a token");
1628                 return NULL;
1629         }
1630
1631         q = attr;
1632         for (len = 0; len < sizeof(attr); len++) {
1633                 if (valid_attr_name[(int)*p]) {
1634                         *q++ = *p++;
1635                         continue;
1636                 }
1637                 break;
1638         }
1639
1640         if (len == sizeof(attr)) {
1641                 *eol = T_OP_INVALID;
1642                 fr_strerror_printf("Attribute name is too long");
1643                 return NULL;
1644         }
1645
1646         /*
1647          *      We may have Foo-Bar:= stuff, so back up.
1648          */
1649         if ((len > 0) && (attr[len - 1] == ':')) {
1650                 p--;
1651                 len--;
1652         }
1653
1654         attr[len] = '\0';
1655         *ptr = p;
1656
1657         /* Now we should have an operator here. */
1658         token = gettoken(ptr, buf, sizeof(buf));
1659         if (token < T_EQSTART || token > T_EQEND) {
1660                 fr_strerror_printf("expecting operator");
1661                 return NULL;
1662         }
1663
1664         /* Read value.  Note that empty string values are allowed */
1665         xlat = gettoken(ptr, value, sizeof(value));
1666         if (xlat == T_EOL) {
1667                 fr_strerror_printf("failed to get value");
1668                 return NULL;
1669         }
1670
1671         /*
1672          *      Peek at the next token. Must be T_EOL, T_COMMA, or T_HASH
1673          */
1674         p = *ptr;
1675         t = gettoken(&p, buf, sizeof(buf));
1676         if (t != T_EOL && t != T_COMMA && t != T_HASH) {
1677                 fr_strerror_printf("Expected end of line or comma");
1678                 return NULL;
1679         }
1680
1681         *eol = t;
1682         if (t == T_COMMA) {
1683                 *ptr = p;
1684         }
1685
1686         vp = NULL;
1687         switch (xlat) {
1688                 /*
1689                  *      Make the full pair now.
1690                  */
1691         default:
1692                 vp = pairmake(attr, value, token);
1693                 break;
1694
1695                 /*
1696                  *      Perhaps do xlat's
1697                  */
1698         case T_DOUBLE_QUOTED_STRING:
1699                 p = strchr(value, '%');
1700                 if (p && (p[1] == '{')) {
1701                         if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1702                                 fr_strerror_printf("Value too long");
1703                                 return NULL;
1704                         }
1705                         vp = pairmake(attr, NULL, token);
1706                         if (!vp) {
1707                                 *eol = T_OP_INVALID;
1708                                 return NULL;
1709                         }
1710
1711                         strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1712                         vp->flags.do_xlat = 1;
1713                         vp->length = 0;
1714                 } else {
1715                         /*
1716                          *      Parse && escape it, as defined by the
1717                          *      data type.
1718                          */
1719                         vp = pairmake(attr, value, token);
1720                         if (!vp) {
1721                                 *eol = T_OP_INVALID;
1722                                 return NULL;
1723                         }
1724                 }
1725                 break;
1726
1727         case T_SINGLE_QUOTED_STRING:
1728                 vp = pairmake(attr, NULL, token);
1729                 if (!vp) {
1730                         *eol = T_OP_INVALID;
1731                         return NULL;
1732                 }
1733
1734                 /*
1735                  *      String and octet types get copied verbatim.
1736                  */
1737                 if ((vp->type == PW_TYPE_STRING) ||
1738                     (vp->type == PW_TYPE_OCTETS)) {
1739                         strlcpy(vp->vp_strvalue, value,
1740                                 sizeof(vp->vp_strvalue));
1741                         vp->length = strlen(vp->vp_strvalue);
1742
1743                         /*
1744                          *      Everything else gets parsed: it's
1745                          *      DATA, not a string!
1746                          */
1747                 } else if (!pairparsevalue(vp, value)) {
1748                         pairfree(&vp);
1749                         *eol = T_OP_INVALID;
1750                         return NULL;
1751                 }
1752                 break;
1753
1754                 /*
1755                  *      Mark the pair to be allocated later.
1756                  */
1757         case T_BACK_QUOTED_STRING:
1758                 if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1759                         fr_strerror_printf("Value too long");
1760                         return NULL;
1761                 }
1762
1763                 vp = pairmake(attr, NULL, token);
1764                 if (!vp) {
1765                         *eol = T_OP_INVALID;
1766                         return NULL;
1767                 }
1768
1769                 vp->flags.do_xlat = 1;
1770                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1771                 vp->length = 0;
1772                 break;
1773         }
1774
1775         /*
1776          *      If we didn't make a pair, return an error.
1777          */
1778         if (!vp) {
1779                 *eol = T_OP_INVALID;
1780                 return NULL;
1781         }
1782
1783         return vp;
1784 }
1785
1786 /*
1787  *      Read one line of attribute/value pairs. This might contain
1788  *      multiple pairs seperated by comma's.
1789  */
1790 FR_TOKEN userparse(const char *buffer, VALUE_PAIR **first_pair)
1791 {
1792         VALUE_PAIR      *vp;
1793         const char      *p;
1794         FR_TOKEN        last_token = T_OP_INVALID;
1795         FR_TOKEN        previous_token;
1796
1797         /*
1798          *      We allow an empty line.
1799          */
1800         if (buffer[0] == 0)
1801                 return T_EOL;
1802
1803         p = buffer;
1804         do {
1805                 previous_token = last_token;
1806                 if ((vp = pairread(&p, &last_token)) == NULL) {
1807                         return last_token;
1808                 }
1809                 pairadd(first_pair, vp);
1810         } while (*p && (last_token == T_COMMA));
1811
1812         /*
1813          *      Don't tell the caller that there was a comment.
1814          */
1815         if (last_token == T_HASH) {
1816                 return previous_token;
1817         }
1818
1819         /*
1820          *      And return the last token which we read.
1821          */
1822         return last_token;
1823 }
1824
1825 /*
1826  *      Read valuepairs from the fp up to End-Of-File.
1827  *
1828  *      Hmm... this function is only used by radclient..
1829  */
1830 VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix)
1831 {
1832         char buf[8192];
1833         FR_TOKEN last_token = T_EOL;
1834         VALUE_PAIR *vp;
1835         VALUE_PAIR *list;
1836         int error = 0;
1837
1838         list = NULL;
1839
1840         while (!error && fgets(buf, sizeof(buf), fp) != NULL) {
1841                 /*
1842                  *      If we get a '\n' by itself, we assume that's
1843                  *      the end of that VP
1844                  */
1845                 if ((buf[0] == '\n') && (list)) {
1846                         return list;
1847                 }
1848                 if ((buf[0] == '\n') && (!list)) {
1849                         continue;
1850                 }
1851
1852                 /*
1853                  *      Comments get ignored
1854                  */
1855                 if (buf[0] == '#') continue;
1856
1857                 /*
1858                  *      Read all of the attributes on the current line.
1859                  */
1860                 vp = NULL;
1861                 last_token = userparse(buf, &vp);
1862                 if (!vp) {
1863                         if (last_token != T_EOL) {
1864                                 fr_perror("%s", errprefix);
1865                                 error = 1;
1866                                 break;
1867                         }
1868                         break;
1869                 }
1870
1871                 pairadd(&list, vp);
1872                 buf[0] = '\0';
1873         }
1874
1875         if (error) pairfree(&list);
1876
1877         *pfiledone = 1;
1878
1879         return error ? NULL: list;
1880 }
1881
1882
1883
1884 /*
1885  *      Compare two pairs, using the operator from "one".
1886  *
1887  *      i.e. given two attributes, it does:
1888  *
1889  *      (two->data) (one->operator) (one->data)
1890  *
1891  *      e.g. "foo" != "bar"
1892  *
1893  *      Returns true (comparison is true), or false (comparison is not true);
1894  *
1895  *      FIXME: Ignores tags!
1896  */
1897 int paircmp(VALUE_PAIR *one, VALUE_PAIR *two)
1898 {
1899         int compare;
1900
1901         switch (one->operator) {
1902         case T_OP_CMP_TRUE:
1903                 return (two != NULL);
1904
1905         case T_OP_CMP_FALSE:
1906                 return (two == NULL);
1907
1908                 /*
1909                  *      One is a regex, compile it, print two to a string,
1910                  *      and then do string comparisons.
1911                  */
1912         case T_OP_REG_EQ:
1913         case T_OP_REG_NE:
1914 #ifndef HAVE_REGEX_H
1915                 return -1;
1916 #else
1917                 {
1918                         regex_t reg;
1919                         char buffer[MAX_STRING_LEN * 4 + 1];
1920
1921                         compare = regcomp(&reg, one->vp_strvalue,
1922                                           REG_EXTENDED);
1923                         if (compare != 0) {
1924                                 regerror(compare, &reg, buffer, sizeof(buffer));
1925                                 fr_strerror_printf("Illegal regular expression in attribute: %s: %s",
1926                                            one->name, buffer);
1927                                 return -1;
1928                         }
1929
1930                         vp_prints_value(buffer, sizeof(buffer), two, 0);
1931
1932                         /*
1933                          *      Don't care about substring matches,
1934                          *      oh well...
1935                          */
1936                         compare = regexec(&reg, buffer, 0, NULL, 0);
1937
1938                         regfree(&reg);
1939                         if (one->operator == T_OP_REG_EQ) return (compare == 0);
1940                         return (compare != 0);
1941                 }
1942 #endif
1943
1944         default:                /* we're OK */
1945                 break;
1946         }
1947
1948         /*
1949          *      After doing the previous check for special comparisons,
1950          *      do the per-type comparison here.
1951          */
1952         switch (one->type) {
1953         case PW_TYPE_ABINARY:
1954         case PW_TYPE_OCTETS:
1955         {
1956                 size_t length;
1957
1958                 if (one->length < two->length) {
1959                         length = one->length;
1960                 } else {
1961                         length = two->length;
1962                 }
1963
1964                 if (length) {
1965                         compare = memcmp(two->vp_octets, one->vp_octets,
1966                                          length);
1967                         if (compare != 0) break;
1968                 }
1969
1970                 /*
1971                  *      Contents are the same.  The return code
1972                  *      is therefore the difference in lengths.
1973                  *
1974                  *      i.e. "0x00" is smaller than "0x0000"
1975                  */
1976                 compare = two->length - one->length;
1977         }
1978                 break;
1979
1980         case PW_TYPE_STRING:
1981                 compare = strcmp(two->vp_strvalue, one->vp_strvalue);
1982                 break;
1983
1984         case PW_TYPE_BYTE:
1985         case PW_TYPE_SHORT:
1986         case PW_TYPE_INTEGER:
1987         case PW_TYPE_DATE:
1988                 compare = two->vp_integer - one->vp_integer;
1989                 break;
1990
1991         case PW_TYPE_IPADDR:
1992                 compare = ntohl(two->vp_ipaddr) - ntohl(one->vp_ipaddr);
1993                 break;
1994
1995         case PW_TYPE_IPV6ADDR:
1996                 compare = memcmp(&two->vp_ipv6addr, &one->vp_ipv6addr,
1997                                  sizeof(two->vp_ipv6addr));
1998                 break;
1999
2000         case PW_TYPE_IPV6PREFIX:
2001                 compare = memcmp(&two->vp_ipv6prefix, &one->vp_ipv6prefix,
2002                                  sizeof(two->vp_ipv6prefix));
2003                 break;
2004
2005         case PW_TYPE_IFID:
2006                 compare = memcmp(&two->vp_ifid, &one->vp_ifid,
2007                                  sizeof(two->vp_ifid));
2008                 break;
2009
2010         default:
2011                 return 0;       /* unknown type */
2012         }
2013
2014         /*
2015          *      Now do the operator comparison.
2016          */
2017         switch (one->operator) {
2018         case T_OP_CMP_EQ:
2019                 return (compare == 0);
2020
2021         case T_OP_NE:
2022                 return (compare != 0);
2023
2024         case T_OP_LT:
2025                 return (compare < 0);
2026
2027         case T_OP_GT:
2028                 return (compare > 0);
2029
2030         case T_OP_LE:
2031                 return (compare <= 0);
2032
2033         case T_OP_GE:
2034                 return (compare >= 0);
2035
2036         default:
2037                 return 0;
2038         }
2039
2040         return 0;
2041 }