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 volatile int lrad_rand_index = -1;
89 static unsigned int salt_offset = 0;
91 static const char *packet_codes[] = {
97 "Accounting-Response",
102 "Accounting-Message",
113 "Resource-Free-Request",
114 "Resource-Free-Response",
115 "Resource-Query-Request",
116 "Resource-Query-Response",
117 "Alternate-Resource-Reclaim-Request",
118 "NAS-Reboot-Request",
119 "NAS-Reboot-Response",
132 "Disconnect-Request",
142 "IP-Address-Allocate",
147 #define AUTH_PASS_LEN (AUTH_VECTOR_LEN)
148 /*************************************************************************
150 * Function: make_secret
152 * Purpose: Build an encrypted secret value to return in a reply
153 * packet. The secret is hidden by xoring with a MD5 digest
154 * created from the shared secret and the authentication
155 * vector. We put them into MD5 in the reverse order from
156 * that used when encrypting passwords to RADIUS.
158 *************************************************************************/
159 static void make_secret(uint8_t *digest, const uint8_t *vector,
160 const char *secret, const uint8_t *value)
166 MD5Update(&context, vector, AUTH_VECTOR_LEN);
167 MD5Update(&context, secret, strlen(secret));
168 MD5Final(digest, &context);
170 for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
171 digest[i] ^= value[i];
175 #define MAX_PASS_LEN (128)
176 static void make_passwd(uint8_t *output, int *outlen,
177 const uint8_t *input, int inlen,
178 const char *secret, const uint8_t *vector)
180 MD5_CTX context, old;
181 uint8_t digest[AUTH_VECTOR_LEN];
182 uint8_t passwd[MAX_PASS_LEN];
187 * If the length is zero, round it up.
193 else if (len > MAX_PASS_LEN) len = MAX_PASS_LEN;
195 else if ((len & 0x0f) != 0) {
201 memcpy(passwd, input, len);
202 memset(passwd + len, 0, sizeof(passwd) - len);
205 MD5Update(&context, secret, strlen(secret));
211 MD5Update(&context, vector, AUTH_PASS_LEN);
213 for (n = 0; n < len; n += AUTH_PASS_LEN) {
217 passwd + n - AUTH_PASS_LEN,
221 MD5Final(digest, &context);
222 for (i = 0; i < AUTH_PASS_LEN; i++) {
223 passwd[i + n] ^= digest[i];
227 memcpy(output, passwd, len);
230 static void make_tunnel_passwd(uint8_t *output, int *outlen,
231 const uint8_t *input, int inlen,
232 const char *secret, const uint8_t *vector)
234 MD5_CTX context, old;
235 uint8_t digest[AUTH_VECTOR_LEN];
236 uint8_t passwd[AUTH_PASS_LEN + AUTH_VECTOR_LEN];
241 * Length of the encrypted data is password length plus
242 * one byte for the length of the password.
245 if (len > AUTH_PASS_LEN) len = AUTH_PASS_LEN;
246 else if ((len & 0x0f) != 0) {
250 *outlen = len + 2; /* account for the salt */
253 * Copy the password over.
255 memcpy(passwd + 3, input, inlen);
256 memset(passwd + 3 + inlen, 0, sizeof(passwd) - 3 - inlen);
259 * Generate salt. The RFC's say:
261 * The high bit of salt[0] must be set, each salt in a
262 * packet should be unique, and they should be random
264 * So, we set the high bit, add in a counter, and then
265 * add in some CSPRNG data. should be OK..
267 passwd[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
268 (lrad_rand() & 0x07));
269 passwd[1] = lrad_rand();
270 passwd[2] = inlen; /* length of the password string */
273 MD5Update(&context, secret, strlen(secret));
276 MD5Update(&context, vector, AUTH_VECTOR_LEN);
277 MD5Update(&context, &passwd[0], 2);
279 for (n = 0; n < len; n += AUTH_PASS_LEN) {
283 passwd + 2 + n - AUTH_PASS_LEN,
287 MD5Final(digest, &context);
288 for (i = 0; i < AUTH_PASS_LEN; i++) {
289 passwd[i + 2 + n] ^= digest[i];
292 memcpy(output, passwd, len + 2);
296 * Parse a data structure into a RADIUS attribute.
298 int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
299 const char *secret, const VALUE_PAIR *vp, uint8_t *ptr)
302 int offset, len, total_length;
304 uint8_t *length_ptr, *vsa_length_ptr;
305 const uint8_t *data = NULL;
308 vendorcode = total_length = 0;
309 length_ptr = vsa_length_ptr = NULL;
312 * For interoperability, always put vendor attributes
313 * into their own VSA.
315 if ((vendorcode = VENDOR(vp->attribute)) != 0) {
317 * Build a VSA header.
319 *ptr++ = PW_VENDOR_SPECIFIC;
320 vsa_length_ptr = ptr;
322 lvalue = htonl(vendorcode);
323 memcpy(ptr, &lvalue, 4);
327 if (vendorcode == VENDORPEC_USR) {
328 lvalue = htonl(vp->attribute & 0xFFFF);
329 memcpy(ptr, &lvalue, 4);
331 length_ptr = vsa_length_ptr;
338 * We don't have two different lengths.
340 vsa_length_ptr = NULL;
342 } else if (vendorcode == VENDORPEC_LUCENT) {
344 * 16-bit attribute, 8-bit length
346 *ptr++ = ((vp->attribute >> 8) & 0xFF);
347 *ptr++ = (vp->attribute & 0xFF);
349 *vsa_length_ptr += 3;
353 } else if (vendorcode == VENDORPEC_STARENT) {
355 * 16-bit attribute, 16-bit length
356 * with the upper 8 bits of the length
359 *ptr++ = ((vp->attribute >> 8) & 0xFF);
360 *ptr++ = (vp->attribute & 0xFF);
363 *vsa_length_ptr += 4;
368 * All other VSA's are encoded the same
371 *vsa_length_ptr += 2;
377 * All other attributes are encoded as
380 *ptr++ = (vp->attribute & 0xFF);
387 if (vp->flags.has_tag) {
388 if (TAG_VALID(vp->flags.tag)) {
389 ptr[0] = vp->flags.tag & 0xff;
392 } else if (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
394 * Tunnel passwords REQUIRE a tag, even
395 * if don't have a valid tag.
399 } /* else don't write a tag */
400 } /* else the attribute doesn't have a tag */
403 * Set up the default sources for the data.
409 * Encrypted passwords can't be very long.
410 * This check also ensures that the hashed version
411 * of the password + attribute header fits into one
414 * FIXME: Print a warning message if it's too long?
416 if (vp->flags.encrypt && (len > MAX_PASS_LEN)) {
424 case PW_TYPE_IPV6ADDR:
425 case PW_TYPE_IPV6PREFIX:
426 case PW_TYPE_ABINARY:
427 /* nothing more to do */
430 case PW_TYPE_INTEGER:
431 len = 4; /* just in case */
432 lvalue = htonl(vp->lvalue);
433 memcpy(array, &lvalue, sizeof(lvalue));
436 * Perhaps discard the first octet.
438 data = &array[offset];
443 data = (const uint8_t *) &vp->lvalue;
444 len = 4; /* just in case */
448 * There are no tagged date attributes.
451 lvalue = htonl(vp->lvalue);
452 data = (const uint8_t *) &lvalue;
453 len = 4; /* just in case */
456 default: /* unknown type: ignore it */
457 librad_log("ERROR: Unknown attribute type %d", vp->type);
462 * Bound the data to 255 bytes.
464 if (len + offset + total_length > 255) {
465 len = 255 - offset - total_length;
469 * Encrypt the various password styles
471 * Attributes with encrypted values MUST be less than
474 switch (vp->flags.encrypt) {
475 case FLAG_ENCRYPT_USER_PASSWORD:
476 make_passwd(ptr + offset, &len,
478 secret, packet->vector);
481 case FLAG_ENCRYPT_TUNNEL_PASSWORD:
483 librad_log("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->name);
487 make_tunnel_passwd(ptr + offset, &len,
489 secret, original->vector);
493 * The code above ensures that this attribute
496 case FLAG_ENCRYPT_ASCEND_SECRET:
497 make_secret(ptr + offset, packet->vector,
499 len = AUTH_VECTOR_LEN;
505 * Just copy the data over
507 memcpy(ptr + offset, data, len);
509 } /* switch over encryption flags */
512 * Account for the tag (if any).
517 * RFC 2865 section 5 says that zero-length attributes
520 if (len == 0) return 0;
523 * Update the various lengths.
526 if (vsa_length_ptr) *vsa_length_ptr += len;
530 return total_length; /* of attribute */
537 int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
540 radius_packet_t *hdr;
542 uint16_t total_length;
547 * For simplicity in the following logic, we allow
548 * the attributes to "overflow" the 4k maximum
549 * RADIUS packet size, by one attribute.
551 * It's uint32_t, for alignment purposes.
553 uint32_t data[(MAX_PACKET_LEN + 256) / 4];
556 * Double-check some things based on packet code.
558 switch (packet->code) {
559 case PW_AUTHENTICATION_ACK:
560 case PW_AUTHENTICATION_REJECT:
561 case PW_ACCESS_CHALLENGE:
563 librad_log("ERROR: Cannot sign response packet without a request packet.");
569 * These packet vectors start off as all zero.
571 case PW_ACCOUNTING_REQUEST:
572 case PW_DISCONNECT_REQUEST:
573 memset(packet->vector, 0, sizeof(packet->vector));
581 * Use memory on the stack, until we know how
582 * large the packet will be.
584 hdr = (radius_packet_t *) data;
587 * Build standard header
589 hdr->code = packet->code;
590 hdr->id = packet->id;
592 memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
594 total_length = AUTH_HDR_LEN;
595 packet->verified = 0;
598 * Load up the configuration values for the user
603 * FIXME: Loop twice over the reply list. The first time,
604 * calculate the total length of data. The second time,
605 * allocate the memory, and fill in the VP's.
607 * Hmm... this may be slower than just doing a small
612 * Loop over the reply attributes for the packet.
614 for (reply = packet->vps; reply; reply = reply->next) {
616 * Ignore non-wire attributes
618 if ((VENDOR(reply->attribute) == 0) &&
619 ((reply->attribute & 0xFFFF) > 0xff)) {
624 * Check that the packet is no more than 4k in
625 * size, AFTER over-flowing the 4k boundary.
626 * Note that the 'data' buffer, above, is one
627 * attribute longer than necessary, in order to
628 * permit this overflow.
630 if (total_length > MAX_PACKET_LEN) {
631 librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
636 * Set the Message-Authenticator to the correct
637 * length and initial value.
639 if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
640 reply->length = AUTH_VECTOR_LEN;
641 memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
642 packet->verified = total_length; /* HACK! */
646 * Print out ONLY the attributes which
647 * we're sending over the wire, and print
648 * them out BEFORE they're encrypted.
652 len = rad_vp2attr(packet, original, secret, reply, ptr);
653 if (len < 0) return -1;
656 } /* done looping over all attributes */
659 * Fill in the rest of the fields, and copy the data over
660 * from the local stack to the newly allocated memory.
662 * Yes, all this 'memcpy' is slow, but it means
663 * that we only allocate the minimum amount of
664 * memory for a request.
666 packet->data_len = total_length;
667 packet->data = (uint8_t *) malloc(packet->data_len);
669 librad_log("Out of memory");
673 memcpy(packet->data, data, packet->data_len);
674 hdr = (radius_packet_t *) packet->data;
676 total_length = htons(total_length);
677 memcpy(hdr->length, &total_length, sizeof(total_length));
684 * Sign a previously encoded packet.
686 int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
689 radius_packet_t *hdr = (radius_packet_t *)packet->data;
692 * It wasn't assigned an Id, this is bad!
694 if (packet->id < 0) {
695 librad_log("ERROR: RADIUS packets must be assigned an Id.");
699 if (!packet->data || (packet->data_len < AUTH_HDR_LEN) ||
700 (packet->verified < 0)) {
701 librad_log("ERROR: You must call rad_encode() before rad_sign()");
706 * If there's a Message-Authenticator, update it
707 * now, BEFORE updating the authentication vector.
711 if (packet->verified > 0) {
712 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
714 switch (packet->code) {
715 case PW_ACCOUNTING_REQUEST:
716 case PW_ACCOUNTING_RESPONSE:
717 case PW_DISCONNECT_REQUEST:
718 case PW_DISCONNECT_ACK:
719 case PW_DISCONNECT_NAK:
723 memset(hdr->vector, 0, AUTH_VECTOR_LEN);
726 case PW_AUTHENTICATION_ACK:
727 case PW_AUTHENTICATION_REJECT:
728 case PW_ACCESS_CHALLENGE:
730 librad_log("ERROR: Cannot sign response packet without a request packet.");
733 memcpy(hdr->vector, original->vector,
737 default: /* others have vector already set to zero */
743 * Set the authentication vector to zero,
744 * calculate the signature, and put it
745 * into the Message-Authenticator
748 lrad_hmac_md5(packet->data, packet->data_len,
749 secret, strlen(secret),
751 memcpy(packet->data + packet->verified + 2,
752 calc_auth_vector, AUTH_VECTOR_LEN);
755 * Copy the original request vector back
758 memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
762 * Switch over the packet code, deciding how to
765 switch (packet->code) {
767 * Request packets are not signed, bur
768 * have a random authentication vector.
770 case PW_AUTHENTICATION_REQUEST:
771 case PW_STATUS_SERVER:
775 * Reply packets are signed with the
776 * authentication vector of the request.
784 MD5Update(&context, packet->data, packet->data_len);
785 MD5Update(&context, secret, strlen(secret));
786 MD5Final(digest, &context);
788 memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
789 memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
792 }/* switch over packet codes */
798 * Reply to the request. Also attach
799 * reply attribute value pairs and any user message provided.
801 int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
807 struct sockaddr_in saremote;
808 struct sockaddr_in *sa;
811 * Maybe it's a fake packet. Don't send it.
813 if (!packet || (packet->sockfd < 0)) {
817 if ((packet->code > 0) && (packet->code < 52)) {
818 what = packet_codes[packet->code];
824 * First time through, allocate room for the packet
827 DEBUG("Sending %s of id %d to %s port %d\n",
829 ip_ntoa(ip_buffer, packet->dst_ipaddr),
835 if (rad_encode(packet, original, secret) < 0) {
840 * Re-sign it, including updating the
841 * Message-Authenticator.
843 if (rad_sign(packet, original, secret) < 0) {
848 * If packet->data points to data, then we print out
849 * the VP list again only for debugging.
851 } else if (librad_debug) {
852 DEBUG("Re-sending %s of id %d to %s port %d\n", what, packet->id,
853 ip_ntoa(ip_buffer, packet->dst_ipaddr),
856 for (reply = packet->vps; reply; reply = reply->next) {
857 /* FIXME: ignore attributes > 0xff */
863 * And send it on it's way.
865 sa = (struct sockaddr_in *) &saremote;
866 memset ((char *) sa, '\0', sizeof (saremote));
867 sa->sin_family = AF_INET;
868 sa->sin_addr.s_addr = packet->dst_ipaddr;
869 sa->sin_port = htons(packet->dst_port);
870 #ifndef WITH_UDPFROMTO
871 return sendto(packet->sockfd, packet->data, (int)packet->data_len, 0,
872 (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
875 struct sockaddr_in salocal;
876 memset ((char *) &salocal, '\0', sizeof (salocal));
877 salocal.sin_family = AF_INET;
878 salocal.sin_addr.s_addr = packet->src_ipaddr;
880 return sendfromto(packet->sockfd, packet->data, (int)packet->data_len, 0,
881 (struct sockaddr *)&salocal, sizeof(struct sockaddr_in),
882 (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
889 * Validates the requesting client NAS. Calculates the
890 * signature based on the clients private key.
892 static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
894 u_char digest[AUTH_VECTOR_LEN];
898 * Older clients have the authentication vector set to
899 * all zeros. Return `1' in that case.
901 memset(digest, 0, sizeof(digest));
902 if (memcmp(packet->vector, digest, AUTH_VECTOR_LEN) == 0) {
903 packet->verified = 1;
908 * Zero out the auth_vector in the received packet.
909 * Then append the shared secret to the received packet,
910 * and calculate the MD5 sum. This must be the same
911 * as the original MD5 sum (packet->vector).
913 memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
916 * MD5(packet + secret);
919 MD5Update(&context, packet->data, packet->data_len);
920 MD5Update(&context, secret, strlen(secret));
921 MD5Final(digest, &context);
924 * Return 0 if OK, 2 if not OK.
927 memcmp(digest, packet->vector, AUTH_VECTOR_LEN) ? 2 : 0;
929 return packet->verified;
933 * Validates the requesting client NAS. Calculates the
934 * signature based on the clients private key.
936 static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
939 uint8_t calc_digest[AUTH_VECTOR_LEN];
945 if (original == NULL) {
950 * Copy the original vector in place.
952 memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
955 * MD5(packet + secret);
958 MD5Update(&context, packet->data, packet->data_len);
959 MD5Update(&context, secret, strlen(secret));
960 MD5Final(calc_digest, &context);
963 * Copy the packet's vector back to the packet.
965 memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
968 * Return 0 if OK, 2 if not OK.
971 memcmp(packet->vector, calc_digest, AUTH_VECTOR_LEN) ? 2 : 0;
972 return packet->verified;
976 * Receive UDP client requests, and fill in
977 * the basics of a RADIUS_PACKET structure.
979 RADIUS_PACKET *rad_recv(int fd)
981 RADIUS_PACKET *packet;
982 struct sockaddr_in saremote;
987 radius_packet_t *hdr;
988 char host_ipaddr[16];
990 uint8_t data[MAX_PACKET_LEN];
994 * Allocate the new request data structure
996 if ((packet = malloc(sizeof(RADIUS_PACKET))) == NULL) {
997 librad_log("out of memory");
1000 memset(packet, 0, sizeof(RADIUS_PACKET));
1003 * Receive the packet.
1005 salen = sizeof(saremote);
1006 memset(&saremote, 0, sizeof(saremote));
1007 #ifndef WITH_UDPFROMTO
1008 packet->data_len = recvfrom(fd, data, sizeof(data),
1009 0, (struct sockaddr *)&saremote, &salen);
1010 packet->dst_ipaddr = htonl(INADDR_ANY); /* i.e. unknown */
1013 socklen_t salen_local;
1014 struct sockaddr_in salocal;
1015 salen_local = sizeof(salocal);
1016 memset(&salocal, 0, sizeof(salocal));
1017 packet->data_len = recvfromto(fd, data, sizeof(data), 0,
1018 (struct sockaddr *)&saremote, &salen,
1019 (struct sockaddr *)&salocal, &salen_local);
1020 packet->dst_ipaddr = salocal.sin_addr.s_addr;
1025 * Check for socket errors.
1027 if (packet->data_len < 0) {
1028 librad_log("Error receiving packet: %s", strerror(errno));
1034 * Fill IP header fields. We need these for the error
1035 * messages which may come later.
1037 packet->sockfd = fd;
1038 packet->src_ipaddr = saremote.sin_addr.s_addr;
1039 packet->src_port = ntohs(saremote.sin_port);
1042 * FIXME: Do even more filtering by only permitting
1043 * certain IP's. The problem is that we don't know
1044 * how to do this properly for all possible clients...
1048 * Explicitely set the VP list to empty.
1053 * Check for packets smaller than the packet header.
1055 * RFC 2865, Section 3., subsection 'length' says:
1057 * "The minimum length is 20 ..."
1059 if (packet->data_len < AUTH_HDR_LEN) {
1060 librad_log("WARNING: Malformed RADIUS packet from host %s: too short (received %d < minimum %d)",
1061 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1062 packet->data_len, AUTH_HDR_LEN);
1068 * RFC 2865, Section 3., subsection 'length' says:
1070 * " ... and maximum length is 4096."
1072 if (packet->data_len > MAX_PACKET_LEN) {
1073 librad_log("WARNING: Malformed RADIUS packet from host %s: too long (received %d > maximum %d)",
1074 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1075 packet->data_len, MAX_PACKET_LEN);
1081 * Check for packets with mismatched size.
1082 * i.e. We've received 128 bytes, and the packet header
1083 * says it's 256 bytes long.
1085 totallen = (data[2] << 8) | data[3];
1086 hdr = (radius_packet_t *)data;
1089 * Code of 0 is not understood.
1090 * Code of 16 or greate is not understood.
1092 if ((hdr->code == 0) ||
1093 (hdr->code >= 52)) {
1094 librad_log("WARNING: Bad RADIUS packet from host %s: unknown packet code %d",
1095 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1102 * Repeat the length checks. This time, instead of
1103 * looking at the data we received, look at the value
1104 * of the 'length' field inside of the packet.
1106 * Check for packets smaller than the packet header.
1108 * RFC 2865, Section 3., subsection 'length' says:
1110 * "The minimum length is 20 ..."
1112 if (totallen < AUTH_HDR_LEN) {
1113 librad_log("WARNING: Malformed RADIUS packet from host %s: too short (length %d < minimum %d)",
1114 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1115 totallen, AUTH_HDR_LEN);
1121 * And again, for the value of the 'length' field.
1123 * RFC 2865, Section 3., subsection 'length' says:
1125 * " ... and maximum length is 4096."
1127 if (totallen > MAX_PACKET_LEN) {
1128 librad_log("WARNING: Malformed RADIUS packet from host %s: too long (length %d > maximum %d)",
1129 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1130 totallen, MAX_PACKET_LEN);
1136 * RFC 2865, Section 3., subsection 'length' says:
1138 * "If the packet is shorter than the Length field
1139 * indicates, it MUST be silently discarded."
1141 * i.e. No response to the NAS.
1143 if (packet->data_len < totallen) {
1144 librad_log("WARNING: Malformed RADIUS packet from host %s: received %d octets, packet length says %d",
1145 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1146 packet->data_len, totallen);
1152 * RFC 2865, Section 3., subsection 'length' says:
1154 * "Octets outside the range of the Length field MUST be
1155 * treated as padding and ignored on reception."
1157 if (packet->data_len > totallen) {
1159 * We're shortening the packet below, but just
1160 * to be paranoid, zero out the extra data.
1162 memset(data + totallen, 0, packet->data_len - totallen);
1163 packet->data_len = totallen;
1167 * Walk through the packet's attributes, ensuring that
1168 * they add up EXACTLY to the size of the packet.
1170 * If they don't, then the attributes either under-fill
1171 * or over-fill the packet. Any parsing of the packet
1172 * is impossible, and will result in unknown side effects.
1174 * This would ONLY happen with buggy RADIUS implementations,
1175 * or with an intentional attack. Either way, we do NOT want
1176 * to be vulnerable to this problem.
1179 count = totallen - AUTH_HDR_LEN;
1185 * Attribute number zero is NOT defined.
1188 librad_log("WARNING: Malformed RADIUS packet from host %s: Invalid attribute 0",
1189 ip_ntoa(host_ipaddr, packet->src_ipaddr));
1195 * Attributes are at LEAST as long as the ID & length
1196 * fields. Anything shorter is an invalid attribute.
1199 librad_log("WARNING: Malformed RADIUS packet from host %s: attribute %d too short",
1200 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1207 * Sanity check the attributes for length.
1210 default: /* don't do anything by default */
1213 case PW_EAP_MESSAGE:
1214 seen_eap |= PW_EAP_MESSAGE;
1217 case PW_MESSAGE_AUTHENTICATOR:
1218 if (attr[1] != 2 + AUTH_VECTOR_LEN) {
1219 librad_log("WARNING: Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
1220 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1225 seen_eap |= PW_MESSAGE_AUTHENTICATOR;
1230 * FIXME: Look up the base 255 attributes in the
1231 * dictionary, and switch over their type. For
1232 * integer/date/ip, the attribute length SHOULD
1235 count -= attr[1]; /* grab the attribute length */
1237 num_attributes++; /* seen one more attribute */
1241 * If the attributes add up to a packet, it's allowed.
1243 * If not, we complain, and throw the packet away.
1246 librad_log("WARNING: Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
1247 ip_ntoa(host_ipaddr, packet->src_ipaddr));
1253 * If we're configured to look for a maximum number of
1254 * attributes, and we've seen more than that maximum,
1255 * then throw the packet away, as a possible DoS.
1257 if ((librad_max_attributes > 0) &&
1258 (num_attributes > librad_max_attributes)) {
1259 librad_log("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
1260 ip_ntoa(host_ipaddr, packet->src_ipaddr),
1261 num_attributes, librad_max_attributes);
1267 * http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
1269 * A packet with an EAP-Message attribute MUST also have
1270 * a Message-Authenticator attribute.
1272 * A Message-Authenticator all by itself is OK, though.
1275 (seen_eap != PW_MESSAGE_AUTHENTICATOR) &&
1276 (seen_eap != (PW_EAP_MESSAGE | PW_MESSAGE_AUTHENTICATOR))) {
1277 librad_log("WARNING: Insecure packet from host %s: Received EAP-Message with no Message-Authenticator.",
1278 ip_ntoa(host_ipaddr, packet->src_ipaddr));
1284 if ((hdr->code > 0) && (hdr->code < 52)) {
1285 printf("rad_recv: %s packet from host %s:%d",
1286 packet_codes[hdr->code],
1287 ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port);
1289 printf("rad_recv: Packet from host %s:%d code=%d",
1290 ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port,
1293 printf(", id=%d, length=%d\n", hdr->id, totallen);
1297 * Fill RADIUS header fields
1299 packet->code = hdr->code;
1300 packet->id = hdr->id;
1301 memcpy(packet->vector, hdr->vector, AUTH_VECTOR_LEN);
1304 * Now that we've sanity checked the packet, we can allocate
1305 * memory for it, and copy the data from the local area to
1306 * the packet buffer.
1308 if ((packet->data = malloc(packet->data_len)) == NULL) {
1310 librad_log("out of memory");
1313 memcpy(packet->data, data, packet->data_len);
1320 * Verify the signature of a packet.
1322 static int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1329 if (!packet || !packet->data) return -1;
1332 * Before we allocate memory for the attributes, do more
1335 ptr = packet->data + AUTH_HDR_LEN;
1336 length = packet->data_len - AUTH_HDR_LEN;
1337 while (length > 0) {
1338 uint8_t msg_auth_vector[AUTH_VECTOR_LEN];
1339 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
1344 default: /* don't do anything. */
1348 * Note that more than one Message-Authenticator
1349 * attribute is invalid.
1351 case PW_MESSAGE_AUTHENTICATOR:
1352 memcpy(msg_auth_vector, &ptr[2], sizeof(msg_auth_vector));
1353 memset(&ptr[2], 0, AUTH_VECTOR_LEN);
1355 switch (packet->code) {
1359 case PW_ACCOUNTING_REQUEST:
1360 case PW_ACCOUNTING_RESPONSE:
1361 case PW_DISCONNECT_REQUEST:
1362 case PW_DISCONNECT_ACK:
1363 case PW_DISCONNECT_NAK:
1364 case PW_COF_REQUEST:
1367 memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
1370 case PW_AUTHENTICATION_ACK:
1371 case PW_AUTHENTICATION_REJECT:
1372 case PW_ACCESS_CHALLENGE:
1374 librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
1377 memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
1381 lrad_hmac_md5(packet->data, packet->data_len,
1382 secret, strlen(secret), calc_auth_vector);
1383 if (memcmp(calc_auth_vector, msg_auth_vector,
1384 sizeof(calc_auth_vector)) != 0) {
1386 librad_log("Received packet from %s with invalid Message-Authenticator! (Shared secret is incorrect.)",
1387 ip_ntoa(buffer, packet->src_ipaddr));
1388 /* Silently drop packet, according to RFC 3579 */
1390 } /* else the message authenticator was good */
1393 * Reinitialize Authenticators.
1395 memcpy(&ptr[2], msg_auth_vector, AUTH_VECTOR_LEN);
1396 memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
1398 } /* switch over the attributes */
1402 } /* loop over the packet, sanity checking the attributes */
1405 * Calculate and/or verify digest.
1407 switch(packet->code) {
1410 case PW_AUTHENTICATION_REQUEST:
1411 case PW_STATUS_SERVER:
1412 case PW_DISCONNECT_REQUEST:
1414 * The authentication vector is random
1415 * nonsense, invented by the client.
1419 case PW_ACCOUNTING_REQUEST:
1420 if (calc_acctdigest(packet, secret) > 1) {
1422 librad_log("Received Accounting-Request packet "
1423 "from %s with invalid signature! (Shared secret is incorrect.)",
1424 ip_ntoa(buffer, packet->src_ipaddr));
1429 /* Verify the reply digest */
1430 case PW_AUTHENTICATION_ACK:
1431 case PW_AUTHENTICATION_REJECT:
1432 case PW_ACCOUNTING_RESPONSE:
1433 rcode = calc_replydigest(packet, original, secret);
1436 librad_log("Received %s packet "
1437 "from client %s port %d with invalid signature (err=%d)! (Shared secret is incorrect.)",
1438 packet_codes[packet->code],
1439 ip_ntoa(buffer, packet->src_ipaddr),
1452 * Parse a RADIUS attribute into a data structure.
1454 static VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
1455 const char *secret, int attribute, int length,
1456 const uint8_t *data)
1461 if ((vp = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
1466 * If length is greater than 253, something is SERIOUSLY
1469 if (length > 253) length = 253; /* paranoia (pair-anoia?) */
1471 vp->length = length;
1472 vp->operator = T_OP_EQ;
1478 if (vp->flags.has_tag) {
1479 if (TAG_VALID(data[0]) ||
1480 (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD)) {
1482 * Tunnel passwords REQUIRE a tag, even
1483 * if don't have a valid tag.
1485 vp->flags.tag = data[0];
1487 if ((vp->type == PW_TYPE_STRING) ||
1488 (vp->type == PW_TYPE_OCTETS)) offset = 1;
1493 * Copy the data to be decrypted
1495 memcpy(&vp->strvalue[0], data + offset, length - offset);
1496 vp->length -= offset;
1499 * Decrypt the attribute.
1501 switch (vp->flags.encrypt) {
1505 case FLAG_ENCRYPT_USER_PASSWORD:
1507 rad_pwdecode((char *)vp->strvalue,
1511 rad_pwdecode((char *)vp->strvalue,
1515 if (vp->attribute == PW_USER_PASSWORD) {
1516 vp->length = strlen(vp->strvalue);
1521 * Tunnel-Password's may go ONLY
1522 * in response packets.
1524 case FLAG_ENCRYPT_TUNNEL_PASSWORD:
1525 if (!original) goto raw;
1527 if (rad_tunnel_pwdecode(vp->strvalue, &vp->length,
1528 secret, original->vector) < 0) {
1534 * Ascend-Send-Secret
1535 * Ascend-Receive-Secret
1537 case FLAG_ENCRYPT_ASCEND_SECRET:
1541 uint8_t my_digest[AUTH_VECTOR_LEN];
1542 make_secret(my_digest,
1545 memcpy(vp->strvalue, my_digest,
1547 vp->strvalue[AUTH_VECTOR_LEN] = '\0';
1548 vp->length = strlen(vp->strvalue);
1554 } /* switch over encryption flags */
1558 case PW_TYPE_STRING:
1559 case PW_TYPE_OCTETS:
1560 /* nothing more to do */
1563 case PW_TYPE_INTEGER:
1564 if (vp->length != 4) goto raw;
1566 memcpy(&vp->lvalue, vp->strvalue, 4);
1567 vp->lvalue = ntohl(vp->lvalue);
1569 if (vp->flags.has_tag) vp->lvalue &= 0x00ffffff;
1572 * Try to get named VALUEs
1576 dval = dict_valbyattr(vp->attribute,
1579 strNcpy(vp->strvalue,
1581 sizeof(vp->strvalue));
1587 if (vp->length != 4) goto raw;
1589 memcpy(&vp->lvalue, vp->strvalue, 4);
1590 vp->lvalue = ntohl(vp->lvalue);
1594 case PW_TYPE_IPADDR:
1595 if (vp->length != 4) goto raw;
1597 memcpy(&vp->lvalue, vp->strvalue, 4);
1601 * IPv6 interface ID is 8 octets long.
1604 if (vp->length != 8) goto raw;
1605 /* vp->vp_ifid == vp->strvalue */
1609 * IPv6 addresses are 16 octets long
1611 case PW_TYPE_IPV6ADDR:
1612 if (vp->length != 16) goto raw;
1613 /* vp->vp_ipv6addr == vp->strvalue */
1617 * IPv6 prefixes are 2 to 18 octets long.
1619 * RFC 3162: The first octet is unused.
1620 * The second is the length of the prefix
1621 * the rest are the prefix data.
1623 * The prefix length can have value 0 to 128.
1625 case PW_TYPE_IPV6PREFIX:
1626 if (vp->length < 2 || vp->length > 18) goto raw;
1627 if (vp->strvalue[1] > 128) goto raw;
1630 * FIXME: double-check that
1631 * (vp->strvalue[1] >> 3) matches vp->length + 2
1633 if (vp->length < 18) {
1634 memset(vp->strvalue + vp->length, 0,
1641 vp->type = PW_TYPE_OCTETS;
1642 vp->length = length;
1643 memcpy(vp->strvalue, data, length);
1647 * Ensure there's no encryption or tag stuff,
1648 * we just pass the attribute as-is.
1650 memset(&vp->flags, 0, sizeof(vp->flags));
1658 * Calculate/check digest, and decode radius attributes.
1660 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1664 uint32_t vendorcode;
1672 radius_packet_t *hdr;
1673 int vsa_tlen, vsa_llen;
1674 DICT_VENDOR *dv = NULL;
1676 if (rad_verify(packet, original, secret) < 0) return -1;
1679 * Extract attribute-value pairs
1681 hdr = (radius_packet_t *)packet->data;
1683 packet_length = packet->data_len - AUTH_HDR_LEN;
1686 * There may be VP's already in the packet. Don't
1689 for (tail = &packet->vps; *tail != NULL; tail = &((*tail)->next)) {
1695 vsa_tlen = vsa_llen = 1;
1698 * We have to read at least two bytes.
1700 * rad_recv() above ensures that this is OK.
1702 while (packet_length > 0) {
1707 * Normal attribute, handle it like normal.
1709 if (vendorcode == 0) {
1711 * No room to read attr/length,
1712 * or bad attribute, or attribute is
1713 * too short, or attribute is too long,
1714 * stop processing the packet.
1716 if ((packet_length < 2) ||
1717 (ptr[0] == 0) || (ptr[1] < 2) ||
1718 (ptr[1] > packet_length)) break;
1726 if (attribute != PW_VENDOR_SPECIFIC) goto create_pair;
1729 * No vendor code, or ONLY vendor code.
1731 if (attrlen <= 4) goto create_pair;
1737 * Handle Vendor-Specific
1739 if (vendorlen == 0) {
1745 * attrlen was checked above.
1747 memcpy(&lvalue, ptr, 4);
1748 myvendor = ntohl(lvalue);
1751 * Zero isn't allowed.
1753 if (myvendor == 0) goto create_pair;
1756 * This is an implementation issue.
1757 * We currently pack vendor into the upper
1758 * 16 bits of a 32-bit attribute number,
1759 * so we can't handle vendor numbers larger
1762 if (myvendor > 65535) goto create_pair;
1764 vsa_tlen = vsa_llen = 1;
1765 dv = dict_vendorbyvalue(myvendor);
1767 vsa_tlen = dv->type;
1768 vsa_llen = dv->length;
1772 * Sweep through the list of VSA's,
1773 * seeing if they exactly fill the
1774 * outer Vendor-Specific attribute.
1776 * If not, create a raw Vendor-Specific.
1779 sublen = attrlen - 4;
1782 * See if we can parse it.
1788 * Don't have a type, it's bad.
1790 if (sublen < vsa_tlen) goto create_pair;
1793 * Ensure that the attribute number
1802 myattr = (subptr[0] << 8) | subptr[1];
1806 if ((subptr[0] != 0) ||
1807 (subptr[1] != 0)) goto create_pair;
1809 myattr = (subptr[2] << 8) | subptr[3];
1813 * Our dictionary is broken.
1820 * Not enough room for one more
1823 if (sublen < vsa_tlen + vsa_llen) goto create_pair;
1826 attribute = (myvendor << 16) | myattr;
1827 ptr += 4 + vsa_tlen;
1828 attrlen -= (4 + vsa_tlen);
1829 packet_length -= 4 + vsa_tlen;
1833 if (subptr[vsa_tlen] < (vsa_tlen + vsa_llen))
1836 if (subptr[vsa_tlen] > sublen)
1838 sublen -= subptr[vsa_tlen];
1839 subptr += subptr[vsa_tlen];
1843 if (subptr[vsa_tlen] != 0) goto create_pair;
1844 if (subptr[vsa_tlen + 1] < (vsa_tlen + vsa_llen))
1846 if (subptr[vsa_tlen + 1] > sublen)
1848 sublen -= subptr[vsa_tlen + 1];
1849 subptr += subptr[vsa_tlen + 1];
1853 * Our dictionaries are
1859 } while (sublen > 0);
1861 vendorcode = myvendor;
1862 vendorlen = attrlen - 4;
1869 * attrlen is the length of this attribute.
1870 * total_len is the length of the encompassing
1879 attribute = (ptr[0] << 8) | ptr[1];
1882 default: /* can't hit this. */
1885 attribute |= (vendorcode << 16);
1890 attrlen = ptr[0] - (vsa_tlen + vsa_llen);
1894 attrlen = ptr[1] - (vsa_tlen + vsa_llen);
1897 default: /* can't hit this. */
1901 vendorlen -= vsa_tlen + vsa_llen + attrlen;
1902 if (vendorlen == 0) vendorcode = 0;
1903 packet_length -= (vsa_tlen + vsa_llen);
1906 * Create the attribute, setting the default type
1907 * to 'octects'. If the type in the dictionary
1908 * is different, then the dictionary type will
1909 * over-ride this one.
1912 pair = rad_attr2vp(packet, original, secret,
1913 attribute, attrlen, ptr);
1915 pairfree(&packet->vps);
1916 librad_log("out of memory");
1925 packet_length -= attrlen;
1929 * Merge information from the outside world into our
1932 lrad_rand_seed(packet->data, AUTH_HDR_LEN);
1941 * We assume that the passwd buffer passed is big enough.
1942 * RFC2138 says the password is max 128 chars, so the size
1943 * of the passwd buffer must be at least 129 characters.
1944 * Preferably it's just MAX_STRING_LEN.
1946 * int *pwlen is updated to the new length of the encrypted
1947 * password - a multiple of 16 bytes.
1949 int rad_pwencode(char *passwd, int *pwlen, const char *secret,
1952 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
1953 char digest[AUTH_VECTOR_LEN];
1954 int i, n, secretlen;
1958 * Pad password to multiple of AUTH_PASS_LEN bytes.
1961 if (len > 128) len = 128;
1963 if (len % AUTH_PASS_LEN != 0) {
1964 n = AUTH_PASS_LEN - (len % AUTH_PASS_LEN);
1965 for (i = len; n > 0; n--, i++)
1969 } else if (len == 0) {
1970 memset(passwd, 0, AUTH_PASS_LEN);
1971 *pwlen = len = AUTH_PASS_LEN;
1975 * Use the secret to setup the decryption digest
1977 secretlen = strlen(secret);
1978 memcpy(buffer, secret, secretlen);
1979 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1980 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
1983 * Now we can encode the password *in place*
1985 for (i = 0; i < AUTH_PASS_LEN; i++)
1986 passwd[i] ^= digest[i];
1988 if (len <= AUTH_PASS_LEN) return 0;
1991 * Length > AUTH_PASS_LEN, so we need to use the extended
1994 for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) {
1995 memcpy(buffer + secretlen, passwd + n, AUTH_PASS_LEN);
1996 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
1997 for (i = 0; i < AUTH_PASS_LEN; i++)
1998 passwd[i + n + AUTH_PASS_LEN] ^= digest[i];
2007 int rad_pwdecode(char *passwd, int pwlen, const char *secret,
2010 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
2011 char digest[AUTH_VECTOR_LEN];
2012 char r[AUTH_VECTOR_LEN];
2014 int i, n, secretlen;
2018 * Use the secret to setup the decryption digest
2020 secretlen = strlen(secret);
2021 memcpy(buffer, secret, secretlen);
2022 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
2023 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
2026 * Now we can decode the password *in place*
2028 memcpy(r, passwd, AUTH_PASS_LEN);
2029 for (i = 0; i < AUTH_PASS_LEN && i < pwlen; i++)
2030 passwd[i] ^= digest[i];
2032 if (pwlen <= AUTH_PASS_LEN) {
2033 passwd[pwlen+1] = 0;
2038 * Length > AUTH_PASS_LEN, so we need to use the extended
2041 rlen = ((pwlen - 1) / AUTH_PASS_LEN) * AUTH_PASS_LEN;
2043 for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) {
2044 s = (n == AUTH_PASS_LEN) ? r : (passwd + n - AUTH_PASS_LEN);
2045 memcpy(buffer + secretlen, s, AUTH_PASS_LEN);
2046 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
2047 for (i = 0; i < AUTH_PASS_LEN && (i + n) < pwlen; i++)
2048 passwd[i + n] ^= digest[i];
2057 * Encode Tunnel-Password attributes when sending them out on the wire.
2059 * int *pwlen is updated to the new length of the encrypted
2060 * password - a multiple of 16 bytes.
2062 * This is per RFC-2868 which adds a two char SALT to the initial intermediate
2065 int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret,
2068 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
2069 unsigned char digest[AUTH_VECTOR_LEN];
2071 int i, n, secretlen;
2076 if (len > 127) len = 127;
2078 * Shift the password 3 positions right to place a salt and original
2079 * length, tag will be added automatically on packet send
2081 for (n=len ; n>=0 ; n--) passwd[n+3] = passwd[n];
2085 * save original password length as first password character;
2092 * Generate salt. The RFC's say:
2094 * The high bit of salt[0] must be set, each salt in a
2095 * packet should be unique, and they should be random
2097 * So, we set the high bit, add in a counter, and then
2098 * add in some CSPRNG data. should be OK..
2100 salt[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
2101 (lrad_rand() & 0x07));
2102 salt[1] = lrad_rand();
2105 * Padd password to multiple of AUTH_PASS_LEN bytes.
2107 n = len % AUTH_PASS_LEN;
2109 n = AUTH_PASS_LEN - n;
2110 for (; n > 0; n--, len++)
2113 /* set new password length */
2117 * Use the secret to setup the decryption digest
2119 secretlen = strlen(secret);
2120 memcpy(buffer, secret, secretlen);
2122 for (n2 = 0; n2 < len; n2+=AUTH_PASS_LEN) {
2124 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
2125 memcpy(buffer + secretlen + AUTH_VECTOR_LEN, salt, 2);
2126 librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
2128 memcpy(buffer + secretlen, passwd + n2 - AUTH_PASS_LEN, AUTH_PASS_LEN);
2129 librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
2132 for (i = 0; i < AUTH_PASS_LEN; i++) {
2133 passwd[i + n2] ^= digest[i];
2141 * Decode Tunnel-Password encrypted attributes.
2143 * Defined in RFC-2868, this uses a two char SALT along with the
2144 * initial intermediate value, to differentiate it from the
2147 int rad_tunnel_pwdecode(uint8_t *passwd, int *pwlen, const char *secret,
2150 uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
2151 uint8_t digest[AUTH_VECTOR_LEN];
2152 uint8_t decrypted[MAX_STRING_LEN + 1];
2159 * We need at least a salt.
2162 librad_log("tunnel password is too short");
2167 * There's a salt, but no password. Or, there's a salt
2168 * and a 'data_len' octet. It's wrong, but at least we
2169 * can figure out what it means: the password is empty.
2171 * Note that this means we ignore the 'data_len' field,
2172 * if the attribute length tells us that there's no
2173 * more data. So the 'data_len' field may be wrong,
2182 len -= 2; /* discount the salt */
2185 * Use the secret to setup the decryption digest
2187 secretlen = strlen(secret);
2190 * Set up the initial key:
2192 * b(1) = MD5(secret + vector + salt)
2194 memcpy(buffer, secret, secretlen);
2195 memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
2196 memcpy(buffer + secretlen + AUTH_VECTOR_LEN, passwd, 2);
2197 librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
2200 * A quick check: decrypt the first octet of the password,
2201 * which is the 'data_len' field. Ensure it's sane.
2203 * 'n' doesn't include the 'data_len' octet
2206 n = passwd[2] ^ digest[0];
2208 librad_log("tunnel password is too long for the attribute");
2213 * Loop over the data, decrypting it, and generating
2214 * the key for the next round of decryption.
2216 for (n = 0; n < len; n += AUTH_PASS_LEN) {
2217 for (i = 0; i < AUTH_PASS_LEN; i++) {
2218 decrypted[n + i] = passwd[n + i + 2] ^ digest[i];
2221 * Encrypted password may not be aligned
2222 * on 16 octets, so we catch that here...
2224 if ((n + i) == len) break;
2228 * Update the digest, based on
2230 * b(n) = MD5(secret + cleartext(n-1)
2232 * but only if there's more data...
2234 memcpy(buffer + secretlen, passwd + n + 2, AUTH_PASS_LEN);
2235 librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
2239 * We've already validated the length of the decrypted
2240 * password. Copy it back to the caller.
2242 memcpy(passwd, decrypted + 1, decrypted[0]);
2243 passwd[decrypted[0]] = 0;
2244 *pwlen = decrypted[0];
2246 return decrypted[0];
2250 * Encode a CHAP password
2252 * FIXME: might not work with Ascend because
2253 * we use vp->length, and Ascend gear likes
2254 * to send an extra '\0' in the string!
2256 int rad_chap_encode(RADIUS_PACKET *packet, char *output, int id,
2257 VALUE_PAIR *password)
2261 char string[MAX_STRING_LEN * 2 + 1];
2262 VALUE_PAIR *challenge;
2265 * Sanity check the input parameters
2267 if ((packet == NULL) || (password == NULL)) {
2272 * Note that the password VP can be EITHER
2273 * a User-Password attribute (from a check-item list),
2274 * or a CHAP-Password attribute (the client asking
2275 * the library to encode it).
2283 memcpy(ptr, password->strvalue, password->length);
2284 ptr += password->length;
2285 i += password->length;
2288 * Use Chap-Challenge pair if present,
2289 * Request-Authenticator otherwise.
2291 challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE);
2293 memcpy(ptr, challenge->strvalue, challenge->length);
2294 i += challenge->length;
2296 memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
2297 i += AUTH_VECTOR_LEN;
2301 librad_md5_calc((u_char *)output + 1, (u_char *)string, i);
2308 * Seed the random number generator.
2310 * May be called any number of times.
2312 void lrad_rand_seed(const void *data, size_t size)
2317 * Ensure that the pool is initialized.
2319 if (lrad_rand_index < 0) {
2322 memset(&lrad_rand_pool, 0, sizeof(lrad_rand_pool));
2324 fd = open("/dev/urandom", O_RDONLY);
2330 while (total < sizeof(lrad_rand_pool.randrsl)) {
2331 this = read(fd, lrad_rand_pool.randrsl,
2332 sizeof(lrad_rand_pool.randrsl) - total);
2333 if ((this < 0) && (errno != EINTR)) break;
2334 if (this > 0) total += this;
2338 lrad_rand_pool.randrsl[0] = fd;
2339 lrad_rand_pool.randrsl[1] = time(NULL);
2340 lrad_rand_pool.randrsl[2] = errno;
2343 lrad_randinit(&lrad_rand_pool, 1);
2344 lrad_rand_index = 0;
2350 * Hash the user data
2352 hash = lrad_hash(data, size);
2354 lrad_rand_pool.randrsl[lrad_rand_index & 0xff] ^= hash;
2356 lrad_rand_index &= 0xff;
2359 * Churn the pool every so often after seeding it.
2361 if (((int) (hash & 0xff)) == lrad_rand_index) {
2362 lrad_isaac(&lrad_rand_pool);
2368 * Return a 32-bit random number.
2370 uint32_t lrad_rand(void)
2375 * Ensure that the pool is initialized.
2377 if (lrad_rand_index < 0) {
2378 lrad_rand_seed(NULL, 0);
2382 * We don't return data directly from the pool.
2383 * Rather, we return a summary of the data.
2385 num = lrad_rand_pool.randrsl[lrad_rand_index & 0xff];
2387 lrad_rand_index &= 0xff;
2390 * Every so often, churn the pool.
2392 if (((int) (num & 0xff)) == lrad_rand_index) {
2393 lrad_isaac(&lrad_rand_pool);
2400 * Allocate a new RADIUS_PACKET
2402 RADIUS_PACKET *rad_alloc(int newvector)
2406 if ((rp = malloc(sizeof(RADIUS_PACKET))) == NULL) {
2407 librad_log("out of memory");
2410 memset(rp, 0, sizeof(RADIUS_PACKET));
2413 uint32_t hash, base;
2416 * Don't expose the actual contents of the random
2420 for (i = 0; i < AUTH_VECTOR_LEN; i += sizeof(uint32_t)) {
2421 hash = lrad_rand() ^ base;
2422 memcpy(rp->vector + i, &hash, sizeof(hash));
2431 * Free a RADIUS_PACKET
2433 void rad_free(RADIUS_PACKET **radius_packet_ptr)
2435 RADIUS_PACKET *radius_packet;
2437 if (!radius_packet_ptr) return;
2438 radius_packet = *radius_packet_ptr;
2440 if (radius_packet->data) free(radius_packet->data);
2441 if (radius_packet->vps) pairfree(&radius_packet->vps);
2443 free(radius_packet);
2445 *radius_packet_ptr = NULL;