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