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