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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20 * Copyright 2000-2003 The FreeRADIUS server project
23 static const char rcsid[] = "$Id$";
38 #include "libradius.h"
40 #include "udpfromto.h"
43 #ifdef HAVE_NETINET_IN_H
44 #include <netinet/in.h>
47 #include <sys/socket.h>
49 #ifdef HAVE_ARPA_INET_H
50 #include <arpa/inet.h>
62 * The RFC says 4096 octets max, and most packets are less than 256.
64 #define MAX_PACKET_LEN 4096
67 * The maximum number of attributes which we allow in an incoming
68 * request. If there are more attributes than this, the request
71 * This helps to minimize the potential for a DoS, when an
72 * attacker spoofs Access-Request packets, which don't have a
73 * Message-Authenticator attribute. This means that the packet
74 * is unsigned, and the attacker can use resources on the server,
75 * even if the end request is rejected.
77 int librad_max_attributes = 0;
79 typedef struct radius_packet_t {
83 uint8_t vector[AUTH_VECTOR_LEN];
87 static lrad_randctx lrad_rand_pool; /* across multiple calls */
88 static int lrad_pool_initialized = 0;
90 static const char *packet_codes[] = {
96 "Accounting-Response",
101 "Accounting-Message",
112 "Resource-Free-Request",
113 "Resource-Free-Response",
114 "Resource-Query-Request",
115 "Resource-Query-Response",
116 "Alternate-Resource-Reclaim-Request",
117 "NAS-Reboot-Request",
118 "NAS-Reboot-Response",
131 "Disconnect-Request",
141 "IP-Address-Allocate",
146 * Internal prototypes
148 static void make_secret(unsigned char *digest, uint8_t *vector,
149 const char *secret, char *value);
152 * Reply to the request. Also attach
153 * reply attribute value pairs and any user message provided.
155 int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
159 struct sockaddr_in saremote;
160 struct sockaddr_in *sa;
162 uint8_t ip_buffer[16];
165 * Maybe it's a fake packet. Don't send it.
167 if (!packet || (packet->sockfd < 0)) {
171 if ((packet->code > 0) && (packet->code < 52)) {
172 what = packet_codes[packet->code];
178 * First time through, allocate room for the packet
181 radius_packet_t *hdr;
183 uint8_t *ptr, *length_ptr, *vsa_length_ptr;
186 int vendorcode, vendorpec;
187 u_short total_length;
189 int msg_auth_offset = 0;
192 * For simplicity in the following logic, we allow
193 * the attributes to "overflow" the 4k maximum
194 * RADIUS packet size, by one attribute.
196 uint8_t data[MAX_PACKET_LEN + 256];
199 * Use memory on the stack, until we know how
200 * large the packet will be.
202 hdr = (radius_packet_t *) data;
205 * Build standard header
207 hdr->code = packet->code;
208 hdr->id = packet->id;
211 * Double-check some things based on packet code.
213 switch (packet->code) {
214 case PW_AUTHENTICATION_ACK:
215 case PW_AUTHENTICATION_REJECT:
216 case PW_ACCESS_CHALLENGE:
218 librad_log("ERROR: Cannot sign response packet without a request packet.");
224 * These packet vectors start off as all zero.
226 case PW_ACCOUNTING_REQUEST:
227 case PW_DISCONNECT_REQUEST:
228 memset(packet->vector, 0, sizeof(packet->vector));
235 memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
237 DEBUG("Sending %s of id %d to %s:%d\n",
239 ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
242 total_length = AUTH_HDR_LEN;
245 * Load up the configuration values for the user
250 vsa_length_ptr = NULL;
253 * Loop over the reply attributes for the packet.
255 for (reply = packet->vps; reply; reply = reply->next) {
257 * Ignore non-wire attributes
259 if ((VENDOR(reply->attribute) == 0) &&
260 ((reply->attribute & 0xFFFF) > 0xff)) {
265 * Check that the packet is no more than
266 * 4k in size, AFTER over-flowing the 4k
267 * boundary. Note that the 'data'
268 * buffer, above, is one attribute longer
269 * than necessary, in order to permit
272 if (total_length > MAX_PACKET_LEN) {
273 librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
278 * Set the Message-Authenticator to the
279 * correct length and initial value.
281 if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
282 reply->length = AUTH_VECTOR_LEN;
283 memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
284 msg_auth_offset = total_length;
288 * Print out ONLY the attributes which
289 * we're sending over the wire, and print
290 * them out BEFORE they're encrypted.
295 * We have a different vendor. Re-set
298 if (vendorcode != VENDOR(reply->attribute)) {
301 vsa_length_ptr = NULL;
305 * If the Vendor-Specific attribute is getting
306 * full, then create a new VSA attribute
308 * FIXME: Multiple VSA's per Vendor-Specific
309 * SHOULD be configurable. When that's done,
310 * the (1), below, can be changed to point to
311 * a configuration variable which is set TRUE
312 * if the NAS cannot understand multiple VSA's
313 * per Vendor-Specific
315 if ((1) || /* ALWAYS create a new Vendor-Specific */
317 (reply->length + *vsa_length_ptr) >= MAX_STRING_LEN)) {
320 vsa_length_ptr = NULL;
324 * Maybe we have the start of a set of
325 * (possibly many) VSA attributes from
326 * one vendor. Set a global VSA wrapper
328 if ((vendorcode == 0) &&
329 ((vendorcode = VENDOR(reply->attribute)) != 0)) {
330 vendorpec = dict_vendorpec(vendorcode);
333 * This is a potentially bad error...
334 * we can't find the vendor ID!
336 if (vendorpec == 0) {
337 /* FIXME: log an error */
342 * Build a VSA header.
344 *ptr++ = PW_VENDOR_SPECIFIC;
345 vsa_length_ptr = ptr;
347 lvalue = htonl(vendorpec);
348 memcpy(ptr, &lvalue, 4);
353 if (vendorpec == VENDORPEC_USR) {
354 lvalue = htonl(reply->attribute & 0xFFFF);
355 memcpy(ptr, &lvalue, 4);
357 length_ptr = vsa_length_ptr;
364 * Each USR-style attribute gets
365 * it's own VSA wrapper, so we
366 * re-set the vendor specific
371 vsa_length_ptr = NULL;
375 * All other attributes are as
378 *ptr++ = (reply->attribute & 0xFF);
380 if (vsa_length_ptr) *vsa_length_ptr += 2;
385 switch(reply->type) {
388 * Ascend binary attributes are
389 * stored internally in binary form.
392 case PW_TYPE_IPV6ADDR:
393 case PW_TYPE_IPV6PREFIX:
394 case PW_TYPE_ABINARY:
398 * Encrypt the various password styles
400 switch (reply->flags.encrypt) {
404 case FLAG_ENCRYPT_USER_PASSWORD:
405 rad_pwencode((char *)reply->strvalue,
407 (const char *)secret,
408 (const char *)packet->vector);
411 case FLAG_ENCRYPT_TUNNEL_PASSWORD:
413 librad_log("ERROR: No request packet, cannot encrypt Tunnel-Password attribute in the reply.");
416 rad_tunnel_pwencode(reply->strvalue,
423 case FLAG_ENCRYPT_ASCEND_SECRET:
424 make_secret(digest, packet->vector,
425 secret, reply->strvalue);
426 memcpy(reply->strvalue, digest, AUTH_VECTOR_LEN );
427 reply->length = AUTH_VECTOR_LEN;
429 } /* switch over encryption flags */
434 * Set the TAG at the beginning
435 * of the string if tagged. If
436 * tag value is not valid for
437 * tagged attribute, make it 0x00
438 * per RFC 2868. -cparker
440 if (reply->flags.has_tag) {
441 if (TAG_VALID(reply->flags.tag)) {
443 *ptr++ = reply->flags.tag;
445 } else if (reply->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
455 } /* else don't write a tag */
456 } /* else the attribute doesn't have a tag */
459 * Ensure we don't go too far.
460 * The 'length' of the attribute
461 * may be 0..255, minus whatever
462 * octets are used in the attribute
466 if (vsa_length_ptr) {
467 allowed -= *vsa_length_ptr;
469 allowed -= *length_ptr;
477 if (vsa_length_ptr) *vsa_length_ptr += len;
479 * If we have tagged attributes we can't assume that
480 * len == reply->length. Use reply->length for copying
481 * the string data into the packet. Use len for the
482 * true length of the string+tags.
484 memcpy(ptr, reply->strvalue, reply->length);
485 ptr += reply->length;
489 case PW_TYPE_INTEGER:
492 if (vsa_length_ptr) *vsa_length_ptr += 4;
494 if (reply->type == PW_TYPE_INTEGER ) {
495 /* If tagged, the tag becomes the MSB of the value */
496 if(reply->flags.has_tag) {
497 /* Tag must be ( 0x01 -> 0x1F ) OR 0x00 */
498 if(!TAG_VALID(reply->flags.tag)) {
499 reply->flags.tag = 0x00;
501 lvalue = htonl((reply->lvalue & 0xffffff) |
502 ((reply->flags.tag & 0xff) << 24));
504 lvalue = htonl(reply->lvalue);
508 * IP address is already in
509 * network byte order.
511 lvalue = reply->lvalue;
513 memcpy(ptr, &lvalue, 4);
519 * There are no tagged date attributes.
523 if (vsa_length_ptr) *vsa_length_ptr += 4;
525 lvalue = htonl(reply->lvalue);
526 memcpy(ptr, &lvalue, 4);
533 } /* done looping over all attributes */
536 * Fill in the rest of the fields, and copy
537 * the data over from the local stack to
538 * the newly allocated memory.
540 * Yes, all this 'memcpy' is slow, but it means
541 * that we only allocate the minimum amount of
542 * memory for a request.
544 packet->data_len = total_length;
545 packet->data = (uint8_t *) malloc(packet->data_len);
547 librad_log("Out of memory");
550 memcpy(packet->data, data, packet->data_len);
551 hdr = (radius_packet_t *) packet->data;
553 total_length = htons(total_length);
554 memcpy(hdr->length, &total_length, sizeof(u_short));
557 * If this is not an authentication request, we
558 * need to calculate the md5 hash over the entire packet
559 * and put it in the vector.
561 secretlen = strlen(secret);
564 * If there's a Message-Authenticator, update it
565 * now, BEFORE updating the authentication vector.
567 if (msg_auth_offset) {
568 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
570 switch (packet->code) {
574 case PW_AUTHENTICATION_ACK:
575 case PW_AUTHENTICATION_REJECT:
576 case PW_ACCESS_CHALLENGE:
577 /* this was checked above */
578 memcpy(hdr->vector, original->vector,
584 * Set the authentication vector to zero,
585 * calculate the signature, and put it
586 * into the Message-Authenticator
589 memset(packet->data + msg_auth_offset + 2,
591 lrad_hmac_md5(packet->data, packet->data_len,
592 secret, secretlen, calc_auth_vector);
593 memcpy(packet->data + msg_auth_offset + 2,
594 calc_auth_vector, AUTH_VECTOR_LEN);
597 * Copy the original request vector back
600 memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
604 * Switch over the packet code, deciding how to
607 switch (packet->code) {
609 * Request packets are not signed, bur
610 * have a random authentication vector.
612 case PW_AUTHENTICATION_REQUEST:
613 case PW_STATUS_SERVER:
617 * Reply packets are signed with the
618 * authentication vector of the request.
624 MD5Update(&context, packet->data, packet->data_len);
625 MD5Update(&context, secret, strlen(secret));
626 MD5Final(digest, &context);
628 memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
629 memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
632 } /* switch over packet codes */
636 * If packet->data points to data, then we print out
637 * the VP list again only for debugging.
639 } else if (librad_debug) {
640 DEBUG("Re-sending %s of id %d to %s:%d\n", what, packet->id,
641 ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
644 for (reply = packet->vps; reply; reply = reply->next) {
645 /* FIXME: ignore attributes > 0xff */
651 * And send it on it's way.
653 sa = (struct sockaddr_in *) &saremote;
654 memset ((char *) sa, '\0', sizeof (saremote));
655 sa->sin_family = AF_INET;
656 sa->sin_addr.s_addr = packet->dst_ipaddr;
657 sa->sin_port = htons(packet->dst_port);
658 #ifndef WITH_UDPFROMTO
659 return sendto(packet->sockfd, packet->data, (int)packet->data_len, 0,
660 (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
663 struct sockaddr_in salocal;
664 memset ((char *) &salocal, '\0', sizeof (salocal));
665 salocal.sin_family = AF_INET;
666 salocal.sin_addr.s_addr = packet->src_ipaddr;
668 return sendfromto(packet->sockfd, packet->data, (int)packet->data_len, 0,
669 (struct sockaddr *)&salocal, sizeof(struct sockaddr_in),
670 (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
677 * Validates the requesting client NAS. Calculates the
678 * signature based on the clients private key.
680 static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
682 u_char digest[AUTH_VECTOR_LEN];
686 * Older clients have the authentication vector set to
687 * all zeros. Return `1' in that case.
689 memset(digest, 0, sizeof(digest));
690 if (memcmp(packet->vector, digest, AUTH_VECTOR_LEN) == 0) {
691 packet->verified = 1;
696 * Zero out the auth_vector in the received packet.
697 * Then append the shared secret to the received packet,
698 * and calculate the MD5 sum. This must be the same
699 * as the original MD5 sum (packet->vector).
701 memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
704 * MD5(packet + secret);
707 MD5Update(&context, packet->data, packet->data_len);
708 MD5Update(&context, secret, strlen(secret));
709 MD5Final(digest, &context);
712 * Return 0 if OK, 2 if not OK.
715 memcmp(digest, packet->vector, AUTH_VECTOR_LEN) ? 2 : 0;
717 return packet->verified;
721 * Validates the requesting client NAS. Calculates the
722 * signature based on the clients private key.
724 static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
727 uint8_t calc_digest[AUTH_VECTOR_LEN];
733 if (original == NULL) {
738 * Copy the original vector in place.
740 memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
743 * MD5(packet + secret);
746 MD5Update(&context, packet->data, packet->data_len);
747 MD5Update(&context, secret, strlen(secret));
748 MD5Final(calc_digest, &context);
751 * Copy the packet's vector back to the packet.
753 memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
756 * Return 0 if OK, 2 if not OK.
759 memcmp(packet->vector, calc_digest, AUTH_VECTOR_LEN) ? 2 : 0;
760 return packet->verified;
764 * Receive UDP client requests, and fill in
765 * the basics of a RADIUS_PACKET structure.
767 RADIUS_PACKET *rad_recv(int fd)
769 RADIUS_PACKET *packet;
770 struct sockaddr_in saremote;
775 radius_packet_t *hdr;
776 char host_ipaddr[16];
778 uint8_t data[MAX_PACKET_LEN];
782 * Allocate the new request data structure
784 if ((packet = malloc(sizeof(RADIUS_PACKET))) == NULL) {
785 librad_log("out of memory");
788 memset(packet, 0, sizeof(RADIUS_PACKET));
791 * Receive the packet.
793 salen = sizeof(saremote);
794 memset(&saremote, 0, sizeof(saremote));
795 #ifndef WITH_UDPFROMTO
796 packet->data_len = recvfrom(fd, data, sizeof(data),
797 0, (struct sockaddr *)&saremote, &salen);
798 packet->dst_ipaddr = htonl(INADDR_ANY); /* i.e. unknown */
801 socklen_t salen_local;
802 struct sockaddr_in salocal;
803 salen_local = sizeof(salocal);
804 memset(&salocal, 0, sizeof(salocal));
805 packet->data_len = recvfromto(fd, data, sizeof(data), 0,
806 (struct sockaddr *)&saremote, &salen,
807 (struct sockaddr *)&salocal, &salen_local);
808 packet->dst_ipaddr = salocal.sin_addr.s_addr;
813 * Check for socket errors.
815 if (packet->data_len < 0) {
816 librad_log("Error receiving packet: %s", strerror(errno));
822 * Fill IP header fields. We need these for the error
823 * messages which may come later.
826 packet->src_ipaddr = saremote.sin_addr.s_addr;
827 packet->src_port = ntohs(saremote.sin_port);
830 * FIXME: Do even more filtering by only permitting
831 * certain IP's. The problem is that we don't know
832 * how to do this properly for all possible clients...
836 * Explicitely set the VP list to empty.
841 * Check for packets smaller than the packet header.
843 * RFC 2865, Section 3., subsection 'length' says:
845 * "The minimum length is 20 ..."
847 if (packet->data_len < AUTH_HDR_LEN) {
848 librad_log("WARNING: Malformed RADIUS packet from host %s: too short (received %d < minimum %d)",
849 ip_ntoa(host_ipaddr, packet->src_ipaddr),
850 packet->data_len, AUTH_HDR_LEN);
856 * RFC 2865, Section 3., subsection 'length' says:
858 * " ... and maximum length is 4096."
860 if (packet->data_len > MAX_PACKET_LEN) {
861 librad_log("WARNING: Malformed RADIUS packet from host %s: too long (received %d > maximum %d)",
862 ip_ntoa(host_ipaddr, packet->src_ipaddr),
863 packet->data_len, MAX_PACKET_LEN);
869 * Check for packets with mismatched size.
870 * i.e. We've received 128 bytes, and the packet header
871 * says it's 256 bytes long.
873 totallen = (data[2] << 8) | data[3];
874 hdr = (radius_packet_t *)data;
877 * Code of 0 is not understood.
878 * Code of 16 or greate is not understood.
880 if ((hdr->code == 0) ||
882 librad_log("WARNING: Bad RADIUS packet from host %s: unknown packet code %d",
883 ip_ntoa(host_ipaddr, packet->src_ipaddr),
890 * Repeat the length checks. This time, instead of
891 * looking at the data we received, look at the value
892 * of the 'length' field inside of the packet.
894 * Check for packets smaller than the packet header.
896 * RFC 2865, Section 3., subsection 'length' says:
898 * "The minimum length is 20 ..."
900 if (totallen < AUTH_HDR_LEN) {
901 librad_log("WARNING: Malformed RADIUS packet from host %s: too short (length %d < minimum %d)",
902 ip_ntoa(host_ipaddr, packet->src_ipaddr),
903 totallen, AUTH_HDR_LEN);
909 * And again, for the value of the 'length' field.
911 * RFC 2865, Section 3., subsection 'length' says:
913 * " ... and maximum length is 4096."
915 if (totallen > MAX_PACKET_LEN) {
916 librad_log("WARNING: Malformed RADIUS packet from host %s: too long (length %d > maximum %d)",
917 ip_ntoa(host_ipaddr, packet->src_ipaddr),
918 totallen, MAX_PACKET_LEN);
924 * RFC 2865, Section 3., subsection 'length' says:
926 * "If the packet is shorter than the Length field
927 * indicates, it MUST be silently discarded."
929 * i.e. No response to the NAS.
931 if (packet->data_len < totallen) {
932 librad_log("WARNING: Malformed RADIUS packet from host %s: received %d octets, packet length says %d",
933 ip_ntoa(host_ipaddr, packet->src_ipaddr),
934 packet->data_len, totallen);
940 * RFC 2865, Section 3., subsection 'length' says:
942 * "Octets outside the range of the Length field MUST be
943 * treated as padding and ignored on reception."
945 if (packet->data_len > totallen) {
947 * We're shortening the packet below, but just
948 * to be paranoid, zero out the extra data.
950 memset(data + totallen, 0, packet->data_len - totallen);
951 packet->data_len = totallen;
955 * Walk through the packet's attributes, ensuring that
956 * they add up EXACTLY to the size of the packet.
958 * If they don't, then the attributes either under-fill
959 * or over-fill the packet. Any parsing of the packet
960 * is impossible, and will result in unknown side effects.
962 * This would ONLY happen with buggy RADIUS implementations,
963 * or with an intentional attack. Either way, we do NOT want
964 * to be vulnerable to this problem.
967 count = totallen - AUTH_HDR_LEN;
973 * Attribute number zero is NOT defined.
976 librad_log("WARNING: Malformed RADIUS packet from host %s: Invalid attribute 0",
977 ip_ntoa(host_ipaddr, packet->src_ipaddr));
983 * Attributes are at LEAST as long as the ID & length
984 * fields. Anything shorter is an invalid attribute.
987 librad_log("WARNING: Malformed RADIUS packet from host %s: attribute %d too short",
988 ip_ntoa(host_ipaddr, packet->src_ipaddr),
995 * Sanity check the attributes for length.
998 default: /* don't do anything by default */
1001 case PW_EAP_MESSAGE:
1002 seen_eap |= PW_EAP_MESSAGE;
1005 case PW_MESSAGE_AUTHENTICATOR:
1006 if (attr[1] != 2 + AUTH_VECTOR_LEN) {
1007 librad_log("WARNING: Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
1008 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1013 seen_eap |= PW_MESSAGE_AUTHENTICATOR;
1016 case PW_VENDOR_SPECIFIC:
1018 librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has invalid length %d",
1019 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1026 * Don't allow VSA's with vendor zero.
1028 if ((attr[2] == 0) && (attr[3] == 0) &&
1029 (attr[4] == 0) && (attr[5] == 0)) {
1030 librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has vendor ID of zero",
1031 ip_ntoa(host_ipaddr, packet->src_ipaddr));
1037 * Don't look at the contents of VSA's,
1038 * too many vendors have non-standard
1045 * FIXME: Look up the base 255 attributes in the
1046 * dictionary, and switch over their type. For
1047 * integer/date/ip, the attribute length SHOULD
1050 count -= attr[1]; /* grab the attribute length */
1052 num_attributes++; /* seen one more attribute */
1056 * If the attributes add up to a packet, it's allowed.
1058 * If not, we complain, and throw the packet away.
1061 librad_log("WARNING: Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
1062 ip_ntoa(host_ipaddr, packet->src_ipaddr));
1068 * If we're configured to look for a maximum number of
1069 * attributes, and we've seen more than that maximum,
1070 * then throw the packet away, as a possible DoS.
1072 if ((librad_max_attributes > 0) &&
1073 (num_attributes > librad_max_attributes)) {
1074 librad_log("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
1075 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1076 num_attributes, librad_max_attributes);
1082 * http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
1084 * A packet with an EAP-Message attribute MUST also have
1085 * a Message-Authenticator attribute.
1087 * A Message-Authenticator all by itself is OK, though.
1090 (seen_eap != PW_MESSAGE_AUTHENTICATOR) &&
1091 (seen_eap != (PW_EAP_MESSAGE | PW_MESSAGE_AUTHENTICATOR))) {
1092 librad_log("WARNING: Insecure packet from host %s: Received EAP-Message with no Message-Authenticator.",
1093 ip_ntoa(host_ipaddr, packet->src_ipaddr));
1099 if ((hdr->code > 0) && (hdr->code < 52)) {
1100 printf("rad_recv: %s packet from host %s:%d",
1101 packet_codes[hdr->code],
1102 ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port);
1104 printf("rad_recv: Packet from host %s:%d code=%d",
1105 ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port,
1108 printf(", id=%d, length=%d\n", hdr->id, totallen);
1112 * Fill RADIUS header fields
1114 packet->code = hdr->code;
1115 packet->id = hdr->id;
1116 memcpy(packet->vector, hdr->vector, AUTH_VECTOR_LEN);
1119 * Now that we've sanity checked the packet, we can allocate
1120 * memory for it, and copy the data from the local area to
1121 * the packet buffer.
1123 if ((packet->data = malloc(packet->data_len)) == NULL) {
1125 librad_log("out of memory");
1128 memcpy(packet->data, data, packet->data_len);
1134 * Calculate/check digest, and decode radius attributes.
1136 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1140 uint32_t vendorcode;
1148 radius_packet_t *hdr;
1150 hdr = (radius_packet_t *)packet->data;
1153 * Before we allocate memory for the attributes, do more
1157 length = packet->data_len - AUTH_HDR_LEN;
1158 while (length > 0) {
1159 uint8_t msg_auth_vector[AUTH_VECTOR_LEN];
1160 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
1165 default: /* don't do anything. */
1169 * Note that more than one Message-Authenticator
1170 * attribute is invalid.
1172 case PW_MESSAGE_AUTHENTICATOR:
1173 memcpy(msg_auth_vector, &ptr[2], sizeof(msg_auth_vector));
1174 memset(&ptr[2], 0, AUTH_VECTOR_LEN);
1176 switch (packet->code) {
1180 case PW_AUTHENTICATION_ACK:
1181 case PW_AUTHENTICATION_REJECT:
1182 case PW_ACCESS_CHALLENGE:
1184 librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
1187 memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
1191 lrad_hmac_md5(packet->data, packet->data_len,
1192 secret, strlen(secret), calc_auth_vector);
1193 if (memcmp(calc_auth_vector, msg_auth_vector,
1194 sizeof(calc_auth_vector)) != 0) {
1196 librad_log("Received packet from %s with invalid Message-Authenticator! (Shared secret is incorrect.)",
1197 ip_ntoa(buffer, packet->src_ipaddr));
1199 } /* else the message authenticator was good */
1202 * Reinitialize Authenticators.
1204 memcpy(&ptr[2], msg_auth_vector, AUTH_VECTOR_LEN);
1205 memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
1207 } /* switch over the attributes */
1211 } /* loop over the packet, sanity checking the attributes */
1214 * Calculate and/or verify digest.
1216 switch(packet->code) {
1219 case PW_AUTHENTICATION_REQUEST:
1220 case PW_STATUS_SERVER:
1221 case PW_DISCONNECT_REQUEST:
1223 * The authentication vector is random
1224 * nonsense, invented by the client.
1228 case PW_ACCOUNTING_REQUEST:
1229 if (calc_acctdigest(packet, secret) > 1) {
1231 librad_log("Received Accounting-Request packet "
1232 "from %s with invalid signature! (Shared secret is incorrect.)",
1233 ip_ntoa(buffer, packet->src_ipaddr));
1238 /* Verify the reply digest */
1239 case PW_AUTHENTICATION_ACK:
1240 case PW_AUTHENTICATION_REJECT:
1241 case PW_ACCOUNTING_RESPONSE:
1242 rcode = calc_replydigest(packet, original, secret);
1245 librad_log("Received %s packet "
1246 "from %s:%d with invalid signature (err=%d)! (Shared secret is incorrect.)",
1247 packet_codes[packet->code],
1248 ip_ntoa(buffer, packet->src_ipaddr),
1257 * Extract attribute-value pairs
1260 length = packet->data_len - AUTH_HDR_LEN;
1263 * There may be VP's already in the packet. Don't
1266 for (tail = &packet->vps; *tail != NULL; tail = &((*tail)->next)) {
1273 while (length > 0) {
1274 if (vendorlen > 0) {
1275 attribute = *ptr++ | (vendorcode << 16);
1286 * This could be a Vendor-Specific attribute.
1288 if ((vendorlen <= 0) &&
1289 (attribute == PW_VENDOR_SPECIFIC)) {
1294 * attrlen was checked to be >= 6, in rad_recv
1296 memcpy(&lvalue, ptr, 4);
1297 vendorcode = ntohl(lvalue);
1300 * This is an implementation issue.
1301 * We currently pack vendor into the upper
1302 * 16 bits of a 32-bit attribute number,
1303 * so we can't handle vendor numbers larger
1306 if (vendorcode > 65535) goto create_pair;
1309 * vendorcode was checked to be non-zero
1310 * above, in rad_recv.
1314 * First, check to see if the
1315 * sub-attributes fill the VSA, as
1316 * defined by the RFC. If not, then it
1317 * may be a USR-style VSA, or it may be a
1318 * vendor who packs all of the
1319 * information into one nonsense
1323 sublen = attrlen - 4;
1325 while (sublen > 0) {
1326 if (subptr[1] < 2) { /* too short */
1330 if (subptr[1] > sublen) { /* too long */
1334 sublen -= subptr[1]; /* just right */
1335 subptr += subptr[1];
1339 * If the attribute is RFC compatible,
1340 * then allow it as an RFC style VSA.
1344 vendorlen = attrlen - 4;
1345 attribute = *ptr++ | (vendorcode << 16);
1351 * USR-style attributes are 4 octets,
1352 * with the upper 2 octets being zero.
1354 * The upper octets may not be zero,
1355 * but that then means we won't be
1356 * able to pack the vendor & attribute
1357 * into a 32-bit number, so we can't
1361 * FIXME: Update the dictionaries so
1362 * that we key off of per-attribute
1363 * flags "4-octet", instead of hard
1364 * coding USR here. This will also
1365 * let us send packets with other
1366 * vendors having 4-octet attributes.
1368 } else if ((vendorcode == VENDORPEC_USR) &&
1369 ((ptr[4] == 0) && (ptr[5] == 0)) &&
1373 da = dict_attrbyvalue((vendorcode << 16) |
1378 * See if it's in the dictionary.
1379 * If so, it's a valid USR style
1380 * attribute. If not, it's not...
1382 * Don't touch 'attribute' until
1383 * we know what to do!
1386 attribute = ((vendorcode << 16) |
1392 } /* else it's not in the dictionary */
1393 } /* else it was a stupid vendor format */
1394 } /* else it wasn't a VSA */
1397 * Create the attribute, setting the default type
1398 * to 'octects'. If the type in the dictionary
1399 * is different, then the dictionary type will
1400 * over-ride this one.
1403 if ((pair = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
1404 pairfree(&packet->vps);
1405 librad_log("out of memory");
1409 pair->length = attrlen;
1410 pair->operator = T_OP_EQ;
1413 switch (pair->type) {
1416 * The attribute may be zero length,
1417 * or it may have a tag, and then no data...
1419 case PW_TYPE_STRING:
1420 if (pair->flags.has_tag) {
1424 * If there's sufficient room for
1425 * a tag, and the tag looks valid,
1428 if ((pair->length > 0) &&
1429 TAG_VALID_ZERO(*ptr)) {
1430 pair->flags.tag = *ptr;
1435 * If the leading tag
1436 * isn't valid, then it's
1437 * ignored for the tunnel
1438 * password attribute.
1440 } else if (pair->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
1442 * from RFC2868 - 3.5. Tunnel-Password
1443 * If the value of the Tag field is greater than
1444 * 0x00 and less than or equal to 0x1F, it SHOULD
1445 * be interpreted as indicating which tunnel
1446 * (of several alternatives) this attribute pertains;
1447 * otherwise, the Tag field SHOULD be ignored.
1449 pair->flags.tag = 0x00;
1450 if (pair->length > 0) pair->length--;
1453 pair->flags.tag = 0x00;
1457 * pair->length MAY be zero here.
1459 memcpy(pair->strvalue, ptr + offset,
1463 * Ascend binary attributes never have a
1464 * tag, and neither do the 'octets' type.
1466 case PW_TYPE_ABINARY:
1467 case PW_TYPE_OCTETS:
1468 /* attrlen always < MAX_STRING_LEN */
1469 memcpy(pair->strvalue, ptr, attrlen);
1470 pair->flags.tag = 0;
1474 * Decrypt passwords here.
1476 switch (pair->flags.encrypt) {
1483 case FLAG_ENCRYPT_USER_PASSWORD:
1485 rad_pwdecode((char *)pair->strvalue,
1486 pair->length, secret,
1487 (char *)original->vector);
1489 rad_pwdecode((char *)pair->strvalue,
1490 pair->length, secret,
1491 (char *)packet->vector);
1493 if (pair->attribute == PW_USER_PASSWORD) {
1494 pair->length = strlen(pair->strvalue);
1499 * Tunnel-Password's may go ONLY
1500 * in response packets.
1502 case FLAG_ENCRYPT_TUNNEL_PASSWORD:
1504 librad_log("ERROR: Tunnel-Password attribute in request: Cannot decrypt it.");
1508 if (rad_tunnel_pwdecode(pair->strvalue,
1511 (char *)original->vector) < 0) {
1518 * Ascend-Send-Secret
1519 * Ascend-Receive-Secret
1521 case FLAG_ENCRYPT_ASCEND_SECRET:
1523 librad_log("ERROR: Ascend-Send-Secret attribute in request: Cannot decrypt it.");
1527 uint8_t my_digest[AUTH_VECTOR_LEN];
1528 make_secret(my_digest,
1531 memcpy(pair->strvalue, my_digest,
1533 pair->strvalue[AUTH_VECTOR_LEN] = '\0';
1534 pair->length = strlen(pair->strvalue);
1537 } /* switch over encryption flags */
1538 break; /* from octets/string/abinary */
1540 case PW_TYPE_INTEGER:
1542 case PW_TYPE_IPADDR:
1544 * Check for RFC compliance. If the
1545 * attribute isn't compliant, turn it
1546 * into a string of raw octets.
1548 * Also set the lvalue to something
1549 * which should never match anything.
1552 pair->type = PW_TYPE_OCTETS;
1553 memcpy(pair->strvalue, ptr, attrlen);
1554 pair->lvalue = 0xbad1bad1;
1558 memcpy(&lvalue, ptr, 4);
1560 if (pair->type != PW_TYPE_IPADDR) {
1561 pair->lvalue = ntohl(lvalue);
1564 * It's an IP address, keep it in network
1565 * byte order, and put the ASCII IP
1566 * address or host name into the string
1569 pair->lvalue = lvalue;
1570 ip_ntoa(pair->strvalue, pair->lvalue);
1574 * Tagged attributes of type integer have
1575 * special treatment.
1577 if (pair->flags.has_tag &&
1578 pair->type == PW_TYPE_INTEGER) {
1579 pair->flags.tag = (pair->lvalue >> 24) & 0xff;
1580 pair->lvalue &= 0x00ffffff;
1584 * Try to get the name for integer
1587 if (pair->type == PW_TYPE_INTEGER) {
1589 dval = dict_valbyattr(pair->attribute,
1592 strNcpy(pair->strvalue,
1594 sizeof(pair->strvalue));
1600 * IPv6 interface ID is 8 octets long.
1604 pair->type = PW_TYPE_OCTETS;
1605 memcpy(pair->strvalue, ptr, attrlen);
1609 * IPv6 addresses are 16 octets long
1611 case PW_TYPE_IPV6ADDR:
1613 pair->type = PW_TYPE_OCTETS;
1614 memcpy(pair->strvalue, ptr, attrlen);
1618 * IPv6 prefixes are 2 to 18 octets long.
1620 * RFC 3162: The first octet is unused.
1621 * The second is the length of the prefix
1622 * the rest are the prefix data.
1624 * The prefix length can have value 0 to 128.
1626 case PW_TYPE_IPV6PREFIX:
1627 if (attrlen < 2 || attrlen > 18)
1628 pair->type = PW_TYPE_OCTETS;
1631 pair->type = PW_TYPE_OCTETS;
1634 * FIXME: double-check that
1635 * (ptr[1] >> 3) matches attrlen + 2
1638 memcpy(pair->strvalue, ptr, attrlen);
1642 DEBUG(" %s (Unknown Type %d)\n",
1643 pair->name, pair->type);
1657 if (vendorlen > 0) vendorlen -= (attrlen + 2);
1661 * Merge information from the outside world into our
1664 for (length = 0; length < AUTH_VECTOR_LEN; length++) {
1665 lrad_rand_pool.randmem[length] += packet->vector[length];
1667 lrad_rand_pool.randmem[lrad_rand_pool.randmem[0] & 0xff] += packet->id;
1668 lrad_rand_pool.randmem[lrad_rand_pool.randmem[1] & 0xff] += packet->data_len;
1677 * We assume that the passwd buffer passed is big enough.
1678 * RFC2138 says the password is max 128 chars, so the size
1679 * of the passwd buffer must be at least 129 characters.
1680 * Preferably it's just MAX_STRING_LEN.
1682 * int *pwlen is updated to the new length of the encrypted
1683 * password - a multiple of 16 bytes.
1685 #define AUTH_PASS_LEN (16)
1686 int rad_pwencode(char *passwd, int *pwlen, const char *secret,
1689 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
1690 char digest[AUTH_VECTOR_LEN];
1691 int i, n, secretlen;
1695 * Pad password to multiple of AUTH_PASS_LEN bytes.
1698 if (len > 128) len = 128;
1700 if (len % AUTH_PASS_LEN != 0) {
1701 n = AUTH_PASS_LEN - (len % AUTH_PASS_LEN);
1702 for (i = len; n > 0; n--, i++)
1706 } else if (len == 0) {
1707 memset(passwd, 0, AUTH_PASS_LEN);
1708 *pwlen = len = AUTH_PASS_LEN;
1712 * Use the secret to setup the decryption digest
1714 secretlen = strlen(secret);
1715 memcpy(buffer, secret, secretlen);
1716 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1717 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
1720 * Now we can encode the password *in place*
1722 for (i = 0; i < AUTH_PASS_LEN; i++)
1723 passwd[i] ^= digest[i];
1725 if (len <= AUTH_PASS_LEN) return 0;
1728 * Length > AUTH_PASS_LEN, so we need to use the extended
1731 for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) {
1732 memcpy(buffer + secretlen, passwd + n, AUTH_PASS_LEN);
1733 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
1734 for (i = 0; i < AUTH_PASS_LEN; i++)
1735 passwd[i + n + AUTH_PASS_LEN] ^= digest[i];
1744 int rad_pwdecode(char *passwd, int pwlen, const char *secret,
1747 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
1748 char digest[AUTH_VECTOR_LEN];
1749 char r[AUTH_VECTOR_LEN];
1751 int i, n, secretlen;
1755 * Use the secret to setup the decryption digest
1757 secretlen = strlen(secret);
1758 memcpy(buffer, secret, secretlen);
1759 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1760 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
1763 * Now we can decode the password *in place*
1765 memcpy(r, passwd, AUTH_PASS_LEN);
1766 for (i = 0; i < AUTH_PASS_LEN && i < pwlen; i++)
1767 passwd[i] ^= digest[i];
1769 if (pwlen <= AUTH_PASS_LEN) {
1770 passwd[pwlen+1] = 0;
1775 * Length > AUTH_PASS_LEN, so we need to use the extended
1778 rlen = ((pwlen - 1) / AUTH_PASS_LEN) * AUTH_PASS_LEN;
1780 for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) {
1781 s = (n == AUTH_PASS_LEN) ? r : (passwd + n - AUTH_PASS_LEN);
1782 memcpy(buffer + secretlen, s, AUTH_PASS_LEN);
1783 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
1784 for (i = 0; i < AUTH_PASS_LEN && (i + n) < pwlen; i++)
1785 passwd[i + n] ^= digest[i];
1792 static unsigned int salt_offset = 0;
1795 * Encode Tunnel-Password attributes when sending them out on the wire.
1797 * int *pwlen is updated to the new length of the encrypted
1798 * password - a multiple of 16 bytes.
1800 * This is per RFC-2868 which adds a two char SALT to the initial intermediate
1803 int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret,
1806 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
1807 unsigned char digest[AUTH_VECTOR_LEN];
1809 int i, n, secretlen;
1814 if (len > 127) len = 127;
1816 * Shift the password 3 positions right to place a salt and original
1817 * length, tag will be added automatically on packet send
1819 for (n=len ; n>=0 ; n--) passwd[n+3] = passwd[n];
1823 * save original password length as first password character;
1830 * Generate salt. The RFC's say:
1832 * The high bit of salt[0] must be set, each salt in a
1833 * packet should be unique, and they should be random
1835 * So, we set the high bit, add in a counter, and then
1836 * add in some CSPRNG data. should be OK..
1838 salt[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
1839 (lrad_rand() & 0x07));
1840 salt[1] = lrad_rand();
1843 * Padd password to multiple of AUTH_PASS_LEN bytes.
1845 n = len % AUTH_PASS_LEN;
1847 n = AUTH_PASS_LEN - n;
1848 for (; n > 0; n--, len++)
1851 /* set new password length */
1855 * Use the secret to setup the decryption digest
1857 secretlen = strlen(secret);
1858 memcpy(buffer, secret, secretlen);
1860 for (n2 = 0; n2 < len; n2+=AUTH_PASS_LEN) {
1862 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1863 memcpy(buffer + secretlen + AUTH_VECTOR_LEN, salt, 2);
1864 librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
1866 memcpy(buffer + secretlen, passwd + n2 - AUTH_PASS_LEN, AUTH_PASS_LEN);
1867 librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
1870 for (i = 0; i < AUTH_PASS_LEN; i++) {
1871 passwd[i + n2] ^= digest[i];
1879 * Decode Tunnel-Password encrypted attributes.
1881 * Defined in RFC-2868, this uses a two char SALT along with the
1882 * initial intermediate value, to differentiate it from the
1885 int rad_tunnel_pwdecode(uint8_t *passwd, int *pwlen, const char *secret,
1888 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
1889 uint8_t digest[AUTH_VECTOR_LEN];
1890 uint8_t decrypted[MAX_STRING_LEN + 1];
1897 * We need at least a salt.
1900 librad_log("tunnel password is too short");
1905 * There's a salt, but no password. Or, there's a salt
1906 * and a 'data_len' octet. It's wrong, but at least we
1907 * can figure out what it means: the password is empty.
1909 * Note that this means we ignore the 'data_len' field,
1910 * if the attribute length tells us that there's no
1911 * more data. So the 'data_len' field may be wrong,
1920 len -= 2; /* discount the salt */
1923 * Use the secret to setup the decryption digest
1925 secretlen = strlen(secret);
1928 * Set up the initial key:
1930 * b(1) = MD5(secret + vector + salt)
1932 memcpy(buffer, secret, secretlen);
1933 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1934 memcpy(buffer + secretlen + AUTH_VECTOR_LEN, passwd, 2);
1935 librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
1938 * A quick check: decrypt the first octet of the password,
1939 * which is the 'data_len' field. Ensure it's sane.
1941 * 'n' doesn't include the 'data_len' octet
1944 n = passwd[2] ^ digest[0];
1946 librad_log("tunnel password is too long for the attribute");
1951 * Loop over the data, decrypting it, and generating
1952 * the key for the next round of decryption.
1954 for (n = 0; n < len; n += AUTH_PASS_LEN) {
1955 for (i = 0; i < AUTH_PASS_LEN; i++) {
1956 decrypted[n + i] = passwd[n + i + 2] ^ digest[i];
1959 * Encrypted password may not be aligned
1960 * on 16 octets, so we catch that here...
1962 if ((n + i) == len) break;
1966 * Update the digest, based on
1968 * b(n) = MD5(secret + cleartext(n-1)
1970 * but only if there's more data...
1972 memcpy(buffer + secretlen, passwd + n + 2, AUTH_PASS_LEN);
1973 librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
1977 * We've already validated the length of the decrypted
1978 * password. Copy it back to the caller.
1980 memcpy(passwd, decrypted + 1, decrypted[0]);
1981 passwd[decrypted[0]] = 0;
1982 *pwlen = decrypted[0];
1984 return decrypted[0];
1988 * Encode a CHAP password
1990 * FIXME: might not work with Ascend because
1991 * we use vp->length, and Ascend gear likes
1992 * to send an extra '\0' in the string!
1994 int rad_chap_encode(RADIUS_PACKET *packet, char *output, int id,
1995 VALUE_PAIR *password)
1999 char string[MAX_STRING_LEN * 2 + 1];
2000 VALUE_PAIR *challenge;
2003 * Sanity check the input parameters
2005 if ((packet == NULL) || (password == NULL)) {
2010 * Note that the password VP can be EITHER
2011 * a User-Password attribute (from a check-item list),
2012 * or a CHAP-Password attribute (the client asking
2013 * the library to encode it).
2021 memcpy(ptr, password->strvalue, password->length);
2022 ptr += password->length;
2023 i += password->length;
2026 * Use Chap-Challenge pair if present,
2027 * Request-Authenticator otherwise.
2029 challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE);
2031 memcpy(ptr, challenge->strvalue, challenge->length);
2032 i += challenge->length;
2034 memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
2035 i += AUTH_VECTOR_LEN;
2039 librad_md5_calc((u_char *)output + 1, (u_char *)string, i);
2045 * Create a random vector of AUTH_VECTOR_LEN bytes.
2047 static void random_vector(uint8_t *vector)
2051 if (!lrad_pool_initialized) {
2052 memset(&lrad_rand_pool, 0, sizeof(lrad_rand_pool));
2055 * Initialize the state to something, using
2056 * numbers which aren't random, but which also
2059 lrad_rand_pool.randrsl[0] = (uint32_t) &lrad_pool_initialized;
2060 lrad_rand_pool.randrsl[1] = (uint32_t) &i;
2061 lrad_rand_pool.randrsl[2] = (uint32_t) vector;
2063 lrad_randinit(&lrad_rand_pool, 1);
2064 lrad_pool_initialized = 1;
2067 lrad_isaac(&lrad_rand_pool);
2070 * Copy the random data over.
2072 for (i = 0; i < AUTH_VECTOR_LEN; i++) {
2073 *(vector++) = lrad_rand_pool.randrsl[i] & 0xff;
2078 * Return a 32-bit random number.
2080 uint32_t lrad_rand(void)
2083 static int rand_index = 0;
2086 * Ensure that the pool is initialized.
2088 if (!lrad_pool_initialized) {
2089 uint8_t vector[AUTH_VECTOR_LEN];
2091 random_vector(vector);
2095 * Grab an entry from the pool.
2097 answer = lrad_rand_pool.randrsl[rand_index];
2100 * Go to the next entry (wrapping around to zero).
2106 * Every 256 numbers, churn the pool again.
2108 if (rand_index == 0) {
2109 lrad_isaac(&lrad_rand_pool);
2116 * Allocate a new RADIUS_PACKET
2118 RADIUS_PACKET *rad_alloc(int newvector)
2122 if ((rp = malloc(sizeof(RADIUS_PACKET))) == NULL) {
2123 librad_log("out of memory");
2126 memset(rp, 0, sizeof(RADIUS_PACKET));
2128 random_vector(rp->vector);
2135 * Free a RADIUS_PACKET
2137 void rad_free(RADIUS_PACKET **radius_packet_ptr)
2139 RADIUS_PACKET *radius_packet;
2141 if (!radius_packet_ptr) return;
2142 radius_packet = *radius_packet_ptr;
2144 if (radius_packet->data) free(radius_packet->data);
2145 if (radius_packet->vps) pairfree(&radius_packet->vps);
2147 free(radius_packet);
2149 *radius_packet_ptr = NULL;
2152 /*************************************************************************
2154 * Function: make_secret
2156 * Purpose: Build an encrypted secret value to return in a reply
2157 * packet. The secret is hidden by xoring with a MD5 digest
2158 * created from the shared secret and the authentication
2159 * vector. We put them into MD5 in the reverse order from
2160 * that used when encrypting passwords to RADIUS.
2162 *************************************************************************/
2163 static void make_secret(unsigned char *digest, uint8_t *vector,
2164 const char *secret, char *value)
2166 u_char buffer[256 + AUTH_VECTOR_LEN];
2167 int secretLen = strlen(secret);
2170 memcpy(buffer, vector, AUTH_VECTOR_LEN );
2171 memcpy(buffer + AUTH_VECTOR_LEN, secret, secretLen );
2173 librad_md5_calc(digest, buffer, AUTH_VECTOR_LEN + secretLen );
2174 memset(buffer, 0, sizeof(buffer));
2176 for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
2177 digest[i] ^= value[i];