Skip zero-length attributes
[freeradius.git] / src / lib / radius.c
1 /*
2  * radius.c     Functions to send/receive radius packets.
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-2003,2006  The FreeRADIUS server project
21  */
22
23 #include        <freeradius-devel/ident.h>
24 RCSID("$Id$")
25
26 #include        <freeradius-devel/libradius.h>
27 #include        <freeradius-devel/md5.h>
28
29 #include        <fcntl.h>
30 #include        <ctype.h>
31
32 #ifdef WITH_UDPFROMTO
33 #include        <freeradius-devel/udpfromto.h>
34 #endif
35
36 #ifdef HAVE_MALLOC_H
37 #include        <malloc.h>
38 #endif
39
40 #if 0
41 #define VP_TRACE if (fr_debug_flag) printf
42 #else
43 #define VP_TRACE(_x, ...)
44 #endif
45
46
47 /*
48  *  The RFC says 4096 octets max, and most packets are less than 256.
49  */
50 #define MAX_PACKET_LEN 4096
51
52 /*
53  *      The maximum number of attributes which we allow in an incoming
54  *      request.  If there are more attributes than this, the request
55  *      is rejected.
56  *
57  *      This helps to minimize the potential for a DoS, when an
58  *      attacker spoofs Access-Request packets, which don't have a
59  *      Message-Authenticator attribute.  This means that the packet
60  *      is unsigned, and the attacker can use resources on the server,
61  *      even if the end request is rejected.
62  */
63 int fr_max_attributes = 0;
64 FILE *fr_log_fp = NULL;
65
66 typedef struct radius_packet_t {
67   uint8_t       code;
68   uint8_t       id;
69   uint8_t       length[2];
70   uint8_t       vector[AUTH_VECTOR_LEN];
71   uint8_t       data[1];
72 } radius_packet_t;
73
74 static fr_randctx fr_rand_pool; /* across multiple calls */
75 static int fr_rand_initialized = 0;
76 static unsigned int salt_offset = 0;
77
78 const char *fr_packet_codes[FR_MAX_PACKET_CODE] = {
79   "",
80   "Access-Request",
81   "Access-Accept",
82   "Access-Reject",
83   "Accounting-Request",
84   "Accounting-Response",
85   "Accounting-Status",
86   "Password-Request",
87   "Password-Accept",
88   "Password-Reject",
89   "Accounting-Message",
90   "Access-Challenge",
91   "Status-Server",
92   "Status-Client",
93   "14",
94   "15",
95   "16",
96   "17",
97   "18",
98   "19",
99   "20",
100   "Resource-Free-Request",
101   "Resource-Free-Response",
102   "Resource-Query-Request",
103   "Resource-Query-Response",
104   "Alternate-Resource-Reclaim-Request",
105   "NAS-Reboot-Request",
106   "NAS-Reboot-Response",
107   "28",
108   "Next-Passcode",
109   "New-Pin",
110   "Terminate-Session",
111   "Password-Expired",
112   "Event-Request",
113   "Event-Response",
114   "35",
115   "36",
116   "37",
117   "38",
118   "39",
119   "Disconnect-Request",
120   "Disconnect-ACK",
121   "Disconnect-NAK",
122   "CoA-Request",
123   "CoA-ACK",
124   "CoA-NAK",
125   "46",
126   "47",
127   "48",
128   "49",
129   "IP-Address-Allocate",
130   "IP-Address-Release"
131 };
132
133
134 void fr_printf_log(const char *fmt, ...)
135 {
136         va_list ap;
137
138         va_start(ap, fmt);
139         if ((fr_debug_flag == 0) || !fr_log_fp) {
140                 va_end(ap);
141                 return;
142         }
143
144         vfprintf(fr_log_fp, fmt, ap);
145         va_end(ap);
146
147         return;
148 }
149
150 static const char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
151
152 static void print_hex_data(const uint8_t *ptr, int attrlen, int depth)
153 {
154         int i;
155
156         for (i = 0; i < attrlen; i++) {
157                 if ((i > 0) && ((i & 0x0f) == 0x00))
158                         fprintf(fr_log_fp, "%.*s", depth, tabs);
159                 fprintf(fr_log_fp, "%02x ", ptr[i]);
160                 if ((i & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");
161         }
162         if ((i & 0x0f) != 0) fprintf(fr_log_fp, "\n");
163 }
164
165
166 void rad_print_hex(RADIUS_PACKET *packet)
167 {
168         int i;
169
170         if (!packet->data || !fr_log_fp) return;
171
172         fprintf(fr_log_fp, "  Code:\t\t%u\n", packet->data[0]);
173         fprintf(fr_log_fp, "  Id:\t\t%u\n", packet->data[1]);
174         fprintf(fr_log_fp, "  Length:\t%u\n", ((packet->data[2] << 8) |
175                                    (packet->data[3])));
176         fprintf(fr_log_fp, "  Vector:\t");
177         for (i = 4; i < 20; i++) {
178                 fprintf(fr_log_fp, "%02x", packet->data[i]);
179         }
180         fprintf(fr_log_fp, "\n");
181
182         if (packet->data_len > 20) {
183                 int total;
184                 const uint8_t *ptr;
185                 fprintf(fr_log_fp, "  Data:");
186
187                 total = packet->data_len - 20;
188                 ptr = packet->data + 20;
189
190                 while (total > 0) {
191                         int attrlen;
192                         unsigned int vendor = 0;
193
194                         fprintf(fr_log_fp, "\t\t");
195                         if (total < 2) { /* too short */
196                                 fprintf(fr_log_fp, "%02x\n", *ptr);
197                                 break;
198                         }
199
200                         if (ptr[1] > total) { /* too long */
201                                 for (i = 0; i < total; i++) {
202                                         fprintf(fr_log_fp, "%02x ", ptr[i]);
203                                 }
204                                 break;
205                         }
206
207                         fprintf(fr_log_fp, "%02x  %02x  ", ptr[0], ptr[1]);
208                         attrlen = ptr[1] - 2;
209
210                         if ((ptr[0] == PW_VENDOR_SPECIFIC) &&
211                             (attrlen > 4)) {
212                                 vendor = (ptr[3] << 16) | (ptr[4] << 8) | ptr[5];
213                                 fprintf(fr_log_fp, "%02x%02x%02x%02x (%u)  ",
214                                        ptr[2], ptr[3], ptr[4], ptr[5], vendor);
215                                 attrlen -= 4;
216                                 ptr += 6;
217                                 total -= 6;
218
219                         } else {
220                                 ptr += 2;
221                                 total -= 2;
222                                 vendor = 0;
223                         }
224
225                         print_hex_data(ptr, attrlen, 3);
226
227                         ptr += attrlen;
228                         total -= attrlen;
229                 }
230         }
231         fflush(stdout);
232 }
233
234 /*
235  *      Wrapper for sendto which handles sendfromto, IPv6, and all
236  *      possible combinations.
237  */
238 static int rad_sendto(int sockfd, void *data, size_t data_len, int flags,
239                       fr_ipaddr_t *src_ipaddr, int src_port,
240                       fr_ipaddr_t *dst_ipaddr, int dst_port)
241 {
242         int rcode;
243         struct sockaddr_storage dst;
244         socklen_t               sizeof_dst;
245
246 #ifdef WITH_UDPFROMTO
247         struct sockaddr_storage src;
248         socklen_t               sizeof_src;
249
250         fr_ipaddr2sockaddr(src_ipaddr, src_port, &src, &sizeof_src);
251 #else
252         src_port = src_port;    /* -Wunused */
253 #endif
254
255         if (!fr_ipaddr2sockaddr(dst_ipaddr, dst_port, &dst, &sizeof_dst)) {
256                 return -1;
257         }
258
259 #ifdef WITH_UDPFROMTO
260         /*
261          *      And if they don't specify a source IP address, don't
262          *      use udpfromto.
263          */
264         if (((dst_ipaddr->af == AF_INET) || (dst_ipaddr->af == AF_INET6)) &&
265             (src_ipaddr->af != AF_UNSPEC) &&
266             !fr_inaddr_any(src_ipaddr)) {
267                 rcode = sendfromto(sockfd, data, data_len, flags,
268                                    (struct sockaddr *)&src, sizeof_src,
269                                    (struct sockaddr *)&dst, sizeof_dst);
270                 goto done;
271         }
272 #else
273         src_ipaddr = src_ipaddr; /* -Wunused */
274 #endif
275
276         /*
277          *      No udpfromto, fail gracefully.
278          */
279         rcode = sendto(sockfd, data, data_len, flags,
280                        (struct sockaddr *) &dst, sizeof_dst);
281         if (rcode < 0) {
282                 DEBUG("rad_send() failed: %s\n", strerror(errno));
283         }
284
285         return rcode;
286 }
287
288
289 void rad_recv_discard(int sockfd)
290 {
291         uint8_t                 header[4];
292         struct sockaddr_storage src;
293         socklen_t               sizeof_src = sizeof(src);
294
295         recvfrom(sockfd, header, sizeof(header), 0,
296                  (struct sockaddr *)&src, &sizeof_src);
297 }
298
299
300 ssize_t rad_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, int *src_port,
301                         int *code)
302 {
303         ssize_t                 data_len, packet_len;
304         uint8_t                 header[4];
305         struct sockaddr_storage src;
306         socklen_t               sizeof_src = sizeof(src);
307
308         data_len = recvfrom(sockfd, header, sizeof(header), MSG_PEEK,
309                             (struct sockaddr *)&src, &sizeof_src);
310         if (data_len < 0) {
311                 if ((errno == EAGAIN) || (errno == EINTR)) return 0;
312                 return -1;
313         }
314
315         /*
316          *      Too little data is available, discard the packet.
317          */
318         if (data_len < 4) {
319                 recvfrom(sockfd, header, sizeof(header), 0,
320                          (struct sockaddr *)&src, &sizeof_src);
321                 return 1;
322
323         } else {                /* we got 4 bytes of data. */
324                 /*
325                  *      See how long the packet says it is.
326                  */
327                 packet_len = (header[2] * 256) + header[3];
328
329                 /*
330                  *      The length in the packet says it's less than
331                  *      a RADIUS header length: discard it.
332                  */
333                 if (packet_len < AUTH_HDR_LEN) {
334                         recvfrom(sockfd, header, sizeof(header), 0,
335                                  (struct sockaddr *)&src, &sizeof_src);
336                         return 1;
337
338                         /*
339                          *      Enforce RFC requirements, for sanity.
340                          *      Anything after 4k will be discarded.
341                          */
342                 } else if (packet_len > MAX_PACKET_LEN) {
343                         recvfrom(sockfd, header, sizeof(header), 0,
344                                  (struct sockaddr *)&src, &sizeof_src);
345                         return 1;
346                 }
347         }
348
349         /*
350          *      Convert AF.  If unknown, discard packet.
351          */
352         if (!fr_sockaddr2ipaddr(&src, sizeof_src, src_ipaddr, src_port)) {
353                 recvfrom(sockfd, header, sizeof(header), 0,
354                          (struct sockaddr *)&src, &sizeof_src);
355                 return 1;
356         }
357
358         *code = header[0];
359
360         /*
361          *      The packet says it's this long, but the actual UDP
362          *      size could still be smaller.
363          */
364         return packet_len;
365 }
366
367
368 /*
369  *      wrapper for recvfrom, which handles recvfromto, IPv6, and all
370  *      possible combinations.
371  */
372 static ssize_t rad_recvfrom(int sockfd, uint8_t **pbuf, int flags,
373                             fr_ipaddr_t *src_ipaddr, uint16_t *src_port,
374                             fr_ipaddr_t *dst_ipaddr, uint16_t *dst_port)
375 {
376         struct sockaddr_storage src;
377         struct sockaddr_storage dst;
378         socklen_t               sizeof_src = sizeof(src);
379         socklen_t               sizeof_dst = sizeof(dst);
380         ssize_t                 data_len;
381         uint8_t                 header[4];
382         void                    *buf;
383         size_t                  len;
384         int                     port;
385
386         memset(&src, 0, sizeof_src);
387         memset(&dst, 0, sizeof_dst);
388
389         /*
390          *      Get address family, etc. first, so we know if we
391          *      need to do udpfromto.
392          *
393          *      FIXME: udpfromto also does this, but it's not
394          *      a critical problem.
395          */
396         if (getsockname(sockfd, (struct sockaddr *)&dst,
397                         &sizeof_dst) < 0) return -1;
398
399         /*
400          *      Read the length of the packet, from the packet.
401          *      This lets us allocate the buffer to use for
402          *      reading the rest of the packet.
403          */
404         data_len = recvfrom(sockfd, header, sizeof(header), MSG_PEEK,
405                             (struct sockaddr *)&src, &sizeof_src);
406         if (data_len < 0) {
407                 if ((errno == EAGAIN) || (errno == EINTR)) return 0;
408                 return -1;
409         }
410
411         /*
412          *      Too little data is available, discard the packet.
413          */
414         if (data_len < 4) {
415                 recvfrom(sockfd, header, sizeof(header), flags,
416                          (struct sockaddr *)&src, &sizeof_src);
417                 return 0;
418
419         } else {                /* we got 4 bytes of data. */
420                 /*
421                  *      See how long the packet says it is.
422                  */
423                 len = (header[2] * 256) + header[3];
424
425                 /*
426                  *      The length in the packet says it's less than
427                  *      a RADIUS header length: discard it.
428                  */
429                 if (len < AUTH_HDR_LEN) {
430                         recvfrom(sockfd, header, sizeof(header), flags,
431                                  (struct sockaddr *)&src, &sizeof_src);
432                         return 0;
433
434                         /*
435                          *      Enforce RFC requirements, for sanity.
436                          *      Anything after 4k will be discarded.
437                          */
438                 } else if (len > MAX_PACKET_LEN) {
439                         recvfrom(sockfd, header, sizeof(header), flags,
440                                  (struct sockaddr *)&src, &sizeof_src);
441                         return len;
442                 }
443         }
444
445         buf = malloc(len);
446         if (!buf) return -1;
447
448         /*
449          *      Receive the packet.  The OS will discard any data in the
450          *      packet after "len" bytes.
451          */
452 #ifdef WITH_UDPFROMTO
453         if ((dst.ss_family == AF_INET) || (dst.ss_family == AF_INET6)) {
454                 data_len = recvfromto(sockfd, buf, len, flags,
455                                       (struct sockaddr *)&src, &sizeof_src,
456                                       (struct sockaddr *)&dst, &sizeof_dst);
457         } else
458 #endif
459                 /*
460                  *      No udpfromto, fail gracefully.
461                  */
462                 data_len = recvfrom(sockfd, buf, len, flags,
463                                     (struct sockaddr *)&src, &sizeof_src);
464         if (data_len < 0) {
465                 free(buf);
466                 return data_len;
467         }
468
469         if (!fr_sockaddr2ipaddr(&src, sizeof_src, src_ipaddr, &port)) {
470                 free(buf);
471                 return -1;      /* Unknown address family, Die Die Die! */
472         }
473         *src_port = port;
474
475         fr_sockaddr2ipaddr(&dst, sizeof_dst, dst_ipaddr, &port);
476         *dst_port = port;
477
478         /*
479          *      Different address families should never happen.
480          */
481         if (src.ss_family != dst.ss_family) {
482                 free(buf);
483                 return -1;
484         }
485
486         /*
487          *      Tell the caller about the data
488          */
489         *pbuf = buf;
490
491         return data_len;
492 }
493
494
495 #define AUTH_PASS_LEN (AUTH_VECTOR_LEN)
496 /*************************************************************************
497  *
498  *      Function: make_secret
499  *
500  *      Purpose: Build an encrypted secret value to return in a reply
501  *               packet.  The secret is hidden by xoring with a MD5 digest
502  *               created from the shared secret and the authentication
503  *               vector.  We put them into MD5 in the reverse order from
504  *               that used when encrypting passwords to RADIUS.
505  *
506  *************************************************************************/
507 static void make_secret(uint8_t *digest, const uint8_t *vector,
508                         const char *secret, const uint8_t *value)
509 {
510         FR_MD5_CTX context;
511         int             i;
512
513         fr_MD5Init(&context);
514         fr_MD5Update(&context, vector, AUTH_VECTOR_LEN);
515         fr_MD5Update(&context, (const uint8_t *) secret, strlen(secret));
516         fr_MD5Final(digest, &context);
517
518         for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
519                 digest[i] ^= value[i];
520         }
521 }
522
523 #define MAX_PASS_LEN (128)
524 static void make_passwd(uint8_t *output, ssize_t *outlen,
525                         const uint8_t *input, size_t inlen,
526                         const char *secret, const uint8_t *vector)
527 {
528         FR_MD5_CTX context, old;
529         uint8_t digest[AUTH_VECTOR_LEN];
530         uint8_t passwd[MAX_PASS_LEN];
531         int     i, n;
532         int     len;
533
534         /*
535          *      If the length is zero, round it up.
536          */
537         len = inlen;
538
539         if (len > MAX_PASS_LEN) len = MAX_PASS_LEN;
540
541         memcpy(passwd, input, len);
542         memset(passwd + len, 0, sizeof(passwd) - len);
543
544         if (len == 0) {
545                 len = AUTH_PASS_LEN;
546         }
547
548         else if ((len & 0x0f) != 0) {
549                 len += 0x0f;
550                 len &= ~0x0f;
551         }
552         *outlen = len;
553
554         fr_MD5Init(&context);
555         fr_MD5Update(&context, (const uint8_t *) secret, strlen(secret));
556         old = context;
557
558         /*
559          *      Do first pass.
560          */
561         fr_MD5Update(&context, vector, AUTH_PASS_LEN);
562
563         for (n = 0; n < len; n += AUTH_PASS_LEN) {
564                 if (n > 0) {
565                         context = old;
566                         fr_MD5Update(&context,
567                                        passwd + n - AUTH_PASS_LEN,
568                                        AUTH_PASS_LEN);
569                 }
570
571                 fr_MD5Final(digest, &context);
572                 for (i = 0; i < AUTH_PASS_LEN; i++) {
573                         passwd[i + n] ^= digest[i];
574                 }
575         }
576
577         memcpy(output, passwd, len);
578 }
579
580 static void make_tunnel_passwd(uint8_t *output, ssize_t *outlen,
581                                const uint8_t *input, size_t inlen, size_t room,
582                                const char *secret, const uint8_t *vector)
583 {
584         FR_MD5_CTX context, old;
585         uint8_t digest[AUTH_VECTOR_LEN];
586         uint8_t passwd[MAX_STRING_LEN + AUTH_VECTOR_LEN];
587         int     i, n;
588         int     len;
589
590         /*
591          *      Be paranoid.
592          */
593         if (room > 253) room = 253;
594
595         /*
596          *      Account for 2 bytes of the salt, and round the room
597          *      available down to the nearest multiple of 16.  Then,
598          *      subtract one from that to account for the length byte,
599          *      and the resulting number is the upper bound on the data
600          *      to copy.
601          *
602          *      We could short-cut this calculation just be forcing
603          *      inlen to be no more than 239.  It would work for all
604          *      VSA's, as we don't pack multiple VSA's into one
605          *      attribute.
606          *
607          *      However, this calculation is more general, if a little
608          *      complex.  And it will work in the future for all possible
609          *      kinds of weird attribute packing.
610          */
611         room -= 2;
612         room -= (room & 0x0f);
613         room--;
614
615         if (inlen > room) inlen = room;
616
617         /*
618          *      Length of the encrypted data is password length plus
619          *      one byte for the length of the password.
620          */
621         len = inlen + 1;
622         if ((len & 0x0f) != 0) {
623                 len += 0x0f;
624                 len &= ~0x0f;
625         }
626         *outlen = len + 2;      /* account for the salt */
627
628         /*
629          *      Copy the password over.
630          */
631         memcpy(passwd + 3, input, inlen);
632         memset(passwd + 3 + inlen, 0, sizeof(passwd) - 3 - inlen);
633
634         /*
635          *      Generate salt.  The RFC's say:
636          *
637          *      The high bit of salt[0] must be set, each salt in a
638          *      packet should be unique, and they should be random
639          *
640          *      So, we set the high bit, add in a counter, and then
641          *      add in some CSPRNG data.  should be OK..
642          */
643         passwd[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
644                      (fr_rand() & 0x07));
645         passwd[1] = fr_rand();
646         passwd[2] = inlen;      /* length of the password string */
647
648         fr_MD5Init(&context);
649         fr_MD5Update(&context, (const uint8_t *) secret, strlen(secret));
650         old = context;
651
652         fr_MD5Update(&context, vector, AUTH_VECTOR_LEN);
653         fr_MD5Update(&context, &passwd[0], 2);
654
655         for (n = 0; n < len; n += AUTH_PASS_LEN) {
656                 if (n > 0) {
657                         context = old;
658                         fr_MD5Update(&context,
659                                        passwd + 2 + n - AUTH_PASS_LEN,
660                                        AUTH_PASS_LEN);
661                 }
662
663                 fr_MD5Final(digest, &context);
664
665                 for (i = 0; i < AUTH_PASS_LEN; i++) {
666                         passwd[i + 2 + n] ^= digest[i];
667                 }
668         }
669         memcpy(output, passwd, len + 2);
670 }
671
672 extern int fr_attr_max_tlv;
673 extern int fr_attr_shift[];
674 extern int fr_attr_mask[];
675
676 static int do_next_tlv(const VALUE_PAIR *vp, const VALUE_PAIR *next, int nest)
677 {
678         unsigned int tlv1, tlv2;
679
680         if (nest > fr_attr_max_tlv) return 0;
681
682         if (!vp) return 0;
683
684         /*
685          *      Keep encoding TLVs which have the same scope.
686          *      e.g. two attributes of:
687          *              ATTR.TLV1.TLV2.TLV3 = data1
688          *              ATTR.TLV1.TLV2.TLV4 = data2
689          *      both get put into a container of "ATTR.TLV1.TLV2"
690          */
691
692         /*
693          *      Nothing to follow, we're done.
694          */
695         if (!next) return 0;
696
697         /*
698          *      Not from the same vendor, skip it.
699          */
700         if (vp->vendor != next->vendor) return 0;
701
702         /*
703          *      In a different TLV space, skip it.
704          */
705         tlv1 = vp->attribute;
706         tlv2 = next->attribute;
707         
708         tlv1 &= ((1 << fr_attr_shift[nest]) - 1);
709         tlv2 &= ((1 << fr_attr_shift[nest]) - 1);
710         
711         if (tlv1 != tlv2) return 0;
712
713         return 1;
714 }
715
716
717 static ssize_t vp2data_any(const RADIUS_PACKET *packet,
718                            const RADIUS_PACKET *original,
719                            const char *secret, int nest,
720                            const VALUE_PAIR **pvp,
721                            uint8_t *start, size_t room);
722
723 static ssize_t vp2attr_rfc(const RADIUS_PACKET *packet,
724                            const RADIUS_PACKET *original,
725                            const char *secret, const VALUE_PAIR **pvp,
726                            unsigned int attribute, uint8_t *ptr, size_t room);
727
728 /*
729  *      This is really a sub-function of vp2data_any.  It encodes
730  *      the *data* portion of the TLV, and assumes that the encapsulating
731  *      attribute has already been encoded.
732  */
733 static ssize_t vp2data_tlvs(const RADIUS_PACKET *packet,
734                             const RADIUS_PACKET *original,
735                             const char *secret, int nest,
736                             const VALUE_PAIR **pvp,
737                             uint8_t *start, size_t room)
738 {
739         ssize_t len;
740         size_t my_room;
741         uint8_t *ptr = start;
742         const VALUE_PAIR *old_vp;
743         const VALUE_PAIR *vp = *pvp;
744         const VALUE_PAIR *svp = vp;
745
746 #ifndef NDEBUG
747
748         if (nest > fr_attr_max_tlv) {
749                 fr_strerror_printf("vp2data_tlvs: attribute nesting overflow");
750                 return -1;
751         }
752 #endif
753
754         while (vp) {
755                 if (room < 2) return ptr - start;
756                 
757                 old_vp = vp;
758                 ptr[0] = (vp->attribute >> fr_attr_shift[nest]) & fr_attr_mask[nest];
759                 ptr[1] = 2;
760                 
761                 my_room = room;
762                 if (room > 255) my_room = 255;
763
764                 len = vp2data_any(packet, original, secret, nest,
765                                   &vp, ptr + 2, my_room - 2);
766                 if (len < 0) return len;
767                 if (len == 0) return ptr - start;
768                 /* len can NEVER be more than 253 */
769
770                 ptr[1] += len;
771
772 #ifndef NDEBUG
773                 if ((fr_debug_flag > 3) && fr_log_fp) {
774                         fprintf(fr_log_fp, "\t\t%02x %02x  ", ptr[0], ptr[1]);
775                         print_hex_data(ptr + 2, len, 3);
776                 }
777 #endif
778
779                 room -= ptr[1];
780                 ptr += ptr[1];
781                 *pvp = vp;
782                 
783                 if (!do_next_tlv(svp, vp, nest)) break;
784         }
785
786 #ifndef NDEBUG
787         if ((fr_debug_flag > 3) && fr_log_fp) {
788                 DICT_ATTR *da;
789                 
790                 da = dict_attrbyvalue(svp->attribute & ((1 << fr_attr_shift[nest ]) - 1), svp->vendor);
791                 if (da) fprintf(fr_log_fp, "\t%s = ...\n", da->name);
792         }
793 #endif
794
795         return ptr - start;
796 }
797
798
799 /*
800  *      Encodes the data portion of an attribute.
801  *      Returns -1 on error, or the length of the data portion.
802  */
803 static ssize_t vp2data_any(const RADIUS_PACKET *packet,
804                            const RADIUS_PACKET *original,
805                            const char *secret, int nest,
806                            const VALUE_PAIR **pvp,
807                            uint8_t *start, size_t room)
808 {
809         uint32_t lvalue;
810         ssize_t len;
811         const uint8_t *data;
812         uint8_t *ptr = start;
813         uint8_t array[4];
814         const VALUE_PAIR *vp = *pvp;
815
816         /*
817          *      See if we need to encode a TLV.  The low portion of
818          *      the attribute has already been placed into the packer.
819          *      If there are still attribute bytes left, then go
820          *      encode them as TLVs.
821          *
822          *      If we cared about the stack, we could unroll the loop.
823          */
824         if (vp->flags.is_tlv && (nest < fr_attr_max_tlv) &&
825             ((vp->attribute >> fr_attr_shift[nest + 1]) != 0)) {
826                 return vp2data_tlvs(packet, original, secret, nest + 1, pvp,
827                                     start, room);
828         }
829
830         debug_pair(vp);
831
832         /*
833          *      Set up the default sources for the data.
834          */
835         data = vp->vp_octets;
836         len = vp->length;
837
838         switch(vp->type) {
839         case PW_TYPE_STRING:
840         case PW_TYPE_OCTETS:
841         case PW_TYPE_IFID:
842         case PW_TYPE_IPV6ADDR:
843         case PW_TYPE_IPV6PREFIX:
844         case PW_TYPE_ABINARY:
845                 /* nothing more to do */
846                 break;
847
848         case PW_TYPE_BYTE:
849                 len = 1;        /* just in case */
850                 array[0] = vp->vp_integer & 0xff;
851                 data = array;
852                 break;
853
854         case PW_TYPE_SHORT:
855                 len = 2;        /* just in case */
856                 array[0] = (vp->vp_integer >> 8) & 0xff;
857                 array[1] = vp->vp_integer & 0xff;
858                 data = array;
859                 break;
860
861         case PW_TYPE_INTEGER:
862                 len = 4;        /* just in case */
863                 lvalue = htonl(vp->vp_integer);
864                 memcpy(array, &lvalue, sizeof(lvalue));
865                 data = array;
866                 break;
867
868         case PW_TYPE_IPADDR:
869                 data = (const uint8_t *) &vp->vp_ipaddr;
870                 len = 4;        /* just in case */
871                 break;
872
873                 /*
874                  *  There are no tagged date attributes.
875                  */
876         case PW_TYPE_DATE:
877                 lvalue = htonl(vp->vp_date);
878                 data = (const uint8_t *) &lvalue;
879                 len = 4;        /* just in case */
880                 break;
881
882         case PW_TYPE_SIGNED:
883         {
884                 int32_t slvalue;
885
886                 len = 4;        /* just in case */
887                 slvalue = htonl(vp->vp_signed);
888                 memcpy(array, &slvalue, sizeof(slvalue));
889                 break;
890         }
891
892         case PW_TYPE_TLV:
893                 data = vp->vp_tlv;
894                 if (!data) {
895                         fr_strerror_printf("ERROR: Cannot encode NULL TLV");
896                         return -1;
897                 }
898                 len = vp->length;
899                 break;
900
901         default:                /* unknown type: ignore it */
902                 fr_strerror_printf("ERROR: Unknown attribute type %d", vp->type);
903                 return -1;
904         }
905
906         /*
907          *      No data: skip it.
908          */
909         if (len == 0) {
910                 *pvp = vp->next;
911                 return 0;
912         }
913
914         /*
915          *      Bound the data to the calling size
916          */
917         if (len > (ssize_t) room) len = room;
918
919         /*
920          *      Encrypt the various password styles
921          *
922          *      Attributes with encrypted values MUST be less than
923          *      128 bytes long.
924          */
925         switch (vp->flags.encrypt) {
926         case FLAG_ENCRYPT_USER_PASSWORD:
927                 make_passwd(ptr, &len, data, len,
928                             secret, packet->vector);
929                 break;
930
931         case FLAG_ENCRYPT_TUNNEL_PASSWORD:
932                 lvalue = 0;
933                 if (vp->flags.has_tag) lvalue = 1;
934
935                 /*
936                  *      Check if there's enough room.  If there isn't,
937                  *      we discard the attribute.
938                  *
939                  *      This is ONLY a problem if we have multiple VSA's
940                  *      in one Vendor-Specific, though.
941                  */
942                 if (room < (18 + lvalue)) return 0;
943
944                 switch (packet->code) {
945                 case PW_AUTHENTICATION_ACK:
946                 case PW_AUTHENTICATION_REJECT:
947                 case PW_ACCESS_CHALLENGE:
948                 default:
949                         if (!original) {
950                                 fr_strerror_printf("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->name);
951                                 return -1;
952                         }
953
954                         if (lvalue) ptr[0] = vp->flags.tag;
955                         make_tunnel_passwd(ptr + lvalue, &len, data, len,
956                                            room - lvalue,
957                                            secret, original->vector);
958                         break;
959                 case PW_ACCOUNTING_REQUEST:
960                 case PW_DISCONNECT_REQUEST:
961                 case PW_COA_REQUEST:
962                         ptr[0] = vp->flags.tag;
963                         make_tunnel_passwd(ptr + 1, &len, data, len - 1, room,
964                                            secret, packet->vector);
965                         break;
966                 }
967                 break;
968
969                 /*
970                  *      The code above ensures that this attribute
971                  *      always fits.
972                  */
973         case FLAG_ENCRYPT_ASCEND_SECRET:
974                 make_secret(ptr, packet->vector, secret, data);
975                 len = AUTH_VECTOR_LEN;
976                 break;
977
978
979         default:
980                 if (vp->flags.has_tag && TAG_VALID(vp->flags.tag)) {
981                         if (vp->type == PW_TYPE_STRING) {
982                                 if (len > ((ssize_t) (room - 1))) len = room - 1;
983                                 ptr[0] = vp->flags.tag;
984                                 ptr++;
985                         } else if (vp->type == PW_TYPE_INTEGER) {
986                                 array[0] = vp->flags.tag;
987                         } /* else it can't be any other type */
988                 }
989                 memcpy(ptr, data, len);
990                 break;
991         } /* switch over encryption flags */
992
993         *pvp = vp->next;
994         return len + (ptr - start);
995 }
996
997 static ssize_t attr_shift(const uint8_t *start, const uint8_t *end,
998                           uint8_t *ptr, int hdr_len, ssize_t len,
999                           int flag_offset, int vsa_offset)
1000 {
1001         int check_len = len - ptr[1];
1002         int total = len + hdr_len;
1003         
1004         /*
1005          *      Pass 1: Check if the addition of the headers
1006          *      overflows the available room.  If so, return
1007          *      what we were capable of encoding.
1008          */
1009         
1010         while (check_len > (255 - hdr_len)) {
1011                 total += hdr_len;
1012                 check_len -= (255 - hdr_len);
1013         }
1014
1015         /*
1016          *      Note that this results in a number of attributes maybe
1017          *      being marked as "encoded", but which aren't in the
1018          *      packet.  Oh well.  The solution is to fix the
1019          *      "vp2data_any" function to take into account the header
1020          *      lengths.
1021          */
1022         if ((ptr + ptr[1] + total) > end) {
1023                 return (ptr + ptr[1]) - start;
1024         }
1025         
1026         /*
1027          *      Pass 2: Now that we know there's enough room,
1028          *      re-arrange the data to form a set of valid
1029          *      RADIUS attributes.
1030          */
1031         while (1) {
1032                 int sublen = 255 - ptr[1];
1033                 
1034                 if (len <= sublen) {
1035                         break;
1036                 }
1037                 
1038                 len -= sublen;
1039                 memmove(ptr + 255 + hdr_len, ptr + 255, sublen);
1040                 memcpy(ptr + 255, ptr, hdr_len);
1041                 ptr[1] += sublen;
1042                 if (vsa_offset) ptr[vsa_offset] += sublen;
1043                 ptr[flag_offset] |= 0x80;
1044                 
1045                 ptr += 255;
1046                 ptr[1] = hdr_len;
1047                 if (vsa_offset) ptr[vsa_offset] = 3;
1048         }
1049
1050         ptr[1] += len;
1051         if (vsa_offset) ptr[vsa_offset] += len;
1052
1053         return (ptr + ptr[1]) - start;
1054 }
1055
1056
1057 /*
1058  *      Encode an "extended" attribute.
1059  */
1060 int rad_vp2extended(const RADIUS_PACKET *packet,
1061                     const RADIUS_PACKET *original,
1062                     const char *secret, const VALUE_PAIR **pvp,
1063                     uint8_t *ptr, size_t room)
1064 {
1065         int len;
1066         int hdr_len;
1067         int nest = 1;
1068         uint8_t *start = ptr;
1069         const VALUE_PAIR *vp = *pvp;
1070
1071         if (vp->vendor < VENDORPEC_EXTENDED) {
1072                 fr_strerror_printf("rad_vp2extended called for non-extended attribute");
1073                 return -1;
1074         }
1075
1076         if (room < 3) return 0;
1077
1078         ptr[0] = vp->attribute & 0xff;
1079         ptr[1] = 3;
1080
1081         if (vp->flags.extended) {
1082                 ptr[2] = (vp->attribute & 0xff00) >> 8;
1083
1084         } else if (vp->flags.extended_flags) {
1085                 if (room < 4) return 0;
1086
1087                 ptr[1] = 4;
1088                 ptr[2] = (vp->attribute & 0xff00) >> 8;
1089                 ptr[3] = 0;
1090         }
1091
1092         /*
1093          *      Only "flagged" attributes can be longer than one
1094          *      attribute.
1095          */
1096         if (!vp->flags.extended_flags && (room > 255)) {
1097                 room = 255;
1098         }
1099
1100         /*
1101          *      Handle EVS VSAs.
1102          */
1103         if (vp->flags.evs) {
1104                 uint8_t *evs = ptr + ptr[1];
1105
1106                 if (room < (size_t) (ptr[1] + 5)) return 0;
1107
1108                 /*
1109                  *      RADIUS Attribute Type is packed into the high byte
1110                  *      of the Vendor Id.  So over-write it in the packet.
1111                  *
1112                  *      And hard-code Extended-Type to Vendor-Specific.
1113                  */
1114                 ptr[0] = (vp->vendor >> 24) & 0xff;
1115                 ptr[2] = 26;
1116
1117                 evs[0] = 0;     /* always zero */
1118                 evs[1] = (vp->vendor >> 16) & 0xff;
1119                 evs[2] = (vp->vendor >> 8) & 0xff;
1120                 evs[3] = vp->vendor & 0xff;
1121                 evs[4] = vp->attribute & 0xff;          
1122
1123                 ptr[1] += 5;
1124                 nest = 0;
1125         }
1126         hdr_len = ptr[1];
1127
1128         len = vp2data_any(packet, original, secret, nest,
1129                           pvp, ptr + ptr[1], room - hdr_len);
1130         if (len <= 0) return len;
1131
1132         /*
1133          *      There may be more than 252 octets of data encoded in
1134          *      the attribute.  If so, move the data up in the packet,
1135          *      and copy the existing header over.  Set the "M" flag ONLY
1136          *      after copying the rest of the data.
1137          */
1138         if (vp->flags.extended_flags && (len > (255 - ptr[1]))) {
1139                 return attr_shift(start, start + room, ptr, 4, len, 3, 0);
1140         }
1141
1142         ptr[1] += len;
1143         
1144 #ifndef NDEBUG
1145         if ((fr_debug_flag > 3) && fr_log_fp) {
1146                 int jump = 3;
1147
1148                 fprintf(fr_log_fp, "\t\t%02x %02x  ", ptr[0], ptr[1]);
1149                 if (!vp->flags.extended_flags) {
1150                         fprintf(fr_log_fp, "%02x  ", ptr[2]);
1151                         
1152                 } else {
1153                         fprintf(fr_log_fp, "%02x %02x  ", ptr[2], ptr[3]);
1154                         jump = 4;
1155                 }
1156
1157                 if (vp->flags.evs) {
1158                         fprintf(fr_log_fp, "%02x%02x%02x%02x (%u)  %02x  ",
1159                                 ptr[jump], ptr[jump + 1],
1160                                 ptr[jump + 2], ptr[jump + 3],
1161                                 ((ptr[jump + 1] << 16) |
1162                                  (ptr[jump + 2] << 8) |
1163                                  ptr[jump + 3]),
1164                                 ptr[jump + 4]);
1165                         jump += 5;
1166                 }
1167
1168                 print_hex_data(ptr + jump, len, 3);
1169         }
1170 #endif
1171
1172         return (ptr + ptr[1]) - start;
1173 }
1174
1175
1176 /*
1177  *      Encode a WiMAX attribute.
1178  */
1179 int rad_vp2wimax(const RADIUS_PACKET *packet,
1180                  const RADIUS_PACKET *original,
1181                  const char *secret, const VALUE_PAIR **pvp,
1182                  uint8_t *ptr, size_t room)
1183 {
1184         int len;
1185         uint32_t lvalue;
1186         int hdr_len;
1187         uint8_t *start = ptr;
1188         const VALUE_PAIR *vp = *pvp;
1189
1190         /*
1191          *      Double-check for WiMAX format.
1192          */
1193         if (!vp->flags.wimax) {
1194                 fr_strerror_printf("rad_vp2wimax called for non-WIMAX VSA");
1195                 return -1;
1196         }
1197
1198         /*
1199          *      Not enough room for:
1200          *              attr, len, vendor-id, vsa, vsalen, continuation
1201          */
1202         if (room < 9) return 0;
1203
1204         /*
1205          *      Build the Vendor-Specific header
1206          */
1207         ptr = start;
1208         ptr[0] = PW_VENDOR_SPECIFIC;
1209         ptr[1] = 9;
1210         lvalue = htonl(vp->vendor);
1211         memcpy(ptr + 2, &lvalue, 4);
1212         ptr[6] = (vp->attribute & fr_attr_mask[1]);
1213         ptr[7] = 3;
1214         ptr[8] = 0;             /* continuation byte */
1215
1216         hdr_len = 9;
1217
1218         len = vp2data_any(packet, original, secret, 0, pvp, ptr + ptr[1],
1219                           room - hdr_len);
1220         if (len <= 0) return len;
1221
1222         /*
1223          *      There may be more than 252 octets of data encoded in
1224          *      the attribute.  If so, move the data up in the packet,
1225          *      and copy the existing header over.  Set the "C" flag
1226          *      ONLY after copying the rest of the data.
1227          */
1228         if (len > (255 - ptr[1])) {
1229                 return attr_shift(start, start + room, ptr, hdr_len, len, 8, 7);
1230         }
1231
1232         ptr[1] += len;
1233         ptr[7] += len;
1234
1235 #ifndef NDEBUG
1236         if ((fr_debug_flag > 3) && fr_log_fp) {
1237                 fprintf(fr_log_fp, "\t\t%02x %02x  %02x%02x%02x%02x (%u)  %02x %02x %02x   ",
1238                        ptr[0], ptr[1],
1239                        ptr[2], ptr[3], ptr[4], ptr[5],
1240                        (ptr[3] << 16) | (ptr[4] << 8) | ptr[5],
1241                        ptr[6], ptr[7], ptr[8]);
1242                 print_hex_data(ptr + 9, len, 3);
1243         }
1244 #endif
1245
1246         return (ptr + ptr[1]) - start;
1247 }
1248
1249 /*
1250  *      Encode an RFC format TLV.  This could be a standard attribute,
1251  *      or a TLV data type.  If it's a standard attribute, then
1252  *      vp->attribute == attribute.  Otherwise, attribute may be
1253  *      something else.
1254  */
1255 static ssize_t vp2attr_rfc(const RADIUS_PACKET *packet,
1256                            const RADIUS_PACKET *original,
1257                            const char *secret, const VALUE_PAIR **pvp,
1258                            unsigned int attribute, uint8_t *ptr, size_t room)
1259 {
1260         ssize_t len;
1261
1262         if (room < 2) return 0;
1263
1264         ptr[0] = attribute & 0xff;
1265         ptr[1] = 2;
1266
1267         if (room > ((unsigned) 255 - ptr[1])) room = 255 - ptr[1];
1268
1269         len = vp2data_any(packet, original, secret, 0, pvp, ptr + ptr[1], room);
1270         if (len <= 0) return len;
1271
1272         ptr[1] += len;
1273
1274 #ifndef NDEBUG
1275         if ((fr_debug_flag > 3) && fr_log_fp) {
1276                 fprintf(fr_log_fp, "\t\t%02x %02x  ", ptr[0], ptr[1]);
1277                 print_hex_data(ptr + 2, len, 3);
1278         }
1279 #endif
1280
1281         return ptr[1];
1282 }
1283
1284
1285 /*
1286  *      Encode a VSA which is a TLV.  If it's in the RFC format, call
1287  *      vp2attr_rfc.  Otherwise, encode it here.
1288  */
1289 static ssize_t vp2attr_vsa(const RADIUS_PACKET *packet,
1290                            const RADIUS_PACKET *original,
1291                            const char *secret, const VALUE_PAIR **pvp,
1292                            unsigned int attribute, unsigned int vendor,
1293                            uint8_t *ptr, size_t room)
1294 {
1295         ssize_t len;
1296         DICT_VENDOR *dv;
1297         const VALUE_PAIR *vp = *pvp;
1298
1299         /*
1300          *      Unknown vendor: RFC format.
1301          *      Known vendor and RFC format: go do that.
1302          */
1303         dv = dict_vendorbyvalue(vendor);
1304         if (!dv ||
1305             (!vp->flags.is_tlv && (dv->type == 1) && (dv->length == 1))) {
1306                 return vp2attr_rfc(packet, original, secret, pvp,
1307                                    attribute, ptr, room);
1308         }
1309
1310         switch (dv->type) {
1311         default:
1312                 fr_strerror_printf("vp2attr_vsa: Internal sanity check failed,"
1313                                    " type %u", (unsigned) dv->type);
1314                 return -1;
1315
1316         case 4:
1317                 ptr[0] = 0;     /* attr must be 24-bit */
1318                 ptr[1] = (attribute >> 16) & 0xff;
1319                 ptr[2] = (attribute >> 8) & 0xff;
1320                 ptr[3] = attribute & 0xff;
1321                 break;
1322
1323         case 2:
1324                 ptr[0] = (attribute >> 8) & 0xff;
1325                 ptr[1] = attribute & 0xff;
1326                 break;
1327
1328         case 1:
1329                 ptr[0] = attribute & 0xff;
1330                 break;
1331         }
1332
1333         switch (dv->length) {
1334         default:
1335                 fr_strerror_printf("vp2attr_vsa: Internal sanity check failed,"
1336                                    " length %u", (unsigned) dv->length);
1337                 return -1;
1338
1339         case 0:
1340                 break;
1341
1342         case 2:
1343                 ptr[dv->type] = 0;
1344                 ptr[dv->type + 1] = dv->type + 2;
1345                 break;
1346
1347         case 1:
1348                 ptr[dv->type] = dv->type + 1;
1349                 break;
1350
1351         }
1352
1353         if (room > ((unsigned) 255 - (dv->type + dv->length))) {
1354                 room = 255 - (dv->type + dv->length);
1355         }
1356
1357         len = vp2data_any(packet, original, secret, 0, pvp,
1358                           ptr + dv->type + dv->length, room);
1359         if (len <= 0) return len;
1360
1361         if (dv->length) ptr[dv->type + dv->length - 1] += len;
1362
1363 #ifndef NDEBUG
1364         if ((fr_debug_flag > 3) && fr_log_fp) {
1365                 switch (dv->type) {
1366                 default:
1367                         break;
1368
1369                 case 4:
1370                         if ((fr_debug_flag > 3) && fr_log_fp)
1371                                 fprintf(fr_log_fp, "\t\t%02x%02x%02x%02x ",
1372                                         ptr[0], ptr[1], ptr[2], ptr[3]);
1373                         break;
1374                         
1375                 case 2:
1376                         if ((fr_debug_flag > 3) && fr_log_fp)
1377                                 fprintf(fr_log_fp, "\t\t%02x%02x ",
1378                                         ptr[0], ptr[1]);
1379                 break;
1380                 
1381                 case 1:
1382                         if ((fr_debug_flag > 3) && fr_log_fp)
1383                                 fprintf(fr_log_fp, "\t\t%02x ", ptr[0]);
1384                         break;
1385                 }
1386                 
1387                 switch (dv->length) {
1388                 default:
1389                         break;
1390
1391                 case 0:
1392                         fprintf(fr_log_fp, "  ");
1393                         break;
1394
1395                 case 1:
1396                         fprintf(fr_log_fp, "%02x  ",
1397                                 ptr[dv->type]);
1398                         break;
1399
1400                 case 2:
1401                         fprintf(fr_log_fp, "%02x%02x  ",
1402                                 ptr[dv->type], ptr[dv->type] + 1);
1403                         break;
1404                 }
1405
1406                 print_hex_data(ptr + dv->type + dv->length, len, 3);
1407         }
1408 #endif
1409
1410         return dv->type + dv->length + len;
1411 }
1412
1413
1414 /*
1415  *      Encode a Vendor-Specific attribute.
1416  */
1417 int rad_vp2vsa(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1418                 const char *secret, const VALUE_PAIR **pvp, uint8_t *ptr,
1419                 size_t room)
1420 {
1421         ssize_t len;
1422         uint32_t lvalue;
1423         const VALUE_PAIR *vp = *pvp;
1424
1425         /*
1426          *      Double-check for WiMAX format.
1427          */
1428         if (vp->flags.wimax) {
1429                 return rad_vp2wimax(packet, original, secret, pvp,
1430                                     ptr, room);
1431         }
1432
1433         if (vp->vendor > FR_MAX_VENDOR) {
1434                 fr_strerror_printf("rad_vp2vsa: Invalid arguments");
1435                 return -1;
1436         }
1437
1438         /*
1439          *      Not enough room for:
1440          *              attr, len, vendor-id
1441          */
1442         if (room < 6) return 0;
1443
1444         /*
1445          *      Build the Vendor-Specific header
1446          */
1447         ptr[0] = PW_VENDOR_SPECIFIC;
1448         ptr[1] = 6;
1449         lvalue = htonl(vp->vendor);
1450         memcpy(ptr + 2, &lvalue, 4);
1451
1452         if (room > ((unsigned) 255 - ptr[1])) room = 255 - ptr[1];
1453
1454         len = vp2attr_vsa(packet, original, secret, pvp,
1455                           vp->attribute, vp->vendor,
1456                           ptr + ptr[1], room);
1457         if (len < 0) return len;
1458
1459 #ifndef NDEBUG
1460         if ((fr_debug_flag > 3) && fr_log_fp) {
1461                 fprintf(fr_log_fp, "\t\t%02x %02x  %02x%02x%02x%02x (%u)  ",
1462                        ptr[0], ptr[1],
1463                        ptr[2], ptr[3], ptr[4], ptr[5],
1464                        (ptr[3] << 16) | (ptr[4] << 8) | ptr[5]);
1465                 print_hex_data(ptr + 6, len, 3);
1466         }
1467 #endif
1468
1469         ptr[1] += len;
1470
1471         return ptr[1];
1472 }
1473
1474
1475 /*
1476  *      Encode an RFC standard attribute 1..255
1477  */
1478 int rad_vp2rfc(const RADIUS_PACKET *packet,
1479                const RADIUS_PACKET *original,
1480                const char *secret, const VALUE_PAIR **pvp,
1481                uint8_t *ptr, size_t room)
1482 {
1483         const VALUE_PAIR *vp = *pvp;
1484
1485         if (vp->vendor != 0) {
1486                 fr_strerror_printf("rad_vp2rfc called with VSA");
1487                 return -1;
1488         }
1489
1490         if ((vp->attribute == 0) || (vp->attribute > 255)) {
1491                 fr_strerror_printf("rad_vp2rfc called with non-standard attribute %u", vp->attribute);
1492                 return -1;
1493         }
1494
1495         if ((vp->length == 0) &&
1496             (vp->attribute != PW_CHARGEABLE_USER_IDENTITY)) {
1497                 *pvp = vp->next;
1498                 return 0;
1499         }
1500
1501         return vp2attr_rfc(packet, original, secret, pvp, vp->attribute,
1502                            ptr, room);
1503 }
1504
1505
1506 /*
1507  *      Parse a data structure into a RADIUS attribute.
1508  */
1509 int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1510                 const char *secret, const VALUE_PAIR **pvp, uint8_t *start,
1511                 size_t room)
1512 {
1513         const VALUE_PAIR *vp;
1514
1515         if (!pvp || !*pvp || !start || (room <= 2)) return -1;
1516
1517         vp = *pvp;
1518
1519         /*
1520          *      RFC format attributes take the fast path.
1521          */
1522         if (vp->vendor == 0) {
1523                 if (vp->attribute > 255) return 0;
1524
1525                 /*
1526                  *      Message-Authenticator is hard-coded.
1527                  */
1528                 if (vp->attribute == PW_MESSAGE_AUTHENTICATOR) {
1529                         if (room < 18) return -1;
1530                         
1531                         debug_pair(vp);
1532                         start[0] = PW_MESSAGE_AUTHENTICATOR;
1533                         start[1] = 18;
1534                         memset(start + 2, 0, 16);
1535 #ifndef NDEBUG
1536                         if ((fr_debug_flag > 3) && fr_log_fp) {
1537                                 fprintf(fr_log_fp, "\t\t50 12 ...\n");
1538                         }
1539 #endif
1540
1541                         *pvp = (*pvp)->next;
1542                         return 18;
1543                 }
1544
1545                 return rad_vp2rfc(packet, original, secret, pvp,
1546                                   start, room);
1547         }
1548
1549         if (vp->vendor > FR_MAX_VENDOR) {
1550                 return rad_vp2extended(packet, original, secret, pvp,
1551                                        start, room);
1552         }
1553
1554         if (vp->flags.wimax) {
1555                 return rad_vp2wimax(packet, original, secret, pvp,
1556                                     start, room);
1557         }
1558
1559         return rad_vp2vsa(packet, original, secret, pvp,
1560                           start, room);
1561 }
1562
1563
1564 /*
1565  *      Encode a packet.
1566  */
1567 int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1568                const char *secret)
1569 {
1570         radius_packet_t *hdr;
1571         uint8_t         *ptr;
1572         uint16_t        total_length;
1573         int             len;
1574         const VALUE_PAIR        *reply;
1575         const char      *what;
1576         char            ip_buffer[128];
1577
1578         /*
1579          *      A 4K packet, aligned on 64-bits.
1580          */
1581         uint64_t        data[MAX_PACKET_LEN / sizeof(uint64_t)];
1582
1583         if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
1584                 what = fr_packet_codes[packet->code];
1585         } else {
1586                 what = "Reply";
1587         }
1588
1589         DEBUG("Sending %s of id %d to %s port %d\n",
1590               what, packet->id,
1591               inet_ntop(packet->dst_ipaddr.af,
1592                         &packet->dst_ipaddr.ipaddr,
1593                         ip_buffer, sizeof(ip_buffer)),
1594               packet->dst_port);
1595
1596         /*
1597          *      Double-check some things based on packet code.
1598          */
1599         switch (packet->code) {
1600         case PW_AUTHENTICATION_ACK:
1601         case PW_AUTHENTICATION_REJECT:
1602         case PW_ACCESS_CHALLENGE:
1603                 if (!original) {
1604                         fr_strerror_printf("ERROR: Cannot sign response packet without a request packet.");
1605                         return -1;
1606                 }
1607                 break;
1608
1609                 /*
1610                  *      These packet vectors start off as all zero.
1611                  */
1612         case PW_ACCOUNTING_REQUEST:
1613         case PW_DISCONNECT_REQUEST:
1614         case PW_COA_REQUEST:
1615                 memset(packet->vector, 0, sizeof(packet->vector));
1616                 break;
1617
1618         default:
1619                 break;
1620         }
1621
1622         /*
1623          *      Use memory on the stack, until we know how
1624          *      large the packet will be.
1625          */
1626         hdr = (radius_packet_t *) data;
1627
1628         /*
1629          *      Build standard header
1630          */
1631         hdr->code = packet->code;
1632         hdr->id = packet->id;
1633
1634         memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
1635
1636         total_length = AUTH_HDR_LEN;
1637
1638         /*
1639          *      Load up the configuration values for the user
1640          */
1641         ptr = hdr->data;
1642         packet->offset = 0;
1643
1644         /*
1645          *      FIXME: Loop twice over the reply list.  The first time,
1646          *      calculate the total length of data.  The second time,
1647          *      allocate the memory, and fill in the VP's.
1648          *
1649          *      Hmm... this may be slower than just doing a small
1650          *      memcpy.
1651          */
1652
1653         /*
1654          *      Loop over the reply attributes for the packet.
1655          */
1656         reply = packet->vps;
1657         while (reply) {
1658                 size_t last_len;
1659                 const char *last_name = NULL;
1660
1661                 /*
1662                  *      Ignore non-wire attributes, but allow extended
1663                  *      attributes.
1664                  */
1665                 if ((reply->vendor == 0) &&
1666                     ((reply->attribute & 0xFFFF) >= 256) &&
1667                     !reply->flags.extended && !reply->flags.extended_flags) {
1668 #ifndef NDEBUG
1669                         /*
1670                          *      Permit the admin to send BADLY formatted
1671                          *      attributes with a debug build.
1672                          */
1673                         if (reply->attribute == PW_RAW_ATTRIBUTE) {
1674                                 memcpy(ptr, reply->vp_octets, reply->length);
1675                                 len = reply->length;
1676                                 reply = reply->next;
1677                                 goto next;
1678                         }
1679 #endif
1680                         reply = reply->next;
1681                         continue;
1682                 }
1683
1684                 /*
1685                  *      Set the Message-Authenticator to the correct
1686                  *      length and initial value.
1687                  */
1688                 if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
1689                         /*
1690                          *      Cache the offset to the
1691                          *      Message-Authenticator
1692                          */
1693                         packet->offset = total_length;
1694                         last_len = 16;
1695                 } else {
1696                         last_len = reply->length;
1697                 }
1698                 last_name = reply->name;
1699
1700                 len = rad_vp2attr(packet, original, secret, &reply, ptr,
1701                                   ((uint8_t *) data) + sizeof(data) - ptr);
1702                 if (len < 0) return -1;
1703
1704                 /*
1705                  *      Failed to encode the attribute, likely because
1706                  *      the packet is full.
1707                  */
1708                 if (len == 0) {
1709                         if (last_len != 0) {
1710                                 DEBUG("WARNING: Failed encoding attribute %s\n", last_name);
1711                         } else {
1712                                 DEBUG("WARNING: Skipping zero-length attribute %s\n", last_name);
1713                         }
1714                 }
1715
1716 #ifndef NDEBUG
1717         next:                   /* Used only for Raw-Attribute */
1718 #endif
1719                 ptr += len;
1720                 total_length += len;
1721         } /* done looping over all attributes */
1722
1723         /*
1724          *      Fill in the rest of the fields, and copy the data over
1725          *      from the local stack to the newly allocated memory.
1726          *
1727          *      Yes, all this 'memcpy' is slow, but it means
1728          *      that we only allocate the minimum amount of
1729          *      memory for a request.
1730          */
1731         packet->data_len = total_length;
1732         packet->data = (uint8_t *) malloc(packet->data_len);
1733         if (!packet->data) {
1734                 fr_strerror_printf("Out of memory");
1735                 return -1;
1736         }
1737
1738         memcpy(packet->data, hdr, packet->data_len);
1739         hdr = (radius_packet_t *) packet->data;
1740
1741         total_length = htons(total_length);
1742         memcpy(hdr->length, &total_length, sizeof(total_length));
1743
1744         return 0;
1745 }
1746
1747
1748 /*
1749  *      Sign a previously encoded packet.
1750  */
1751 int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1752              const char *secret)
1753 {
1754         radius_packet_t *hdr = (radius_packet_t *)packet->data;
1755
1756         /*
1757          *      It wasn't assigned an Id, this is bad!
1758          */
1759         if (packet->id < 0) {
1760                 fr_strerror_printf("ERROR: RADIUS packets must be assigned an Id.");
1761                 return -1;
1762         }
1763
1764         if (!packet->data || (packet->data_len < AUTH_HDR_LEN) ||
1765             (packet->offset < 0)) {
1766                 fr_strerror_printf("ERROR: You must call rad_encode() before rad_sign()");
1767                 return -1;
1768         }
1769
1770         /*
1771          *      If there's a Message-Authenticator, update it
1772          *      now, BEFORE updating the authentication vector.
1773          */
1774         if (packet->offset > 0) {
1775                 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
1776
1777                 switch (packet->code) {
1778                 case PW_ACCOUNTING_REQUEST:
1779                 case PW_ACCOUNTING_RESPONSE:
1780                 case PW_DISCONNECT_REQUEST:
1781                 case PW_DISCONNECT_ACK:
1782                 case PW_DISCONNECT_NAK:
1783                 case PW_COA_REQUEST:
1784                 case PW_COA_ACK:
1785                 case PW_COA_NAK:
1786                         memset(hdr->vector, 0, AUTH_VECTOR_LEN);
1787                         break;
1788
1789                 case PW_AUTHENTICATION_ACK:
1790                 case PW_AUTHENTICATION_REJECT:
1791                 case PW_ACCESS_CHALLENGE:
1792                         if (!original) {
1793                                 fr_strerror_printf("ERROR: Cannot sign response packet without a request packet.");
1794                                 return -1;
1795                         }
1796                         memcpy(hdr->vector, original->vector,
1797                                AUTH_VECTOR_LEN);
1798                         break;
1799
1800                 default:        /* others have vector already set to zero */
1801                         break;
1802
1803                 }
1804
1805                 /*
1806                  *      Set the authentication vector to zero,
1807                  *      calculate the signature, and put it
1808                  *      into the Message-Authenticator
1809                  *      attribute.
1810                  */
1811                 fr_hmac_md5(packet->data, packet->data_len,
1812                             (const uint8_t *) secret, strlen(secret),
1813                             calc_auth_vector);
1814                 memcpy(packet->data + packet->offset + 2,
1815                        calc_auth_vector, AUTH_VECTOR_LEN);
1816
1817                 /*
1818                  *      Copy the original request vector back
1819                  *      to the raw packet.
1820                  */
1821                 memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
1822         }
1823
1824         /*
1825          *      Switch over the packet code, deciding how to
1826          *      sign the packet.
1827          */
1828         switch (packet->code) {
1829                 /*
1830                  *      Request packets are not signed, bur
1831                  *      have a random authentication vector.
1832                  */
1833         case PW_AUTHENTICATION_REQUEST:
1834         case PW_STATUS_SERVER:
1835                 break;
1836
1837                 /*
1838                  *      Reply packets are signed with the
1839                  *      authentication vector of the request.
1840                  */
1841         default:
1842                 {
1843                         uint8_t digest[16];
1844
1845                         FR_MD5_CTX      context;
1846                         fr_MD5Init(&context);
1847                         fr_MD5Update(&context, packet->data, packet->data_len);
1848                         fr_MD5Update(&context, (const uint8_t *) secret,
1849                                      strlen(secret));
1850                         fr_MD5Final(digest, &context);
1851
1852                         memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
1853                         memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
1854                         break;
1855                 }
1856         }/* switch over packet codes */
1857
1858         return 0;
1859 }
1860
1861 /*
1862  *      Reply to the request.  Also attach
1863  *      reply attribute value pairs and any user message provided.
1864  */
1865 int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1866              const char *secret)
1867 {
1868         VALUE_PAIR              *reply;
1869         const char              *what;
1870         char                    ip_buffer[128];
1871
1872         /*
1873          *      Maybe it's a fake packet.  Don't send it.
1874          */
1875         if (!packet || (packet->sockfd < 0)) {
1876                 return 0;
1877         }
1878
1879         if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
1880                 what = fr_packet_codes[packet->code];
1881         } else {
1882                 what = "Reply";
1883         }
1884
1885         /*
1886          *  First time through, allocate room for the packet
1887          */
1888         if (!packet->data) {
1889                 /*
1890                  *      Encode the packet.
1891                  */
1892                 if (rad_encode(packet, original, secret) < 0) {
1893                         return -1;
1894                 }
1895
1896                 /*
1897                  *      Re-sign it, including updating the
1898                  *      Message-Authenticator.
1899                  */
1900                 if (rad_sign(packet, original, secret) < 0) {
1901                         return -1;
1902                 }
1903
1904                 /*
1905                  *      If packet->data points to data, then we print out
1906                  *      the VP list again only for debugging.
1907                  */
1908         } else if (fr_debug_flag) {
1909                 DEBUG("Sending %s of id %d to %s port %d\n", what, packet->id,
1910                       inet_ntop(packet->dst_ipaddr.af,
1911                                 &packet->dst_ipaddr.ipaddr,
1912                                 ip_buffer, sizeof(ip_buffer)),
1913                       packet->dst_port);
1914
1915                 for (reply = packet->vps; reply; reply = reply->next) {
1916                         if ((reply->vendor == 0) &&
1917                             ((reply->attribute & 0xFFFF) > 0xff)) continue;
1918                         debug_pair(reply);
1919                 }
1920         }
1921
1922 #ifndef NDEBUG
1923         if ((fr_debug_flag > 3) && fr_log_fp) rad_print_hex(packet);
1924 #endif
1925
1926         /*
1927          *      And send it on it's way.
1928          */
1929         return rad_sendto(packet->sockfd, packet->data, packet->data_len, 0,
1930                           &packet->src_ipaddr, packet->src_port,
1931                           &packet->dst_ipaddr, packet->dst_port);
1932 }
1933
1934 /*
1935  *      Do a comparison of two authentication digests by comparing
1936  *      the FULL digest.  Otehrwise, the server can be subject to
1937  *      timing attacks that allow attackers find a valid message
1938  *      authenticator.
1939  *
1940  *      http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf
1941  */
1942 int rad_digest_cmp(const uint8_t *a, const uint8_t *b, size_t length)
1943 {
1944         int result = 0;
1945         size_t i;
1946
1947         for (i = 0; i < length; i++) {
1948                 result |= a[i] ^ b[i];
1949         }
1950
1951         return result;          /* 0 is OK, !0 is !OK, just like memcmp */
1952 }
1953
1954
1955 /*
1956  *      Validates the requesting client NAS.  Calculates the
1957  *      signature based on the clients private key.
1958  */
1959 static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
1960 {
1961         uint8_t         digest[AUTH_VECTOR_LEN];
1962         FR_MD5_CTX              context;
1963
1964         /*
1965          *      Zero out the auth_vector in the received packet.
1966          *      Then append the shared secret to the received packet,
1967          *      and calculate the MD5 sum. This must be the same
1968          *      as the original MD5 sum (packet->vector).
1969          */
1970         memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
1971
1972         /*
1973          *  MD5(packet + secret);
1974          */
1975         fr_MD5Init(&context);
1976         fr_MD5Update(&context, packet->data, packet->data_len);
1977         fr_MD5Update(&context, (const uint8_t *) secret, strlen(secret));
1978         fr_MD5Final(digest, &context);
1979
1980         /*
1981          *      Return 0 if OK, 2 if not OK.
1982          */
1983         if (rad_digest_cmp(digest, packet->vector, AUTH_VECTOR_LEN) != 0) return 2;
1984         return 0;
1985 }
1986
1987
1988 /*
1989  *      Validates the requesting client NAS.  Calculates the
1990  *      signature based on the clients private key.
1991  */
1992 static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1993                             const char *secret)
1994 {
1995         uint8_t         calc_digest[AUTH_VECTOR_LEN];
1996         FR_MD5_CTX              context;
1997
1998         /*
1999          *      Very bad!
2000          */
2001         if (original == NULL) {
2002                 return 3;
2003         }
2004
2005         /*
2006          *  Copy the original vector in place.
2007          */
2008         memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
2009
2010         /*
2011          *  MD5(packet + secret);
2012          */
2013         fr_MD5Init(&context);
2014         fr_MD5Update(&context, packet->data, packet->data_len);
2015         fr_MD5Update(&context, (const uint8_t *) secret, strlen(secret));
2016         fr_MD5Final(calc_digest, &context);
2017
2018         /*
2019          *  Copy the packet's vector back to the packet.
2020          */
2021         memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
2022
2023         /*
2024          *      Return 0 if OK, 2 if not OK.
2025          */
2026         if (rad_digest_cmp(packet->vector, calc_digest, AUTH_VECTOR_LEN) != 0) return 2;
2027         return 0;
2028 }
2029
2030
2031 /*
2032  *      Check if a set of RADIUS formatted TLVs are OK.
2033  */
2034 int rad_tlv_ok(const uint8_t *data, size_t length,
2035                size_t dv_type, size_t dv_length)
2036 {
2037         const uint8_t *end = data + length;
2038
2039         if ((dv_length > 2) || (dv_type == 0) || (dv_type > 4)) {
2040                 fr_strerror_printf("rad_tlv_ok: Invalid arguments");
2041                 return -1;
2042         }
2043
2044         while (data < end) {
2045                 size_t attrlen;
2046
2047                 if ((data + dv_type + dv_length) > end) {
2048                         fr_strerror_printf("Attribute header overflow");
2049                         return -1;
2050                 }
2051
2052                 switch (dv_type) {
2053                 case 4:
2054                         if ((data[0] == 0) && (data[1] == 0) &&
2055                             (data[2] == 0) && (data[3] == 0)) {
2056                         zero:
2057                                 fr_strerror_printf("Invalid attribute 0");
2058                                 return -1;
2059                         }
2060
2061                         if (data[0] != 0) {
2062                                 fr_strerror_printf("Invalid attribute > 2^24");
2063                                 return -1;
2064                         }
2065                         break;
2066
2067                 case 2:
2068                         if ((data[1] == 0) && (data[1] == 0)) goto zero;
2069                         break;
2070
2071                 case 1:
2072                         if (data[0] == 0) goto zero;
2073                         break;
2074
2075                 default:
2076                         fr_strerror_printf("Internal sanity check failed");
2077                         return -1;
2078                 }
2079
2080                 switch (dv_length) {
2081                 case 0:
2082                         return 0;
2083
2084                 case 2:
2085                         if (data[dv_type + 1] != 0) {
2086                                 fr_strerror_printf("Attribute is longer than 256 octets");
2087                                 return -1;
2088                         }
2089                         /* FALL-THROUGH */
2090                 case 1:
2091                         attrlen = data[dv_type + dv_length - 1];
2092                         break;
2093
2094
2095                 default:
2096                         fr_strerror_printf("Internal sanity check failed");
2097                         return -1;
2098                 }
2099
2100                 if (attrlen < (dv_type + dv_length)) {
2101                         fr_strerror_printf("Attribute header has invalid length");
2102                         return -1;
2103                 }
2104
2105                 if (attrlen > length) {
2106                         fr_strerror_printf("Attribute overflows container");
2107                         return -1;
2108                 }
2109
2110                 data += attrlen;
2111                 length -= attrlen;
2112         }
2113
2114         return 0;
2115 }
2116
2117
2118 /*
2119  *      See if the data pointed to by PTR is a valid RADIUS packet.
2120  *
2121  *      packet is not 'const * const' because we may update data_len,
2122  *      if there's more data in the UDP packet than in the RADIUS packet.
2123  */
2124 int rad_packet_ok(RADIUS_PACKET *packet, int flags)
2125 {
2126         uint8_t                 *attr;
2127         int                     totallen;
2128         int                     count;
2129         radius_packet_t         *hdr;
2130         char                    host_ipaddr[128];
2131         int                     require_ma = 0;
2132         int                     seen_ma = 0;
2133         int                     num_attributes;
2134
2135         /*
2136          *      Check for packets smaller than the packet header.
2137          *
2138          *      RFC 2865, Section 3., subsection 'length' says:
2139          *
2140          *      "The minimum length is 20 ..."
2141          */
2142         if (packet->data_len < AUTH_HDR_LEN) {
2143                 fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: too short (received %d < minimum %d)",
2144                            inet_ntop(packet->src_ipaddr.af,
2145                                      &packet->src_ipaddr.ipaddr,
2146                                      host_ipaddr, sizeof(host_ipaddr)),
2147                                    (int) packet->data_len, AUTH_HDR_LEN);
2148                 return 0;
2149         }
2150
2151         /*
2152          *      RFC 2865, Section 3., subsection 'length' says:
2153          *
2154          *      " ... and maximum length is 4096."
2155          */
2156         if (packet->data_len > MAX_PACKET_LEN) {
2157                 fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: too long (received %d > maximum %d)",
2158                            inet_ntop(packet->src_ipaddr.af,
2159                                      &packet->src_ipaddr.ipaddr,
2160                                      host_ipaddr, sizeof(host_ipaddr)),
2161                                    (int) packet->data_len, MAX_PACKET_LEN);
2162                 return 0;
2163         }
2164
2165         /*
2166          *      Check for packets with mismatched size.
2167          *      i.e. We've received 128 bytes, and the packet header
2168          *      says it's 256 bytes long.
2169          */
2170         totallen = (packet->data[2] << 8) | packet->data[3];
2171         hdr = (radius_packet_t *)packet->data;
2172
2173         /*
2174          *      Code of 0 is not understood.
2175          *      Code of 16 or greate is not understood.
2176          */
2177         if ((hdr->code == 0) ||
2178             (hdr->code >= FR_MAX_PACKET_CODE)) {
2179                 fr_strerror_printf("WARNING: Bad RADIUS packet from host %s: unknown packet code%d ",
2180                            inet_ntop(packet->src_ipaddr.af,
2181                                      &packet->src_ipaddr.ipaddr,
2182                                      host_ipaddr, sizeof(host_ipaddr)),
2183                            hdr->code);
2184                 return 0;
2185         }
2186
2187         /*
2188          *      Message-Authenticator is required in Status-Server
2189          *      packets, otherwise they can be trivially forged.
2190          */
2191         if (hdr->code == PW_STATUS_SERVER) require_ma = 1;
2192
2193         /*
2194          *      It's also required if the caller asks for it.
2195          */
2196         if (flags) require_ma = 1;
2197
2198         /*
2199          *      Repeat the length checks.  This time, instead of
2200          *      looking at the data we received, look at the value
2201          *      of the 'length' field inside of the packet.
2202          *
2203          *      Check for packets smaller than the packet header.
2204          *
2205          *      RFC 2865, Section 3., subsection 'length' says:
2206          *
2207          *      "The minimum length is 20 ..."
2208          */
2209         if (totallen < AUTH_HDR_LEN) {
2210                 fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: too short (length %d < minimum %d)",
2211                            inet_ntop(packet->src_ipaddr.af,
2212                                      &packet->src_ipaddr.ipaddr,
2213                                      host_ipaddr, sizeof(host_ipaddr)),
2214                            totallen, AUTH_HDR_LEN);
2215                 return 0;
2216         }
2217
2218         /*
2219          *      And again, for the value of the 'length' field.
2220          *
2221          *      RFC 2865, Section 3., subsection 'length' says:
2222          *
2223          *      " ... and maximum length is 4096."
2224          */
2225         if (totallen > MAX_PACKET_LEN) {
2226                 fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: too long (length %d > maximum %d)",
2227                            inet_ntop(packet->src_ipaddr.af,
2228                                      &packet->src_ipaddr.ipaddr,
2229                                      host_ipaddr, sizeof(host_ipaddr)),
2230                            totallen, MAX_PACKET_LEN);
2231                 return 0;
2232         }
2233
2234         /*
2235          *      RFC 2865, Section 3., subsection 'length' says:
2236          *
2237          *      "If the packet is shorter than the Length field
2238          *      indicates, it MUST be silently discarded."
2239          *
2240          *      i.e. No response to the NAS.
2241          */
2242         if (packet->data_len < totallen) {
2243                 fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: received %d octets, packet length says %d",
2244                            inet_ntop(packet->src_ipaddr.af,
2245                                      &packet->src_ipaddr.ipaddr,
2246                                      host_ipaddr, sizeof(host_ipaddr)),
2247                                    (int) packet->data_len, totallen);
2248                 return 0;
2249         }
2250
2251         /*
2252          *      RFC 2865, Section 3., subsection 'length' says:
2253          *
2254          *      "Octets outside the range of the Length field MUST be
2255          *      treated as padding and ignored on reception."
2256          */
2257         if (packet->data_len > totallen) {
2258                 /*
2259                  *      We're shortening the packet below, but just
2260                  *      to be paranoid, zero out the extra data.
2261                  */
2262                 memset(packet->data + totallen, 0, packet->data_len - totallen);
2263                 packet->data_len = totallen;
2264         }
2265
2266         /*
2267          *      Walk through the packet's attributes, ensuring that
2268          *      they add up EXACTLY to the size of the packet.
2269          *
2270          *      If they don't, then the attributes either under-fill
2271          *      or over-fill the packet.  Any parsing of the packet
2272          *      is impossible, and will result in unknown side effects.
2273          *
2274          *      This would ONLY happen with buggy RADIUS implementations,
2275          *      or with an intentional attack.  Either way, we do NOT want
2276          *      to be vulnerable to this problem.
2277          */
2278         attr = hdr->data;
2279         count = totallen - AUTH_HDR_LEN;
2280         num_attributes = 0;
2281
2282         while (count > 0) {
2283                 /*
2284                  *      We need at least 2 bytes to check the
2285                  *      attribute header.
2286                  */
2287                 if (count < 2) {
2288                         fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: attribute header overflows the packet",
2289                                    inet_ntop(packet->src_ipaddr.af,
2290                                              &packet->src_ipaddr.ipaddr,
2291                                              host_ipaddr, sizeof(host_ipaddr)));
2292                         return 0;
2293                 }
2294
2295                 /*
2296                  *      Attribute number zero is NOT defined.
2297                  */
2298                 if (attr[0] == 0) {
2299                         fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: Invalid attribute 0",
2300                                    inet_ntop(packet->src_ipaddr.af,
2301                                              &packet->src_ipaddr.ipaddr,
2302                                              host_ipaddr, sizeof(host_ipaddr)));
2303                         return 0;
2304                 }
2305
2306                 /*
2307                  *      Attributes are at LEAST as long as the ID & length
2308                  *      fields.  Anything shorter is an invalid attribute.
2309                  */
2310                 if (attr[1] < 2) {
2311                         fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: attribute %u too short",
2312                                    inet_ntop(packet->src_ipaddr.af,
2313                                              &packet->src_ipaddr.ipaddr,
2314                                              host_ipaddr, sizeof(host_ipaddr)),
2315                                    attr[0]);
2316                         return 0;
2317                 }
2318
2319                 /*
2320                  *      If there are fewer bytes in the packet than in the
2321                  *      attribute, it's a bad packet.
2322                  */
2323                 if (count < attr[1]) {
2324                         fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: attribute %u data overflows the packet",
2325                                    inet_ntop(packet->src_ipaddr.af,
2326                                              &packet->src_ipaddr.ipaddr,
2327                                              host_ipaddr, sizeof(host_ipaddr)),
2328                                            attr[0]);
2329                         return 0;
2330                 }
2331
2332                 /*
2333                  *      Sanity check the attributes for length.
2334                  */
2335                 switch (attr[0]) {
2336                 default:        /* don't do anything by default */
2337                         break;
2338
2339                         /*
2340                          *      If there's an EAP-Message, we require
2341                          *      a Message-Authenticator.
2342                          */
2343                 case PW_EAP_MESSAGE:
2344                         require_ma = 1;
2345                         break;
2346
2347                 case PW_MESSAGE_AUTHENTICATOR:
2348                         if (attr[1] != 2 + AUTH_VECTOR_LEN) {
2349                                 fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
2350                                            inet_ntop(packet->src_ipaddr.af,
2351                                                      &packet->src_ipaddr.ipaddr,
2352                                                      host_ipaddr, sizeof(host_ipaddr)),
2353                                            attr[1] - 2);
2354                                 return 0;
2355                         }
2356                         seen_ma = 1;
2357                         break;
2358                 }
2359
2360                 /*
2361                  *      FIXME: Look up the base 255 attributes in the
2362                  *      dictionary, and switch over their type.  For
2363                  *      integer/date/ip, the attribute length SHOULD
2364                  *      be 6.
2365                  */
2366                 count -= attr[1];       /* grab the attribute length */
2367                 attr += attr[1];
2368                 num_attributes++;       /* seen one more attribute */
2369         }
2370
2371         /*
2372          *      If the attributes add up to a packet, it's allowed.
2373          *
2374          *      If not, we complain, and throw the packet away.
2375          */
2376         if (count != 0) {
2377                 fr_strerror_printf("WARNING: Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
2378                            inet_ntop(packet->src_ipaddr.af,
2379                                      &packet->src_ipaddr.ipaddr,
2380                                      host_ipaddr, sizeof(host_ipaddr)));
2381                 return 0;
2382         }
2383
2384         /*
2385          *      If we're configured to look for a maximum number of
2386          *      attributes, and we've seen more than that maximum,
2387          *      then throw the packet away, as a possible DoS.
2388          */
2389         if ((fr_max_attributes > 0) &&
2390             (num_attributes > fr_max_attributes)) {
2391                 fr_strerror_printf("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
2392                            inet_ntop(packet->src_ipaddr.af,
2393                                      &packet->src_ipaddr.ipaddr,
2394                                      host_ipaddr, sizeof(host_ipaddr)),
2395                            num_attributes, fr_max_attributes);
2396                 return 0;
2397         }
2398
2399         /*
2400          *      http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
2401          *
2402          *      A packet with an EAP-Message attribute MUST also have
2403          *      a Message-Authenticator attribute.
2404          *
2405          *      A Message-Authenticator all by itself is OK, though.
2406          *
2407          *      Similarly, Status-Server packets MUST contain
2408          *      Message-Authenticator attributes.
2409          */
2410         if (require_ma && ! seen_ma) {
2411                 fr_strerror_printf("WARNING: Insecure packet from host %s:  Packet does not contain required Message-Authenticator attribute",
2412                            inet_ntop(packet->src_ipaddr.af,
2413                                      &packet->src_ipaddr.ipaddr,
2414                                      host_ipaddr, sizeof(host_ipaddr)));
2415                 return 0;
2416         }
2417
2418         /*
2419          *      Fill RADIUS header fields
2420          */
2421         packet->code = hdr->code;
2422         packet->id = hdr->id;
2423         memcpy(packet->vector, hdr->vector, AUTH_VECTOR_LEN);
2424
2425         return 1;
2426 }
2427
2428
2429 /*
2430  *      Receive UDP client requests, and fill in
2431  *      the basics of a RADIUS_PACKET structure.
2432  */
2433 RADIUS_PACKET *rad_recv(int fd, int flags)
2434 {
2435         int sock_flags = 0;
2436         RADIUS_PACKET           *packet;
2437
2438         /*
2439          *      Allocate the new request data structure
2440          */
2441         if ((packet = malloc(sizeof(*packet))) == NULL) {
2442                 fr_strerror_printf("out of memory");
2443                 return NULL;
2444         }
2445         memset(packet, 0, sizeof(*packet));
2446
2447         if (flags & 0x02) {
2448                 sock_flags = MSG_PEEK;
2449                 flags &= ~0x02;
2450         }
2451
2452         packet->data_len = rad_recvfrom(fd, &packet->data, sock_flags,
2453                                         &packet->src_ipaddr, &packet->src_port,
2454                                         &packet->dst_ipaddr, &packet->dst_port);
2455
2456         /*
2457          *      Check for socket errors.
2458          */
2459         if (packet->data_len < 0) {
2460                 fr_strerror_printf("Error receiving packet: %s", strerror(errno));
2461                 /* packet->data is NULL */
2462                 free(packet);
2463                 return NULL;
2464         }
2465
2466         /*
2467          *      If the packet is too big, then rad_recvfrom did NOT
2468          *      allocate memory.  Instead, it just discarded the
2469          *      packet.
2470          */
2471         if (packet->data_len > MAX_PACKET_LEN) {
2472                 fr_strerror_printf("Discarding packet: Larger than RFC limitation of 4096 bytes.");
2473                 /* packet->data is NULL */
2474                 free(packet);
2475                 return NULL;
2476         }
2477
2478         /*
2479          *      Read no data.  Continue.
2480          *      This check is AFTER the MAX_PACKET_LEN check above, because
2481          *      if the packet is larger than MAX_PACKET_LEN, we also have
2482          *      packet->data == NULL
2483          */
2484         if ((packet->data_len == 0) || !packet->data) {
2485                 fr_strerror_printf("Empty packet: Socket is not ready.");
2486                 free(packet);
2487                 return NULL;
2488         }
2489
2490         /*
2491          *      See if it's a well-formed RADIUS packet.
2492          */
2493         if (!rad_packet_ok(packet, flags)) {
2494                 rad_free(&packet);
2495                 return NULL;
2496         }
2497
2498         /*
2499          *      Remember which socket we read the packet from.
2500          */
2501         packet->sockfd = fd;
2502
2503         /*
2504          *      FIXME: Do even more filtering by only permitting
2505          *      certain IP's.  The problem is that we don't know
2506          *      how to do this properly for all possible clients...
2507          */
2508
2509         /*
2510          *      Explicitely set the VP list to empty.
2511          */
2512         packet->vps = NULL;
2513
2514         if (fr_debug_flag) {
2515                 char host_ipaddr[128];
2516
2517                 if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
2518                         DEBUG("rad_recv: %s packet from host %s port %d",
2519                               fr_packet_codes[packet->code],
2520                               inet_ntop(packet->src_ipaddr.af,
2521                                         &packet->src_ipaddr.ipaddr,
2522                                         host_ipaddr, sizeof(host_ipaddr)),
2523                               packet->src_port);
2524                 } else {
2525                         DEBUG("rad_recv: Packet from host %s port %d code=%d",
2526                               inet_ntop(packet->src_ipaddr.af,
2527                                         &packet->src_ipaddr.ipaddr,
2528                                         host_ipaddr, sizeof(host_ipaddr)),
2529                               packet->src_port,
2530                               packet->code);
2531                 }
2532                 DEBUG(", id=%d, length=%d\n",
2533                       packet->id, (int) packet->data_len);
2534         }
2535
2536 #ifndef NDEBUG
2537         if ((fr_debug_flag > 3) && fr_log_fp) rad_print_hex(packet);
2538 #endif
2539
2540         return packet;
2541 }
2542
2543
2544 /*
2545  *      Verify the signature of a packet.
2546  */
2547 int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
2548                const char *secret)
2549 {
2550         uint8_t                 *ptr;
2551         int                     length;
2552         int                     attrlen;
2553
2554         if (!packet || !packet->data) return -1;
2555
2556         /*
2557          *      Before we allocate memory for the attributes, do more
2558          *      sanity checking.
2559          */
2560         ptr = packet->data + AUTH_HDR_LEN;
2561         length = packet->data_len - AUTH_HDR_LEN;
2562         while (length > 0) {
2563                 uint8_t msg_auth_vector[AUTH_VECTOR_LEN];
2564                 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
2565
2566                 attrlen = ptr[1];
2567
2568                 switch (ptr[0]) {
2569                 default:        /* don't do anything. */
2570                         break;
2571
2572                         /*
2573                          *      Note that more than one Message-Authenticator
2574                          *      attribute is invalid.
2575                          */
2576                 case PW_MESSAGE_AUTHENTICATOR:
2577                         memcpy(msg_auth_vector, &ptr[2], sizeof(msg_auth_vector));
2578                         memset(&ptr[2], 0, AUTH_VECTOR_LEN);
2579
2580                         switch (packet->code) {
2581                         default:
2582                                 break;
2583
2584                         case PW_ACCOUNTING_REQUEST:
2585                         case PW_ACCOUNTING_RESPONSE:
2586                         case PW_DISCONNECT_REQUEST:
2587                         case PW_DISCONNECT_ACK:
2588                         case PW_DISCONNECT_NAK:
2589                         case PW_COA_REQUEST:
2590                         case PW_COA_ACK:
2591                         case PW_COA_NAK:
2592                                 memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
2593                                 break;
2594
2595                         case PW_AUTHENTICATION_ACK:
2596                         case PW_AUTHENTICATION_REJECT:
2597                         case PW_ACCESS_CHALLENGE:
2598                                 if (!original) {
2599                                         fr_strerror_printf("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
2600                                         return -1;
2601                                 }
2602                                 memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
2603                                 break;
2604                         }
2605
2606                         fr_hmac_md5(packet->data, packet->data_len,
2607                                     (const uint8_t *) secret, strlen(secret),
2608                                     calc_auth_vector);
2609                         if (rad_digest_cmp(calc_auth_vector, msg_auth_vector,
2610                                    sizeof(calc_auth_vector)) != 0) {
2611                                 char buffer[32];
2612                                 fr_strerror_printf("Received packet from %s with invalid Message-Authenticator!  (Shared secret is incorrect.)",
2613                                            inet_ntop(packet->src_ipaddr.af,
2614                                                      &packet->src_ipaddr.ipaddr,
2615                                                      buffer, sizeof(buffer)));
2616                                 /* Silently drop packet, according to RFC 3579 */
2617                                 return -1;
2618                         } /* else the message authenticator was good */
2619
2620                         /*
2621                          *      Reinitialize Authenticators.
2622                          */
2623                         memcpy(&ptr[2], msg_auth_vector, AUTH_VECTOR_LEN);
2624                         memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
2625                         break;
2626                 } /* switch over the attributes */
2627
2628                 ptr += attrlen;
2629                 length -= attrlen;
2630         } /* loop over the packet, sanity checking the attributes */
2631
2632         /*
2633          *      It looks like a RADIUS packet, but we can't validate
2634          *      the signature.
2635          */
2636         if ((packet->code == 0) || (packet->code >= FR_MAX_PACKET_CODE)) {
2637                 char buffer[32];
2638                 fr_strerror_printf("Received Unknown packet code %d "
2639                            "from client %s port %d: Cannot validate signature.",
2640                            packet->code,
2641                            inet_ntop(packet->src_ipaddr.af,
2642                                      &packet->src_ipaddr.ipaddr,
2643                                      buffer, sizeof(buffer)),
2644                            packet->src_port);
2645                 return -1;
2646         }
2647
2648         /*
2649          *      Calculate and/or verify digest.
2650          */
2651         switch(packet->code) {
2652                 int rcode;
2653                 char buffer[32];
2654
2655                 case PW_AUTHENTICATION_REQUEST:
2656                 case PW_STATUS_SERVER:
2657                         /*
2658                          *      The authentication vector is random
2659                          *      nonsense, invented by the client.
2660                          */
2661                         break;
2662
2663                 case PW_COA_REQUEST:
2664                 case PW_DISCONNECT_REQUEST:
2665                 case PW_ACCOUNTING_REQUEST:
2666                         if (calc_acctdigest(packet, secret) > 1) {
2667                                 fr_strerror_printf("Received %s packet "
2668                                            "from client %s with invalid signature!  (Shared secret is incorrect.)",
2669                                            fr_packet_codes[packet->code],
2670                                            inet_ntop(packet->src_ipaddr.af,
2671                                                      &packet->src_ipaddr.ipaddr,
2672                                                      buffer, sizeof(buffer)));
2673                                 return -1;
2674                         }
2675                         break;
2676
2677                         /* Verify the reply digest */
2678                 case PW_AUTHENTICATION_ACK:
2679                 case PW_AUTHENTICATION_REJECT:
2680                 case PW_ACCESS_CHALLENGE:
2681                 case PW_ACCOUNTING_RESPONSE:
2682                 case PW_DISCONNECT_ACK:
2683                 case PW_DISCONNECT_NAK:
2684                 case PW_COA_ACK:
2685                 case PW_COA_NAK:
2686                         rcode = calc_replydigest(packet, original, secret);
2687                         if (rcode > 1) {
2688                                 fr_strerror_printf("Received %s packet "
2689                                            "from home server %s port %d with invalid signature!  (Shared secret is incorrect.)",
2690                                            fr_packet_codes[packet->code],
2691                                            inet_ntop(packet->src_ipaddr.af,
2692                                                      &packet->src_ipaddr.ipaddr,
2693                                                      buffer, sizeof(buffer)),
2694                                            packet->src_port);
2695                                 return -1;
2696                         }
2697                         break;
2698
2699                 default:
2700                         fr_strerror_printf("Received Unknown packet code %d "
2701                                    "from client %s port %d: Cannot validate signature",
2702                                    packet->code,
2703                                    inet_ntop(packet->src_ipaddr.af,
2704                                              &packet->src_ipaddr.ipaddr,
2705                                                      buffer, sizeof(buffer)),
2706                                    packet->src_port);
2707                         return -1;
2708         }
2709
2710         return 0;
2711 }
2712
2713
2714 /*
2715  *      Create a "raw" attribute from the attribute contents.
2716  */
2717 static ssize_t data2vp_raw(UNUSED const RADIUS_PACKET *packet,
2718                            UNUSED const RADIUS_PACKET *original,
2719                            UNUSED const char *secret,
2720                            unsigned int attribute, unsigned int vendor,
2721                            const uint8_t *data, size_t length,
2722                            VALUE_PAIR **pvp)
2723 {
2724         VALUE_PAIR *vp;
2725
2726         /*
2727          *      Keep the next function happy.
2728          */
2729         vp = pairalloc(NULL);
2730         vp = paircreate_raw(attribute, vendor, PW_TYPE_OCTETS, vp);
2731         if (!vp) {
2732                 fr_strerror_printf("data2vp_raw: Failed creating attribute");
2733                 return -1;
2734         }
2735
2736         vp->length = length;
2737
2738         /*
2739          *      If the data is too large, mark it as a "TLV".
2740          */
2741         if (length <= sizeof(vp->vp_octets)) {
2742                 memcpy(vp->vp_octets, data, length);
2743         } else {
2744                 vp->type = PW_TYPE_TLV;
2745                 vp->vp_tlv = malloc(length);
2746                 if (!vp->vp_tlv) {
2747                         pairfree(&vp);
2748                         return -1;
2749                 }
2750                 memcpy(vp->vp_tlv, data, length);
2751         }
2752
2753         *pvp = vp;
2754
2755         return length;
2756 }
2757
2758
2759 static ssize_t data2vp_tlvs(const RADIUS_PACKET *packet,
2760                             const RADIUS_PACKET *original,
2761                             const char *secret,
2762                             unsigned int attribute, unsigned int vendor,
2763                             int nest,
2764                             const uint8_t *start, size_t length,
2765                             VALUE_PAIR **pvp);
2766
2767 /*
2768  *      Create any kind of VP from the attribute contents.
2769  *
2770  *      Will return -1 on error, or "length".
2771  */
2772 static ssize_t data2vp_any(const RADIUS_PACKET *packet,
2773                            const RADIUS_PACKET *original,
2774                            const char *secret, int nest,
2775                            unsigned int attribute, unsigned int vendor,
2776                            const uint8_t *data, size_t length,
2777                            VALUE_PAIR **pvp)
2778 {
2779         int data_offset = 0;
2780         DICT_ATTR *da;
2781         VALUE_PAIR *vp = NULL;
2782
2783         if (length == 0) {
2784                 /*
2785                  *      Hacks for CUI.  The WiMAX spec says that it
2786                  *      can be zero length, even though this is
2787                  *      forbidden by the RADIUS specs.  So... we make
2788                  *      a special case for it.
2789                  */
2790                 if ((vendor == 0) &&
2791                     (attribute == PW_CHARGEABLE_USER_IDENTITY)) {
2792                         data = (const uint8_t *) "";
2793                         length = 1;
2794                 } else {
2795                         *pvp = NULL;
2796                         return 0;
2797                 }
2798         }
2799
2800         da = dict_attrbyvalue(attribute, vendor);
2801
2802         /*
2803          *      Unknown attribute.  Create it as a "raw" attribute.
2804          */
2805         if (!da) {
2806                 VP_TRACE("Not found %u.%u\n", vendor, attribute);
2807         raw:
2808                 if (vp) pairfree(&vp);
2809                 return data2vp_raw(packet, original, secret,
2810                                    attribute, vendor, data, length, pvp);
2811         }
2812
2813         /*
2814          *      TLVs are handled first.  They can't be tagged, and
2815          *      they can't be encrypted.
2816          */
2817         if (da->type == PW_TYPE_TLV) {
2818                 VP_TRACE("Found TLV %u.%u\n", vendor, attribute);
2819                 return data2vp_tlvs(packet, original, secret,
2820                                     attribute, vendor, nest,
2821                                     data, length, pvp);
2822         }
2823
2824         /*
2825          *      The attribute is known, and well formed.  We can now
2826          *      create it.  The main failure from here on in is being
2827          *      out of memory.
2828          */
2829         vp = pairalloc(da);
2830         if (!vp) return -1;
2831
2832         /*
2833          *      Handle tags.
2834          */
2835         if (vp->flags.has_tag) {
2836                 if (TAG_VALID(data[0]) ||
2837                     (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD)) {
2838                         /*
2839                          *      Tunnel passwords REQUIRE a tag, even
2840                          *      if don't have a valid tag.
2841                          */
2842                         vp->flags.tag = data[0];
2843
2844                         if ((vp->type == PW_TYPE_STRING) ||
2845                             (vp->type == PW_TYPE_OCTETS)) {
2846                                 if (length == 0) goto raw;
2847                                 data_offset = 1;
2848                         }
2849                 }
2850         }
2851
2852         /*
2853          *      Copy the data to be decrypted
2854          */
2855         vp->length = length - data_offset;
2856         memcpy(&vp->vp_octets[0], data + data_offset, vp->length);
2857
2858         /*
2859          *      Decrypt the attribute.
2860          */
2861         switch (vp->flags.encrypt) {
2862                 /*
2863                  *  User-Password
2864                  */
2865         case FLAG_ENCRYPT_USER_PASSWORD:
2866                 if (original) {
2867                         rad_pwdecode(vp->vp_strvalue,
2868                                      vp->length, secret,
2869                                      original->vector);
2870                 } else {
2871                         rad_pwdecode(vp->vp_strvalue,
2872                                      vp->length, secret,
2873                                      packet->vector);
2874                 }
2875                 if (vp->attribute == PW_USER_PASSWORD) {
2876                         vp->length = strlen(vp->vp_strvalue);
2877                 }
2878                 break;
2879
2880                 /*
2881                  *      Tunnel-Password's may go ONLY
2882                  *      in response packets.
2883                  */
2884         case FLAG_ENCRYPT_TUNNEL_PASSWORD:
2885                 if (!original) goto raw;
2886
2887                 if (rad_tunnel_pwdecode(vp->vp_octets, &vp->length,
2888                                         secret, original->vector) < 0) {
2889                         goto raw;
2890                 }
2891                 break;
2892
2893                 /*
2894                  *  Ascend-Send-Secret
2895                  *  Ascend-Receive-Secret
2896                  */
2897         case FLAG_ENCRYPT_ASCEND_SECRET:
2898                 if (!original) {
2899                         goto raw;
2900                 } else {
2901                         uint8_t my_digest[AUTH_VECTOR_LEN];
2902                         make_secret(my_digest,
2903                                     original->vector,
2904                                     secret, data);
2905                         memcpy(vp->vp_strvalue, my_digest,
2906                                AUTH_VECTOR_LEN );
2907                         vp->vp_strvalue[AUTH_VECTOR_LEN] = '\0';
2908                         vp->length = strlen(vp->vp_strvalue);
2909                 }
2910                 break;
2911
2912         default:
2913                 break;
2914         } /* switch over encryption flags */
2915
2916
2917         switch (vp->type) {
2918         case PW_TYPE_STRING:
2919         case PW_TYPE_OCTETS:
2920         case PW_TYPE_ABINARY:
2921                 /* nothing more to do */
2922                 break;
2923
2924         case PW_TYPE_BYTE:
2925                 if (vp->length != 1) goto raw;
2926
2927                 vp->vp_integer = vp->vp_octets[0];
2928                 break;
2929
2930
2931         case PW_TYPE_SHORT:
2932                 if (vp->length != 2) goto raw;
2933
2934                 vp->vp_integer = (vp->vp_octets[0] << 8) | vp->vp_octets[1];
2935                 break;
2936
2937         case PW_TYPE_INTEGER:
2938                 if (vp->length != 4) goto raw;
2939
2940                 memcpy(&vp->vp_integer, vp->vp_octets, 4);
2941                 vp->vp_integer = ntohl(vp->vp_integer);
2942
2943                 if (vp->flags.has_tag) vp->vp_integer &= 0x00ffffff;
2944
2945                 /*
2946                  *      Try to get named VALUEs
2947                  */
2948                 {
2949                         DICT_VALUE *dval;
2950                         dval = dict_valbyattr(vp->attribute, vp->vendor,
2951                                               vp->vp_integer);
2952                         if (dval) {
2953                                 strlcpy(vp->vp_strvalue,
2954                                         dval->name,
2955                                         sizeof(vp->vp_strvalue));
2956                         }
2957                 }
2958                 break;
2959
2960         case PW_TYPE_DATE:
2961                 if (vp->length != 4) goto raw;
2962
2963                 memcpy(&vp->vp_date, vp->vp_octets, 4);
2964                 vp->vp_date = ntohl(vp->vp_date);
2965                 break;
2966
2967
2968         case PW_TYPE_IPADDR:
2969                 if (vp->length != 4) goto raw;
2970
2971                 memcpy(&vp->vp_ipaddr, vp->vp_octets, 4);
2972                 break;
2973
2974                 /*
2975                  *      IPv6 interface ID is 8 octets long.
2976                  */
2977         case PW_TYPE_IFID:
2978                 if (vp->length != 8) goto raw;
2979                 /* vp->vp_ifid == vp->vp_octets */
2980                 break;
2981
2982                 /*
2983                  *      IPv6 addresses are 16 octets long
2984                  */
2985         case PW_TYPE_IPV6ADDR:
2986                 if (vp->length != 16) goto raw;
2987                 /* vp->vp_ipv6addr == vp->vp_octets */
2988                 break;
2989
2990                 /*
2991                  *      IPv6 prefixes are 2 to 18 octets long.
2992                  *
2993                  *      RFC 3162: The first octet is unused.
2994                  *      The second is the length of the prefix
2995                  *      the rest are the prefix data.
2996                  *
2997                  *      The prefix length can have value 0 to 128.
2998                  */
2999         case PW_TYPE_IPV6PREFIX:
3000                 if (vp->length < 2 || vp->length > 18) goto raw;
3001                 if (vp->vp_octets[1] > 128) goto raw;
3002
3003                 /*
3004                  *      FIXME: double-check that
3005                  *      (vp->vp_octets[1] >> 3) matches vp->length + 2
3006                  */
3007                 if (vp->length < 18) {
3008                         memset(vp->vp_octets + vp->length, 0,
3009                                18 - vp->length);
3010                 }
3011                 break;
3012
3013         case PW_TYPE_SIGNED:
3014                 if (vp->length != 4) goto raw;
3015
3016                 /*
3017                  *      Overload vp_integer for ntohl, which takes
3018                  *      uint32_t, not int32_t
3019                  */
3020                 memcpy(&vp->vp_integer, vp->vp_octets, 4);
3021                 vp->vp_integer = ntohl(vp->vp_integer);
3022                 memcpy(&vp->vp_signed, &vp->vp_integer, 4);
3023                 break;
3024
3025         case PW_TYPE_TLV:
3026                 pairfree(&vp);
3027                 fr_strerror_printf("data2vp_any: Internal sanity check failed");
3028                 return -1;
3029
3030         case PW_TYPE_COMBO_IP:
3031                 if (vp->length == 4) {
3032                         vp->type = PW_TYPE_IPADDR;
3033                         memcpy(&vp->vp_ipaddr, vp->vp_octets, 4);
3034                         break;
3035
3036                 } else if (vp->length == 16) {
3037                         vp->type = PW_TYPE_IPV6ADDR;
3038                         /* vp->vp_ipv6addr == vp->vp_octets */
3039                         break;
3040
3041                 }
3042                 /* FALL-THROUGH */
3043
3044         default:
3045                 goto raw;
3046         }
3047
3048         *pvp = vp;
3049
3050         return length;
3051 }
3052
3053
3054 /*
3055  *      Convert a top-level VSA to a VP.
3056  */
3057 static ssize_t attr2vp_vsa(const RADIUS_PACKET *packet,
3058                            const RADIUS_PACKET *original,
3059                            const char *secret, unsigned int vendor,
3060                            size_t dv_type, size_t dv_length,
3061                            const uint8_t *data, size_t length,
3062                            VALUE_PAIR **pvp)
3063 {
3064         unsigned int attribute;
3065         ssize_t attrlen, my_len;
3066
3067 #ifndef NDEBUG
3068         if (length <= (dv_type + dv_length)) {
3069                 fr_strerror_printf("attr2vp_vsa: Failure to call rad_tlv_ok");
3070                 return -1;
3071         }
3072 #endif  
3073
3074         switch (dv_type) {
3075         case 4:
3076                 /* data[0] must be zero */
3077                 attribute = data[1] << 16;
3078                 attribute |= data[2] << 8;
3079                 attribute |= data[3];
3080                 break;
3081
3082         case 2:
3083                 attribute = data[0] << 8;
3084                 attribute |= data[1];
3085                 break;
3086
3087         case 1:
3088                 attribute = data[0];
3089                 break;
3090
3091         default:
3092                 fr_strerror_printf("attr2vp_vsa: Internal sanity check failed");
3093                 return -1;
3094         }
3095
3096         switch (dv_length) {
3097         case 2:
3098                 /* data[dv_type] must be zero */
3099                 attrlen = data[dv_type + 1];
3100                 break;
3101
3102         case 1:
3103                 attrlen = data[dv_type];
3104                 break;
3105
3106         case 0:
3107                 attrlen = length;
3108                 break;
3109
3110         default:
3111                 fr_strerror_printf("attr2vp_vsa: Internal sanity check failed");
3112                 return -1;
3113         }
3114
3115 #ifndef NDEBUG
3116         if (attrlen <= (ssize_t) (dv_type + dv_length)) {
3117                 fr_strerror_printf("attr2vp_vsa: Failure to call rad_tlv_ok");
3118                 return -1;
3119         }
3120 #endif
3121
3122         attrlen -= (dv_type + dv_length);
3123         
3124         my_len = data2vp_any(packet, original, secret, 0,
3125                              attribute, vendor,
3126                              data + dv_type + dv_length, attrlen, pvp);
3127         if (my_len < 0) return my_len;
3128
3129 #ifndef NDEBUG
3130         if (my_len != attrlen) {
3131                 pairfree(pvp);
3132                 fr_strerror_printf("attr2vp_vsa: Incomplete decode %d != %d",
3133                                    (int) my_len, (int) attrlen);
3134                 return -1;
3135         }
3136 #endif
3137
3138         return dv_type + dv_length + attrlen;
3139 }
3140
3141 /*
3142  *      Convert one or more TLVs to VALUE_PAIRs.  This function can
3143  *      be called recursively...
3144  */
3145 static ssize_t data2vp_tlvs(const RADIUS_PACKET *packet,
3146                             const RADIUS_PACKET *original,
3147                             const char *secret,
3148                             unsigned int attribute, unsigned int vendor,
3149                             int nest,
3150                             const uint8_t *start, size_t length,
3151                             VALUE_PAIR **pvp)
3152 {
3153         size_t dv_type, dv_length;
3154         const uint8_t *data, *end;
3155         VALUE_PAIR *head, **last, *vp;
3156
3157         data = start;
3158
3159         /*
3160          *      The default format for a VSA is the RFC recommended
3161          *      format.
3162          */
3163         dv_type = 1;
3164         dv_length = 1;
3165
3166         /*
3167          *      Top-level TLVs can be of a weird format.  TLVs
3168          *      encapsulated in a TLV can only be in the RFC format.
3169          */
3170         if (nest == 1) {
3171                 DICT_VENDOR *dv;
3172                 dv = dict_vendorbyvalue(vendor);        
3173                 if (dv) {
3174                         dv_type = dv->type;
3175                         dv_length = dv->length;
3176                         /* dict.c enforces sane values on the above fields */
3177                 }
3178         }
3179
3180         if (nest >= fr_attr_max_tlv) {
3181                 fr_strerror_printf("data2vp_tlvs: Internal sanity check failed in recursion");
3182                 return -1;
3183         }
3184
3185         /*
3186          *      The VSAs do not exactly fill the data,
3187          *      The *entire* TLV is malformed.
3188          */
3189         if (rad_tlv_ok(data, length, dv_type, dv_length) < 0) {
3190                 VP_TRACE("TLV malformed %u.%u\n", vendor, attribute);
3191                 return data2vp_raw(packet, original, secret,
3192                                    attribute, vendor, data, length, pvp);
3193         }
3194
3195         end = data + length;
3196         head = NULL;
3197         last = &head;
3198
3199         while (data < end) {
3200                 unsigned int my_attr;
3201                 unsigned int my_len;
3202
3203 #ifndef NDEBUG
3204                 if ((data + dv_type + dv_length) > end) {
3205                         fr_strerror_printf("data2vp_tlvs: Internal sanity check failed in tlvs: Insufficient data");
3206                         pairfree(&head);
3207                         return -1;
3208                 }
3209 #endif
3210
3211                 switch (dv_type) {
3212                 case 1:
3213                         my_attr = attribute;
3214                         my_attr |= ((data[0] & fr_attr_mask[nest + 1])
3215                                     << fr_attr_shift[nest + 1]);
3216                         break;
3217                 case 2:
3218                         my_attr = (data[0] << 8) | data[1];
3219                         break;
3220
3221                 case 4:
3222                         my_attr = (data[1] << 16) | (data[1] << 8) | data[3];
3223                         break;
3224
3225                 default:
3226                         fr_strerror_printf("data2vp_tlvs: Internal sanity check failed");
3227                         return -1;
3228                 }
3229
3230                 switch (dv_length) {
3231                 case 0:
3232                         my_len = length;
3233                         break;
3234
3235                 case 1:
3236                 case 2:
3237                         my_len = data[dv_type + dv_length - 1];
3238                         break;
3239
3240                 default:
3241                         fr_strerror_printf("data2vp_tlvs: Internal sanity check failed");
3242                         return -1;
3243                 }
3244                 
3245 #ifndef NDEBUG
3246                 if (my_len < (dv_type + dv_length)) {
3247                         fr_strerror_printf("data2vp_tlvs: Internal sanity check failed in tlvs: underflow");
3248                         pairfree(&head);
3249                         return -1;
3250                 }
3251
3252                 if ((data + my_len) > end) {
3253                         fr_strerror_printf("data2vp_tlvs: Internal sanity check failed in tlvs: overflow");
3254                         pairfree(&head);
3255                         return -1;
3256                 }
3257 #endif
3258
3259                 my_len -= dv_type + dv_length;
3260
3261                 /*
3262                  *      If this returns > 0, it returns "my_len"
3263                  */
3264                 if (data2vp_any(packet, original, secret, nest + 1,
3265                                 my_attr, vendor,
3266                                 data + dv_type + dv_length, my_len, &vp) < 0) {
3267                         pairfree(&head);
3268                         return -1;
3269                 }
3270
3271                 data += my_len + dv_type + dv_length;
3272                 *last = vp;
3273
3274                 while (vp) {
3275                         last = &(vp->next);
3276                         vp = vp->next;
3277                 }
3278         }
3279
3280         *pvp = head;
3281         return data - start;
3282 }
3283
3284
3285 /*
3286  *      Group "continued" attributes together, and create VPs from them.
3287  *      The caller ensures that the RADIUS packet is OK, and that the
3288  *      continuations have all been checked.
3289  */
3290 static ssize_t data2vp_continued(const RADIUS_PACKET *packet,
3291                                  const RADIUS_PACKET *original,
3292                                  const char *secret,
3293                                  const uint8_t *start, size_t length,
3294                                  VALUE_PAIR **pvp, int nest,
3295                                  unsigned int attribute, unsigned int vendor,
3296                                  int first_offset, int later_offset,
3297                                  ssize_t attrlen)
3298 {
3299         ssize_t left;
3300         uint8_t *attr, *ptr;
3301         const uint8_t *data;
3302
3303         attr = malloc(attrlen);
3304         if (!attr) {
3305                 fr_strerror_printf("Out of memory");
3306                 return -1;
3307         }
3308
3309         left = attrlen;
3310         ptr = attr;
3311         data = start;
3312
3313         /*
3314          *      Do the first one.
3315          */
3316         memcpy(ptr, data + first_offset, data[1] - first_offset);
3317         ptr += data[1] - first_offset;
3318         left -= data[1] - first_offset;
3319         data += data[1];
3320
3321         while (left > 0) {
3322 #ifndef NDEBUG
3323                 if (data >= (start + length)) {
3324                         fr_strerror_printf("data2vp_continued: Internal sanity check failed");
3325                         return -1;
3326                 }
3327 #endif
3328                 memcpy(ptr, data + later_offset, data[1] - later_offset);
3329                 ptr += data[1] - later_offset;
3330                 left -= data[1] - later_offset;
3331                 data += data[1];
3332         }
3333
3334         left = data2vp_any(packet, original, secret, nest,
3335                            attribute, vendor,
3336                            attr, attrlen, pvp);
3337         free(attr);
3338         if (left < 0) return left;
3339
3340         return data - start;
3341 }
3342
3343
3344 /*
3345  *      Create a "raw" VALUE_PAIR from a RADIUS attribute.
3346  */
3347 ssize_t rad_attr2vp_raw(const RADIUS_PACKET *packet,
3348                         const RADIUS_PACKET *original,
3349                         const char *secret,
3350                         const uint8_t *data, size_t length,
3351                         VALUE_PAIR **pvp)
3352 {
3353         ssize_t my_len;
3354
3355         if ((length < 2) || (data[1] < 2) || (data[1] > length)) {
3356                 fr_strerror_printf("rad_attr2vp_raw: Invalid length");
3357                 return -1;
3358         }
3359
3360         my_len = data2vp_raw(packet, original, secret, data[0], 0,
3361                              data + 2, data[1] - 2, pvp);
3362         if (my_len < 0) return my_len;
3363         
3364         return data[1];
3365 }
3366
3367
3368 /*
3369  *      Get the length of the data portion of all of the contiguous
3370  *      continued attributes.
3371  *
3372  *      0 for "no continuation"
3373  *      -1 on malformed packets (continuation followed by non-wimax, etc.)
3374  */
3375 static ssize_t wimax_attrlen(uint32_t vendor,
3376                              const uint8_t *start, const uint8_t *end)
3377 {
3378         ssize_t total;
3379         const uint8_t *data = start;
3380
3381         if ((data[8] & 0x80) == 0) return 0;
3382         total = data[7] - 3;
3383         data += data[1];
3384
3385         while (data < end) {
3386                 
3387                 if ((data + 9) > end) return -1;
3388
3389                 if ((data[0] != PW_VENDOR_SPECIFIC) ||
3390                     (data[1] < 9) ||
3391                     (memcmp(data + 2, &vendor, 4) != 0) ||
3392                     (data[6] != start[6]) ||
3393                     ((data[7] + 6) != data[1])) return -1;
3394
3395                 total += data[7] - 3;
3396                 if ((data[8] & 0x80) == 0) break;
3397                 data += data[1];
3398         }
3399
3400         return total;
3401 }
3402
3403
3404 /*
3405  *      Get the length of the data portion of all of the contiguous
3406  *      continued attributes.
3407  *
3408  *      0 for "no continuation"
3409  *      -1 on malformed packets (continuation followed by non-wimax, etc.)
3410  */
3411 static ssize_t extended_attrlen(const uint8_t *start, const uint8_t *end)
3412 {
3413         ssize_t total;
3414         const uint8_t *data = start;
3415
3416         if ((data[3] & 0x80) == 0) return 0;
3417         total = data[1] - 4;
3418         data += data[1];
3419         
3420         while (data < end) {
3421                 if ((data + 4) > end) return -1;
3422
3423                 if ((data[0] != start[0]) ||
3424                     (data[1] < 4) ||
3425                     (data[2] != start[2])) return -1;
3426
3427                 total += data[1] - 4;
3428                 if ((data[3] & 0x80) == 0) break;
3429                 data += data[1];
3430         }
3431
3432         return total;
3433 }
3434
3435
3436 /*
3437  *      Create WiMAX VALUE_PAIRs from a RADIUS attribute.
3438  */
3439 ssize_t rad_attr2vp_wimax(const RADIUS_PACKET *packet,
3440                           const RADIUS_PACKET *original,
3441                           const char *secret,
3442                           const uint8_t *data,  size_t length,
3443                           VALUE_PAIR **pvp)
3444 {
3445         ssize_t my_len;
3446         unsigned int attribute;
3447         uint32_t lvalue;
3448
3449         if ((length < 2) || (data[1] < 2) || (data[1] > length)) {
3450                 fr_strerror_printf("rad_attr2vp_wimax: Invalid length");
3451                 return -1;
3452         }
3453
3454         if (data[0] != PW_VENDOR_SPECIFIC) {
3455                 fr_strerror_printf("rad_attr2vp_wimax: Invalid attribute");
3456                 return -1;
3457         }
3458
3459         /*
3460          *      Not enough room for a Vendor-Id. + WiMAX header
3461          */
3462         if (data[1] < 9) {
3463                 return rad_attr2vp_raw(packet, original, secret,
3464                                        data, length, pvp);
3465         }
3466
3467         memcpy(&lvalue, data + 2, 4);
3468         lvalue = ntohl(lvalue);
3469
3470         /*
3471          *      Not WiMAX format.
3472          */
3473         if (lvalue != VENDORPEC_WIMAX) {
3474                 DICT_VENDOR *dv;
3475
3476                 dv = dict_vendorbyvalue(lvalue);
3477                 if (!dv || !dv->flags) {
3478                         fr_strerror_printf("rad_attr2vp_wimax: Not a WiMAX attribute");
3479                         return -1;
3480                 }
3481         }
3482
3483         /*
3484          *      The WiMAX attribute is encapsulated in a VSA.  If the
3485          *      WiMAX length disagrees with the VSA length, it's malformed.
3486          */
3487         if ((data[7] + 6) != data[1]) {
3488                 return rad_attr2vp_raw(packet, original, secret,
3489                                        data, length, pvp);
3490         }
3491
3492         attribute = data[6];
3493
3494         /*
3495          *      Attribute is continued.  Do some more work.
3496          */
3497         if (data[8] != 0) {
3498                 my_len = wimax_attrlen(htonl(lvalue), data, data + length);
3499                 if (my_len < 0) {
3500                         return rad_attr2vp_raw(packet, original, secret,
3501                                                data, length, pvp);
3502                 }
3503
3504                 return data2vp_continued(packet, original, secret,
3505                                          data, length, pvp, 0,
3506                                          data[6], lvalue,
3507                                          9, 9, my_len);
3508         }
3509
3510         my_len = data2vp_any(packet, original, secret, 0, attribute, lvalue,
3511                              data + 9, data[1] - 9, pvp);
3512         if (my_len < 0) return my_len;
3513
3514         return data[1];
3515 }
3516
3517 /*
3518  *      Create Vendor-Specifc VALUE_PAIRs from a RADIUS attribute.
3519  */
3520 ssize_t rad_attr2vp_vsa(const RADIUS_PACKET *packet,
3521                         const RADIUS_PACKET *original,
3522                         const char *secret,
3523                         const uint8_t *data, size_t length,
3524                         VALUE_PAIR **pvp)
3525 {
3526         size_t dv_type, dv_length;
3527         ssize_t my_len;
3528         uint32_t lvalue;
3529         DICT_VENDOR *dv;
3530
3531         if ((length < 2) || (data[1] < 2) || (data[1] > length)) {
3532                 fr_strerror_printf("rad_attr2vp_vsa: Invalid length");
3533                 return -1;
3534         }
3535
3536         if (data[0] != PW_VENDOR_SPECIFIC) {
3537                 fr_strerror_printf("rad_attr2vp_vsa: Invalid attribute");
3538                 return -1;
3539         }
3540
3541         /*
3542          *      Not enough room for a Vendor-Id.
3543          *      Or the high octet of the Vendor-Id is set.
3544          */
3545         if ((data[1] < 6) || (data[2] != 0)) {
3546                 return rad_attr2vp_raw(packet, original, secret,
3547                                        data, length, pvp);
3548         }
3549
3550         memcpy(&lvalue, data + 2, 4);
3551         lvalue = ntohl(lvalue);
3552
3553         /*
3554          *      WiMAX gets its own set of magic.
3555          */
3556         if (lvalue == VENDORPEC_WIMAX) {
3557         wimax:
3558                 return rad_attr2vp_wimax(packet, original, secret,
3559                                          data, length, pvp);
3560         }
3561
3562         dv_type = dv_length = 1;
3563         dv = dict_vendorbyvalue(lvalue);
3564         if (dv) {
3565                 dv_type = dv->type;
3566                 dv_length = dv->length;
3567
3568                 if (dv->flags) goto wimax;
3569         }
3570
3571         /*
3572          *      Attribute is not in the correct form.
3573          */
3574         if (rad_tlv_ok(data + 6, data[1] - 6, dv_type, dv_length) < 0) {
3575                 return rad_attr2vp_raw(packet, original, secret,
3576                                        data, length, pvp);
3577         }
3578
3579         my_len = attr2vp_vsa(packet, original, secret,
3580                              lvalue, dv_type, dv_length,
3581                              data + 6, data[1] - 6, pvp);
3582         if (my_len < 0) return my_len;
3583
3584         /*
3585          *      Incomplete decode means that something is wrong
3586          *      with the attribute.  Back up, and make it "raw".
3587          */
3588         if (my_len != (data[1] - 6)) {
3589                 pairfree(pvp);
3590                 return rad_attr2vp_raw(packet, original, secret,
3591                                        data, length, pvp);
3592         }
3593
3594         return data[1];
3595 }
3596
3597 /*
3598  *      Create an "extended" VALUE_PAIR from a RADIUS attribute.
3599  */
3600 ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
3601                              const RADIUS_PACKET *original,
3602                              const char *secret,
3603                              const uint8_t *start, size_t length,
3604                              VALUE_PAIR **pvp)
3605 {
3606         unsigned int attribute;
3607         int shift = 1;
3608         int continued = 0;
3609         unsigned int vendor = VENDORPEC_EXTENDED;
3610         size_t data_len = length;
3611         const uint8_t *data;
3612         DICT_ATTR *da;
3613
3614         data = start;
3615
3616         if ((length < 2) || (data[1] < 2) || (data[1] > length)) {
3617                 fr_strerror_printf("rad_attr2vp_extended: Invalid length");
3618                 return -1;
3619         }
3620
3621         da = dict_attrbyvalue(data[0], vendor);
3622         if (!da ||
3623             (!da->flags.extended && !da->flags.extended_flags)) {
3624                 fr_strerror_printf("rad_attr2vp_extended: Attribute is not extended format");
3625                 return -1;
3626         }
3627
3628         data = start;
3629
3630         /*
3631          *      No Extended-Type.  It's a raw attribute.
3632          *      Also, if there's no data following the Extended-Type,
3633          *      it's a raw attribute.
3634          */
3635         if (data[1] <= 3) {
3636         raw:
3637                 return rad_attr2vp_raw(packet, original, secret, start,
3638                                        length, pvp);
3639         }
3640
3641         /*
3642          *      The attribute is "241.1", for example.  Go look that
3643          *      up to see what type it is.
3644          */
3645         attribute = data[0];
3646         attribute |= (data[2] << fr_attr_shift[1]);
3647
3648         da = dict_attrbyvalue(attribute, vendor);
3649         if (!da) goto raw;
3650
3651         vendor = VENDORPEC_EXTENDED;
3652
3653         data_len = length;
3654         if (data[1] < length) data_len = data[1];
3655
3656         data += 3;
3657         data_len -= 3;
3658
3659         /*
3660          *      If there's supposed to be a flag octet.  If not, it's
3661          *      a raw attribute.  If the flag is set, it's supposed to
3662          *      be continued.
3663          */
3664         if (da->flags.extended_flags) {
3665                 if (data_len == 0) goto raw;
3666
3667                 continued = ((data[0] & 0x80) != 0);
3668                 data++;
3669                 data_len--;
3670         }
3671         
3672         /*
3673          *      Extended VSAs have 4 octets of
3674          *      Vendor-Id followed by one octet of
3675          *      Vendor-Type.
3676          */
3677         if (da->flags.evs) {
3678                 if (data_len < 5) goto raw;
3679                 
3680                 /*
3681                  *      Vendor Ids can only be 24-bit.
3682                  */
3683                 if (data[0] != 0) goto raw;
3684                 
3685                 vendor = ((data[1] << 16) |
3686                           (data[2] << 8) |
3687                           data[3]);
3688                 
3689                 /*
3690                  *      Pack the *encapsulating* attribute number into
3691                  *      the vendor id.  This number should be >= 241.
3692                  */
3693                 vendor |= start[0] * FR_MAX_VENDOR;
3694                 shift = 0;
3695                 
3696                 /*
3697                  *      Over-write the attribute with the
3698                  *      VSA.
3699                  */
3700                 attribute = data[4];
3701                 data += 5;
3702                 data_len -= 5;
3703         }
3704
3705         if (continued) {
3706                 int first_offset = 4;
3707                 ssize_t my_len;
3708
3709                 if (vendor != VENDORPEC_EXTENDED) first_offset += 5;
3710
3711                 my_len = extended_attrlen(start, start + length);
3712                 if (my_len < 0) goto raw;
3713
3714                 if (vendor != VENDORPEC_EXTENDED) my_len -= 5;
3715
3716                 return data2vp_continued(packet, original, secret,
3717                                          start, length, pvp, shift,
3718                                          attribute, vendor,
3719                                          first_offset, 4, my_len);
3720         }
3721
3722         if (data2vp_any(packet, original, secret, shift,
3723                         attribute, vendor, data, data_len, pvp) < 0) {
3724                 return -1;
3725         }
3726
3727         return (data + data_len) - start;
3728 }
3729
3730
3731 /*
3732  *      Create a "standard" RFC VALUE_PAIR from the given data.
3733  */
3734 ssize_t rad_attr2vp_rfc(const RADIUS_PACKET *packet,
3735                         const RADIUS_PACKET *original,
3736                         const char *secret,
3737                         const uint8_t *data, size_t length,
3738                         VALUE_PAIR **pvp)
3739 {
3740         if ((length < 2) || (data[1] < 2) || (data[1] > length)) {
3741                 fr_strerror_printf("rad_attr2vp_rfc: Insufficient data");
3742                 return -1;
3743         }
3744         
3745         if (data2vp_any(packet, original, secret, 0,
3746                         data[0], 0, data + 2, data[1] - 2, pvp) < 0) {
3747                 return -1;
3748         }
3749
3750         return data[1];
3751 }       
3752
3753 /*
3754  *      Create a "normal" VALUE_PAIR from the given data.
3755  */
3756 ssize_t rad_attr2vp(const RADIUS_PACKET *packet,
3757                     const RADIUS_PACKET *original,
3758                     const char *secret,
3759                     const uint8_t *data, size_t length,
3760                     VALUE_PAIR **pvp)
3761 {
3762         if ((length < 2) || (data[1] < 2) || (data[1] > length)) {
3763                 fr_strerror_printf("rad_attr2vp: Insufficient data");
3764                 return -1;
3765         }
3766
3767         /*
3768          *      VSAs get their own handler.
3769          */
3770         if (data[0] == PW_VENDOR_SPECIFIC) {
3771                 return rad_attr2vp_vsa(packet, original, secret,
3772                                        data, length, pvp);
3773         }
3774
3775         /*
3776          *      Extended attribute format gets their own handler.
3777          */
3778         if (dict_attrbyvalue(data[0], VENDORPEC_EXTENDED) != NULL) {
3779                 return rad_attr2vp_extended(packet, original, secret,
3780                                             data, length, pvp);
3781         }
3782
3783         return rad_attr2vp_rfc(packet, original, secret, data, length, pvp);
3784 }
3785
3786
3787 /*
3788  *      Calculate/check digest, and decode radius attributes.
3789  *      Returns:
3790  *      -1 on decoding error
3791  *      0 on success
3792  */
3793 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
3794                const char *secret)
3795 {
3796         int                     packet_length;
3797         int                     num_attributes;
3798         uint8_t                 *ptr;
3799         radius_packet_t         *hdr;
3800         VALUE_PAIR *head, **tail, *vp;
3801
3802         /*
3803          *      Extract attribute-value pairs
3804          */
3805         hdr = (radius_packet_t *)packet->data;
3806         ptr = hdr->data;
3807         packet_length = packet->data_len - AUTH_HDR_LEN;
3808
3809         head = NULL;
3810         tail = &head;
3811         num_attributes = 0;
3812
3813         /*
3814          *      Loop over the attributes, decoding them into VPs.
3815          */
3816         while (packet_length > 0) {
3817                 ssize_t my_len;
3818
3819                 /*
3820                  *      This may return many VPs
3821                  */
3822                 my_len = rad_attr2vp(packet, original, secret,
3823                                      ptr, packet_length, &vp);
3824                 if (my_len < 0) {
3825                         pairfree(&head);
3826                         return -1;
3827                 }
3828
3829                 *tail = vp;
3830                 while (vp) {
3831                         num_attributes++;
3832                         debug_pair(vp);
3833                         tail = &(vp->next);
3834                         vp = vp->next;
3835                 }
3836
3837                 /*
3838                  *      VSA's may not have been counted properly in
3839                  *      rad_packet_ok() above, as it is hard to count
3840                  *      then without using the dictionary.  We
3841                  *      therefore enforce the limits here, too.
3842                  */
3843                 if ((fr_max_attributes > 0) &&
3844                     (num_attributes > fr_max_attributes)) {
3845                         char host_ipaddr[128];
3846
3847                         pairfree(&head);
3848                         fr_strerror_printf("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
3849                                    inet_ntop(packet->src_ipaddr.af,
3850                                              &packet->src_ipaddr.ipaddr,
3851                                              host_ipaddr, sizeof(host_ipaddr)),
3852                                    num_attributes, fr_max_attributes);
3853                         return -1;
3854                 }
3855
3856                 ptr += my_len;
3857                 packet_length -= my_len;
3858         }
3859
3860         /*
3861          *      Merge information from the outside world into our
3862          *      random pool.
3863          */
3864         fr_rand_seed(packet->data, AUTH_HDR_LEN);
3865         
3866         /*
3867          *      There may be VP's already in the packet.  Don't
3868          *      destroy them.  Instead, add the decoded attributes to
3869          *      the tail of the list.
3870          */
3871         for (tail = &packet->vps; *tail != NULL; tail = &((*tail)->next)) {
3872                 /* nothing */
3873         }
3874         *tail = head;
3875
3876         return 0;
3877 }
3878
3879
3880 /*
3881  *      Encode password.
3882  *
3883  *      We assume that the passwd buffer passed is big enough.
3884  *      RFC2138 says the password is max 128 chars, so the size
3885  *      of the passwd buffer must be at least 129 characters.
3886  *      Preferably it's just MAX_STRING_LEN.
3887  *
3888  *      int *pwlen is updated to the new length of the encrypted
3889  *      password - a multiple of 16 bytes.
3890  */
3891 int rad_pwencode(char *passwd, size_t *pwlen, const char *secret,
3892                  const uint8_t *vector)
3893 {
3894         FR_MD5_CTX context, old;
3895         uint8_t digest[AUTH_VECTOR_LEN];
3896         int     i, n, secretlen;
3897         int     len;
3898
3899         /*
3900          *      RFC maximum is 128 bytes.
3901          *
3902          *      If length is zero, pad it out with zeros.
3903          *
3904          *      If the length isn't aligned to 16 bytes,
3905          *      zero out the extra data.
3906          */
3907         len = *pwlen;
3908
3909         if (len > 128) len = 128;
3910
3911         if (len == 0) {
3912                 memset(passwd, 0, AUTH_PASS_LEN);
3913                 len = AUTH_PASS_LEN;
3914         } else if ((len % AUTH_PASS_LEN) != 0) {
3915                 memset(&passwd[len], 0, AUTH_PASS_LEN - (len % AUTH_PASS_LEN));
3916                 len += AUTH_PASS_LEN - (len % AUTH_PASS_LEN);
3917         }
3918         *pwlen = len;
3919
3920         /*
3921          *      Use the secret to setup the decryption digest
3922          */
3923         secretlen = strlen(secret);
3924
3925         fr_MD5Init(&context);
3926         fr_MD5Update(&context, (const uint8_t *) secret, secretlen);
3927         old = context;          /* save intermediate work */
3928
3929         /*
3930          *      Encrypt it in place.  Don't bother checking
3931          *      len, as we've ensured above that it's OK.
3932          */
3933         for (n = 0; n < len; n += AUTH_PASS_LEN) {
3934                 if (n == 0) {
3935                         fr_MD5Update(&context, vector, AUTH_PASS_LEN);
3936                         fr_MD5Final(digest, &context);
3937                 } else {
3938                         context = old;
3939                         fr_MD5Update(&context,
3940                                      (uint8_t *) passwd + n - AUTH_PASS_LEN,
3941                                      AUTH_PASS_LEN);
3942                         fr_MD5Final(digest, &context);
3943                 }
3944
3945                 for (i = 0; i < AUTH_PASS_LEN; i++) {
3946                         passwd[i + n] ^= digest[i];
3947                 }
3948         }
3949
3950         return 0;
3951 }
3952
3953 /*
3954  *      Decode password.
3955  */
3956 int rad_pwdecode(char *passwd, size_t pwlen, const char *secret,
3957                  const uint8_t *vector)
3958 {
3959         FR_MD5_CTX context, old;
3960         uint8_t digest[AUTH_VECTOR_LEN];
3961         int     i;
3962         size_t  n, secretlen;
3963
3964         /*
3965          *      The RFC's say that the maximum is 128.
3966          *      The buffer we're putting it into above is 254, so
3967          *      we don't need to do any length checking.
3968          */
3969         if (pwlen > 128) pwlen = 128;
3970
3971         /*
3972          *      Catch idiots.
3973          */
3974         if (pwlen == 0) goto done;
3975
3976         /*
3977          *      Use the secret to setup the decryption digest
3978          */
3979         secretlen = strlen(secret);
3980
3981         fr_MD5Init(&context);
3982         fr_MD5Update(&context, (const uint8_t *) secret, secretlen);
3983         old = context;          /* save intermediate work */
3984
3985         /*
3986          *      The inverse of the code above.
3987          */
3988         for (n = 0; n < pwlen; n += AUTH_PASS_LEN) {
3989                 if (n == 0) {
3990                         fr_MD5Update(&context, vector, AUTH_VECTOR_LEN);
3991                         fr_MD5Final(digest, &context);
3992
3993                         context = old;
3994                         if (pwlen > AUTH_PASS_LEN) {
3995                                 fr_MD5Update(&context, (uint8_t *) passwd,
3996                                              AUTH_PASS_LEN);
3997                         }
3998                 } else {
3999                         fr_MD5Final(digest, &context);
4000
4001                         context = old;
4002                         if (pwlen > (n + AUTH_PASS_LEN)) {
4003                                 fr_MD5Update(&context, (uint8_t *) passwd + n,
4004                                              AUTH_PASS_LEN);
4005                         }
4006                 }
4007
4008                 for (i = 0; i < AUTH_PASS_LEN; i++) {
4009                         passwd[i + n] ^= digest[i];
4010                 }
4011         }
4012
4013  done:
4014         passwd[pwlen] = '\0';
4015         return strlen(passwd);
4016 }
4017
4018
4019 /*
4020  *      Encode Tunnel-Password attributes when sending them out on the wire.
4021  *
4022  *      int *pwlen is updated to the new length of the encrypted
4023  *      password - a multiple of 16 bytes.
4024  *
4025  *      This is per RFC-2868 which adds a two char SALT to the initial intermediate
4026  *      value MD5 hash.
4027  */
4028 int rad_tunnel_pwencode(char *passwd, size_t *pwlen, const char *secret,
4029                         const uint8_t *vector)
4030 {
4031         uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
4032         unsigned char   digest[AUTH_VECTOR_LEN];
4033         char*   salt;
4034         int     i, n, secretlen;
4035         unsigned len, n2;
4036
4037         len = *pwlen;
4038
4039         if (len > 127) len = 127;
4040
4041         /*
4042          * Shift the password 3 positions right to place a salt and original
4043          * length, tag will be added automatically on packet send
4044          */
4045         for (n=len ; n>=0 ; n--) passwd[n+3] = passwd[n];
4046         salt = passwd;
4047         passwd += 2;
4048         /*
4049          * save original password length as first password character;
4050          */
4051         *passwd = len;
4052         len += 1;
4053
4054
4055         /*
4056          *      Generate salt.  The RFC's say:
4057          *
4058          *      The high bit of salt[0] must be set, each salt in a
4059          *      packet should be unique, and they should be random
4060          *
4061          *      So, we set the high bit, add in a counter, and then
4062          *      add in some CSPRNG data.  should be OK..
4063          */
4064         salt[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
4065                    (fr_rand() & 0x07));
4066         salt[1] = fr_rand();
4067
4068         /*
4069          *      Padd password to multiple of AUTH_PASS_LEN bytes.
4070          */
4071         n = len % AUTH_PASS_LEN;
4072         if (n) {
4073                 n = AUTH_PASS_LEN - n;
4074                 for (; n > 0; n--, len++)
4075                         passwd[len] = 0;
4076         }
4077         /* set new password length */
4078         *pwlen = len + 2;
4079
4080         /*
4081          *      Use the secret to setup the decryption digest
4082          */
4083         secretlen = strlen(secret);
4084         memcpy(buffer, secret, secretlen);
4085
4086         for (n2 = 0; n2 < len; n2+=AUTH_PASS_LEN) {
4087                 if (!n2) {
4088                         memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
4089                         memcpy(buffer + secretlen + AUTH_VECTOR_LEN, salt, 2);
4090                         fr_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
4091                 } else {
4092                         memcpy(buffer + secretlen, passwd + n2 - AUTH_PASS_LEN, AUTH_PASS_LEN);
4093                         fr_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
4094                 }
4095
4096                 for (i = 0; i < AUTH_PASS_LEN; i++) {
4097                         passwd[i + n2] ^= digest[i];
4098                 }
4099         }
4100         passwd[n2] = 0;
4101         return 0;
4102 }
4103
4104 /*
4105  *      Decode Tunnel-Password encrypted attributes.
4106  *
4107  *      Defined in RFC-2868, this uses a two char SALT along with the
4108  *      initial intermediate value, to differentiate it from the
4109  *      above.
4110  */
4111 int rad_tunnel_pwdecode(uint8_t *passwd, size_t *pwlen, const char *secret,
4112                         const uint8_t *vector)
4113 {
4114         FR_MD5_CTX  context, old;
4115         uint8_t         digest[AUTH_VECTOR_LEN];
4116         int             secretlen;
4117         unsigned        i, n, len, reallen;
4118
4119         len = *pwlen;
4120
4121         /*
4122          *      We need at least a salt.
4123          */
4124         if (len < 2) {
4125                 fr_strerror_printf("tunnel password is too short");
4126                 return -1;
4127         }
4128
4129         /*
4130          *      There's a salt, but no password.  Or, there's a salt
4131          *      and a 'data_len' octet.  It's wrong, but at least we
4132          *      can figure out what it means: the password is empty.
4133          *
4134          *      Note that this means we ignore the 'data_len' field,
4135          *      if the attribute length tells us that there's no
4136          *      more data.  So the 'data_len' field may be wrong,
4137          *      but that's ok...
4138          */
4139         if (len <= 3) {
4140                 passwd[0] = 0;
4141                 *pwlen = 0;
4142                 return 0;
4143         }
4144
4145         len -= 2;               /* discount the salt */
4146
4147         /*
4148          *      Use the secret to setup the decryption digest
4149          */
4150         secretlen = strlen(secret);
4151
4152         fr_MD5Init(&context);
4153         fr_MD5Update(&context, (const uint8_t *) secret, secretlen);
4154         old = context;          /* save intermediate work */
4155
4156         /*
4157          *      Set up the initial key:
4158          *
4159          *       b(1) = MD5(secret + vector + salt)
4160          */
4161         fr_MD5Update(&context, vector, AUTH_VECTOR_LEN);
4162         fr_MD5Update(&context, passwd, 2);
4163
4164         reallen = 0;
4165         for (n = 0; n < len; n += AUTH_PASS_LEN) {
4166                 int base = 0;
4167
4168                 if (n == 0) {
4169                         fr_MD5Final(digest, &context);
4170
4171                         context = old;
4172
4173                         /*
4174                          *      A quick check: decrypt the first octet
4175                          *      of the password, which is the
4176                          *      'data_len' field.  Ensure it's sane.
4177                          */
4178                         reallen = passwd[2] ^ digest[0];
4179                         if (reallen >= len) {
4180                                 fr_strerror_printf("tunnel password is too long for the attribute");
4181                                 return -1;
4182                         }
4183
4184                         fr_MD5Update(&context, passwd + 2, AUTH_PASS_LEN);
4185
4186                         base = 1;
4187                 } else {
4188                         fr_MD5Final(digest, &context);
4189
4190                         context = old;
4191                         fr_MD5Update(&context, passwd + n + 2, AUTH_PASS_LEN);
4192                 }
4193
4194                 for (i = base; i < AUTH_PASS_LEN; i++) {
4195                         passwd[n + i - 1] = passwd[n + i + 2] ^ digest[i];
4196                 }
4197         }
4198
4199         /*
4200          *      See make_tunnel_password, above.
4201          */
4202         if (reallen > 239) reallen = 239;
4203
4204         *pwlen = reallen;
4205         passwd[reallen] = 0;
4206
4207         return reallen;
4208 }
4209
4210 /*
4211  *      Encode a CHAP password
4212  *
4213  *      FIXME: might not work with Ascend because
4214  *      we use vp->length, and Ascend gear likes
4215  *      to send an extra '\0' in the string!
4216  */
4217 int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id,
4218                     VALUE_PAIR *password)
4219 {
4220         int             i;
4221         uint8_t         *ptr;
4222         uint8_t         string[MAX_STRING_LEN * 2 + 1];
4223         VALUE_PAIR      *challenge;
4224
4225         /*
4226          *      Sanity check the input parameters
4227          */
4228         if ((packet == NULL) || (password == NULL)) {
4229                 return -1;
4230         }
4231
4232         /*
4233          *      Note that the password VP can be EITHER
4234          *      a User-Password attribute (from a check-item list),
4235          *      or a CHAP-Password attribute (the client asking
4236          *      the library to encode it).
4237          */
4238
4239         i = 0;
4240         ptr = string;
4241         *ptr++ = id;
4242
4243         i++;
4244         memcpy(ptr, password->vp_strvalue, password->length);
4245         ptr += password->length;
4246         i += password->length;
4247
4248         /*
4249          *      Use Chap-Challenge pair if present,
4250          *      Request-Authenticator otherwise.
4251          */
4252         challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE, 0);
4253         if (challenge) {
4254                 memcpy(ptr, challenge->vp_strvalue, challenge->length);
4255                 i += challenge->length;
4256         } else {
4257                 memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
4258                 i += AUTH_VECTOR_LEN;
4259         }
4260
4261         *output = id;
4262         fr_md5_calc((uint8_t *)output + 1, (uint8_t *)string, i);
4263
4264         return 0;
4265 }
4266
4267
4268 /*
4269  *      Seed the random number generator.
4270  *
4271  *      May be called any number of times.
4272  */
4273 void fr_rand_seed(const void *data, size_t size)
4274 {
4275         uint32_t hash;
4276
4277         /*
4278          *      Ensure that the pool is initialized.
4279          */
4280         if (!fr_rand_initialized) {
4281                 int fd;
4282
4283                 memset(&fr_rand_pool, 0, sizeof(fr_rand_pool));
4284
4285                 fd = open("/dev/urandom", O_RDONLY);
4286                 if (fd >= 0) {
4287                         size_t total;
4288                         ssize_t this;
4289
4290                         total = 0;
4291                         while (total < sizeof(fr_rand_pool.randrsl)) {
4292                                 this = read(fd, fr_rand_pool.randrsl,
4293                                             sizeof(fr_rand_pool.randrsl) - total);
4294                                 if ((this < 0) && (errno != EINTR)) break;
4295                                 if (this > 0) total += this;
4296                         }
4297                         close(fd);
4298                 } else {
4299                         fr_rand_pool.randrsl[0] = fd;
4300                         fr_rand_pool.randrsl[1] = time(NULL);
4301                         fr_rand_pool.randrsl[2] = errno;
4302                 }
4303
4304                 fr_randinit(&fr_rand_pool, 1);
4305                 fr_rand_pool.randcnt = 0;
4306                 fr_rand_initialized = 1;
4307         }
4308
4309         if (!data) return;
4310
4311         /*
4312          *      Hash the user data
4313          */
4314         hash = fr_rand();
4315         if (!hash) hash = fr_rand();
4316         hash = fr_hash_update(data, size, hash);
4317
4318         fr_rand_pool.randmem[fr_rand_pool.randcnt] ^= hash;
4319 }
4320
4321
4322 /*
4323  *      Return a 32-bit random number.
4324  */
4325 uint32_t fr_rand(void)
4326 {
4327         uint32_t num;
4328
4329         /*
4330          *      Ensure that the pool is initialized.
4331          */
4332         if (!fr_rand_initialized) {
4333                 fr_rand_seed(NULL, 0);
4334         }
4335
4336         num = fr_rand_pool.randrsl[fr_rand_pool.randcnt++];
4337         if (fr_rand_pool.randcnt >= 256) {
4338                 fr_rand_pool.randcnt = 0;
4339                 fr_isaac(&fr_rand_pool);
4340         }
4341
4342         return num;
4343 }
4344
4345
4346 /*
4347  *      Allocate a new RADIUS_PACKET
4348  */
4349 RADIUS_PACKET *rad_alloc(int newvector)
4350 {
4351         RADIUS_PACKET   *rp;
4352
4353         if ((rp = malloc(sizeof(RADIUS_PACKET))) == NULL) {
4354                 fr_strerror_printf("out of memory");
4355                 return NULL;
4356         }
4357         memset(rp, 0, sizeof(*rp));
4358         rp->id = -1;
4359         rp->offset = -1;
4360
4361         if (newvector) {
4362                 int i;
4363                 uint32_t hash, base;
4364
4365                 /*
4366                  *      Don't expose the actual contents of the random
4367                  *      pool.
4368                  */
4369                 base = fr_rand();
4370                 for (i = 0; i < AUTH_VECTOR_LEN; i += sizeof(uint32_t)) {
4371                         hash = fr_rand() ^ base;
4372                         memcpy(rp->vector + i, &hash, sizeof(hash));
4373                 }
4374         }
4375         fr_rand();              /* stir the pool again */
4376
4377         return rp;
4378 }
4379
4380 RADIUS_PACKET *rad_alloc_reply(RADIUS_PACKET *packet)
4381 {
4382         RADIUS_PACKET *reply;
4383
4384         if (!packet) return NULL;
4385
4386         reply = rad_alloc(0);
4387         if (!reply) return NULL;
4388
4389         /*
4390          *      Initialize the fields from the request.
4391          */
4392         reply->sockfd = packet->sockfd;
4393         reply->dst_ipaddr = packet->src_ipaddr;
4394         reply->src_ipaddr = packet->dst_ipaddr;
4395         reply->dst_port = packet->src_port;
4396         reply->src_port = packet->dst_port;
4397         reply->id = packet->id;
4398         reply->code = 0; /* UNKNOWN code */
4399         memcpy(reply->vector, packet->vector,
4400                sizeof(reply->vector));
4401         reply->vps = NULL;
4402         reply->data = NULL;
4403         reply->data_len = 0;
4404
4405         return reply;
4406 }
4407
4408
4409 /*
4410  *      Free a RADIUS_PACKET
4411  */
4412 void rad_free(RADIUS_PACKET **radius_packet_ptr)
4413 {
4414         RADIUS_PACKET *radius_packet;
4415
4416         if (!radius_packet_ptr || !*radius_packet_ptr) return;
4417         radius_packet = *radius_packet_ptr;
4418
4419         free(radius_packet->data);
4420
4421         pairfree(&radius_packet->vps);
4422
4423         free(radius_packet);
4424
4425         *radius_packet_ptr = NULL;
4426 }