strcpy to a NULL pointer is bad.
[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".
622                  */
623                 if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC)) {
624                         /*
625                          *      It's a VSA: move it over.
626                          */
627                         if (i->vendor != 0) goto move;
628
629                         /*
630                          *      It's Vendor-Specific: move it over.
631                          */
632                         if (i->attribute == attr) goto move;
633
634                         /*
635                          *      It's not a VSA: ignore it.
636                          */
637                         iprev = i;
638                         continue;
639                 }
640
641                 /*
642                  *      If it isn't an exact match, ignore it.
643                  */
644                 if (!((i->vendor == vendor) && (i->attribute == attr))) {
645                         iprev = i;
646                         continue;
647                 }
648
649         move:
650                 /*
651                  *      Remove the attribute from the "from" list.
652                  */
653                 if (iprev)
654                         iprev->next = next;
655                 else
656                         *from = next;
657
658                 /*
659                  *      Add the attribute to the "to" list.
660                  */
661                 if (to_tail)
662                         to_tail->next = i;
663                 else
664                         *to = i;
665                 to_tail = i;
666                 i->next = NULL;
667         }
668 }
669
670
671 /*
672  *      Sort of strtok/strsep function.
673  */
674 static char *mystrtok(char **ptr, const char *sep)
675 {
676         char    *res;
677
678         if (**ptr == 0)
679                 return NULL;
680         while (**ptr && strchr(sep, **ptr))
681                 (*ptr)++;
682         if (**ptr == 0)
683                 return NULL;
684         res = *ptr;
685         while (**ptr && strchr(sep, **ptr) == NULL)
686                 (*ptr)++;
687         if (**ptr != 0)
688                 *(*ptr)++ = 0;
689         return res;
690 }
691
692 /*
693  *      Turn printable string into time_t
694  *      Returns -1 on error, 0 on OK.
695  */
696 static int gettime(const char *valstr, time_t *date)
697 {
698         int             i;
699         time_t          t;
700         struct tm       *tm, s_tm;
701         char            buf[64];
702         char            *p;
703         char            *f[4];
704         char            *tail = '\0';
705
706         /*
707          * Test for unix timestamp date
708          */
709         *date = strtoul(valstr, &tail, 10);
710         if (*tail == '\0') {
711                 return 0;
712         }
713
714         tm = &s_tm;
715         memset(tm, 0, sizeof(*tm));
716         tm->tm_isdst = -1;      /* don't know, and don't care about DST */
717
718         strlcpy(buf, valstr, sizeof(buf));
719
720         p = buf;
721         f[0] = mystrtok(&p, " \t");
722         f[1] = mystrtok(&p, " \t");
723         f[2] = mystrtok(&p, " \t");
724         f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
725         if (!f[0] || !f[1] || !f[2]) return -1;
726
727         /*
728          *      The time has a colon, where nothing else does.
729          *      So if we find it, bubble it to the back of the list.
730          */
731         if (f[3]) {
732                 for (i = 0; i < 3; i++) {
733                         if (strchr(f[i], ':')) {
734                                 p = f[3];
735                                 f[3] = f[i];
736                                 f[i] = p;
737                                 break;
738                         }
739                 }
740         }
741
742         /*
743          *  The month is text, which allows us to find it easily.
744          */
745         tm->tm_mon = 12;
746         for (i = 0; i < 3; i++) {
747                 if (isalpha( (int) *f[i])) {
748                         /*
749                          *  Bubble the month to the front of the list
750                          */
751                         p = f[0];
752                         f[0] = f[i];
753                         f[i] = p;
754
755                         for (i = 0; i < 12; i++) {
756                                 if (strncasecmp(months[i], f[0], 3) == 0) {
757                                         tm->tm_mon = i;
758                                         break;
759                                 }
760                         }
761                 }
762         }
763
764         /* month not found? */
765         if (tm->tm_mon == 12) return -1;
766
767         /*
768          *  The year may be in f[1], or in f[2]
769          */
770         tm->tm_year = atoi(f[1]);
771         tm->tm_mday = atoi(f[2]);
772
773         if (tm->tm_year >= 1900) {
774                 tm->tm_year -= 1900;
775
776         } else {
777                 /*
778                  *  We can't use 2-digit years any more, they make it
779                  *  impossible to tell what's the day, and what's the year.
780                  */
781                 if (tm->tm_mday < 1900) return -1;
782
783                 /*
784                  *  Swap the year and the day.
785                  */
786                 i = tm->tm_year;
787                 tm->tm_year = tm->tm_mday - 1900;
788                 tm->tm_mday = i;
789         }
790
791         /*
792          *  If the day is out of range, die.
793          */
794         if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
795                 return -1;
796         }
797
798         /*
799          *      There may be %H:%M:%S.  Parse it in a hacky way.
800          */
801         if (f[3]) {
802                 f[0] = f[3];    /* HH */
803                 f[1] = strchr(f[0], ':'); /* find : separator */
804                 if (!f[1]) return -1;
805
806                 *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
807
808                 f[2] = strchr(f[1], ':'); /* find : separator */
809                 if (f[2]) {
810                   *(f[2]++) = '\0';     /* nuke it, and point to SS */
811                   tm->tm_sec = atoi(f[2]);
812                 }                       /* else leave it as zero */
813
814                 tm->tm_hour = atoi(f[0]);
815                 tm->tm_min = atoi(f[1]);
816         }
817
818         /*
819          *  Returns -1 on error.
820          */
821         t = mktime(tm);
822         if (t == (time_t) -1) return -1;
823
824         *date = t;
825
826         return 0;
827 }
828
829 static const char *hextab = "0123456789abcdef";
830
831 /*
832  *  Parse a string value into a given VALUE_PAIR
833  *
834  *  FIXME: we probably want to fix this function to accept
835  *  octets as values for any type of attribute.  We should then
836  *  double-check the parsed value, to be sure it's legal for that
837  *  type (length, etc.)
838  */
839 static uint32_t getint(const char *value, char **end)
840 {
841         if ((value[0] == '0') && (value[1] == 'x')) {
842                 return strtoul(value, end, 16);
843         }
844
845         return strtoul(value, end, 10);
846 }
847
848 static int check_for_whitespace(const char *value)
849 {
850         while (*value) {
851                 if (!isspace((int) *value)) return 0;
852
853                 value++;
854         }
855
856         return 1;
857 }
858
859
860 VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
861 {
862         char            *p, *s=0;
863         const char      *cp, *cs;
864         int             x;
865         size_t          length;
866         DICT_VALUE      *dval;
867
868         if (!value) return NULL;
869
870         /*
871          *      Even for integers, dates and ip addresses we
872          *      keep the original string in vp->vp_strvalue.
873          */
874         if (vp->type != PW_TYPE_TLV) {
875                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
876                 vp->length = strlen(vp->vp_strvalue);
877         }
878
879         switch(vp->type) {
880                 case PW_TYPE_STRING:
881                         /*
882                          *      Do escaping here
883                          */
884                         p = vp->vp_strvalue;
885                         cp = value;
886                         length = 0;
887
888                         while (*cp && (length < (sizeof(vp->vp_strvalue) - 1))) {
889                                 char c = *cp++;
890
891                                 if (c == '\\') {
892                                         switch (*cp) {
893                                         case 'r':
894                                                 c = '\r';
895                                                 cp++;
896                                                 break;
897                                         case 'n':
898                                                 c = '\n';
899                                                 cp++;
900                                                 break;
901                                         case 't':
902                                                 c = '\t';
903                                                 cp++;
904                                                 break;
905                                         case '"':
906                                                 c = '"';
907                                                 cp++;
908                                                 break;
909                                         case '\'':
910                                                 c = '\'';
911                                                 cp++;
912                                                 break;
913                                         case '`':
914                                                 c = '`';
915                                                 cp++;
916                                                 break;
917                                         case '\0':
918                                                 c = '\\'; /* no cp++ */
919                                                 break;
920                                         default:
921                                                 if ((cp[0] >= '0') &&
922                                                     (cp[0] <= '9') &&
923                                                     (cp[1] >= '0') &&
924                                                     (cp[1] <= '9') &&
925                                                     (cp[2] >= '0') &&
926                                                     (cp[2] <= '9') &&
927                                                     (sscanf(cp, "%3o", &x) == 1)) {
928                                                         c = x;
929                                                         cp += 3;
930                                                 } /* else just do '\\' */
931                                         }
932                                 }
933                                 *p++ = c;
934                                 length++;
935                         }
936                         vp->vp_strvalue[length] = '\0';
937                         vp->length = length;
938                         break;
939
940                 case PW_TYPE_IPADDR:
941                         /*
942                          *      It's a comparison, not a real IP.
943                          */
944                         if ((vp->operator == T_OP_REG_EQ) ||
945                             (vp->operator == T_OP_REG_NE)) {
946                                 break;
947                         }
948
949                         /*
950                          *      FIXME: complain if hostname
951                          *      cannot be resolved, or resolve later!
952                          */
953                         s = NULL;
954                         if ((p = strrchr(value, '+')) != NULL && !p[1]) {
955                                 cs = s = strdup(value);
956                                 if (!s) return NULL;
957                                 p = strrchr(s, '+');
958                                 *p = 0;
959                                 vp->flags.addport = 1;
960                         } else {
961                                 p = NULL;
962                                 cs = value;
963                         }
964
965                         {
966                                 fr_ipaddr_t ipaddr;
967
968                                 if (ip_hton(cs, AF_INET, &ipaddr) < 0) {
969                                         free(s);
970                                         fr_strerror_printf("Failed to find IP address for %s", cs);
971                                         return NULL;
972                                 }
973
974                                 vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
975                         }
976                         free(s);
977                         vp->length = 4;
978                         break;
979
980                 case PW_TYPE_BYTE:
981                         vp->length = 1;
982
983                         /*
984                          *      Note that ALL integers are unsigned!
985                          */
986                         vp->vp_integer = getint(value, &p);
987                         if (!*p) {
988                                 if (vp->vp_integer > 255) {
989                                         fr_strerror_printf("Byte value \"%s\" is larger than 255", value);
990                                         return NULL;
991                                 }
992                                 break;
993                         }
994                         if (check_for_whitespace(p)) break;
995                         goto check_for_value;
996
997                 case PW_TYPE_SHORT:
998                         /*
999                          *      Note that ALL integers are unsigned!
1000                          */
1001                         vp->vp_integer = getint(value, &p);
1002                         vp->length = 2;
1003                         if (!*p) {
1004                                 if (vp->vp_integer > 65535) {
1005                                         fr_strerror_printf("Byte value \"%s\" is larger than 65535", value);
1006                                         return NULL;
1007                                 }
1008                                 break;
1009                         }
1010                         if (check_for_whitespace(p)) break;
1011                         goto check_for_value;
1012
1013                 case PW_TYPE_INTEGER:
1014                         /*
1015                          *      Note that ALL integers are unsigned!
1016                          */
1017                         vp->vp_integer = getint(value, &p);
1018                         vp->length = 4;
1019                         if (!*p) break;
1020                         if (check_for_whitespace(p)) break;
1021
1022         check_for_value:
1023                         /*
1024                          *      Look for the named value for the given
1025                          *      attribute.
1026                          */
1027                         if ((dval = dict_valbyname(vp->attribute, vp->vendor, value)) == NULL) {
1028                                 fr_strerror_printf("Unknown value %s for attribute %s",
1029                                            value, vp->name);
1030                                 return NULL;
1031                         }
1032                         vp->vp_integer = dval->value;
1033                         break;
1034
1035                 case PW_TYPE_DATE:
1036                         {
1037                                 /*
1038                                  *      time_t may be 64 bits, whule vp_date
1039                                  *      MUST be 32-bits.  We need an
1040                                  *      intermediary variable to handle
1041                                  *      the conversions.
1042                                  */
1043                                 time_t date;
1044
1045                                 if (gettime(value, &date) < 0) {
1046                                         fr_strerror_printf("failed to parse time string "
1047                                                    "\"%s\"", value);
1048                                         return NULL;
1049                                 }
1050
1051                                 vp->vp_date = date;
1052                         }
1053                         vp->length = 4;
1054                         break;
1055
1056                 case PW_TYPE_ABINARY:
1057 #ifdef ASCEND_BINARY
1058                         if (strncasecmp(value, "0x", 2) == 0) {
1059                                 vp->type = PW_TYPE_OCTETS;
1060                                 goto do_octets;
1061                         }
1062
1063                         if (ascend_parse_filter(vp) < 0 ) {
1064                                 fr_strerror_printf("failed to parse Ascend binary attribute: %s",
1065                                            fr_strerror());
1066                                 return NULL;
1067                         }
1068                         break;
1069
1070                         /*
1071                          *      If Ascend binary is NOT defined,
1072                          *      then fall through to raw octets, so that
1073                          *      the user can at least make them by hand...
1074                          */
1075         do_octets:
1076 #endif
1077                         /* raw octets: 0x01020304... */
1078                 case PW_TYPE_OCTETS:
1079                         if (strncasecmp(value, "0x", 2) == 0) {
1080                                 uint8_t *us;
1081                                 cp = value + 2;
1082                                 us = vp->vp_octets;
1083                                 vp->length = 0;
1084
1085
1086                                 /*
1087                                  *      There is only one character,
1088                                  *      die.
1089                                  */
1090                                 if ((strlen(cp) & 0x01) != 0) {
1091                                         fr_strerror_printf("Hex string is not an even length string.");
1092                                         return NULL;
1093                                 }
1094
1095
1096                                 while (*cp &&
1097                                        (vp->length < MAX_STRING_LEN)) {
1098                                         unsigned int tmp;
1099
1100                                         if (sscanf(cp, "%02x", &tmp) != 1) {
1101                                                 fr_strerror_printf("Non-hex characters at %c%c", cp[0], cp[1]);
1102                                                 return NULL;
1103                                         }
1104
1105                                         cp += 2;
1106                                         *(us++) = tmp;
1107                                         vp->length++;
1108                                 }
1109                         }
1110                         break;
1111
1112                 case PW_TYPE_IFID:
1113                         if (ifid_aton(value, (void *) &vp->vp_ifid) == NULL) {
1114                                 fr_strerror_printf("failed to parse interface-id "
1115                                            "string \"%s\"", value);
1116                                 return NULL;
1117                         }
1118                         vp->length = 8;
1119                         break;
1120
1121                 case PW_TYPE_IPV6ADDR:
1122                         {
1123                                 fr_ipaddr_t ipaddr;
1124
1125                                 if (ip_hton(value, AF_INET6, &ipaddr) < 0) {
1126                                         char buffer[1024];
1127
1128                                         strlcpy(buffer, fr_strerror(), sizeof(buffer));
1129
1130                                         fr_strerror_printf("failed to parse IPv6 address "
1131                                                            "string \"%s\": %s", value, buffer);
1132                                         return NULL;
1133                                 }
1134                                 vp->vp_ipv6addr = ipaddr.ipaddr.ip6addr;
1135                                 vp->length = 16; /* length of IPv6 address */
1136                         }
1137                         break;
1138
1139                 case PW_TYPE_IPV6PREFIX:
1140                         p = strchr(value, '/');
1141                         if (!p || ((p - value) >= 256)) {
1142                                 fr_strerror_printf("invalid IPv6 prefix "
1143                                            "string \"%s\"", value);
1144                                 return NULL;
1145                         } else {
1146                                 unsigned int prefix;
1147                                 char buffer[256], *eptr;
1148
1149                                 memcpy(buffer, value, p - value);
1150                                 buffer[p - value] = '\0';
1151
1152                                 if (inet_pton(AF_INET6, buffer, vp->vp_octets + 2) <= 0) {
1153                                         fr_strerror_printf("failed to parse IPv6 address "
1154                                                    "string \"%s\"", value);
1155                                         return NULL;
1156                                 }
1157
1158                                 prefix = strtoul(p + 1, &eptr, 10);
1159                                 if ((prefix > 128) || *eptr) {
1160                                         fr_strerror_printf("failed to parse IPv6 address "
1161                                                    "string \"%s\"", value);
1162                                         return NULL;
1163                                 }
1164                                 vp->vp_octets[1] = prefix;
1165                         }
1166                         vp->vp_octets[0] = '\0';
1167                         vp->length = 16 + 2;
1168                         break;
1169
1170                 case PW_TYPE_ETHERNET:
1171                         {
1172                                 const char *c1, *c2;
1173
1174                                 length = 0;
1175                                 cp = value;
1176                                 while (*cp) {
1177                                         if (cp[1] == ':') {
1178                                                 c1 = hextab;
1179                                                 c2 = memchr(hextab, tolower((int) cp[0]), 16);
1180                                                 cp += 2;
1181                                         } else if ((cp[1] != '\0') &&
1182                                                    ((cp[2] == ':') ||
1183                                                     (cp[2] == '\0'))) {
1184                                                    c1 = memchr(hextab, tolower((int) cp[0]), 16);
1185                                                    c2 = memchr(hextab, tolower((int) cp[1]), 16);
1186                                                    cp += 2;
1187                                                    if (*cp == ':') cp++;
1188                                         } else {
1189                                                 c1 = c2 = NULL;
1190                                         }
1191                                         if (!c1 || !c2 || (length >= sizeof(vp->vp_ether))) {
1192                                                 fr_strerror_printf("failed to parse Ethernet address \"%s\"", value);
1193                                                 return NULL;
1194                                         }
1195                                         vp->vp_ether[length] = ((c1-hextab)<<4) + (c2-hextab);
1196                                         length++;
1197                                 }
1198                         }
1199                         vp->length = 6;
1200                         break;
1201
1202                 case PW_TYPE_COMBO_IP:
1203                         if (inet_pton(AF_INET6, value, vp->vp_strvalue) > 0) {
1204                                 vp->type = PW_TYPE_IPV6ADDR;
1205                                 vp->length = 16; /* length of IPv6 address */
1206                                 vp->vp_strvalue[vp->length] = '\0';
1207
1208                         } else {
1209                                 fr_ipaddr_t ipaddr;
1210
1211                                 if (ip_hton(value, AF_INET, &ipaddr) < 0) {
1212                                         fr_strerror_printf("Failed to find IPv4 address for %s", value);
1213                                         return NULL;
1214                                 }
1215
1216                                 vp->type = PW_TYPE_IPADDR;
1217                                 vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
1218                                 vp->length = 4;
1219                         }
1220                         break;
1221
1222                 case PW_TYPE_SIGNED: /* Damned code for 1 WiMAX attribute */
1223                         vp->vp_signed = (int32_t) strtol(value, &p, 10);
1224                         vp->length = 4;
1225                         break;
1226
1227                 case PW_TYPE_TLV: /* don't use this! */
1228                         if (strncasecmp(value, "0x", 2) != 0) {
1229                                 fr_strerror_printf("Invalid TLV specification");
1230                                 return NULL;
1231                         }
1232                         length = strlen(value + 2) / 2;
1233                         if (vp->length < length) {
1234                                 free(vp->vp_tlv);
1235                                 vp->vp_tlv = NULL;
1236                         }
1237                         vp->vp_tlv = malloc(length);
1238                         if (!vp->vp_tlv) {
1239                                 fr_strerror_printf("No memory");
1240                                 return NULL;
1241                         }
1242                         if (fr_hex2bin(value + 2, vp->vp_tlv,
1243                                        length) != length) {
1244                                 fr_strerror_printf("Invalid hex data in TLV");
1245                                 return NULL;
1246                         }
1247                         vp->length = length;
1248                         break;
1249
1250                         /*
1251                          *  Anything else.
1252                          */
1253                 default:
1254                         fr_strerror_printf("unknown attribute type %d", vp->type);
1255                         return NULL;
1256         }
1257
1258         return vp;
1259 }
1260
1261 /*
1262  *      Create a VALUE_PAIR from an ASCII attribute and value,
1263  *      where the attribute name is in the form:
1264  *
1265  *      Attr-%d
1266  *      Vendor-%d-Attr-%d
1267  *      VendorName-Attr-%d
1268  */
1269 static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
1270                                 int operator)
1271 {
1272         int             attr, vendor;
1273         size_t          size;
1274         const char      *p = attribute;
1275         char            *q;
1276         VALUE_PAIR      *vp;
1277
1278         /*
1279          *      Unknown attributes MUST be of type 'octets'
1280          */
1281         if (value && (strncasecmp(value, "0x", 2) != 0)) {
1282                 fr_strerror_printf("Invalid octet string \"%s\" for attribute name \"%s\"", value, attribute);
1283                 return NULL;
1284         }
1285
1286         vendor = 0;
1287
1288         /*
1289          *      Pull off vendor prefix first.
1290          */
1291         if (strncasecmp(p, "Attr-", 5) != 0) {
1292                 if (strncasecmp(p, "Vendor-", 7) == 0) {
1293                         vendor = (int) strtol(p + 7, &q, 10);
1294                         if ((vendor == 0) || (vendor > FR_MAX_VENDOR)) {
1295                                 fr_strerror_printf("Invalid vendor value in attribute name \"%s\"", attribute);
1296                                 return NULL;
1297                         }
1298
1299                         p = q;
1300
1301                 } else {        /* must be vendor name */
1302                         char buffer[256];
1303
1304                         q = strchr(p, '-');
1305
1306                         if (!q) {
1307                                 fr_strerror_printf("Invalid vendor name in attribute name \"%s\"", attribute);
1308                                 return NULL;
1309                         }
1310
1311                         if ((size_t) (q - p) >= sizeof(buffer)) {
1312                                 fr_strerror_printf("Vendor name too long in attribute name \"%s\"", attribute);
1313                                 return NULL;
1314                         }
1315
1316                         memcpy(buffer, p, (q - p));
1317                         buffer[q - p] = '\0';
1318
1319                         vendor = dict_vendorbyname(buffer);
1320                         if (!vendor) {
1321                                 fr_strerror_printf("Unknown vendor name in attribute name \"%s\"", attribute);
1322                                 return NULL;
1323                         }
1324
1325                         p = q;
1326                 }
1327
1328                 if (*p != '-') {
1329                         fr_strerror_printf("Invalid text following vendor definition in attribute name \"%s\"", attribute);
1330                         return NULL;
1331                 }
1332                 p++;
1333         }
1334
1335         /*
1336          *      Attr-%d
1337          */
1338         if (strncasecmp(p, "Attr-", 5) != 0) {
1339                 fr_strerror_printf("Invalid format in attribute name \"%s\"", attribute);
1340                 return NULL;
1341         }
1342
1343         attr = strtol(p + 5, &q, 10);
1344
1345         /*
1346          *      Invalid, or trailing text after number.
1347          */
1348         if ((attr == 0) || *q) {
1349                 fr_strerror_printf("Invalid value in attribute name \"%s\"", attribute);
1350                 return NULL;
1351         }
1352
1353         /*
1354          *      Double-check the size of attr.
1355          */
1356         if (vendor) {
1357                 DICT_VENDOR *dv = dict_vendorbyvalue(vendor);
1358
1359                 if (!dv) {
1360                         if (attr > 255) {
1361                         attr_error:
1362                                 fr_strerror_printf("Invalid attribute number in attribute name \"%s\"", attribute);
1363                                 return NULL;
1364                         }
1365
1366                 } else switch (dv->type) {
1367                         case 1:
1368                                 if (attr > 255) goto attr_error;
1369                                 break;
1370
1371                         case 2:
1372                                 if (attr > 65535) goto attr_error;
1373                                 break;
1374
1375                         case 4:
1376                                 break;
1377
1378                         default:
1379                                 fr_strerror_printf("Internal sanity check failed");
1380                                 return NULL;
1381                 }
1382         }
1383
1384         /*
1385          *      We've now parsed the attribute properly, Let's create
1386          *      it.  This next stop also looks the attribute up in the
1387          *      dictionary, and creates the appropriate type for it.
1388          */
1389         if ((vp = paircreate(attr, vendor, PW_TYPE_OCTETS)) == NULL) {
1390                 fr_strerror_printf("out of memory");
1391                 return NULL;
1392         }
1393
1394         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1395         if (!value) return vp;
1396
1397         size = strlen(value + 2);
1398
1399         /*
1400          *      We may be reading something like Attr-5.  i.e.
1401          *      who-ever wrote the text didn't understand it, but we
1402          *      do.
1403          */
1404         switch (vp->type) {
1405         default:
1406                 if (size == (vp->length * 2)) break;
1407                 vp->type = PW_TYPE_OCTETS;
1408                 /* FALL-THROUGH */
1409                 
1410         case PW_TYPE_STRING:
1411         case PW_TYPE_OCTETS:
1412         case PW_TYPE_ABINARY:
1413                 vp->length = size >> 1;
1414                 break;
1415         }
1416
1417         if (fr_hex2bin(value + 2, vp->vp_octets, size) != vp->length) {
1418                 fr_strerror_printf("Invalid hex string");
1419                 free(vp);
1420                 return NULL;
1421         }
1422
1423         /*
1424          *      Move contents around based on type.  This is
1425          *      to work around the historical use of "lvalue".
1426          */
1427         switch (vp->type) {
1428         case PW_TYPE_DATE:
1429         case PW_TYPE_IPADDR:
1430         case PW_TYPE_INTEGER:
1431                 memcpy(&vp->lvalue, vp->vp_octets, sizeof(vp->lvalue));
1432                 vp->vp_strvalue[0] = '\0';
1433                 break;
1434                 
1435         default:
1436                 break;
1437         }
1438        
1439         return vp;
1440 }
1441
1442
1443 /*
1444  *      Create a VALUE_PAIR from an ASCII attribute and value.
1445  */
1446 VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
1447 {
1448         DICT_ATTR       *da;
1449         VALUE_PAIR      *vp;
1450         char            *tc, *ts;
1451         signed char     tag;
1452         int             found_tag;
1453         char            buffer[64];
1454         const char      *attrname = attribute;
1455
1456         /*
1457          *    Check for tags in 'Attribute:Tag' format.
1458          */
1459         found_tag = 0;
1460         tag = 0;
1461
1462         ts = strrchr(attribute, ':');
1463         if (ts && !ts[1]) {
1464                 fr_strerror_printf("Invalid tag for attribute %s", attribute);
1465                 return NULL;
1466         }
1467
1468         if (ts && ts[1]) {
1469                 strlcpy(buffer, attribute, sizeof(buffer));
1470                 attrname = buffer;
1471                 ts = strrchr(attrname, ':');
1472
1473                  /* Colon found with something behind it */
1474                  if (ts[1] == '*' && ts[2] == 0) {
1475                          /* Wildcard tag for check items */
1476                          tag = TAG_ANY;
1477                          *ts = 0;
1478                  } else if ((ts[1] >= '0') && (ts[1] <= '9')) {
1479                          /* It's not a wild card tag */
1480                          tag = strtol(ts + 1, &tc, 0);
1481                          if (tc && !*tc && TAG_VALID_ZERO(tag))
1482                                  *ts = 0;
1483                          else tag = 0;
1484                  } else {
1485                          fr_strerror_printf("Invalid tag for attribute %s", attribute);
1486                          return NULL;
1487                  }
1488                  found_tag = 1;
1489         }
1490
1491         /*
1492          *      It's not found in the dictionary, so we use
1493          *      another method to create the attribute.
1494          */
1495         if ((da = dict_attrbyname(attrname)) == NULL) {
1496                 return pairmake_any(attrname, value, operator);
1497         }
1498
1499         if ((vp = pairalloc(da)) == NULL) {
1500                 fr_strerror_printf("out of memory");
1501                 return NULL;
1502         }
1503         vp->operator = (operator == 0) ? T_OP_EQ : operator;
1504
1505         /*      Check for a tag in the 'Merit' format of:
1506          *      :Tag:Value.  Print an error if we already found
1507          *      a tag in the Attribute.
1508          */
1509
1510         if (value && (*value == ':' && da->flags.has_tag)) {
1511                 /* If we already found a tag, this is invalid */
1512                 if(found_tag) {
1513                         fr_strerror_printf("Duplicate tag %s for attribute %s",
1514                                    value, vp->name);
1515                         DEBUG("Duplicate tag %s for attribute %s\n",
1516                                    value, vp->name);
1517                         pairbasicfree(vp);
1518                         return NULL;
1519                 }
1520                 /* Colon found and attribute allows a tag */
1521                 if (value[1] == '*' && value[2] == ':') {
1522                        /* Wildcard tag for check items */
1523                        tag = TAG_ANY;
1524                        value += 3;
1525                 } else {
1526                        /* Real tag */
1527                        tag = strtol(value + 1, &tc, 0);
1528                        if (tc && *tc==':' && TAG_VALID_ZERO(tag))
1529                             value = tc + 1;
1530                        else tag = 0;
1531                 }
1532                 found_tag = 1;
1533         }
1534
1535         if (found_tag) {
1536           vp->flags.tag = tag;
1537         }
1538
1539         switch (vp->operator) {
1540         default:
1541                 break;
1542
1543                 /*
1544                  *      For =* and !* operators, the value is irrelevant
1545                  *      so we return now.
1546                  */
1547         case T_OP_CMP_TRUE:
1548         case T_OP_CMP_FALSE:
1549                 vp->vp_strvalue[0] = '\0';
1550                 vp->length = 0;
1551                 return vp;
1552                 break;
1553
1554                 /*
1555                  *      Regular expression comparison of integer attributes
1556                  *      does a STRING comparison of the names of their
1557                  *      integer attributes.
1558                  */
1559         case T_OP_REG_EQ:       /* =~ */
1560         case T_OP_REG_NE:       /* !~ */
1561                 if (!value) {
1562                         fr_strerror_printf("No regular expression found in %s",
1563                                            vp->name);
1564                         pairbasicfree(vp);
1565                         return NULL;
1566                 }
1567           
1568                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1569                 vp->length = strlen(vp->vp_strvalue);
1570                 /*
1571                  *      If anything goes wrong, this is a run-time error,
1572                  *      not a compile-time error.
1573                  */
1574                 return vp;
1575
1576         }
1577
1578         /*
1579          *      FIXME: if (strcasecmp(attribute, vp->name) != 0)
1580          *      then the user MAY have typed in the attribute name
1581          *      as Vendor-%d-Attr-%d, and the value MAY be octets.
1582          *
1583          *      We probably want to fix pairparsevalue to accept
1584          *      octets as values for any attribute.
1585          */
1586         if (value && (pairparsevalue(vp, value) == NULL)) {
1587                 pairbasicfree(vp);
1588                 return NULL;
1589         }
1590
1591         return vp;
1592 }
1593
1594
1595 /*
1596  *      [a-zA-Z0-9_-:]+
1597  */
1598 static const int valid_attr_name[256] = {
1599         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1600         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1601         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1602         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1603         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1604         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
1605         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1606         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1607         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1608         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1609         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1610         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1611         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1612         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1613         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1614         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1615 };
1616
1617 /*
1618  *      Read a valuepair from a buffer, and advance pointer.
1619  *      Sets *eol to T_EOL if end of line was encountered.
1620  */
1621 VALUE_PAIR *pairread(const char **ptr, FR_TOKEN *eol)
1622 {
1623         char            buf[64];
1624         char            attr[64];
1625         char            value[1024], *q;
1626         const char      *p;
1627         FR_TOKEN        token, t, xlat;
1628         VALUE_PAIR      *vp;
1629         size_t          len;
1630
1631         *eol = T_OP_INVALID;
1632
1633         p = *ptr;
1634         while ((*p == ' ') || (*p == '\t')) p++;
1635
1636         if (!*p) {
1637                 *eol = T_OP_INVALID;
1638                 fr_strerror_printf("No token read where we expected an attribute name");
1639                 return NULL;
1640         }
1641
1642         if (*p == '#') {
1643                 *eol = T_HASH;
1644                 fr_strerror_printf("Read a comment instead of a token");
1645                 return NULL;
1646         }
1647
1648         q = attr;
1649         for (len = 0; len < sizeof(attr); len++) {
1650                 if (valid_attr_name[(int)*p]) {
1651                         *q++ = *p++;
1652                         continue;
1653                 }
1654                 break;
1655         }
1656
1657         if (len == sizeof(attr)) {
1658                 *eol = T_OP_INVALID;
1659                 fr_strerror_printf("Attribute name is too long");
1660                 return NULL;
1661         }
1662
1663         /*
1664          *      We may have Foo-Bar:= stuff, so back up.
1665          */
1666         if ((len > 0) && (attr[len - 1] == ':')) {
1667                 p--;
1668                 len--;
1669         }
1670
1671         attr[len] = '\0';
1672         *ptr = p;
1673
1674         /* Now we should have an operator here. */
1675         token = gettoken(ptr, buf, sizeof(buf));
1676         if (token < T_EQSTART || token > T_EQEND) {
1677                 fr_strerror_printf("expecting operator");
1678                 return NULL;
1679         }
1680
1681         /* Read value.  Note that empty string values are allowed */
1682         xlat = gettoken(ptr, value, sizeof(value));
1683         if (xlat == T_EOL) {
1684                 fr_strerror_printf("failed to get value");
1685                 return NULL;
1686         }
1687
1688         /*
1689          *      Peek at the next token. Must be T_EOL, T_COMMA, or T_HASH
1690          */
1691         p = *ptr;
1692         t = gettoken(&p, buf, sizeof(buf));
1693         if (t != T_EOL && t != T_COMMA && t != T_HASH) {
1694                 fr_strerror_printf("Expected end of line or comma");
1695                 return NULL;
1696         }
1697
1698         *eol = t;
1699         if (t == T_COMMA) {
1700                 *ptr = p;
1701         }
1702
1703         vp = NULL;
1704         switch (xlat) {
1705                 /*
1706                  *      Make the full pair now.
1707                  */
1708         default:
1709                 vp = pairmake(attr, value, token);
1710                 break;
1711
1712                 /*
1713                  *      Perhaps do xlat's
1714                  */
1715         case T_DOUBLE_QUOTED_STRING:
1716                 p = strchr(value, '%');
1717                 if (p && (p[1] == '{')) {
1718                         if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1719                                 fr_strerror_printf("Value too long");
1720                                 return NULL;
1721                         }
1722                         vp = pairmake(attr, NULL, token);
1723                         if (!vp) {
1724                                 *eol = T_OP_INVALID;
1725                                 return NULL;
1726                         }
1727
1728                         strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1729                         vp->flags.do_xlat = 1;
1730                         vp->length = 0;
1731                 } else {
1732                         /*
1733                          *      Parse && escape it, as defined by the
1734                          *      data type.
1735                          */
1736                         vp = pairmake(attr, value, token);
1737                         if (!vp) {
1738                                 *eol = T_OP_INVALID;
1739                                 return NULL;
1740                         }
1741                 }
1742                 break;
1743
1744         case T_SINGLE_QUOTED_STRING:
1745                 vp = pairmake(attr, NULL, token);
1746                 if (!vp) {
1747                         *eol = T_OP_INVALID;
1748                         return NULL;
1749                 }
1750
1751                 /*
1752                  *      String and octet types get copied verbatim.
1753                  */
1754                 if ((vp->type == PW_TYPE_STRING) ||
1755                     (vp->type == PW_TYPE_OCTETS)) {
1756                         strlcpy(vp->vp_strvalue, value,
1757                                 sizeof(vp->vp_strvalue));
1758                         vp->length = strlen(vp->vp_strvalue);
1759
1760                         /*
1761                          *      Everything else gets parsed: it's
1762                          *      DATA, not a string!
1763                          */
1764                 } else if (!pairparsevalue(vp, value)) {
1765                         pairfree(&vp);
1766                         *eol = T_OP_INVALID;
1767                         return NULL;
1768                 }
1769                 break;
1770
1771                 /*
1772                  *      Mark the pair to be allocated later.
1773                  */
1774         case T_BACK_QUOTED_STRING:
1775                 if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1776                         fr_strerror_printf("Value too long");
1777                         return NULL;
1778                 }
1779
1780                 vp = pairmake(attr, NULL, token);
1781                 if (!vp) {
1782                         *eol = T_OP_INVALID;
1783                         return NULL;
1784                 }
1785
1786                 vp->flags.do_xlat = 1;
1787                 strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1788                 vp->length = 0;
1789                 break;
1790         }
1791
1792         /*
1793          *      If we didn't make a pair, return an error.
1794          */
1795         if (!vp) {
1796                 *eol = T_OP_INVALID;
1797                 return NULL;
1798         }
1799
1800         return vp;
1801 }
1802
1803 /*
1804  *      Read one line of attribute/value pairs. This might contain
1805  *      multiple pairs seperated by comma's.
1806  */
1807 FR_TOKEN userparse(const char *buffer, VALUE_PAIR **first_pair)
1808 {
1809         VALUE_PAIR      *vp;
1810         const char      *p;
1811         FR_TOKEN        last_token = T_OP_INVALID;
1812         FR_TOKEN        previous_token;
1813
1814         /*
1815          *      We allow an empty line.
1816          */
1817         if (buffer[0] == 0)
1818                 return T_EOL;
1819
1820         p = buffer;
1821         do {
1822                 previous_token = last_token;
1823                 if ((vp = pairread(&p, &last_token)) == NULL) {
1824                         return last_token;
1825                 }
1826                 pairadd(first_pair, vp);
1827         } while (*p && (last_token == T_COMMA));
1828
1829         /*
1830          *      Don't tell the caller that there was a comment.
1831          */
1832         if (last_token == T_HASH) {
1833                 return previous_token;
1834         }
1835
1836         /*
1837          *      And return the last token which we read.
1838          */
1839         return last_token;
1840 }
1841
1842 /*
1843  *      Read valuepairs from the fp up to End-Of-File.
1844  *
1845  *      Hmm... this function is only used by radclient..
1846  */
1847 VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix)
1848 {
1849         char buf[8192];
1850         FR_TOKEN last_token = T_EOL;
1851         VALUE_PAIR *vp;
1852         VALUE_PAIR *list;
1853         int error = 0;
1854
1855         list = NULL;
1856
1857         while (!error && fgets(buf, sizeof(buf), fp) != NULL) {
1858                 /*
1859                  *      If we get a '\n' by itself, we assume that's
1860                  *      the end of that VP
1861                  */
1862                 if ((buf[0] == '\n') && (list)) {
1863                         return list;
1864                 }
1865                 if ((buf[0] == '\n') && (!list)) {
1866                         continue;
1867                 }
1868
1869                 /*
1870                  *      Comments get ignored
1871                  */
1872                 if (buf[0] == '#') continue;
1873
1874                 /*
1875                  *      Read all of the attributes on the current line.
1876                  */
1877                 vp = NULL;
1878                 last_token = userparse(buf, &vp);
1879                 if (!vp) {
1880                         if (last_token != T_EOL) {
1881                                 fr_perror("%s", errprefix);
1882                                 error = 1;
1883                                 break;
1884                         }
1885                         break;
1886                 }
1887
1888                 pairadd(&list, vp);
1889                 buf[0] = '\0';
1890         }
1891
1892         if (error) pairfree(&list);
1893
1894         *pfiledone = 1;
1895
1896         return error ? NULL: list;
1897 }
1898
1899
1900
1901 /*
1902  *      Compare two pairs, using the operator from "one".
1903  *
1904  *      i.e. given two attributes, it does:
1905  *
1906  *      (two->data) (one->operator) (one->data)
1907  *
1908  *      e.g. "foo" != "bar"
1909  *
1910  *      Returns true (comparison is true), or false (comparison is not true);
1911  *
1912  *      FIXME: Ignores tags!
1913  */
1914 int paircmp(VALUE_PAIR *one, VALUE_PAIR *two)
1915 {
1916         int compare;
1917
1918         switch (one->operator) {
1919         case T_OP_CMP_TRUE:
1920                 return (two != NULL);
1921
1922         case T_OP_CMP_FALSE:
1923                 return (two == NULL);
1924
1925                 /*
1926                  *      One is a regex, compile it, print two to a string,
1927                  *      and then do string comparisons.
1928                  */
1929         case T_OP_REG_EQ:
1930         case T_OP_REG_NE:
1931 #ifndef HAVE_REGEX_H
1932                 return -1;
1933 #else
1934                 {
1935                         regex_t reg;
1936                         char buffer[MAX_STRING_LEN * 4 + 1];
1937
1938                         compare = regcomp(&reg, one->vp_strvalue,
1939                                           REG_EXTENDED);
1940                         if (compare != 0) {
1941                                 regerror(compare, &reg, buffer, sizeof(buffer));
1942                                 fr_strerror_printf("Illegal regular expression in attribute: %s: %s",
1943                                            one->name, buffer);
1944                                 return -1;
1945                         }
1946
1947                         vp_prints_value(buffer, sizeof(buffer), two, 0);
1948
1949                         /*
1950                          *      Don't care about substring matches,
1951                          *      oh well...
1952                          */
1953                         compare = regexec(&reg, buffer, 0, NULL, 0);
1954
1955                         regfree(&reg);
1956                         if (one->operator == T_OP_REG_EQ) return (compare == 0);
1957                         return (compare != 0);
1958                 }
1959 #endif
1960
1961         default:                /* we're OK */
1962                 break;
1963         }
1964
1965         /*
1966          *      After doing the previous check for special comparisons,
1967          *      do the per-type comparison here.
1968          */
1969         switch (one->type) {
1970         case PW_TYPE_ABINARY:
1971         case PW_TYPE_OCTETS:
1972         {
1973                 size_t length;
1974
1975                 if (one->length < two->length) {
1976                         length = one->length;
1977                 } else {
1978                         length = two->length;
1979                 }
1980
1981                 if (length) {
1982                         compare = memcmp(two->vp_octets, one->vp_octets,
1983                                          length);
1984                         if (compare != 0) break;
1985                 }
1986
1987                 /*
1988                  *      Contents are the same.  The return code
1989                  *      is therefore the difference in lengths.
1990                  *
1991                  *      i.e. "0x00" is smaller than "0x0000"
1992                  */
1993                 compare = two->length - one->length;
1994         }
1995                 break;
1996
1997         case PW_TYPE_STRING:
1998                 compare = strcmp(two->vp_strvalue, one->vp_strvalue);
1999                 break;
2000
2001         case PW_TYPE_BYTE:
2002         case PW_TYPE_SHORT:
2003         case PW_TYPE_INTEGER:
2004         case PW_TYPE_DATE:
2005                 compare = two->vp_integer - one->vp_integer;
2006                 break;
2007
2008         case PW_TYPE_IPADDR:
2009                 compare = ntohl(two->vp_ipaddr) - ntohl(one->vp_ipaddr);
2010                 break;
2011
2012         case PW_TYPE_IPV6ADDR:
2013                 compare = memcmp(&two->vp_ipv6addr, &one->vp_ipv6addr,
2014                                  sizeof(two->vp_ipv6addr));
2015                 break;
2016
2017         case PW_TYPE_IPV6PREFIX:
2018                 compare = memcmp(&two->vp_ipv6prefix, &one->vp_ipv6prefix,
2019                                  sizeof(two->vp_ipv6prefix));
2020                 break;
2021
2022         case PW_TYPE_IFID:
2023                 compare = memcmp(&two->vp_ifid, &one->vp_ifid,
2024                                  sizeof(two->vp_ifid));
2025                 break;
2026
2027         default:
2028                 return 0;       /* unknown type */
2029         }
2030
2031         /*
2032          *      Now do the operator comparison.
2033          */
2034         switch (one->operator) {
2035         case T_OP_CMP_EQ:
2036                 return (compare == 0);
2037
2038         case T_OP_NE:
2039                 return (compare != 0);
2040
2041         case T_OP_LT:
2042                 return (compare < 0);
2043
2044         case T_OP_GT:
2045                 return (compare > 0);
2046
2047         case T_OP_LE:
2048                 return (compare <= 0);
2049
2050         case T_OP_GE:
2051                 return (compare >= 0);
2052
2053         default:
2054                 return 0;
2055         }
2056
2057         return 0;
2058 }