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