Move .gitignore to lib/ in preparation for moving lib to the root.
[libradsec.git] / radius / attrs.c
1 /*
2 Copyright (c) 2011, Network RADIUS SARL
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in the
11       documentation and/or other materials provided with the distribution.
12     * Neither the name of the <organization> nor the
13       names of its contributors may be used to endorse or promote products
14       derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /** \file attrs.c
29  *  \brief Attribute encoding and decoding routines.
30  */
31
32 #include "client.h"
33
34 /*
35  *      Encodes the data portion of an attribute.
36  *      Returns -1 on error, or the length of the data portion.
37  */
38 static ssize_t vp2data_any(const RADIUS_PACKET *packet,
39                            const RADIUS_PACKET *original,
40                            int nest,
41                            const VALUE_PAIR **pvp,
42                            uint8_t *start, size_t room)
43 {
44         uint32_t lvalue;
45         ssize_t len;
46         const uint8_t *data;
47         uint8_t *ptr = start;
48         uint8_t array[4];
49         const VALUE_PAIR *vp = *pvp;
50
51 #ifdef RS_TYPE_TLV
52         /*
53          *      See if we need to encode a TLV.  The low portion of
54          *      the attribute has already been placed into the packer.
55          *      If there are still attribute bytes left, then go
56          *      encode them as TLVs.
57          *
58          *      If we cared about the stack, we could unroll the loop.
59          */
60         if ((nest > 0) && (nest <= nr_attr_max_tlv) &&
61             ((vp->da->attr >> nr_attr_shift[nest]) != 0)) {
62                 return vp2data_tlvs(packet, original, nest, pvp,
63                                     start, room);
64         }
65 #else
66         nest = nest;            /* -Wunused */
67 #endif
68
69         /*
70          *      Set up the default sources for the data.
71          */
72         data = vp->vp_octets;
73         len = vp->length;
74
75         switch(vp->da->type) {
76         case RS_TYPE_IPV6PREFIX:
77                 len = sizeof(vp->vp_ipv6prefix);
78                 break;
79
80         case RS_TYPE_STRING:
81         case RS_TYPE_OCTETS:
82         case RS_TYPE_IFID:
83         case RS_TYPE_IPV6ADDR:
84 #ifdef RS_TYPE_ABINARY
85         case RS_TYPE_ABINARY:
86 #endif
87                 /* nothing more to do */
88                 break;
89
90         case RS_TYPE_BYTE:
91                 len = 1;        /* just in case */
92                 array[0] = vp->vp_integer & 0xff;
93                 data = array;
94                 break;
95
96         case RS_TYPE_SHORT:
97                 len = 2;        /* just in case */
98                 array[0] = (vp->vp_integer >> 8) & 0xff;
99                 array[1] = vp->vp_integer & 0xff;
100                 data = array;
101                 break;
102
103         case RS_TYPE_INTEGER:
104                 len = 4;        /* just in case */
105                 lvalue = htonl(vp->vp_integer);
106                 memcpy(array, &lvalue, sizeof(lvalue));
107                 data = array;
108                 break;
109
110         case RS_TYPE_IPADDR:
111                 data = (const uint8_t *) &vp->vp_ipaddr;
112                 len = 4;        /* just in case */
113                 break;
114
115                 /*
116                  *  There are no tagged date attributes.
117                  */
118         case RS_TYPE_DATE:
119                 lvalue = htonl(vp->vp_date);
120                 data = (const uint8_t *) &lvalue;
121                 len = 4;        /* just in case */
122                 break;
123
124 #ifdef VENDORPEC_WIMAX
125         case RS_TYPE_SIGNED:
126         {
127                 int32_t slvalue;
128
129                 len = 4;        /* just in case */
130                 slvalue = htonl(vp->vp_signed);
131                 memcpy(array, &slvalue, sizeof(slvalue));
132                 break;
133         }
134 #endif
135
136 #ifdef RS_TYPE_TLV
137         case RS_TYPE_TLV:
138                 data = vp->vp_tlv;
139                 if (!data) {
140                         nr_debug_error("ERROR: Cannot encode NULL TLV");
141                         return -RSE_INVAL;
142                 }
143                 len = vp->length;
144                 break;
145 #endif
146
147         default:                /* unknown type: ignore it */
148                 nr_debug_error("ERROR: Unknown attribute type %d", vp->da->type);
149                 return -RSE_ATTR_TYPE_UNKNOWN;
150         }
151
152         /*
153          *      Bound the data to the calling size
154          */
155         if (len > (ssize_t) room) len = room;
156
157 #ifndef FLAG_ENCRYPT_TUNNEL_PASSWORD
158         original = original;    /* -Wunused */
159 #endif
160
161         /*
162          *      Encrypt the various password styles
163          *
164          *      Attributes with encrypted values MUST be less than
165          *      128 bytes long.
166          */
167         switch (vp->da->flags.encrypt) {
168         case FLAG_ENCRYPT_USER_PASSWORD:
169                 len = nr_password_encrypt(ptr, room, data, len,
170                                           packet->secret, packet->vector);
171                 break;
172
173 #ifdef FLAG_ENCRYPT_TUNNEL_PASSWORD
174         case FLAG_ENCRYPT_TUNNEL_PASSWORD:
175                 lvalue = 0;
176                 if (vp->da->flags.has_tag) lvalue = 1;
177
178                 /*
179                  *      Check if there's enough room.  If there isn't,
180                  *      we discard the attribute.
181                  *
182                  *      This is ONLY a problem if we have multiple VSA's
183                  *      in one Vendor-Specific, though.
184                  */
185                 if (room < (18 + lvalue)) {
186                         *pvp = vp->next;
187                         return 0;
188                 }
189
190                 switch (packet->code) {
191                 case PW_ACCESS_ACCEPT:
192                 case PW_ACCESS_REJECT:
193                 case PW_ACCESS_CHALLENGE:
194                 default:
195                         if (!original) {
196                                 nr_debug_error("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->da->name);
197                                 return -RSE_REQUEST_REQUIRED;
198                         }
199
200                         if (lvalue) ptr[0] = vp->tag;
201                         len = nr_tunnelpw_encrypt(ptr + lvalue,
202                                                   room - lvalue, data, len,
203                                                   packet->secret,
204                                                   original->vector);
205                         if (len < 0) return len;
206                         break;
207                 case PW_ACCOUNTING_REQUEST:
208                 case PW_DISCONNECT_REQUEST:
209                 case PW_COA_REQUEST:
210                         ptr[0] = vp->tag;
211                         len = nr_tunnelpw_encrypt(ptr + 1, room, data, len - 1,
212                                                   packet->secret,
213                                                   packet->vector);
214                         if (len < 0) return len;
215                         break;
216                 }
217                 break;
218 #endif
219
220                 /*
221                  *      The code above ensures that this attribute
222                  *      always fits.
223                  */
224 #ifdef FLAG_ENCRYPT_ASCEND_SECRET
225         case FLAG_ENCRYPT_ASCEND_SECRET:
226                 make_secret(ptr, packet->vector, packet->secret, data);
227                 len = AUTH_VECTOR_LEN;
228                 break;
229 #endif
230
231         default:
232                 if (vp->da->flags.has_tag && TAG_VALID(vp->tag)) {
233                         if (vp->da->type == RS_TYPE_STRING) {
234                                 if (len > ((ssize_t) (room - 1))) len = room - 1;
235                                 ptr[0] = vp->tag;
236                                 ptr++;
237                         } else if (vp->da->type == RS_TYPE_INTEGER) {
238                                 array[0] = vp->tag;
239                         } /* else it can't be any other type */
240                 }
241                 memcpy(ptr, data, len);
242                 break;
243         } /* switch over encryption flags */
244
245         *(pvp) = vp->next;
246         return len + (ptr - start);;
247 }
248
249
250 /*
251  *      Encode an RFC format TLV.  This could be a standard attribute,
252  *      or a TLV data type.  If it's a standard attribute, then
253  *      vp->da->attr == attribute.  Otherwise, attribute may be
254  *      something else.
255  */
256 static ssize_t vp2attr_rfc(const RADIUS_PACKET *packet,
257                            const RADIUS_PACKET *original,
258                            const VALUE_PAIR **pvp,
259                            unsigned int attribute, uint8_t *ptr, size_t room)
260 {
261         ssize_t len;
262
263         if (room < 2) {
264                 *pvp = (*pvp)->next;
265                 return 0;
266         }
267
268         ptr[0] = attribute & 0xff;
269         ptr[1] = 2;
270
271         if (room > ((unsigned) 255 - ptr[1])) room = 255 - ptr[1];
272
273         len = vp2data_any(packet, original, 0, pvp, ptr + ptr[1], room);
274         if (len < 0) return len;
275
276         ptr[1] += len;
277
278         return ptr[1];
279 }
280
281
282 #ifndef WITHOUT_VSAS
283 /*
284  *      Encode a VSA which is a TLV.  If it's in the RFC format, call
285  *      vp2attr_rfc.  Otherwise, encode it here.
286  */
287 static ssize_t vp2attr_vsa(const RADIUS_PACKET *packet,
288                            const RADIUS_PACKET *original,
289                            const VALUE_PAIR **pvp,
290                            unsigned int attribute, unsigned int vendor,
291                            uint8_t *ptr, size_t room)
292 {
293         ssize_t len;
294         const DICT_VENDOR *dv;
295
296         /*
297          *      Unknown vendor: RFC format.
298          *      Known vendor and RFC format: go do that.
299          */
300         dv = nr_dict_vendor_byvalue(vendor);
301         if (!dv ||
302             (
303 #ifdef RS_TYPE_TLV
304                     !(*pvp)->flags.is_tlv &&
305 #endif
306                     (dv->type == 1) && (dv->length == 1))) {
307                 return vp2attr_rfc(packet, original, pvp,
308                                    attribute, ptr, room);
309         }
310
311 #ifdef RS_TYPE_TLV
312         if ((*pvp)->flags.is_tlv) {
313                 return data2vp_tlvs(packet, original, 0, pvp,
314                                     ptr, room);
315         }
316 #endif
317
318         switch (dv->type) {
319         default:
320                 nr_debug_error("vp2attr_vsa: Internal sanity check failed,"
321                                    " type %u", (unsigned) dv->type);
322                 return -RSE_INTERNAL;
323
324         case 4:
325                 ptr[0] = 0;     /* attr must be 24-bit */
326                 ptr[1] = (attribute >> 16) & 0xff;
327                 ptr[2] = (attribute >> 8) & 0xff;
328                 ptr[3] = attribute & 0xff;
329                 break;
330
331         case 2:
332                 ptr[0] = (attribute >> 8) & 0xff;
333                 ptr[1] = attribute & 0xff;
334                 break;
335
336         case 1:
337                 ptr[0] = attribute & 0xff;
338                 break;
339         }
340
341         switch (dv->length) {
342         default:
343                 nr_debug_error("vp2attr_vsa: Internal sanity check failed,"
344                                    " length %u", (unsigned) dv->length);
345                 return -RSE_INTERNAL;
346
347         case 0:
348                 break;
349
350         case 2:
351                 ptr[dv->type] = 0;
352                 /* FALL-THROUGH */
353
354         case 1:
355                 ptr[dv->type + dv->length - 1] = dv->type + dv->length;
356                 break;
357
358         }
359
360         if (room > ((unsigned) 255 - (dv->type + dv->length))) {
361                 room = 255 - (dv->type + dv->length);
362         }
363
364         len = vp2data_any(packet, original, 0, pvp,
365                           ptr + dv->type + dv->length, room);
366         if (len < 0) return len;
367
368         if (dv->length) ptr[dv->type + dv->length - 1] += len;
369
370         return dv->type + dv->length + len;
371 }
372
373
374 /*
375  *      Encode a Vendor-Specific attribute.
376  */
377 ssize_t nr_vp2vsa(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
378               const VALUE_PAIR **pvp, uint8_t *ptr,
379               size_t room)
380 {
381         ssize_t len;
382         uint32_t lvalue;
383         const VALUE_PAIR *vp = *pvp;
384
385 #ifdef VENDORPEC_WIMAX
386         /*
387          *      Double-check for WiMAX
388          */
389         if (vp->da->vendor == VENDORPEC_WIMAX) {
390                 return nr_vp2wimax(packet, original,  pvp,
391                                     ptr, room);
392         }
393 #endif
394
395         if (vp->da->vendor > RS_MAX_VENDOR) {
396                 nr_debug_error("nr_vp2vsa: Invalid arguments");
397                 return -RSE_INVAL;
398         }
399
400         /*
401          *      Not enough room for:
402          *              attr, len, vendor-id
403          */
404         if (room < 6) {
405                 *pvp = vp->next;
406                 return 0;
407         }
408
409         /*
410          *      Build the Vendor-Specific header
411          */
412         ptr[0] = PW_VENDOR_SPECIFIC;
413         ptr[1] = 6;
414         lvalue = htonl(vp->da->vendor);
415         memcpy(ptr + 2, &lvalue, 4);
416
417         if (room > ((unsigned) 255 - ptr[1])) room = 255 - ptr[1];
418
419         len = vp2attr_vsa(packet, original, pvp,
420                           vp->da->attr, vp->da->vendor,
421                           ptr + ptr[1], room);
422         if (len < 0) return len;
423
424         ptr[1] += len;
425
426         return ptr[1];
427 }
428 #endif
429
430
431 /*
432  *      Encode an RFC standard attribute 1..255
433  */
434 ssize_t nr_vp2rfc(const RADIUS_PACKET *packet,
435                const RADIUS_PACKET *original,
436                const VALUE_PAIR **pvp,
437                uint8_t *ptr, size_t room)
438 {
439         const VALUE_PAIR *vp = *pvp;
440
441         if (vp->da->vendor != 0) {
442                 nr_debug_error("nr_vp2rfc called with VSA");
443                 return -RSE_INVAL;
444         }
445
446         if ((vp->da->attr == 0) || (vp->da->attr > 255)) {
447                 nr_debug_error("nr_vp2rfc called with non-standard attribute %u", vp->da->attr);
448                 return -RSE_INVAL;
449         }
450
451 #ifdef PW_CHARGEABLE_USER_IDENTITY
452         if ((vp->length == 0) &&
453             (vp->da != RS_DA_CHARGEABLE_USER_IDENTITY)) {
454                 *pvp = vp->next;
455                 return 0;
456         }
457 #endif
458
459         return vp2attr_rfc(packet, original, pvp, vp->da->attr,
460                            ptr, room);
461 }
462
463 #ifdef PW_CHAP_PASSWORD
464 /*
465  *      Encode an RFC standard attribute 1..255
466  */
467 static ssize_t nr_chap2rfc(const RADIUS_PACKET *packet,
468                         const RADIUS_PACKET *original,
469                         const VALUE_PAIR **pvp,
470                         uint8_t *ptr, size_t room)
471 {
472         ssize_t rcode;
473         const VALUE_PAIR *vp = *pvp;
474         RS_MD5_CTX      ctx;
475         uint8_t         buffer[RS_MAX_STRING_LEN*2 + 1], *p;
476         VALUE_PAIR chap = {
477                 RS_DA_CHAP_PASSWORD,
478                 17,
479                 0,
480                 NULL,
481                 {
482                         .octets = {
483                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
484                         },
485                 },
486         };
487
488         if ((vp->da->vendor != 0) || (vp->da != RS_DA_CHAP_PASSWORD)) {
489                 nr_debug_error("nr_chap2rfc called with non-CHAP");
490                 return -RSE_INVAL;
491         }
492
493         p = buffer;
494         *(p++) = nr_rand() & 0xff; /* id */
495
496         memcpy(p, vp->vp_strvalue, strlen(vp->vp_strvalue));
497         p += strlen(vp->vp_strvalue);
498
499         vp = nr_vps_find(packet->vps, PW_CHAP_CHALLENGE, 0);
500         if (vp) {
501                 memcpy(p, vp->vp_octets, vp->length);
502                 p += vp->length;
503         } else {
504                 memcpy(p, packet->vector, sizeof(packet->vector));
505                 p += sizeof(packet->vector);
506         }
507
508         RS_MD5Init(&ctx);
509         RS_MD5Update(&ctx, buffer, p - buffer);
510         RS_MD5Final(&chap.vp_octets[1], &ctx);
511
512         chap.vp_octets[0] = buffer[0];
513         vp = &chap;
514
515         rcode = vp2attr_rfc(packet, original, &vp, chap.da->attr,
516                             ptr, room);
517         if (rcode < 0) return rcode;
518
519         *pvp = (*pvp)->next;
520         return rcode;
521 }
522 #endif  /* PW_CHAP_PASSWORD */
523
524 #ifdef PW_MESSAGE_AUTHENTICATOR
525 /** Fake Message-Authenticator.
526  *
527  *  This structure is used to replace a Message-Authenticator in the
528  *  input list of VALUE_PAIRs when encoding a packet.  If the caller
529  *  asks us to encode a Message-Authenticator, we ignore the one given
530  *  to us by the caller (which may have the wrong length, etc.), and
531  *  instead use this one, which has the correct length and data.
532  */
533 static const VALUE_PAIR fake_ma = {
534         RS_DA_MESSAGE_AUTHENTICATOR,
535         16,
536         0,
537         NULL,
538         {
539                 .octets = {
540                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
541                 },
542         }
543 };
544 #endif  /* PW_MESSAGE_AUTHENTICATOR */
545
546 /*
547  *      Parse a data structure into a RADIUS attribute.
548  */
549 ssize_t nr_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
550                 const VALUE_PAIR **pvp, uint8_t *start,
551                 size_t room)
552 {
553         const VALUE_PAIR *vp = *pvp;
554
555         /*
556          *      RFC format attributes take the fast path.
557          */
558         if (vp->da->vendor != 0) {
559 #ifdef VENDORPEC_EXTENDED
560                 if (vp->da->vendor > RS_MAX_VENDOR) {
561                         return nr_vp2attr_extended(packet, original,
562                                                    pvp, start, room);
563                                                     
564                 }
565 #endif
566                 
567 #ifdef VENDORPEC_WIMAX
568                 if (vp->da->vendor == VENDORPEC_WIMAX) {
569                         return nr_vp2attr_wimax(packet, original,
570                                                  pvp, start, room);
571                 }
572 #endif
573                 
574 #ifndef WITHOUT_VSAS
575                 return nr_vp2vsa(packet, original, pvp, start, room);
576 #else
577                 nr_debug_error("VSAs are not supported");
578                 return -RSE_UNSUPPORTED;
579 #endif
580         }
581
582         /*
583          *      Ignore non-protocol attributes.
584          */
585         if (vp->da->attr > 255) {
586                 *pvp = vp->next;
587                 return 0;
588         }
589
590 #ifdef PW_MESSAGE_AUTHENTICATOR
591         /*
592          *      The caller wants a Message-Authenticator, but doesn't
593          *      know how to calculate it, or what the correct values
594          *      are.  So... create one for him.
595          */
596         if (vp->da == RS_DA_MESSAGE_AUTHENTICATOR) {
597                 ssize_t rcode;
598
599                 vp = &fake_ma;
600                 rcode = nr_vp2rfc(packet, original, &vp, start, room);
601                 if (rcode <= 0) return rcode;
602                 *pvp = (*pvp)->next;
603                 return rcode;
604         }
605 #endif
606
607 #ifdef PW_CHAP_PASSWORD
608         /*
609          *      The caller wants a CHAP-Password, but doesn't know how
610          *      to calculate it, or what the correct values are.  To
611          *      help, we calculate it for him.
612          */
613         if (vp->da == RS_DA_CHAP_PASSWORD) {
614                 int encoded = 0;
615
616                 /*
617                  *      CHAP is ID + MD5(...).  If it's length is NOT
618                  *      17, then the caller has passed us a password,
619                  *      and wants us to encode it.  If the length IS
620                  *      17, then we need to double-check if the caller
621                  *      has already encoded it.
622                  */
623                 if (vp->length == 17) {
624                         int i;
625
626                         /*
627                          *      ASCII and UTF-8 disallow values 0..31.
628                          *      If they appear, then the CHAP-Password
629                          *      has already been encoded by the
630                          *      caller.  The probability of a
631                          *      CHAP-Password being all 32..256 is
632                          *      (1-32/256)^17 =~ .10
633                          *
634                          *      This check isn't perfect, but it
635                          *      should be pretty rare for people to
636                          *      have 17-character passwords *and* have
637                          *      them all 32..256.
638                          */
639                         for (i = 0; i < 17; i++) {
640                                 if (vp->vp_octets[i] < 32) {
641                                         encoded = 1;
642                                         break;
643                                 }
644                         }
645                 }
646
647                 if (!encoded) {
648                         return nr_chap2rfc(packet, original, pvp, start, room);
649                 }
650         }
651 #endif
652
653         return nr_vp2rfc(packet, original, pvp,
654                           start, room);
655 }
656
657
658 /*
659  *      Ignore unknown attributes, but "decoding" them into nothing.
660  */
661 static ssize_t data2vp_raw(UNUSED const RADIUS_PACKET *packet,
662                            UNUSED const RADIUS_PACKET *original,
663                            unsigned int attribute,
664                            unsigned int vendor,
665                            const uint8_t *data, size_t length,
666                            VALUE_PAIR **pvp)
667 {
668         VALUE_PAIR *vp;
669
670         if (length > sizeof(vp->vp_octets)) return -RSE_ATTR_OVERFLOW;
671
672         vp = nr_vp_alloc_raw(attribute, vendor);
673         if (!vp) return -RSE_NOMEM;
674         
675         memcpy(vp->vp_octets, data, length);
676         vp->length = length;
677
678         *pvp = vp;
679         return length;
680 }
681
682 ssize_t nr_attr2vp_raw(const RADIUS_PACKET *packet,
683                        const RADIUS_PACKET *original,
684                        const uint8_t *data, size_t length,
685                        VALUE_PAIR **pvp)
686 {
687
688         if (length < 2) return -RSE_PACKET_TOO_SMALL;
689         if (data[1] < 2) return -RSE_ATTR_TOO_SMALL;
690         if (data[1] > length) return -RSE_ATTR_OVERFLOW;
691
692         return data2vp_raw(packet, original, data[0], 0,
693                            data + 2, data[1] - 2, pvp);
694 }
695
696 /*
697  *      Create any kind of VP from the attribute contents.
698  *
699  *      Will return -1 on error, or "length".
700  */
701 static ssize_t data2vp_any(const RADIUS_PACKET *packet,
702                            const RADIUS_PACKET *original,
703                            int nest,
704                            unsigned int attribute, unsigned int vendor,
705                            const uint8_t *data, size_t length,
706                            VALUE_PAIR **pvp)
707 {
708 #ifdef FLAG_ENCRYPT_TUNNEL_PASSWORD
709         ssize_t rcode;
710 #endif
711         int data_offset = 0;
712         const DICT_ATTR *da;
713         VALUE_PAIR *vp = NULL;
714
715         if (length == 0) {
716                 /*
717                  *      Hacks for CUI.  The WiMAX spec says that it
718                  *      can be zero length, even though this is
719                  *      forbidden by the RADIUS specs.  So... we make
720                  *      a special case for it.
721                  */
722                 if ((vendor == 0) &&
723                     (attribute == PW_CHARGEABLE_USER_IDENTITY)) {
724                         data = (const uint8_t *) "";
725                         length = 1;
726                 } else {
727                         *pvp = NULL;
728                         return 0;
729                 }
730         }
731
732         da = nr_dict_attr_byvalue(attribute, vendor);
733
734         /*
735          *      Unknown attribute.  Create it as a "raw" attribute.
736          */
737         if (!da) {
738         raw:
739                 if (vp) nr_vp_free(&vp);
740                 return data2vp_raw(packet, original,
741                                    attribute, vendor, data, length, pvp);
742         }
743
744 #ifdef RS_TYPE_TLV
745         /*
746          *      TLVs are handled first.  They can't be tagged, and
747          *      they can't be encrypted.
748          */
749         if (da->da->type == RS_TYPE_TLV) {
750                 return data2vp_tlvs(packet, original,
751                                     attribute, vendor, nest,
752                                     data, length, pvp);
753         }
754 #else
755         nest = nest;            /* -Wunused */
756 #endif
757
758         /*
759          *      The attribute is known, and well formed.  We can now
760          *      create it.  The main failure from here on in is being
761          *      out of memory.
762          */
763         vp = nr_vp_alloc(da);
764         if (!vp) return -RSE_NOMEM;
765
766         /*
767          *      Handle tags.
768          */
769         if (vp->da->flags.has_tag) {
770                 if (TAG_VALID(data[0])
771 #ifdef FLAG_ENCRYPT_TUNNEL_PASSWORD
772                     || (vp->da->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD)
773 #endif
774                         ) {
775                         /*
776                          *      Tunnel passwords REQUIRE a tag, even
777                          *      if don't have a valid tag.
778                          */
779                         vp->tag = data[0];
780
781                         if ((vp->da->type == RS_TYPE_STRING) ||
782                             (vp->da->type == RS_TYPE_OCTETS)) {
783                                 if (length == 0) goto raw;
784                                 data_offset = 1;
785                         }
786                 }
787         }
788
789         /*
790          *      Copy the data to be decrypted
791          */
792         vp->length = length - data_offset;
793         memcpy(&vp->vp_octets[0], data + data_offset, vp->length);
794
795         /*
796          *      Decrypt the attribute.
797          */
798         switch (vp->da->flags.encrypt) {
799                 /*
800                  *  User-Password
801                  */
802         case FLAG_ENCRYPT_USER_PASSWORD:
803                 if (original) {
804                         rcode = nr_password_encrypt(vp->vp_octets,
805                                                     sizeof(vp->vp_strvalue),
806                                                     data + data_offset, vp->length,
807                                                     packet->secret,
808                                                     original->vector);
809                 } else {
810                         rcode = nr_password_encrypt(vp->vp_octets,
811                                                     sizeof(vp->vp_strvalue),
812                                                     data + data_offset, vp->length,
813                                                     packet->secret,
814                                                     packet->vector);
815                 }
816                 if (rcode < 0) goto raw;
817                 vp->vp_strvalue[128] = '\0';
818                 vp->length = strlen(vp->vp_strvalue);
819                 break;
820
821                 /*
822                  *      Tunnel-Password's may go ONLY
823                  *      in response packets.
824                  */
825 #ifdef FLAG_ENCRYPT_TUNNEL_PASSWORD
826         case FLAG_ENCRYPT_TUNNEL_PASSWORD:
827                 if (!original) goto raw;
828
829                 rcode = nr_tunnelpw_decrypt(vp->vp_octets,
830                                             sizeof(vp->vp_octets),
831                                             data + data_offset, vp->length,
832                                             packet->secret, original->vector);
833                 if (rcode < 0) goto raw;
834                 vp->length = rcode;
835                 break;
836 #endif
837
838
839 #ifdef FLAG_ENCRYPT_ASCEND_SECRET
840                 /*
841                  *  Ascend-Send-Secret
842                  *  Ascend-Receive-Secret
843                  */
844         case FLAG_ENCRYPT_ASCEND_SECRET:
845                 if (!original) {
846                         goto raw;
847                 } else {
848                         uint8_t my_digest[AUTH_VECTOR_LEN];
849                         make_secret(my_digest,
850                                     original->vector,
851                                     packet->secret, data);
852                         memcpy(vp->vp_strvalue, my_digest,
853                                AUTH_VECTOR_LEN );
854                         vp->vp_strvalue[AUTH_VECTOR_LEN] = '\0';
855                         vp->length = strlen(vp->vp_strvalue);
856                 }
857                 break;
858 #endif
859
860         default:
861                 break;
862         } /* switch over encryption flags */
863
864         /*
865          *      Expected a certain length, but got something else.
866          */
867         if ((vp->da->flags.length != 0) &&
868             (vp->length != vp->da->flags.length)) {
869                 goto raw;
870         }
871
872         switch (vp->da->type) {
873         case RS_TYPE_STRING:
874         case RS_TYPE_OCTETS:
875 #ifdef RS_TYPE_ABINARY
876         case RS_TYPE_ABINARY:
877 #endif
878                 /* nothing more to do */
879                 break;
880
881         case RS_TYPE_BYTE:
882                 vp->vp_integer = vp->vp_octets[0];
883                 break;
884
885
886         case RS_TYPE_SHORT:
887                 vp->vp_integer = (vp->vp_octets[0] << 8) | vp->vp_octets[1];
888                 break;
889
890         case RS_TYPE_INTEGER:
891                 memcpy(&vp->vp_integer, vp->vp_octets, 4);
892                 vp->vp_integer = ntohl(vp->vp_integer);
893
894                 if (vp->da->flags.has_tag) vp->vp_integer &= 0x00ffffff;
895                 break;
896
897         case RS_TYPE_DATE:
898                 memcpy(&vp->vp_date, vp->vp_octets, 4);
899                 vp->vp_date = ntohl(vp->vp_date);
900                 break;
901
902
903         case RS_TYPE_IPADDR:
904                 memcpy(&vp->vp_ipaddr, vp->vp_octets, 4);
905                 break;
906
907                 /*
908                  *      IPv6 interface ID is 8 octets long.
909                  */
910         case RS_TYPE_IFID:
911                 /* vp->vp_ifid == vp->vp_octets */
912                 break;
913
914                 /*
915                  *      IPv6 addresses are 16 octets long
916                  */
917         case RS_TYPE_IPV6ADDR:
918                 /* vp->vp_ipv6addr == vp->vp_octets */
919                 break;
920
921                 /*
922                  *      IPv6 prefixes are 2 to 18 octets long.
923                  *
924                  *      RFC 3162: The first octet is unused.
925                  *      The second is the length of the prefix
926                  *      the rest are the prefix data.
927                  *
928                  *      The prefix length can have value 0 to 128.
929                  */
930         case RS_TYPE_IPV6PREFIX:
931                 if (vp->length < 2 || vp->length > 18) goto raw;
932                 if (vp->vp_octets[1] > 128) goto raw;
933
934                 /*
935                  *      FIXME: double-check that
936                  *      (vp->vp_octets[1] >> 3) matches vp->length + 2
937                  */
938                 if (vp->length < 18) {
939                         memset(vp->vp_octets + vp->length, 0,
940                                18 - vp->length);
941                 }
942                 break;
943
944 #ifdef VENDORPEC_WIMAX
945         case RS_TYPE_SIGNED:
946                 if (vp->length != 4) goto raw;
947
948                 /*
949                  *      Overload vp_integer for ntohl, which takes
950                  *      uint32_t, not int32_t
951                  */
952                 memcpy(&vp->vp_integer, vp->vp_octets, 4);
953                 vp->vp_integer = ntohl(vp->vp_integer);
954                 memcpy(&vp->vp_signed, &vp->vp_integer, 4);
955                 break;
956 #endif
957
958 #ifdef RS_TYPE_TLV
959         case RS_TYPE_TLV:
960                 nr_vp_free(&vp);
961                 nr_debug_error("data2vp_any: Internal sanity check failed");
962                 return -RSE_ATTR_TYPE_UNKNOWN;
963 #endif
964
965 #ifdef VENDORPEC_WIMAX
966         case RS_TYPE_COMBO_IP:
967                 if (vp->length == 4) {
968                         vp->da->type = RS_TYPE_IPADDR;
969                         memcpy(&vp->vp_ipaddr, vp->vp_octets, 4);
970                         break;
971
972                 } else if (vp->length == 16) {
973                         vp->da->type = RS_TYPE_IPV6ADDR;
974                         /* vp->vp_ipv6addr == vp->vp_octets */
975                         break;
976
977                 }
978                 /* FALL-THROUGH */
979 #endif
980
981         default:
982                 goto raw;
983         }
984
985         *pvp = vp;
986
987         return length;
988 }
989
990
991 /*
992  *      Create a "standard" RFC VALUE_PAIR from the given data.
993  */
994 ssize_t nr_attr2vp_rfc(const RADIUS_PACKET *packet,
995                         const RADIUS_PACKET *original,
996                         const uint8_t *data, size_t length,
997                         VALUE_PAIR **pvp)
998 {
999         ssize_t rcode;
1000
1001         if (length < 2) return -RSE_PACKET_TOO_SMALL;
1002         if (data[1] < 2) return -RSE_ATTR_TOO_SMALL;
1003         if (data[1] > length) return -RSE_ATTR_OVERFLOW;
1004         
1005         rcode = data2vp_any(packet, original, 0,
1006                             data[0], 0, data + 2, data[1] - 2, pvp);
1007         if (rcode < 0) return rcode;
1008
1009         return data[1];
1010 }       
1011
1012 #ifndef WITHOUT_VSAS
1013 /*
1014  *      Check if a set of RADIUS formatted TLVs are OK.
1015  */
1016 int nr_tlv_ok(const uint8_t *data, size_t length,
1017                size_t dv_type, size_t dv_length)
1018 {
1019         const uint8_t *end = data + length;
1020
1021         if ((dv_length > 2) || (dv_type == 0) || (dv_type > 4)) {
1022                 nr_debug_error("nr_tlv_ok: Invalid arguments");
1023                 return -RSE_INVAL;
1024         }
1025
1026         while (data < end) {
1027                 size_t attrlen;
1028
1029                 if ((data + dv_type + dv_length) > end) {
1030                         nr_debug_error("Attribute header overflow");
1031                         return -RSE_ATTR_TOO_SMALL;
1032                 }
1033
1034                 switch (dv_type) {
1035                 case 4:
1036                         if ((data[0] == 0) && (data[1] == 0) &&
1037                             (data[2] == 0) && (data[3] == 0)) {
1038                         zero:
1039                                 nr_debug_error("Invalid attribute 0");
1040                                 return -RSE_ATTR_INVALID;
1041                         }
1042
1043                         if (data[0] != 0) {
1044                                 nr_debug_error("Invalid attribute > 2^24");
1045                                 return -RSE_ATTR_INVALID;
1046                         }
1047                         break;
1048
1049                 case 2:
1050                         if ((data[1] == 0) && (data[1] == 0)) goto zero;
1051                         break;
1052
1053                 case 1:
1054                         if (data[0] == 0) goto zero;
1055                         break;
1056
1057                 default:
1058                         nr_debug_error("Internal sanity check failed");
1059                         return -RSE_INTERNAL;
1060                 }
1061
1062                 switch (dv_length) {
1063                 case 0:
1064                         return 0;
1065
1066                 case 2:
1067                         if (data[dv_type + 1] != 0) {
1068                                 nr_debug_error("Attribute is longer than 256 octets");
1069                                 return -RSE_ATTR_TOO_LARGE;
1070                         }
1071                         /* FALL-THROUGH */
1072                 case 1:
1073                         attrlen = data[dv_type + dv_length - 1];
1074                         break;
1075
1076
1077                 default:
1078                         nr_debug_error("Internal sanity check failed");
1079                         return -RSE_INTERNAL;
1080                 }
1081
1082                 if (attrlen < (dv_type + dv_length)) {
1083                         nr_debug_error("Attribute header has invalid length");
1084                         return -RSE_PACKET_TOO_SMALL;
1085                 }
1086
1087                 if (attrlen > length) {
1088                         nr_debug_error("Attribute overflows container");
1089                         return -RSE_ATTR_OVERFLOW;
1090                 }
1091
1092                 data += attrlen;
1093                 length -= attrlen;
1094         }
1095
1096         return 0;
1097 }
1098
1099
1100 /*
1101  *      Convert a top-level VSA to a VP.
1102  */
1103 static ssize_t attr2vp_vsa(const RADIUS_PACKET *packet,
1104                            const RADIUS_PACKET *original,
1105                            unsigned int vendor,
1106                            size_t dv_type, size_t dv_length,
1107                            const uint8_t *data, size_t length,
1108                            VALUE_PAIR **pvp)
1109 {
1110         unsigned int attribute;
1111         ssize_t attrlen, my_len;
1112
1113 #ifndef NDEBUG
1114         if (length <= (dv_type + dv_length)) {
1115                 nr_debug_error("attr2vp_vsa: Failure to call nr_tlv_ok");
1116                 return -RSE_PACKET_TOO_SMALL;
1117         }
1118 #endif  
1119
1120         switch (dv_type) {
1121         case 4:
1122                 /* data[0] must be zero */
1123                 attribute = data[1] << 16;
1124                 attribute |= data[2] << 8;
1125                 attribute |= data[3];
1126                 break;
1127
1128         case 2:
1129                 attribute = data[0] << 8;
1130                 attribute |= data[1];
1131                 break;
1132
1133         case 1:
1134                 attribute = data[0];
1135                 break;
1136
1137         default:
1138                 nr_debug_error("attr2vp_vsa: Internal sanity check failed");
1139                 return -RSE_INTERNAL;
1140         }
1141
1142         switch (dv_length) {
1143         case 2:
1144                 /* data[dv_type] must be zero */
1145                 attrlen = data[dv_type + 1];
1146                 break;
1147
1148         case 1:
1149                 attrlen = data[dv_type];
1150                 break;
1151
1152         case 0:
1153                 attrlen = length;
1154                 break;
1155
1156         default:
1157                 nr_debug_error("attr2vp_vsa: Internal sanity check failed");
1158                 return -RSE_INTERNAL;
1159         }
1160
1161 #ifndef NDEBUG
1162         if (attrlen <= (ssize_t) (dv_type + dv_length)) {
1163                 nr_debug_error("attr2vp_vsa: Failure to call nr_tlv_ok");
1164                 return -RSE_PACKET_TOO_SMALL;
1165         }
1166 #endif
1167
1168         attrlen -= (dv_type + dv_length);
1169         
1170         my_len = data2vp_any(packet, original, 0,
1171                              attribute, vendor,
1172                              data + dv_type + dv_length, attrlen, pvp);
1173         if (my_len < 0) return my_len;
1174
1175 #ifndef NDEBUG
1176         if (my_len != attrlen) {
1177                 nr_vp_free(pvp);
1178                 nr_debug_error("attr2vp_vsa: Incomplete decode %d != %d",
1179                                    (int) my_len, (int) attrlen);
1180                 return -RSE_INTERNAL;
1181         }
1182 #endif
1183
1184         return dv_type + dv_length + attrlen;
1185 }
1186
1187
1188 /*
1189  *      Create Vendor-Specifc VALUE_PAIRs from a RADIUS attribute.
1190  */
1191 ssize_t nr_attr2vp_vsa(const RADIUS_PACKET *packet,
1192                         const RADIUS_PACKET *original,
1193                         const uint8_t *data, size_t length,
1194                         VALUE_PAIR **pvp)
1195 {
1196         size_t dv_type, dv_length;
1197         ssize_t my_len;
1198         uint32_t lvalue;
1199         const DICT_VENDOR *dv;
1200
1201         if (length < 2) return -RSE_PACKET_TOO_SMALL;
1202         if (data[1] < 2) return -RSE_ATTR_TOO_SMALL;
1203         if (data[1] > length) return -RSE_ATTR_OVERFLOW;
1204
1205         if (data[0] != PW_VENDOR_SPECIFIC) {
1206                 nr_debug_error("nr_attr2vp_vsa: Invalid attribute");
1207                 return -RSE_INVAL;
1208         }
1209
1210         /*
1211          *      Not enough room for a Vendor-Id.
1212          *      Or the high octet of the Vendor-Id is set.
1213          */
1214         if ((data[1] < 6) || (data[2] != 0)) {
1215                 return nr_attr2vp_raw(packet, original,
1216                                        data, length, pvp);
1217         }
1218
1219         memcpy(&lvalue, data + 2, 4);
1220         lvalue = ntohl(lvalue);
1221
1222 #ifdef VENDORPEC_WIMAX
1223         /*
1224          *      WiMAX gets its own set of magic.
1225          */
1226         if (lvalue == VENDORPEC_WIMAX) {
1227                 return nr_attr2vp_wimax(packet, original,
1228                                          data, length, pvp);
1229         }
1230 #endif
1231
1232         dv_type = dv_length = 1;
1233         dv = nr_dict_vendor_byvalue(lvalue);
1234         if (!dv) {
1235                 return nr_attr2vp_rfc(packet, original,
1236                                        data, length, pvp);
1237         }
1238
1239         dv_type = dv->type;
1240         dv_length = dv->length;
1241
1242         /*
1243          *      Attribute is not in the correct form.
1244          */
1245         if (nr_tlv_ok(data + 6, data[1] - 6, dv_type, dv_length) < 0) {
1246                 return nr_attr2vp_raw(packet, original,
1247                                        data, length, pvp);
1248         }
1249
1250         my_len = attr2vp_vsa(packet, original,
1251                              lvalue, dv_type, dv_length,
1252                              data + 6, data[1] - 6, pvp);
1253         if (my_len < 0) return my_len;
1254
1255 #ifndef NDEBUG
1256         if (my_len != (data[1] - 6)) {
1257                 nr_vp_free(pvp);
1258                 nr_debug_error("nr_attr2vp_vsa: Incomplete decode");
1259                 return -RSE_INTERNAL;
1260         }
1261 #endif
1262
1263         return data[1];
1264 }
1265 #endif  /* WITHOUT_VSAS */
1266
1267
1268 /*
1269  *      Create a "normal" VALUE_PAIR from the given data.
1270  */
1271 ssize_t nr_attr2vp(const RADIUS_PACKET *packet,
1272                     const RADIUS_PACKET *original,
1273                     const uint8_t *data, size_t length,
1274                     VALUE_PAIR **pvp)
1275 {
1276         if (length < 2) return -RSE_PACKET_TOO_SMALL;
1277         if (data[1] < 2) return -RSE_ATTR_TOO_SMALL;
1278         if (data[1] > length) return -RSE_ATTR_OVERFLOW;
1279
1280 #ifndef WITHOUT_VSAS
1281         /*
1282          *      VSAs get their own handler.
1283          */
1284         if (data[0] == PW_VENDOR_SPECIFIC) {
1285                 return nr_attr2vp_vsa(packet, original,
1286                                        data, length, pvp);
1287         }
1288 #endif
1289
1290 #ifdef VENDORPEC_EXTENDED
1291         /*
1292          *      Extended attribute format gets their own handler.
1293          */
1294         if (nr_dict_attr_byvalue(data[0], VENDORPEC_EXTENDED) != NULL) {
1295                 return nr_attr2vp_extended(packet, original,
1296                                             data, length, pvp);
1297         }
1298 #endif
1299
1300         return nr_attr2vp_rfc(packet, original, data, length, pvp);
1301 }
1302
1303 ssize_t nr_attr2data(const RADIUS_PACKET *packet, ssize_t start,
1304                       unsigned int attribute, unsigned int vendor,
1305                       const uint8_t **pdata, size_t *plength)
1306 {
1307         uint8_t *data, *attr;
1308         const uint8_t *end;
1309
1310         if (!packet || !pdata || !plength) return -RSE_INVAL;
1311
1312         if (!packet->data) return -RSE_INVAL;
1313         if (packet->length < 20) return -RSE_INVAL;
1314
1315         /*
1316          *      Too long or short, not good.
1317          */
1318         if ((start < 0) ||
1319             ((start > 0) && (start < 20))) return -RSE_INVAL;
1320
1321         if ((size_t) start >= (packet->length - 2)) return -RSE_INVAL;
1322
1323         end = packet->data + packet->length;
1324
1325         /*
1326          *      Loop over the packet, converting attrs to VPs.
1327          */
1328         if (start == 0) {
1329                 data = packet->data + 20;
1330         } else {
1331                 data = packet->data + start;
1332                 data += data[1];
1333                 if (data >= end) return 0;
1334         }
1335
1336         for (attr = data; attr < end; attr += attr[1]) {
1337                 const DICT_VENDOR *dv = NULL;
1338
1339 #ifndef NEBUG
1340                 /*
1341                  *      This code is copied from packet_ok().
1342                  *      It could be put into a separate function.
1343                  */
1344                 if ((attr + 2) > end) {
1345                         nr_debug_error("Attribute overflows packet");
1346                         return -RSE_ATTR_OVERFLOW;
1347                 }
1348
1349                 if (attr[1] < 2) {
1350                         nr_debug_error("Attribute length is too small");
1351                         return -RSE_ATTR_TOO_SMALL;
1352                 }
1353
1354                 if ((attr + attr[1]) > end) {
1355                         nr_debug_error("Attribute length is too large");
1356                         return -RSE_ATTR_TOO_LARGE;
1357                 }
1358 #endif
1359
1360                 if ((vendor == 0) && (attr[0] == attribute)) {
1361                         *pdata = attr + 2;
1362                         *plength = attr[1] - 2;
1363                         return attr - packet->data;
1364                 }
1365
1366 #ifndef WITHOUT_VSAS
1367                 if (vendor != 0) {
1368                         uint32_t vendorpec;
1369
1370                         if (attr[0] != PW_VENDOR_SPECIFIC) continue;
1371
1372                         if (attr[1] < 6) continue;
1373
1374                         memcpy(&vendorpec, attr + 2, 4);
1375                         vendorpec = ntohl(vendorpec);
1376                         if (vendor != vendorpec) continue;
1377
1378                         if (!dv) {
1379                                 dv = nr_dict_vendor_byvalue(vendor);
1380                                 if (dv &&
1381                                     ((dv->type != 1) || (dv->length != 1))) {
1382                                         return -RSE_VENDOR_UNKNOWN;
1383                                 }
1384                         }
1385
1386                         /*
1387                          *      No data.
1388                          */
1389                         if (attr[1] < 9) continue;
1390
1391                         /*
1392                          *      Malformed, or more than one VSA in
1393                          *      the Vendor-Specific
1394                          */
1395                         if (attr[7] + 6 != attr[1]) continue;
1396
1397                         /*
1398                          *      Not the right VSA.
1399                          */
1400                         if (attr[6] != attribute) continue;
1401
1402                         *pdata = attr + 8;
1403                         *plength = attr[1] - 8;
1404                         return attr - packet->data;
1405                 }
1406 #endif
1407         }
1408
1409         return 0;               /* nothing more: stop */
1410 }
1411