2 * radius.c Functions to send/receive radius packets.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2000-2003,2006 The FreeRADIUS server project
23 #include <freeradius-devel/ident.h>
26 #include <freeradius-devel/autoconf.h>
27 #include <freeradius-devel/md5.h>
39 #include <freeradius-devel/udpfromto.h>
51 #include <freeradius-devel/missing.h>
52 #include <freeradius-devel/libradius.h>
55 * The RFC says 4096 octets max, and most packets are less than 256.
57 #define MAX_PACKET_LEN 4096
60 * The maximum number of attributes which we allow in an incoming
61 * request. If there are more attributes than this, the request
64 * This helps to minimize the potential for a DoS, when an
65 * attacker spoofs Access-Request packets, which don't have a
66 * Message-Authenticator attribute. This means that the packet
67 * is unsigned, and the attacker can use resources on the server,
68 * even if the end request is rejected.
70 int librad_max_attributes = 0;
72 typedef struct radius_packet_t {
76 uint8_t vector[AUTH_VECTOR_LEN];
80 static lrad_randctx lrad_rand_pool; /* across multiple calls */
81 static int lrad_rand_initialized = 0;
82 static unsigned int salt_offset = 0;
85 #define MAX_PACKET_CODE (52)
86 static const char *packet_codes[] = {
92 "Accounting-Response",
108 "Resource-Free-Request",
109 "Resource-Free-Response",
110 "Resource-Query-Request",
111 "Resource-Query-Response",
112 "Alternate-Resource-Reclaim-Request",
113 "NAS-Reboot-Request",
114 "NAS-Reboot-Response",
127 "Disconnect-Request",
137 "IP-Address-Allocate",
143 * Wrapper for sendto which handles sendfromto, IPv6, and all
144 * possible combinations.
146 static int rad_sendto(int sockfd, void *data, size_t data_len, int flags,
147 lrad_ipaddr_t *src_ipaddr, lrad_ipaddr_t *dst_ipaddr,
150 struct sockaddr_storage dst;
151 socklen_t sizeof_dst = sizeof(dst);
153 #ifdef WITH_UDPFROMTO
154 struct sockaddr_storage src;
155 socklen_t sizeof_src = sizeof(src);
157 memset(&src, 0, sizeof(src));
159 memset(&dst, 0, sizeof(dst));
164 if (dst_ipaddr->af == AF_INET) {
165 struct sockaddr_in *s4;
167 s4 = (struct sockaddr_in *)&dst;
168 sizeof_dst = sizeof(struct sockaddr_in);
170 s4->sin_family = AF_INET;
171 s4->sin_addr = dst_ipaddr->ipaddr.ip4addr;
172 s4->sin_port = htons(dst_port);
174 #ifdef WITH_UDPFROMTO
175 s4 = (struct sockaddr_in *)&src;
176 sizeof_src = sizeof(struct sockaddr_in);
178 s4->sin_family = AF_INET;
179 s4->sin_addr = src_ipaddr->ipaddr.ip4addr;
183 * IPv6 MAY be supported.
185 #ifdef HAVE_STRUCT_SOCKADDR_IN6
186 } else if (dst_ipaddr->af == AF_INET6) {
187 struct sockaddr_in6 *s6;
189 s6 = (struct sockaddr_in6 *)&dst;
190 sizeof_dst = sizeof(struct sockaddr_in6);
192 s6->sin6_family = AF_INET6;
193 s6->sin6_addr = dst_ipaddr->ipaddr.ip6addr;
194 s6->sin6_port = htons(dst_port);
196 #ifdef WITH_UDPFROMTO
197 return -1; /* UDPFROMTO && IPv6 are not supported */
199 s6 = (struct sockaddr_in6 *)&src;
200 sizeof_src = sizeof(struct sockaddr_in6);
202 s6->sin6_family = AF_INET6;
203 s6->sin6_addr = src_ipaddr->ipaddr.ip6addr;
205 #endif /* WITH_UDPFROMTO */
206 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
207 } else return -1; /* Unknown address family, Die Die Die! */
209 #ifdef WITH_UDPFROMTO
211 * Only IPv4 is supported for udpfromto.
213 * And if they don't specify a source IP address, don't
216 if ((dst_ipaddr->af == AF_INET) ||
217 (src_ipaddr->af != AF_UNSPEC)) {
218 return sendfromto(sockfd, data, data_len, flags,
219 (struct sockaddr *)&src, sizeof_src,
220 (struct sockaddr *)&dst, sizeof_dst);
223 src_ipaddr = src_ipaddr; /* -Wunused */
227 * No udpfromto, OR an IPv6 socket, fail gracefully.
229 return sendto(sockfd, data, data_len, flags,
230 (struct sockaddr *)&dst, sizeof_dst);
235 * Wrapper for recvfrom, which handles recvfromto, IPv6, and all
236 * possible combinations.
238 static ssize_t rad_recvfrom(int sockfd, uint8_t **pbuf, int flags,
239 lrad_ipaddr_t *src_ipaddr, uint16_t *src_port,
240 lrad_ipaddr_t *dst_ipaddr, uint16_t *dst_port)
242 struct sockaddr_storage src;
243 struct sockaddr_storage dst;
244 socklen_t sizeof_src = sizeof(src);
245 socklen_t sizeof_dst = sizeof(dst);
251 memset(&src, 0, sizeof_src);
252 memset(&dst, 0, sizeof_dst);
255 * Get address family, etc. first, so we know if we
256 * need to do udpfromto.
258 * FIXME: udpfromto also does this, but it's not
259 * a critical problem.
261 if (getsockname(sockfd, (struct sockaddr *)&dst,
262 &sizeof_dst) < 0) return -1;
265 * Read the length of the packet, from the packet.
266 * This lets us allocate the buffer to use for
267 * reading the rest of the packet.
269 data_len = recvfrom(sockfd, header, sizeof(header), MSG_PEEK,
270 (struct sockaddr *)&src, &sizeof_src);
271 if (data_len < 0) return -1;
274 * Too little data is available, round it up to 4 bytes.
278 } else { /* we got 4 bytes of data. */
280 * See how long the packet says it is.
282 len = (header[2] * 256) + header[3];
285 * Too short: read 4 bytes, and discard the rest.
291 * Enforce RFC requirements, for sanity.
292 * Anything after 4k will be discarded.
294 } else if (len > MAX_PACKET_LEN) {
295 len = MAX_PACKET_LEN;
303 * Receive the packet. The OS will discard any data in the
304 * packet after "len" bytes.
306 #ifdef WITH_UDPFROMTO
307 if (dst.ss_family == AF_INET) {
308 data_len = recvfromto(sockfd, buf, len, flags,
309 (struct sockaddr *)&src, &sizeof_src,
310 (struct sockaddr *)&dst, &sizeof_dst);
314 * No udpfromto, OR an IPv6 socket. Fail gracefully.
316 data_len = recvfrom(sockfd, buf, len, flags,
317 (struct sockaddr *)&src, &sizeof_src);
324 * Check address families, and update src/dst ports, etc.
326 if (src.ss_family == AF_INET) {
327 struct sockaddr_in *s4;
329 s4 = (struct sockaddr_in *)&src;
330 src_ipaddr->af = AF_INET;
331 src_ipaddr->ipaddr.ip4addr = s4->sin_addr;
332 *src_port = ntohs(s4->sin_port);
334 s4 = (struct sockaddr_in *)&dst;
335 dst_ipaddr->af = AF_INET;
336 dst_ipaddr->ipaddr.ip4addr = s4->sin_addr;
337 *dst_port = ntohs(s4->sin_port);
339 #ifdef HAVE_STRUCT_SOCKADDR_IN6
340 } else if (src.ss_family == AF_INET6) {
341 struct sockaddr_in6 *s6;
343 s6 = (struct sockaddr_in6 *)&src;
344 src_ipaddr->af = AF_INET6;
345 src_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
346 *src_port = ntohs(s6->sin6_port);
348 s6 = (struct sockaddr_in6 *)&dst;
349 dst_ipaddr->af = AF_INET6;
350 dst_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
351 *dst_port = ntohs(s6->sin6_port);
355 return -1; /* Unknown address family, Die Die Die! */
359 * Different address families should never happen.
361 if (src.ss_family != dst.ss_family) {
367 * Tell the caller about the data
375 #define AUTH_PASS_LEN (AUTH_VECTOR_LEN)
376 /*************************************************************************
378 * Function: make_secret
380 * Purpose: Build an encrypted secret value to return in a reply
381 * packet. The secret is hidden by xoring with a MD5 digest
382 * created from the shared secret and the authentication
383 * vector. We put them into MD5 in the reverse order from
384 * that used when encrypting passwords to RADIUS.
386 *************************************************************************/
387 static void make_secret(uint8_t *digest, const uint8_t *vector,
388 const char *secret, const uint8_t *value)
390 lrad_MD5_CTX context;
393 lrad_MD5Init(&context);
394 lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
395 lrad_MD5Update(&context, secret, strlen(secret));
396 lrad_MD5Final(digest, &context);
398 for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
399 digest[i] ^= value[i];
403 #define MAX_PASS_LEN (128)
404 static void make_passwd(uint8_t *output, int *outlen,
405 const uint8_t *input, int inlen,
406 const char *secret, const uint8_t *vector)
408 lrad_MD5_CTX context, old;
409 uint8_t digest[AUTH_VECTOR_LEN];
410 uint8_t passwd[MAX_PASS_LEN];
415 * If the length is zero, round it up.
421 else if (len > MAX_PASS_LEN) len = MAX_PASS_LEN;
423 else if ((len & 0x0f) != 0) {
429 memcpy(passwd, input, len);
430 memset(passwd + len, 0, sizeof(passwd) - len);
432 lrad_MD5Init(&context);
433 lrad_MD5Update(&context, secret, strlen(secret));
439 lrad_MD5Update(&context, vector, AUTH_PASS_LEN);
441 for (n = 0; n < len; n += AUTH_PASS_LEN) {
444 lrad_MD5Update(&context,
445 passwd + n - AUTH_PASS_LEN,
449 lrad_MD5Final(digest, &context);
450 for (i = 0; i < AUTH_PASS_LEN; i++) {
451 passwd[i + n] ^= digest[i];
455 memcpy(output, passwd, len);
458 static void make_tunnel_passwd(uint8_t *output, int *outlen,
459 const uint8_t *input, int inlen, int room,
460 const char *secret, const uint8_t *vector)
462 lrad_MD5_CTX context, old;
463 uint8_t digest[AUTH_VECTOR_LEN];
464 uint8_t passwd[MAX_STRING_LEN + AUTH_VECTOR_LEN];
471 if (room > 253) room = 253;
474 * Account for 2 bytes of the salt, and round the room
475 * available down to the nearest multiple of 16. Then,
476 * subtract one from that to account for the length byte,
477 * and the resulting number is the upper bound on the data
480 * We could short-cut this calculation just be forcing
481 * inlen to be no more than 239. It would work for all
482 * VSA's, as we don't pack multiple VSA's into one
485 * However, this calculation is more general, if a little
486 * complex. And it will work in the future for all possible
487 * kinds of weird attribute packing.
490 room -= (room & 0x0f);
493 if (inlen > room) inlen = room;
496 * Length of the encrypted data is password length plus
497 * one byte for the length of the password.
500 if ((len & 0x0f) != 0) {
504 *outlen = len + 2; /* account for the salt */
507 * Copy the password over.
509 memcpy(passwd + 3, input, inlen);
510 memset(passwd + 3 + inlen, 0, sizeof(passwd) - 3 - inlen);
513 * Generate salt. The RFC's say:
515 * The high bit of salt[0] must be set, each salt in a
516 * packet should be unique, and they should be random
518 * So, we set the high bit, add in a counter, and then
519 * add in some CSPRNG data. should be OK..
521 passwd[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
522 (lrad_rand() & 0x07));
523 passwd[1] = lrad_rand();
524 passwd[2] = inlen; /* length of the password string */
526 lrad_MD5Init(&context);
527 lrad_MD5Update(&context, secret, strlen(secret));
530 lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
531 lrad_MD5Update(&context, &passwd[0], 2);
533 for (n = 0; n < len; n += AUTH_PASS_LEN) {
536 lrad_MD5Update(&context,
537 passwd + 2 + n - AUTH_PASS_LEN,
541 lrad_MD5Final(digest, &context);
542 for (i = 0; i < AUTH_PASS_LEN; i++) {
543 passwd[i + 2 + n] ^= digest[i];
546 memcpy(output, passwd, len + 2);
550 * Hack for IETF RADEXT. Don't use in a production environment!
552 * FIXME: Pack multiple diameter attributes into one
553 * Extended-Attribute!
555 static int vp2diameter(const RADIUS_PACKET *packet,
556 const RADIUS_PACKET *original, const char *secret,
557 const VALUE_PAIR *vp, uint8_t *ptr)
560 uint32_t length = vp->length;
565 *(ptr++) = PW_EXTENDED_ATTRIBUTE;
566 length_ptr = ptr++; /* fill this in later. */
569 attr = vp->attribute;
570 attr &= ~(1 << 31); /* implemented limitations, see dict_addattr */
571 vendor = VENDOR(attr);
572 attr = attr & 0xffff;
575 memcpy(ptr, &attr, sizeof(attr));
578 length += 8; /* includes 8 bytes of attr & length */
579 align = 0; /* no padding */
582 length += 4; /* include 4 bytes of vendor */
585 length = ntohl(length);
586 memcpy(ptr, &length, sizeof(length));
590 vendor = ntohl(vendor);
591 memcpy(ptr, &vendor, sizeof(vendor));
595 length = ntohl(length);
596 memcpy(ptr, &length, sizeof(length));
603 case PW_TYPE_INTEGER:
605 attr = ntohl(vp->lvalue); /* stored in host order */
606 memcpy(ptr, &attr, sizeof(attr));
611 attr = vp->lvalue; /* stored in network order */
612 memcpy(ptr, &attr, sizeof(attr));
617 case PW_TYPE_IPV6ADDR:
618 case PW_TYPE_IPV6PREFIX:
619 case PW_TYPE_ABINARY:
620 memcpy(ptr, vp->vp_strvalue, vp->length);
622 if ((length & 0x03) != 0) align = 4 - (length & 0x03);
626 * Length MAY be larger than can fit into the
627 * encapsulating attribute!
636 if ((length & 0x03) != 0) align = 4 - (length & 0x03);
638 if (total + length > 255) {
640 offset = 255 - total;
642 memcpy(ptr, vp->vp_octets, offset);
644 *(ptr++) = PW_EXTENDED_ATTRIBUTE;
652 memcpy(ptr, vp->vp_octets + offset, length);
658 * Skip to the end of the data.
662 *length_ptr += length;
665 * Align the data to a multiple of 4 bytes.
670 *length_ptr += align;
671 for (i = 0; i < align; i++) {
682 * Parse a data structure into a RADIUS attribute.
684 int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
685 const char *secret, const VALUE_PAIR *vp, uint8_t *ptr)
688 int offset, len, total_length;
690 uint8_t *length_ptr, *vsa_length_ptr;
691 const uint8_t *data = NULL;
694 vendorcode = total_length = 0;
695 length_ptr = vsa_length_ptr = NULL;
698 * For interoperability, always put vendor attributes
699 * into their own VSA.
701 if ((vendorcode = VENDOR(vp->attribute)) == 0) {
702 *(ptr++) = vp->attribute & 0xFF;
710 DICT_VENDOR *dv = dict_vendorbyvalue(vendorcode);
713 * This must be an RFC-format attribute. If it
714 * wasn't, then the "decode" function would have
715 * made a Vendor-Specific attribute (i.e. type
716 * 26), and we would have "vendorcode == 0" here.
720 vsa_llen = dv->length;
724 * Build a VSA header.
726 *ptr++ = PW_VENDOR_SPECIFIC;
727 vsa_length_ptr = ptr;
729 lvalue = htonl(vendorcode);
730 memcpy(ptr, &lvalue, 4);
736 ptr[0] = (vp->attribute & 0xFF);
740 ptr[0] = ((vp->attribute >> 8) & 0xFF);
741 ptr[1] = (vp->attribute & 0xFF);
747 ptr[2] = ((vp->attribute >> 8) & 0xFF);
748 ptr[3] = (vp->attribute & 0xFF);
752 return 0; /* silently discard it */
758 length_ptr = vsa_length_ptr;
759 vsa_length_ptr = NULL;
768 length_ptr = ptr + 1;
772 return 0; /* silently discard it */
776 total_length += vsa_tlen + vsa_llen;
777 if (vsa_length_ptr) *vsa_length_ptr += vsa_tlen + vsa_llen;
778 *length_ptr += vsa_tlen + vsa_llen;
782 if (vp->flags.has_tag) {
783 if (TAG_VALID(vp->flags.tag)) {
784 ptr[0] = vp->flags.tag & 0xff;
787 } else if (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
789 * Tunnel passwords REQUIRE a tag, even
790 * if don't have a valid tag.
794 } /* else don't write a tag */
795 } /* else the attribute doesn't have a tag */
798 * Set up the default sources for the data.
800 data = vp->vp_octets;
807 case PW_TYPE_IPV6ADDR:
808 case PW_TYPE_IPV6PREFIX:
809 case PW_TYPE_ABINARY:
810 /* nothing more to do */
814 len = 1; /* just in case */
815 array[0] = vp->lvalue & 0xff;
822 len = 2; /* just in case */
823 array[0] = (vp->lvalue >> 8) & 0xff;
824 array[1] = vp->lvalue & 0xff;
829 case PW_TYPE_INTEGER:
830 len = 4; /* just in case */
831 lvalue = htonl(vp->lvalue);
832 memcpy(array, &lvalue, sizeof(lvalue));
835 * Perhaps discard the first octet.
837 data = &array[offset];
842 data = (const uint8_t *) &vp->lvalue;
843 len = 4; /* just in case */
847 * There are no tagged date attributes.
850 lvalue = htonl(vp->lvalue);
851 data = (const uint8_t *) &lvalue;
852 len = 4; /* just in case */
855 default: /* unknown type: ignore it */
856 librad_log("ERROR: Unknown attribute type %d", vp->type);
861 * Bound the data to 255 bytes.
863 if (len + offset + total_length > 255) {
864 len = 255 - offset - total_length;
868 * Encrypt the various password styles
870 * Attributes with encrypted values MUST be less than
873 switch (vp->flags.encrypt) {
874 case FLAG_ENCRYPT_USER_PASSWORD:
875 make_passwd(ptr + offset, &len,
877 secret, packet->vector);
880 case FLAG_ENCRYPT_TUNNEL_PASSWORD:
882 librad_log("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->name);
887 * Check if 255 - offset - total_length is less
888 * than 18. If so, we can't fit the data into
889 * the available space, and we discard the
892 * This is ONLY a problem if we have multiple VSA's
893 * in one Vendor-Specific, though.
895 if ((255 - offset - total_length) < 18) return 0;
897 make_tunnel_passwd(ptr + offset, &len,
898 data, len, 255 - offset - total_length,
899 secret, original->vector);
903 * The code above ensures that this attribute
906 case FLAG_ENCRYPT_ASCEND_SECRET:
907 make_secret(ptr + offset, packet->vector,
909 len = AUTH_VECTOR_LEN;
915 * Just copy the data over
917 memcpy(ptr + offset, data, len);
919 } /* switch over encryption flags */
922 * Account for the tag (if any).
927 * RFC 2865 section 5 says that zero-length attributes
930 if (len == 0) return 0;
933 * Update the various lengths.
936 if (vsa_length_ptr) *vsa_length_ptr += len;
940 return total_length; /* of attribute */
947 int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
950 radius_packet_t *hdr;
952 uint16_t total_length;
959 * For simplicity in the following logic, we allow
960 * the attributes to "overflow" the 4k maximum
961 * RADIUS packet size, by one attribute.
963 * It's uint32_t, for alignment purposes.
965 uint32_t data[(MAX_PACKET_LEN + 256) / 4];
967 if ((packet->code > 0) && (packet->code < MAX_PACKET_CODE)) {
968 what = packet_codes[packet->code];
973 DEBUG("Sending %s of id %d to %s port %d\n",
975 inet_ntop(packet->dst_ipaddr.af,
976 &packet->dst_ipaddr.ipaddr,
977 ip_buffer, sizeof(ip_buffer)),
981 * Double-check some things based on packet code.
983 switch (packet->code) {
984 case PW_AUTHENTICATION_ACK:
985 case PW_AUTHENTICATION_REJECT:
986 case PW_ACCESS_CHALLENGE:
988 librad_log("ERROR: Cannot sign response packet without a request packet.");
994 * These packet vectors start off as all zero.
996 case PW_ACCOUNTING_REQUEST:
997 case PW_DISCONNECT_REQUEST:
999 memset(packet->vector, 0, sizeof(packet->vector));
1007 * Use memory on the stack, until we know how
1008 * large the packet will be.
1010 hdr = (radius_packet_t *) data;
1013 * Build standard header
1015 hdr->code = packet->code;
1016 hdr->id = packet->id;
1018 memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
1020 total_length = AUTH_HDR_LEN;
1021 packet->verified = 0;
1024 * Load up the configuration values for the user
1029 * FIXME: Loop twice over the reply list. The first time,
1030 * calculate the total length of data. The second time,
1031 * allocate the memory, and fill in the VP's.
1033 * Hmm... this may be slower than just doing a small
1038 * Loop over the reply attributes for the packet.
1040 for (reply = packet->vps; reply; reply = reply->next) {
1042 * Ignore non-wire attributes
1044 if ((VENDOR(reply->attribute) == 0) &&
1045 ((reply->attribute & 0xFFFF) > 0xff) &&
1046 !reply->flags.diameter) {
1051 * Check that the packet is no more than 4k in
1052 * size, AFTER over-flowing the 4k boundary.
1053 * Note that the 'data' buffer, above, is one
1054 * attribute longer than necessary, in order to
1055 * permit this overflow.
1057 if (total_length > MAX_PACKET_LEN) {
1058 librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
1063 * Set the Message-Authenticator to the correct
1064 * length and initial value.
1066 if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
1067 reply->length = AUTH_VECTOR_LEN;
1068 memset(reply->vp_strvalue, 0, AUTH_VECTOR_LEN);
1069 packet->verified = total_length; /* HACK! */
1073 * Check for overflow.
1075 if (reply->flags.diameter) {
1076 len = reply->length;
1079 librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
1083 len += 8; /* Code, length */
1084 if (VENDOR(reply->attribute) != 0) len += 4;
1085 if ((len & 0x03) != 0) len += 4 - (len & 0x03);
1087 if (len > 253) len += (len / 253) * 2;
1089 if ((total_length + len) > MAX_PACKET_LEN) {
1090 librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
1096 len = vp2diameter(packet, original, secret, reply, ptr);
1099 * Print out ONLY the attributes which
1100 * we're sending over the wire, and print
1101 * them out BEFORE they're encrypted.
1105 len = rad_vp2attr(packet, original, secret, reply, ptr);
1108 if (len < 0) return -1;
1110 total_length += len;
1111 } /* done looping over all attributes */
1114 * Fill in the rest of the fields, and copy the data over
1115 * from the local stack to the newly allocated memory.
1117 * Yes, all this 'memcpy' is slow, but it means
1118 * that we only allocate the minimum amount of
1119 * memory for a request.
1121 packet->data_len = total_length;
1122 packet->data = (uint8_t *) malloc(packet->data_len);
1123 if (!packet->data) {
1124 librad_log("Out of memory");
1128 memcpy(packet->data, data, packet->data_len);
1129 hdr = (radius_packet_t *) packet->data;
1131 total_length = htons(total_length);
1132 memcpy(hdr->length, &total_length, sizeof(total_length));
1139 * Sign a previously encoded packet.
1141 int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1144 radius_packet_t *hdr = (radius_packet_t *)packet->data;
1147 * It wasn't assigned an Id, this is bad!
1149 if (packet->id < 0) {
1150 librad_log("ERROR: RADIUS packets must be assigned an Id.");
1154 if (!packet->data || (packet->data_len < AUTH_HDR_LEN) ||
1155 (packet->verified < 0)) {
1156 librad_log("ERROR: You must call rad_encode() before rad_sign()");
1161 * If there's a Message-Authenticator, update it
1162 * now, BEFORE updating the authentication vector.
1166 if (packet->verified > 0) {
1167 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
1169 switch (packet->code) {
1170 case PW_ACCOUNTING_REQUEST:
1171 case PW_ACCOUNTING_RESPONSE:
1172 case PW_DISCONNECT_REQUEST:
1173 case PW_DISCONNECT_ACK:
1174 case PW_DISCONNECT_NAK:
1175 case PW_COA_REQUEST:
1178 memset(hdr->vector, 0, AUTH_VECTOR_LEN);
1181 case PW_AUTHENTICATION_ACK:
1182 case PW_AUTHENTICATION_REJECT:
1183 case PW_ACCESS_CHALLENGE:
1185 librad_log("ERROR: Cannot sign response packet without a request packet.");
1188 memcpy(hdr->vector, original->vector,
1192 default: /* others have vector already set to zero */
1198 * Set the authentication vector to zero,
1199 * calculate the signature, and put it
1200 * into the Message-Authenticator
1203 lrad_hmac_md5(packet->data, packet->data_len,
1204 secret, strlen(secret),
1206 memcpy(packet->data + packet->verified + 2,
1207 calc_auth_vector, AUTH_VECTOR_LEN);
1210 * Copy the original request vector back
1211 * to the raw packet.
1213 memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
1217 * Switch over the packet code, deciding how to
1220 switch (packet->code) {
1222 * Request packets are not signed, bur
1223 * have a random authentication vector.
1225 case PW_AUTHENTICATION_REQUEST:
1226 case PW_STATUS_SERVER:
1230 * Reply packets are signed with the
1231 * authentication vector of the request.
1239 MD5Update(&context, packet->data, packet->data_len);
1240 MD5Update(&context, secret, strlen(secret));
1241 MD5Final(digest, &context);
1243 memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
1244 memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
1247 }/* switch over packet codes */
1253 * Reply to the request. Also attach
1254 * reply attribute value pairs and any user message provided.
1256 int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1261 char ip_buffer[128];
1264 * Maybe it's a fake packet. Don't send it.
1266 if (!packet || (packet->sockfd < 0)) {
1270 if ((packet->code > 0) && (packet->code < MAX_PACKET_CODE)) {
1271 what = packet_codes[packet->code];
1277 * First time through, allocate room for the packet
1279 if (!packet->data) {
1281 * Encode the packet.
1283 if (rad_encode(packet, original, secret) < 0) {
1288 * Re-sign it, including updating the
1289 * Message-Authenticator.
1291 if (rad_sign(packet, original, secret) < 0) {
1296 * If packet->data points to data, then we print out
1297 * the VP list again only for debugging.
1299 } else if (librad_debug) {
1300 DEBUG("Re-sending %s of id %d to %s port %d\n", what, packet->id,
1301 inet_ntop(packet->dst_ipaddr.af,
1302 &packet->dst_ipaddr.ipaddr,
1303 ip_buffer, sizeof(ip_buffer)),
1306 for (reply = packet->vps; reply; reply = reply->next) {
1307 /* FIXME: ignore attributes > 0xff */
1313 * And send it on it's way.
1315 return rad_sendto(packet->sockfd, packet->data, packet->data_len, 0,
1316 &packet->src_ipaddr, &packet->dst_ipaddr,
1322 * Validates the requesting client NAS. Calculates the
1323 * signature based on the clients private key.
1325 static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
1327 uint8_t digest[AUTH_VECTOR_LEN];
1331 * Older clients have the authentication vector set to
1332 * all zeros. Return `1' in that case.
1334 memset(digest, 0, sizeof(digest));
1335 if (memcmp(packet->vector, digest, AUTH_VECTOR_LEN) == 0) {
1336 packet->verified = 1;
1341 * Zero out the auth_vector in the received packet.
1342 * Then append the shared secret to the received packet,
1343 * and calculate the MD5 sum. This must be the same
1344 * as the original MD5 sum (packet->vector).
1346 memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
1349 * MD5(packet + secret);
1352 MD5Update(&context, packet->data, packet->data_len);
1353 MD5Update(&context, secret, strlen(secret));
1354 MD5Final(digest, &context);
1357 * Return 0 if OK, 2 if not OK.
1360 memcmp(digest, packet->vector, AUTH_VECTOR_LEN) ? 2 : 0;
1362 return packet->verified;
1366 * Validates the requesting client NAS. Calculates the
1367 * signature based on the clients private key.
1369 static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1372 uint8_t calc_digest[AUTH_VECTOR_LEN];
1378 if (original == NULL) {
1383 * Copy the original vector in place.
1385 memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
1388 * MD5(packet + secret);
1391 MD5Update(&context, packet->data, packet->data_len);
1392 MD5Update(&context, secret, strlen(secret));
1393 MD5Final(calc_digest, &context);
1396 * Copy the packet's vector back to the packet.
1398 memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
1401 * Return 0 if OK, 2 if not OK.
1404 memcmp(packet->vector, calc_digest, AUTH_VECTOR_LEN) ? 2 : 0;
1405 return packet->verified;
1410 * See if the data pointed to by PTR is a valid RADIUS packet.
1412 * packet is not 'const * const' because we may update data_len,
1413 * if there's more data in the UDP packet than in the RADIUS packet.
1415 int rad_packet_ok(RADIUS_PACKET *packet)
1420 radius_packet_t *hdr;
1421 char host_ipaddr[128];
1426 * Check for packets smaller than the packet header.
1428 * RFC 2865, Section 3., subsection 'length' says:
1430 * "The minimum length is 20 ..."
1432 if (packet->data_len < AUTH_HDR_LEN) {
1433 librad_log("WARNING: Malformed RADIUS packet from host %s: too short (received %d < minimum %d)",
1434 inet_ntop(packet->src_ipaddr.af,
1435 &packet->src_ipaddr.ipaddr,
1436 host_ipaddr, sizeof(host_ipaddr)),
1437 packet->data_len, AUTH_HDR_LEN);
1442 * RFC 2865, Section 3., subsection 'length' says:
1444 * " ... and maximum length is 4096."
1446 if (packet->data_len > MAX_PACKET_LEN) {
1447 librad_log("WARNING: Malformed RADIUS packet from host %s: too long (received %d > maximum %d)",
1448 inet_ntop(packet->src_ipaddr.af,
1449 &packet->src_ipaddr.ipaddr,
1450 host_ipaddr, sizeof(host_ipaddr)),
1451 packet->data_len, MAX_PACKET_LEN);
1456 * Check for packets with mismatched size.
1457 * i.e. We've received 128 bytes, and the packet header
1458 * says it's 256 bytes long.
1460 totallen = (packet->data[2] << 8) | packet->data[3];
1461 hdr = (radius_packet_t *)packet->data;
1464 * Code of 0 is not understood.
1465 * Code of 16 or greate is not understood.
1467 if ((hdr->code == 0) ||
1468 (hdr->code >= MAX_PACKET_CODE)) {
1469 librad_log("WARNING: Bad RADIUS packet from host %s: unknown packet code %d",
1470 inet_ntop(packet->src_ipaddr.af,
1471 &packet->src_ipaddr.ipaddr,
1472 host_ipaddr, sizeof(host_ipaddr)),
1478 * Repeat the length checks. This time, instead of
1479 * looking at the data we received, look at the value
1480 * of the 'length' field inside of the packet.
1482 * Check for packets smaller than the packet header.
1484 * RFC 2865, Section 3., subsection 'length' says:
1486 * "The minimum length is 20 ..."
1488 if (totallen < AUTH_HDR_LEN) {
1489 librad_log("WARNING: Malformed RADIUS packet from host %s: too short (length %d < minimum %d)",
1490 inet_ntop(packet->src_ipaddr.af,
1491 &packet->src_ipaddr.ipaddr,
1492 host_ipaddr, sizeof(host_ipaddr)),
1493 totallen, AUTH_HDR_LEN);
1498 * And again, for the value of the 'length' field.
1500 * RFC 2865, Section 3., subsection 'length' says:
1502 * " ... and maximum length is 4096."
1504 if (totallen > MAX_PACKET_LEN) {
1505 librad_log("WARNING: Malformed RADIUS packet from host %s: too long (length %d > maximum %d)",
1506 inet_ntop(packet->src_ipaddr.af,
1507 &packet->src_ipaddr.ipaddr,
1508 host_ipaddr, sizeof(host_ipaddr)),
1509 totallen, MAX_PACKET_LEN);
1514 * RFC 2865, Section 3., subsection 'length' says:
1516 * "If the packet is shorter than the Length field
1517 * indicates, it MUST be silently discarded."
1519 * i.e. No response to the NAS.
1521 if (packet->data_len < totallen) {
1522 librad_log("WARNING: Malformed RADIUS packet from host %s: received %d octets, packet length says %d",
1523 inet_ntop(packet->src_ipaddr.af,
1524 &packet->src_ipaddr.ipaddr,
1525 host_ipaddr, sizeof(host_ipaddr)),
1526 packet->data_len, totallen);
1531 * RFC 2865, Section 3., subsection 'length' says:
1533 * "Octets outside the range of the Length field MUST be
1534 * treated as padding and ignored on reception."
1536 if (packet->data_len > totallen) {
1538 * We're shortening the packet below, but just
1539 * to be paranoid, zero out the extra data.
1541 memset(packet->data + totallen, 0, packet->data_len - totallen);
1542 packet->data_len = totallen;
1546 * Walk through the packet's attributes, ensuring that
1547 * they add up EXACTLY to the size of the packet.
1549 * If they don't, then the attributes either under-fill
1550 * or over-fill the packet. Any parsing of the packet
1551 * is impossible, and will result in unknown side effects.
1553 * This would ONLY happen with buggy RADIUS implementations,
1554 * or with an intentional attack. Either way, we do NOT want
1555 * to be vulnerable to this problem.
1558 count = totallen - AUTH_HDR_LEN;
1564 * Attribute number zero is NOT defined.
1567 librad_log("WARNING: Malformed RADIUS packet from host %s: Invalid attribute 0",
1568 inet_ntop(packet->src_ipaddr.af,
1569 &packet->src_ipaddr.ipaddr,
1570 host_ipaddr, sizeof(host_ipaddr)));
1575 * Attributes are at LEAST as long as the ID & length
1576 * fields. Anything shorter is an invalid attribute.
1579 librad_log("WARNING: Malformed RADIUS packet from host %s: attribute %d too short",
1580 inet_ntop(packet->src_ipaddr.af,
1581 &packet->src_ipaddr.ipaddr,
1582 host_ipaddr, sizeof(host_ipaddr)),
1588 * Sanity check the attributes for length.
1591 default: /* don't do anything by default */
1594 case PW_EAP_MESSAGE:
1595 seen_eap |= PW_EAP_MESSAGE;
1598 case PW_MESSAGE_AUTHENTICATOR:
1599 if (attr[1] != 2 + AUTH_VECTOR_LEN) {
1600 librad_log("WARNING: Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
1601 inet_ntop(packet->src_ipaddr.af,
1602 &packet->src_ipaddr.ipaddr,
1603 host_ipaddr, sizeof(host_ipaddr)),
1607 seen_eap |= PW_MESSAGE_AUTHENTICATOR;
1612 * FIXME: Look up the base 255 attributes in the
1613 * dictionary, and switch over their type. For
1614 * integer/date/ip, the attribute length SHOULD
1617 count -= attr[1]; /* grab the attribute length */
1619 num_attributes++; /* seen one more attribute */
1623 * If the attributes add up to a packet, it's allowed.
1625 * If not, we complain, and throw the packet away.
1628 librad_log("WARNING: Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
1629 inet_ntop(packet->src_ipaddr.af,
1630 &packet->src_ipaddr.ipaddr,
1631 host_ipaddr, sizeof(host_ipaddr)));
1636 * If we're configured to look for a maximum number of
1637 * attributes, and we've seen more than that maximum,
1638 * then throw the packet away, as a possible DoS.
1640 if ((librad_max_attributes > 0) &&
1641 (num_attributes > librad_max_attributes)) {
1642 librad_log("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
1643 inet_ntop(packet->src_ipaddr.af,
1644 &packet->src_ipaddr.ipaddr,
1645 host_ipaddr, sizeof(host_ipaddr)),
1646 num_attributes, librad_max_attributes);
1651 * http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
1653 * A packet with an EAP-Message attribute MUST also have
1654 * a Message-Authenticator attribute.
1656 * A Message-Authenticator all by itself is OK, though.
1659 (seen_eap != PW_MESSAGE_AUTHENTICATOR) &&
1660 (seen_eap != (PW_EAP_MESSAGE | PW_MESSAGE_AUTHENTICATOR))) {
1661 librad_log("WARNING: Insecure packet from host %s: Received EAP-Message with no Message-Authenticator.",
1662 inet_ntop(packet->src_ipaddr.af,
1663 &packet->src_ipaddr.ipaddr,
1664 host_ipaddr, sizeof(host_ipaddr)));
1669 * Fill RADIUS header fields
1671 packet->code = hdr->code;
1672 packet->id = hdr->id;
1673 memcpy(packet->vector, hdr->vector, AUTH_VECTOR_LEN);
1680 * Receive UDP client requests, and fill in
1681 * the basics of a RADIUS_PACKET structure.
1683 RADIUS_PACKET *rad_recv(int fd)
1685 RADIUS_PACKET *packet;
1688 * Allocate the new request data structure
1690 if ((packet = malloc(sizeof(*packet))) == NULL) {
1691 librad_log("out of memory");
1694 memset(packet, 0, sizeof(*packet));
1696 packet->data_len = rad_recvfrom(fd, &packet->data, 0,
1697 &packet->src_ipaddr, &packet->src_port,
1698 &packet->dst_ipaddr, &packet->dst_port);
1701 * Check for socket errors.
1703 if (packet->data_len < 0) {
1704 librad_log("Error receiving packet: %s", strerror(errno));
1705 /* packet->data is NULL */
1711 * See if it's a well-formed RADIUS packet.
1713 if (!rad_packet_ok(packet)) {
1719 * Remember which socket we read the packet from.
1721 packet->sockfd = fd;
1724 * FIXME: Do even more filtering by only permitting
1725 * certain IP's. The problem is that we don't know
1726 * how to do this properly for all possible clients...
1730 * Explicitely set the VP list to empty.
1735 char host_ipaddr[128];
1737 if ((packet->code > 0) && (packet->code < MAX_PACKET_CODE)) {
1738 printf("rad_recv: %s packet from host %s port %d",
1739 packet_codes[packet->code],
1740 inet_ntop(packet->src_ipaddr.af,
1741 &packet->src_ipaddr.ipaddr,
1742 host_ipaddr, sizeof(host_ipaddr)),
1745 printf("rad_recv: Packet from host %s port %d code=%d",
1746 inet_ntop(packet->src_ipaddr.af,
1747 &packet->src_ipaddr.ipaddr,
1748 host_ipaddr, sizeof(host_ipaddr)),
1752 printf(", id=%d, length=%d\n", packet->id, packet->data_len);
1760 * Verify the signature of a packet.
1762 int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1769 if (!packet || !packet->data) return -1;
1772 * Before we allocate memory for the attributes, do more
1775 ptr = packet->data + AUTH_HDR_LEN;
1776 length = packet->data_len - AUTH_HDR_LEN;
1777 while (length > 0) {
1778 uint8_t msg_auth_vector[AUTH_VECTOR_LEN];
1779 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
1784 default: /* don't do anything. */
1788 * Note that more than one Message-Authenticator
1789 * attribute is invalid.
1791 case PW_MESSAGE_AUTHENTICATOR:
1792 memcpy(msg_auth_vector, &ptr[2], sizeof(msg_auth_vector));
1793 memset(&ptr[2], 0, AUTH_VECTOR_LEN);
1795 switch (packet->code) {
1799 case PW_ACCOUNTING_REQUEST:
1800 case PW_ACCOUNTING_RESPONSE:
1801 case PW_DISCONNECT_REQUEST:
1802 case PW_DISCONNECT_ACK:
1803 case PW_DISCONNECT_NAK:
1804 case PW_COA_REQUEST:
1807 memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
1810 case PW_AUTHENTICATION_ACK:
1811 case PW_AUTHENTICATION_REJECT:
1812 case PW_ACCESS_CHALLENGE:
1814 librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
1817 memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
1821 lrad_hmac_md5(packet->data, packet->data_len,
1822 secret, strlen(secret), calc_auth_vector);
1823 if (memcmp(calc_auth_vector, msg_auth_vector,
1824 sizeof(calc_auth_vector)) != 0) {
1826 librad_log("Received packet from %s with invalid Message-Authenticator! (Shared secret is incorrect.)",
1827 inet_ntop(packet->src_ipaddr.af,
1828 &packet->src_ipaddr.ipaddr,
1829 buffer, sizeof(buffer)));
1830 /* Silently drop packet, according to RFC 3579 */
1832 } /* else the message authenticator was good */
1835 * Reinitialize Authenticators.
1837 memcpy(&ptr[2], msg_auth_vector, AUTH_VECTOR_LEN);
1838 memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
1840 } /* switch over the attributes */
1844 } /* loop over the packet, sanity checking the attributes */
1847 * It looks like a RADIUS packet, but we can't validate
1850 if ((packet->code == 0) || packet->code >= MAX_PACKET_CODE) {
1852 librad_log("Received Unknown packet code %d"
1853 "from client %s port %d: Cannot validate signature",
1855 inet_ntop(packet->src_ipaddr.af,
1856 &packet->src_ipaddr.ipaddr,
1857 buffer, sizeof(buffer)),
1863 * Calculate and/or verify digest.
1865 switch(packet->code) {
1869 case PW_AUTHENTICATION_REQUEST:
1870 case PW_STATUS_SERVER:
1871 case PW_DISCONNECT_REQUEST:
1873 * The authentication vector is random
1874 * nonsense, invented by the client.
1878 case PW_ACCOUNTING_REQUEST:
1879 if (calc_acctdigest(packet, secret) > 1) {
1880 librad_log("Received Accounting-Request packet "
1881 "from %s with invalid signature! (Shared secret is incorrect.)",
1882 inet_ntop(packet->src_ipaddr.af,
1883 &packet->src_ipaddr.ipaddr,
1884 buffer, sizeof(buffer)));
1889 /* Verify the reply digest */
1890 case PW_AUTHENTICATION_ACK:
1891 case PW_AUTHENTICATION_REJECT:
1892 case PW_ACCESS_CHALLENGE:
1893 case PW_ACCOUNTING_RESPONSE:
1894 case PW_DISCONNECT_ACK:
1895 case PW_DISCONNECT_NAK:
1898 rcode = calc_replydigest(packet, original, secret);
1900 librad_log("Received %s packet "
1901 "from client %s port %d with invalid signature (err=%d)! (Shared secret is incorrect.)",
1902 packet_codes[packet->code],
1903 inet_ntop(packet->src_ipaddr.af,
1904 &packet->src_ipaddr.ipaddr,
1905 buffer, sizeof(buffer)),
1913 librad_log("Received Unknown packet code %d"
1914 "from client %s port %d: Cannot validate signature",
1916 inet_ntop(packet->src_ipaddr.af,
1917 &packet->src_ipaddr.ipaddr,
1918 buffer, sizeof(buffer)),
1928 * Hack for IETF RADEXT. Don't use in a production environment.
1930 * Note that due to architecture limitations, we can't handle
1931 * AVP's with more than 253 bytes of data, but that should be
1932 * enough for initial inter-operability.
1934 static int diameter2vp(const RADIUS_PACKET *packet,
1935 const RADIUS_PACKET *original, const char *secret,
1936 const uint8_t *data, int total_length,
1939 int lookup, offset, radius_length, attr_length, diameter_length, raw;
1940 uint32_t attr, length, vendor;
1942 VALUE_PAIR *head, **tail, *vp;
1943 uint8_t *header; /* diameter header */
1944 uint8_t diameter[4096];
1946 diameter_length = radius_length = 0;
1952 * Unpack all contiguous Extended-Attributes into a local
1953 * buffer. It's slow, but it's safe.
1955 while (total_length > 0) {
1956 if (data[0] != PW_EXTENDED_ATTRIBUTE) break;
1958 attr_length = data[1];
1959 radius_length += attr_length;
1960 total_length -= attr_length;
1963 memcpy(header, data + 2, attr_length);
1964 header += attr_length;
1965 diameter_length += attr_length;
1967 data += attr_length + 2;
1977 if ((vp = paircreate(PW_EXTENDED_ATTRIBUTE, PW_TYPE_OCTETS)) == NULL) {
1979 return radius_length;
1983 * Don't add it to the tail until we know it's OK.
1987 * Too little data to contain a diameter header.
1989 if (diameter_length < 12) {
1991 vp->type = PW_TYPE_OCTETS;
1992 memcpy(vp->vp_octets, header, diameter_length);
1993 vp->length = diameter_length;
1996 * Ensure there's no encryption or tag stuff,
1997 * we just pass the attribute as-is.
1999 memset(&vp->flags, 0, sizeof(vp->flags));
2002 if (!head) { /* add vp to the list */
2009 return radius_length;
2013 * Sanity check the lengths, next. If the length is too
2014 * short, then the rest of the diameter buffer can't be
2017 length = (header[5] << 16) | (header[6] << 8) | header[7];
2020 * lies about the length (too short)
2021 * or lies about the length (too long)
2023 * with too little diameter data
2024 * or with too little content
2027 (length > diameter_length) ||
2028 (((header[4] & 0x80) != 0) &&
2029 ((diameter_length < 16) || (length < 13)))) {
2031 * The rest of the data is small enough to fit
2032 * into one VP. Copy it over, and return it.
2034 if (diameter_length <= 253) goto done;
2037 * FIXME: make multiple VP's of the rest of the
2038 * data, so that we don't lose anything!
2043 return radius_length;
2046 memcpy(&attr, header, 4);
2048 if (attr > 65535) raw = 1; /* implementation limitations */
2051 * 1..255 are RADIUS, and shouldn't be encapsulated this way.
2052 * 256.. are Diameter.
2054 * We've arbitrarily assigned 32768..65535 from the
2055 * Diameter space to "extended RADIUS" attributes.
2057 if (attr < 32768) raw = 1;
2060 * We don't like any non-vendor flag bits being set.
2062 if ((header[4] & 0x7f) != 0) raw = 1;
2065 if ((header[4] & 0x80) != 0) {
2066 memcpy(&vendor, header + 8 , 4);
2067 vendor = ntohl(vendor);
2068 if (vendor > 32767) raw = 1; /* implementation limitations */
2076 diameter_length -= offset;
2079 * FIXME: This is an implementation limitation. We
2080 * should really allow strings longer than 253 bytes...
2082 * And bailing out completely (i.e. throwing away the rest
2083 * of the data) isn't an intelligent thing to do, either.
2088 return radius_length;
2092 lookup |= (vendor << 16);
2093 lookup |= (1 << 31); /* see dict_addattr */
2095 da = dict_attrbyvalue(lookup);
2100 * Copied from paircreate.
2102 strcpy(vp->name, da->name);
2103 vp->type = da->type;
2104 vp->flags = da->flags;
2105 vp->attribute = da->attr;
2107 vp->type = PW_TYPE_OCTETS;
2111 case PW_TYPE_STRING:
2112 case PW_TYPE_OCTETS:
2113 case PW_TYPE_ABINARY:
2114 memcpy(vp->vp_octets, header, length);
2115 vp->length = length;
2118 case PW_TYPE_INTEGER:
2119 if (length != 4) goto force_octets;
2121 memcpy(&vp->lvalue, header, 4);
2122 vp->lvalue = ntohl(vp->lvalue);
2126 * Try to get named VALUEs
2130 dval = dict_valbyattr(vp->attribute,
2133 strNcpy(vp->vp_strvalue,
2135 sizeof(vp->vp_strvalue));
2141 if (length != 4) goto force_octets;
2143 memcpy(&vp->lvalue, header, 4);
2144 vp->lvalue = ntohl(vp->lvalue);
2149 case PW_TYPE_IPADDR:
2150 if (length != 4) goto force_octets;
2152 memcpy(&vp->lvalue, header, 4);
2157 * IPv6 interface ID is 8 octets long.
2160 if (length != 8) goto force_octets;
2161 memcpy(vp->vp_ifid, header, 8);
2166 * IPv6 addresses are 16 octets long
2168 case PW_TYPE_IPV6ADDR:
2169 if (length != 16) goto force_octets;
2170 memcpy(&vp->vp_ipv6addr, header, 16);
2175 * IPv6 prefixes are 2 to 18 octets long.
2177 * RFC 3162: The first octet is unused.
2178 * The second is the length of the prefix
2179 * the rest are the prefix data.
2181 * The prefix length can have value 0 to 128.
2183 case PW_TYPE_IPV6PREFIX:
2184 if (length < 2 || length > 18) goto force_octets;
2185 if (header[1] > 128) goto force_octets;
2187 memcpy(vp->vp_ipv6prefix, header, length);
2188 vp->length = length;
2192 * FIXME: double-check that
2193 * (vp->vp_octets[1] >> 3) matches vp->length + 2
2195 if (vp->length < 18) {
2196 memset(vp->vp_octets + vp->length, 0,
2203 vp->type = PW_TYPE_OCTETS;
2206 * Ensure there's no encryption or tag stuff,
2207 * we just pass the attribute as-is.
2209 memset(&vp->flags, 0, sizeof(vp->flags));
2221 diameter_length -= length;
2223 if ((length & 0x03) != 0) {
2224 attr_length = 4 - (length & 0x03); /* padding */
2226 if (diameter_length < attr_length) {
2228 return radius_length;
2231 header += attr_length;
2232 diameter_length -= attr_length;
2234 if (diameter_length > 0) goto next_diameter;
2237 return radius_length;
2243 * Parse a RADIUS attribute into a data structure.
2245 VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
2246 const char *secret, int attribute, int length,
2247 const uint8_t *data)
2252 if ((vp = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
2257 * If length is greater than 253, something is SERIOUSLY
2260 if (length > 253) length = 253; /* paranoia (pair-anoia?) */
2262 vp->length = length;
2263 vp->operator = T_OP_EQ;
2269 if (vp->flags.has_tag) {
2270 if (TAG_VALID(data[0]) ||
2271 (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD)) {
2273 * Tunnel passwords REQUIRE a tag, even
2274 * if don't have a valid tag.
2276 vp->flags.tag = data[0];
2278 if ((vp->type == PW_TYPE_STRING) ||
2279 (vp->type == PW_TYPE_OCTETS)) offset = 1;
2284 * Copy the data to be decrypted
2286 memcpy(&vp->vp_octets[0], data + offset, length - offset);
2287 vp->length -= offset;
2290 * Decrypt the attribute.
2292 switch (vp->flags.encrypt) {
2296 case FLAG_ENCRYPT_USER_PASSWORD:
2298 rad_pwdecode((char *)vp->vp_strvalue,
2302 rad_pwdecode((char *)vp->vp_strvalue,
2306 if (vp->attribute == PW_USER_PASSWORD) {
2307 vp->length = strlen(vp->vp_strvalue);
2312 * Tunnel-Password's may go ONLY
2313 * in response packets.
2315 case FLAG_ENCRYPT_TUNNEL_PASSWORD:
2316 if (!original) goto raw;
2318 if (rad_tunnel_pwdecode(vp->vp_octets, &vp->length,
2319 secret, original->vector) < 0) {
2325 * Ascend-Send-Secret
2326 * Ascend-Receive-Secret
2328 case FLAG_ENCRYPT_ASCEND_SECRET:
2332 uint8_t my_digest[AUTH_VECTOR_LEN];
2333 make_secret(my_digest,
2336 memcpy(vp->vp_strvalue, my_digest,
2338 vp->vp_strvalue[AUTH_VECTOR_LEN] = '\0';
2339 vp->length = strlen(vp->vp_strvalue);
2345 } /* switch over encryption flags */
2349 case PW_TYPE_STRING:
2350 case PW_TYPE_OCTETS:
2351 case PW_TYPE_ABINARY:
2352 /* nothing more to do */
2356 if (vp->length != 1) goto raw;
2358 vp->lvalue = vp->vp_octets[0];
2363 if (vp->length != 2) goto raw;
2365 vp->lvalue = (vp->vp_octets[0] << 8) | vp->vp_octets[1];
2368 case PW_TYPE_INTEGER:
2369 if (vp->length != 4) goto raw;
2371 memcpy(&vp->lvalue, vp->vp_octets, 4);
2372 vp->lvalue = ntohl(vp->lvalue);
2374 if (vp->flags.has_tag) vp->lvalue &= 0x00ffffff;
2377 * Try to get named VALUEs
2381 dval = dict_valbyattr(vp->attribute,
2384 strNcpy(vp->vp_strvalue,
2386 sizeof(vp->vp_strvalue));
2392 if (vp->length != 4) goto raw;
2394 memcpy(&vp->lvalue, vp->vp_octets, 4);
2395 vp->lvalue = ntohl(vp->lvalue);
2399 case PW_TYPE_IPADDR:
2400 if (vp->length != 4) goto raw;
2402 memcpy(&vp->lvalue, vp->vp_octets, 4);
2406 * IPv6 interface ID is 8 octets long.
2409 if (vp->length != 8) goto raw;
2410 /* vp->vp_ifid == vp->vp_octets */
2414 * IPv6 addresses are 16 octets long
2416 case PW_TYPE_IPV6ADDR:
2417 if (vp->length != 16) goto raw;
2418 /* vp->vp_ipv6addr == vp->vp_octets */
2422 * IPv6 prefixes are 2 to 18 octets long.
2424 * RFC 3162: The first octet is unused.
2425 * The second is the length of the prefix
2426 * the rest are the prefix data.
2428 * The prefix length can have value 0 to 128.
2430 case PW_TYPE_IPV6PREFIX:
2431 if (vp->length < 2 || vp->length > 18) goto raw;
2432 if (vp->vp_octets[1] > 128) goto raw;
2435 * FIXME: double-check that
2436 * (vp->vp_octets[1] >> 3) matches vp->length + 2
2438 if (vp->length < 18) {
2439 memset(vp->vp_octets + vp->length, 0,
2446 vp->type = PW_TYPE_OCTETS;
2447 vp->length = length;
2448 memcpy(vp->vp_octets, data, length);
2452 * Ensure there's no encryption or tag stuff,
2453 * we just pass the attribute as-is.
2455 memset(&vp->flags, 0, sizeof(vp->flags));
2463 * Calculate/check digest, and decode radius attributes.
2465 * -1 on decoding error
2468 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
2472 uint32_t vendorcode;
2480 radius_packet_t *hdr;
2481 int vsa_tlen, vsa_llen;
2482 DICT_VENDOR *dv = NULL;
2485 * Extract attribute-value pairs
2487 hdr = (radius_packet_t *)packet->data;
2489 packet_length = packet->data_len - AUTH_HDR_LEN;
2492 * There may be VP's already in the packet. Don't
2495 for (tail = &packet->vps; *tail != NULL; tail = &((*tail)->next)) {
2501 vsa_tlen = vsa_llen = 1;
2504 * We have to read at least two bytes.
2506 * rad_recv() above ensures that this is OK.
2508 while (packet_length > 0) {
2513 * Normal attribute, handle it like normal.
2515 if (vendorcode == 0) {
2517 * No room to read attr/length,
2518 * or bad attribute, or attribute is
2519 * too short, or attribute is too long,
2520 * stop processing the packet.
2522 if ((packet_length < 2) ||
2523 (ptr[0] == 0) || (ptr[1] < 2) ||
2524 (ptr[1] > packet_length)) break;
2527 * 192 is "integer" for Ascend. So if we
2528 * get 12 or more bytes, it must be the
2529 * new extended format.
2531 if ((ptr[0] == PW_EXTENDED_ATTRIBUTE) &&
2532 (ptr[1] >= 2 + 12)) {
2534 attrlen = diameter2vp(packet, original, secret,
2535 ptr, packet_length, &pair);
2545 if (attribute != PW_VENDOR_SPECIFIC) goto create_pair;
2548 * No vendor code, or ONLY vendor code.
2550 if (attrlen <= 4) goto create_pair;
2556 * Handle Vendor-Specific
2558 if (vendorlen == 0) {
2564 * attrlen was checked above.
2566 memcpy(&lvalue, ptr, 4);
2567 myvendor = ntohl(lvalue);
2570 * Zero isn't allowed.
2572 if (myvendor == 0) goto create_pair;
2575 * This is an implementation issue.
2576 * We currently pack vendor into the upper
2577 * 16 bits of a 32-bit attribute number,
2578 * so we can't handle vendor numbers larger
2581 if (myvendor > 65535) goto create_pair;
2583 vsa_tlen = vsa_llen = 1;
2584 dv = dict_vendorbyvalue(myvendor);
2586 vsa_tlen = dv->type;
2587 vsa_llen = dv->length;
2591 * Sweep through the list of VSA's,
2592 * seeing if they exactly fill the
2593 * outer Vendor-Specific attribute.
2595 * If not, create a raw Vendor-Specific.
2598 sublen = attrlen - 4;
2601 * See if we can parse it.
2607 * Don't have a type, it's bad.
2609 if (sublen < vsa_tlen) goto create_pair;
2612 * Ensure that the attribute number
2621 myattr = (subptr[0] << 8) | subptr[1];
2625 if ((subptr[0] != 0) ||
2626 (subptr[1] != 0)) goto create_pair;
2628 myattr = (subptr[2] << 8) | subptr[3];
2632 * Our dictionary is broken.
2639 * Not enough room for one more
2642 if (sublen < vsa_tlen + vsa_llen) goto create_pair;
2645 attribute = (myvendor << 16) | myattr;
2646 ptr += 4 + vsa_tlen;
2647 attrlen -= (4 + vsa_tlen);
2648 packet_length -= 4 + vsa_tlen;
2652 if (subptr[vsa_tlen] < (vsa_tlen + vsa_llen))
2655 if (subptr[vsa_tlen] > sublen)
2657 sublen -= subptr[vsa_tlen];
2658 subptr += subptr[vsa_tlen];
2662 if (subptr[vsa_tlen] != 0) goto create_pair;
2663 if (subptr[vsa_tlen + 1] < (vsa_tlen + vsa_llen))
2665 if (subptr[vsa_tlen + 1] > sublen)
2667 sublen -= subptr[vsa_tlen + 1];
2668 subptr += subptr[vsa_tlen + 1];
2672 * Our dictionaries are
2678 } while (sublen > 0);
2680 vendorcode = myvendor;
2681 vendorlen = attrlen - 4;
2688 * attrlen is the length of this attribute.
2689 * total_len is the length of the encompassing
2698 attribute = (ptr[0] << 8) | ptr[1];
2701 default: /* can't hit this. */
2704 attribute |= (vendorcode << 16);
2709 attrlen = ptr[0] - (vsa_tlen + vsa_llen);
2713 attrlen = ptr[1] - (vsa_tlen + vsa_llen);
2716 default: /* can't hit this. */
2720 vendorlen -= vsa_tlen + vsa_llen + attrlen;
2721 if (vendorlen == 0) vendorcode = 0;
2722 packet_length -= (vsa_tlen + vsa_llen);
2725 * Create the attribute, setting the default type
2726 * to 'octets'. If the type in the dictionary
2727 * is different, then the dictionary type will
2728 * over-ride this one.
2731 pair = rad_attr2vp(packet, original, secret,
2732 attribute, attrlen, ptr);
2735 pairfree(&packet->vps);
2736 librad_log("out of memory");
2748 packet_length -= attrlen;
2752 * Merge information from the outside world into our
2755 lrad_rand_seed(packet->data, AUTH_HDR_LEN);
2764 * We assume that the passwd buffer passed is big enough.
2765 * RFC2138 says the password is max 128 chars, so the size
2766 * of the passwd buffer must be at least 129 characters.
2767 * Preferably it's just MAX_STRING_LEN.
2769 * int *pwlen is updated to the new length of the encrypted
2770 * password - a multiple of 16 bytes.
2772 int rad_pwencode(char *passwd, int *pwlen, const char *secret,
2773 const uint8_t *vector)
2775 lrad_MD5_CTX context, old;
2776 uint8_t digest[AUTH_VECTOR_LEN];
2777 int i, n, secretlen;
2781 * RFC maximum is 128 bytes.
2783 * If length is zero, pad it out with zeros.
2785 * If the length isn't aligned to 16 bytes,
2786 * zero out the extra data.
2790 if (len > 128) len = 128;
2793 memset(passwd, 0, AUTH_PASS_LEN);
2794 len = AUTH_PASS_LEN;
2795 } else if ((len % AUTH_PASS_LEN) != 0) {
2796 memset(&passwd[len], 0, AUTH_PASS_LEN - (len % AUTH_PASS_LEN));
2797 len += AUTH_PASS_LEN - (len % AUTH_PASS_LEN);
2802 * Use the secret to setup the decryption digest
2804 secretlen = strlen(secret);
2806 lrad_MD5Init(&context);
2807 lrad_MD5Update(&context, secret, secretlen);
2808 old = context; /* save intermediate work */
2811 * Encrypt it in place. Don't bother checking
2812 * len, as we've ensured above that it's OK.
2814 for (n = 0; n < len; n += AUTH_PASS_LEN) {
2816 lrad_MD5Update(&context, vector, AUTH_PASS_LEN);
2817 lrad_MD5Final(digest, &context);
2820 lrad_MD5Update(&context,
2821 passwd + n - AUTH_PASS_LEN,
2823 lrad_MD5Final(digest, &context);
2826 for (i = 0; i < AUTH_PASS_LEN; i++) {
2827 passwd[i + n] ^= digest[i];
2837 int rad_pwdecode(char *passwd, int pwlen, const char *secret,
2838 const uint8_t *vector)
2840 lrad_MD5_CTX context, old;
2841 uint8_t digest[AUTH_VECTOR_LEN];
2842 int i, n, secretlen;
2845 * The RFC's say that the maximum is 128.
2846 * The buffer we're putting it into above is 254, so
2847 * we don't need to do any length checking.
2849 if (pwlen > 128) pwlen = 128;
2854 if (pwlen == 0) goto done;
2857 * Use the secret to setup the decryption digest
2859 secretlen = strlen(secret);
2861 lrad_MD5Init(&context);
2862 lrad_MD5Update(&context, secret, secretlen);
2863 old = context; /* save intermediate work */
2866 * The inverse of the code above.
2868 for (n = 0; n < pwlen; n += AUTH_PASS_LEN) {
2870 lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
2871 lrad_MD5Final(digest, &context);
2874 lrad_MD5Update(&context, passwd, AUTH_PASS_LEN);
2876 lrad_MD5Final(digest, &context);
2879 lrad_MD5Update(&context, passwd + n, AUTH_PASS_LEN);
2882 for (i = 0; i < AUTH_PASS_LEN; i++) {
2883 passwd[i + n] ^= digest[i];
2888 passwd[pwlen] = '\0';
2889 return strlen(passwd);
2894 * Encode Tunnel-Password attributes when sending them out on the wire.
2896 * int *pwlen is updated to the new length of the encrypted
2897 * password - a multiple of 16 bytes.
2899 * This is per RFC-2868 which adds a two char SALT to the initial intermediate
2902 int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret,
2903 const uint8_t *vector)
2905 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
2906 unsigned char digest[AUTH_VECTOR_LEN];
2908 int i, n, secretlen;
2913 if (len > 127) len = 127;
2916 * Shift the password 3 positions right to place a salt and original
2917 * length, tag will be added automatically on packet send
2919 for (n=len ; n>=0 ; n--) passwd[n+3] = passwd[n];
2923 * save original password length as first password character;
2930 * Generate salt. The RFC's say:
2932 * The high bit of salt[0] must be set, each salt in a
2933 * packet should be unique, and they should be random
2935 * So, we set the high bit, add in a counter, and then
2936 * add in some CSPRNG data. should be OK..
2938 salt[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
2939 (lrad_rand() & 0x07));
2940 salt[1] = lrad_rand();
2943 * Padd password to multiple of AUTH_PASS_LEN bytes.
2945 n = len % AUTH_PASS_LEN;
2947 n = AUTH_PASS_LEN - n;
2948 for (; n > 0; n--, len++)
2951 /* set new password length */
2955 * Use the secret to setup the decryption digest
2957 secretlen = strlen(secret);
2958 memcpy(buffer, secret, secretlen);
2960 for (n2 = 0; n2 < len; n2+=AUTH_PASS_LEN) {
2962 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
2963 memcpy(buffer + secretlen + AUTH_VECTOR_LEN, salt, 2);
2964 librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
2966 memcpy(buffer + secretlen, passwd + n2 - AUTH_PASS_LEN, AUTH_PASS_LEN);
2967 librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
2970 for (i = 0; i < AUTH_PASS_LEN; i++) {
2971 passwd[i + n2] ^= digest[i];
2979 * Decode Tunnel-Password encrypted attributes.
2981 * Defined in RFC-2868, this uses a two char SALT along with the
2982 * initial intermediate value, to differentiate it from the
2985 int rad_tunnel_pwdecode(uint8_t *passwd, int *pwlen, const char *secret,
2986 const uint8_t *vector)
2988 lrad_MD5_CTX context, old;
2989 uint8_t digest[AUTH_VECTOR_LEN];
2991 unsigned i, n, len, reallen;
2996 * We need at least a salt.
2999 librad_log("tunnel password is too short");
3004 * There's a salt, but no password. Or, there's a salt
3005 * and a 'data_len' octet. It's wrong, but at least we
3006 * can figure out what it means: the password is empty.
3008 * Note that this means we ignore the 'data_len' field,
3009 * if the attribute length tells us that there's no
3010 * more data. So the 'data_len' field may be wrong,
3019 len -= 2; /* discount the salt */
3022 * Use the secret to setup the decryption digest
3024 secretlen = strlen(secret);
3026 lrad_MD5Init(&context);
3027 lrad_MD5Update(&context, secret, secretlen);
3028 old = context; /* save intermediate work */
3031 * Set up the initial key:
3033 * b(1) = MD5(secret + vector + salt)
3035 lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
3036 lrad_MD5Update(&context, passwd, 2);
3039 for (n = 0; n < len; n += AUTH_PASS_LEN) {
3043 lrad_MD5Final(digest, &context);
3048 * A quick check: decrypt the first octet
3049 * of the password, which is the
3050 * 'data_len' field. Ensure it's sane.
3052 reallen = passwd[2] ^ digest[0];
3053 if (reallen >= len) {
3054 librad_log("tunnel password is too long for the attribute");
3058 lrad_MD5Update(&context, passwd + 2, AUTH_PASS_LEN);
3062 lrad_MD5Final(digest, &context);
3065 lrad_MD5Update(&context, passwd + n + 2, AUTH_PASS_LEN);
3068 for (i = base; i < AUTH_PASS_LEN; i++) {
3069 passwd[n + i - 1] = passwd[n + i + 2] ^ digest[i];
3074 * See make_tunnel_password, above.
3076 if (reallen > 239) reallen = 239;
3079 passwd[reallen] = 0;
3085 * Encode a CHAP password
3087 * FIXME: might not work with Ascend because
3088 * we use vp->length, and Ascend gear likes
3089 * to send an extra '\0' in the string!
3091 int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id,
3092 VALUE_PAIR *password)
3096 uint8_t string[MAX_STRING_LEN * 2 + 1];
3097 VALUE_PAIR *challenge;
3100 * Sanity check the input parameters
3102 if ((packet == NULL) || (password == NULL)) {
3107 * Note that the password VP can be EITHER
3108 * a User-Password attribute (from a check-item list),
3109 * or a CHAP-Password attribute (the client asking
3110 * the library to encode it).
3118 memcpy(ptr, password->vp_strvalue, password->length);
3119 ptr += password->length;
3120 i += password->length;
3123 * Use Chap-Challenge pair if present,
3124 * Request-Authenticator otherwise.
3126 challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE);
3128 memcpy(ptr, challenge->vp_strvalue, challenge->length);
3129 i += challenge->length;
3131 memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
3132 i += AUTH_VECTOR_LEN;
3136 librad_md5_calc((uint8_t *)output + 1, (uint8_t *)string, i);
3143 * Seed the random number generator.
3145 * May be called any number of times.
3147 void lrad_rand_seed(const void *data, size_t size)
3152 * Ensure that the pool is initialized.
3154 if (!lrad_rand_initialized) {
3157 memset(&lrad_rand_pool, 0, sizeof(lrad_rand_pool));
3159 fd = open("/dev/urandom", O_RDONLY);
3165 while (total < sizeof(lrad_rand_pool.randrsl)) {
3166 this = read(fd, lrad_rand_pool.randrsl,
3167 sizeof(lrad_rand_pool.randrsl) - total);
3168 if ((this < 0) && (errno != EINTR)) break;
3169 if (this > 0) total += this;
3173 lrad_rand_pool.randrsl[0] = fd;
3174 lrad_rand_pool.randrsl[1] = time(NULL);
3175 lrad_rand_pool.randrsl[2] = errno;
3178 lrad_randinit(&lrad_rand_pool, 1);
3179 lrad_rand_pool.randcnt = 0;
3180 lrad_rand_initialized = 1;
3186 * Hash the user data
3189 if (!hash) hash = lrad_rand();
3190 hash = lrad_hash_update(data, size, hash);
3192 lrad_rand_pool.randmem[lrad_rand_pool.randcnt] ^= hash;
3197 * Return a 32-bit random number.
3199 uint32_t lrad_rand(void)
3204 * Ensure that the pool is initialized.
3206 if (!lrad_rand_initialized) {
3207 lrad_rand_seed(NULL, 0);
3210 num = lrad_rand_pool.randrsl[lrad_rand_pool.randcnt++];
3211 if (lrad_rand_pool.randcnt == 256) {
3212 lrad_isaac(&lrad_rand_pool);
3213 lrad_rand_pool.randcnt = 0;
3221 * Allocate a new RADIUS_PACKET
3223 RADIUS_PACKET *rad_alloc(int newvector)
3227 if ((rp = malloc(sizeof(RADIUS_PACKET))) == NULL) {
3228 librad_log("out of memory");
3231 memset(rp, 0, sizeof(*rp));
3237 uint32_t hash, base;
3240 * Don't expose the actual contents of the random
3244 for (i = 0; i < AUTH_VECTOR_LEN; i += sizeof(uint32_t)) {
3245 hash = lrad_rand() ^ base;
3246 memcpy(rp->vector + i, &hash, sizeof(hash));
3249 lrad_rand(); /* stir the pool again */
3255 * Free a RADIUS_PACKET
3257 void rad_free(RADIUS_PACKET **radius_packet_ptr)
3259 RADIUS_PACKET *radius_packet;
3261 if (!radius_packet_ptr) return;
3262 radius_packet = *radius_packet_ptr;
3264 free(radius_packet->data);
3265 pairfree(&radius_packet->vps);
3267 free(radius_packet);
3269 *radius_packet_ptr = NULL;