Check packet pointer in data2vp_any() before using, to allow the
[freeradius.git] / src / lib / radius.c
index 8f2140e..7529189 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * radius.c    Functions to send/receive radius packets.
+/**
+ * @file radius.c
+ * @brief Functions to send/receive radius packets.
  *
  * Version:    $Id$
  *
@@ -230,8 +231,8 @@ void rad_print_hex(RADIUS_PACKET *packet)
        fflush(stdout);
 }
 
-/*
- *     Wrapper for sendto which handles sendfromto, IPv6, and all
+/**
+ * @brief Wrapper for sendto which handles sendfromto, IPv6, and all
  *     possible combinations.
  */
 static int rad_sendto(int sockfd, void *data, size_t data_len, int flags,
@@ -277,6 +278,9 @@ static int rad_sendto(int sockfd, void *data, size_t data_len, int flags,
         */
        rcode = sendto(sockfd, data, data_len, flags,
                       (struct sockaddr *) &dst, sizeof_dst);
+#ifdef WITH_UDPFROMTO
+done:
+#endif
        if (rcode < 0) {
                DEBUG("rad_send() failed: %s\n", strerror(errno));
        }
@@ -364,8 +368,8 @@ ssize_t rad_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, int *src_port,
 }
 
 
-/*
- *     wrapper for recvfrom, which handles recvfromto, IPv6, and all
+/**
+ * @brief wrapper for recvfrom, which handles recvfromto, IPv6, and all
  *     possible combinations.
  */
 static ssize_t rad_recvfrom(int sockfd, uint8_t **pbuf, int flags,
@@ -492,17 +496,15 @@ static ssize_t rad_recvfrom(int sockfd, uint8_t **pbuf, int flags,
 
 
 #define AUTH_PASS_LEN (AUTH_VECTOR_LEN)
-/*************************************************************************
- *
- *      Function: make_secret
- *
- *      Purpose: Build an encrypted secret value to return in a reply
- *               packet.  The secret is hidden by xoring with a MD5 digest
+/**
+ * @brief Build an encrypted secret value to return in a reply packet
+ * 
+ *               The secret is hidden by xoring with a MD5 digest
  *               created from the shared secret and the authentication
  *               vector.  We put them into MD5 in the reverse order from
  *               that used when encrypting passwords to RADIUS.
  *
- *************************************************************************/
+ */
 static void make_secret(uint8_t *digest, const uint8_t *vector,
                        const char *secret, const uint8_t *value)
 {
@@ -724,8 +726,8 @@ static ssize_t vp2attr_rfc(const RADIUS_PACKET *packet,
                           const char *secret, const VALUE_PAIR **pvp,
                           unsigned int attribute, uint8_t *ptr, size_t room);
 
-/*
- *     This is really a sub-function of vp2data_any.  It encodes
+/**
+ * @brief This is really a sub-function of vp2data_any().  It encodes
  *     the *data* portion of the TLV, and assumes that the encapsulating
  *     attribute has already been encoded.
  */
@@ -794,9 +796,9 @@ static ssize_t vp2data_tlvs(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Encodes the data portion of an attribute.
- *     Returns -1 on error, or the length of the data portion.
+/**
+ * @brief Encodes the data portion of an attribute.
+ * @return -1 on error, or the length of the data portion.
  */
 static ssize_t vp2data_any(const RADIUS_PACKET *packet,
                           const RADIUS_PACKET *original,
@@ -809,6 +811,7 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
        const uint8_t *data;
        uint8_t *ptr = start;
        uint8_t array[4];
+       uint64_t lvalue64;
        const VALUE_PAIR *vp = *pvp;
 
        /*
@@ -869,6 +872,12 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
                data = array;
                break;
 
+       case PW_TYPE_INTEGER64:
+               len = 8;        /* just in case */
+               lvalue64 = htonll(vp->vp_integer64);
+               data = (uint8_t *) &lvalue64;
+               break;
+
        case PW_TYPE_IPADDR:
                data = (const uint8_t *) &vp->vp_ipaddr;
                len = 4;        /* just in case */
@@ -1058,8 +1067,8 @@ static ssize_t attr_shift(const uint8_t *start, const uint8_t *end,
 }
 
 
-/*
- *     Encode an "extended" attribute.
+/**
+ * @brief Encode an "extended" attribute.
  */
 int rad_vp2extended(const RADIUS_PACKET *packet,
                    const RADIUS_PACKET *original,
@@ -1177,8 +1186,8 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Encode a WiMAX attribute.
+/**
+ * @brief Encode a WiMAX attribute.
  */
 int rad_vp2wimax(const RADIUS_PACKET *packet,
                 const RADIUS_PACKET *original,
@@ -1250,8 +1259,10 @@ int rad_vp2wimax(const RADIUS_PACKET *packet,
        return (ptr + ptr[1]) - start;
 }
 
-/*
- *     Encode an RFC format TLV.  This could be a standard attribute,
+/**
+ * @brief Encode an RFC format TLV.
+ *
+ *     This could be a standard attribute,
  *     or a TLV data type.  If it's a standard attribute, then
  *     vp->attribute == attribute.  Otherwise, attribute may be
  *     something else.
@@ -1286,8 +1297,8 @@ static ssize_t vp2attr_rfc(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Encode a VSA which is a TLV.  If it's in the RFC format, call
+/**
+ * @brief Encode a VSA which is a TLV.  If it's in the RFC format, call
  *     vp2attr_rfc.  Otherwise, encode it here.
  */
 static ssize_t vp2attr_vsa(const RADIUS_PACKET *packet,
@@ -1415,8 +1426,8 @@ static ssize_t vp2attr_vsa(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Encode a Vendor-Specific attribute.
+/**
+ * @brief Encode a Vendor-Specific attribute.
  */
 int rad_vp2vsa(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                const char *secret, const VALUE_PAIR **pvp, uint8_t *ptr,
@@ -1476,8 +1487,8 @@ int rad_vp2vsa(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 }
 
 
-/*
- *     Encode an RFC standard attribute 1..255
+/**
+ * @brief Encode an RFC standard attribute 1..255
  */
 int rad_vp2rfc(const RADIUS_PACKET *packet,
               const RADIUS_PACKET *original,
@@ -1514,8 +1525,8 @@ int rad_vp2rfc(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Parse a data structure into a RADIUS attribute.
+/**
+ * @brief Parse a data structure into a RADIUS attribute.
  */
 int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                const char *secret, const VALUE_PAIR **pvp, uint8_t *start,
@@ -1572,8 +1583,8 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 }
 
 
-/*
- *     Encode a packet.
+/**
+ * @brief Encode a packet.
  */
 int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
               const char *secret)
@@ -1756,8 +1767,8 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 }
 
 
-/*
- *     Sign a previously encoded packet.
+/**
+ * @brief Sign a previously encoded packet.
  */
 int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
             const char *secret)
@@ -1786,8 +1797,12 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
 
                switch (packet->code) {
-               case PW_ACCOUNTING_REQUEST:
                case PW_ACCOUNTING_RESPONSE:
+                       if (original && original->code == PW_STATUS_SERVER) {
+                               goto do_ack;
+                       }
+
+               case PW_ACCOUNTING_REQUEST:
                case PW_DISCONNECT_REQUEST:
                case PW_DISCONNECT_ACK:
                case PW_DISCONNECT_NAK:
@@ -1797,6 +1812,7 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                        memset(hdr->vector, 0, AUTH_VECTOR_LEN);
                        break;
 
+               do_ack:
                case PW_AUTHENTICATION_ACK:
                case PW_AUTHENTICATION_REJECT:
                case PW_ACCESS_CHALLENGE:
@@ -1869,8 +1885,8 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        return 0;
 }
 
-/*
- *     Reply to the request.  Also attach
+/**
+ * @brief Reply to the request.  Also attach
  *     reply attribute value pairs and any user message provided.
  */
 int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
@@ -1942,9 +1958,11 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                          &packet->dst_ipaddr, packet->dst_port);
 }
 
-/*
- *     Do a comparison of two authentication digests by comparing
- *     the FULL digest.  Otehrwise, the server can be subject to
+/**
+ * @brief Do a comparison of two authentication digests by comparing
+ *     the FULL digest.
+ *
+ *     Otherwise, the server can be subject to
  *     timing attacks that allow attackers find a valid message
  *     authenticator.
  *
@@ -1963,8 +1981,8 @@ int rad_digest_cmp(const uint8_t *a, const uint8_t *b, size_t length)
 }
 
 
-/*
- *     Validates the requesting client NAS.  Calculates the
+/**
+ * @brief Validates the requesting client NAS.  Calculates the
  *     signature based on the clients private key.
  */
 static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
@@ -1996,8 +2014,8 @@ static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
 }
 
 
-/*
- *     Validates the requesting client NAS.  Calculates the
+/**
+ * @brief Validates the requesting client NAS.  Calculates the
  *     signature based on the clients private key.
  */
 static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
@@ -2039,8 +2057,8 @@ static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 }
 
 
-/*
- *     Check if a set of RADIUS formatted TLVs are OK.
+/**
+ * @brief Check if a set of RADIUS formatted TLVs are OK.
  */
 int rad_tlv_ok(const uint8_t *data, size_t length,
               size_t dv_type, size_t dv_length)
@@ -2126,8 +2144,8 @@ int rad_tlv_ok(const uint8_t *data, size_t length,
 }
 
 
-/*
- *     See if the data pointed to by PTR is a valid RADIUS packet.
+/**
+ * @brief See if the data pointed to by PTR is a valid RADIUS packet.
  *
  *     packet is not 'const * const' because we may update data_len,
  *     if there's more data in the UDP packet than in the RADIUS packet.
@@ -2437,8 +2455,8 @@ int rad_packet_ok(RADIUS_PACKET *packet, int flags)
 }
 
 
-/*
- *     Receive UDP client requests, and fill in
+/**
+ * @brief Receive UDP client requests, and fill in
  *     the basics of a RADIUS_PACKET structure.
  */
 RADIUS_PACKET *rad_recv(int fd, int flags)
@@ -2552,8 +2570,8 @@ RADIUS_PACKET *rad_recv(int fd, int flags)
 }
 
 
-/*
- *     Verify the signature of a packet.
+/**
+ * @brief Verify the signature of a packet.
  */
 int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
               const char *secret)
@@ -2592,8 +2610,13 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                        default:
                                break;
 
-                       case PW_ACCOUNTING_REQUEST:
                        case PW_ACCOUNTING_RESPONSE:
+                               if (original &&
+                                   (original->code == PW_STATUS_SERVER)) {
+                                       goto do_ack;
+                               }
+
+                       case PW_ACCOUNTING_REQUEST:
                        case PW_DISCONNECT_REQUEST:
                        case PW_DISCONNECT_ACK:
                        case PW_DISCONNECT_NAK:
@@ -2603,6 +2626,7 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                                memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
                                break;
 
+                       do_ack:
                        case PW_AUTHENTICATION_ACK:
                        case PW_AUTHENTICATION_REJECT:
                        case PW_ACCESS_CHALLENGE:
@@ -2722,8 +2746,8 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 }
 
 
-/*
- *     Create a "raw" attribute from the attribute contents.
+/**
+ * @brief Create a "raw" attribute from the attribute contents.
  */
 static ssize_t data2vp_raw(UNUSED const RADIUS_PACKET *packet,
                           UNUSED const RADIUS_PACKET *original,
@@ -2776,10 +2800,9 @@ static ssize_t data2vp_tlvs(const RADIUS_PACKET *packet,
                            const uint8_t *start, size_t length,
                            VALUE_PAIR **pvp);
 
-/*
- *     Create any kind of VP from the attribute contents.
- *
- *     Will return -1 on error, or "length".
+/**
+ * @brief Create any kind of VP from the attribute contents.
+ * @return -1 on error, or "length".
  */
 static ssize_t data2vp_any(const RADIUS_PACKET *packet,
                           const RADIUS_PACKET *original,
@@ -2791,6 +2814,7 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
        int data_offset = 0;
        DICT_ATTR *da;
        VALUE_PAIR *vp = NULL;
+       uint8_t buffer[256];
 
        if (length == 0) {
                /*
@@ -2889,28 +2913,29 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
        /*
         *      Copy the data to be decrypted
         */
-       vp->length = length - data_offset;
-       memcpy(&vp->vp_octets[0], data + data_offset, vp->length);
+       vp->length = length - data_offset;      
+       memcpy(buffer, data + data_offset, vp->length);
 
        /*
         *      Decrypt the attribute.
         */
-       if (secret) switch (vp->flags.encrypt) {
+       if (secret && packet) switch (vp->flags.encrypt) {
                /*
                 *  User-Password
                 */
        case FLAG_ENCRYPT_USER_PASSWORD:
                if (original) {
-                       rad_pwdecode(vp->vp_strvalue,
+                       rad_pwdecode(buffer,
                                     vp->length, secret,
                                     original->vector);
                } else {
-                       rad_pwdecode(vp->vp_strvalue,
+                       rad_pwdecode(buffer,
                                     vp->length, secret,
                                     packet->vector);
                }
+               buffer[253] = '\0';
                if (vp->attribute == PW_USER_PASSWORD) {
-                       vp->length = strlen(vp->vp_strvalue);
+                       vp->length = strlen(buffer);
                }
                break;
 
@@ -2921,7 +2946,7 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
                if (!original) goto raw;
 
-               if (rad_tunnel_pwdecode(vp->vp_octets, &vp->length,
+               if (rad_tunnel_pwdecode(buffer, &vp->length,
                                        secret, original->vector) < 0) {
                        goto raw;
                }
@@ -2939,10 +2964,10 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
                        make_secret(my_digest,
                                    original->vector,
                                    secret, data);
-                       memcpy(vp->vp_strvalue, my_digest,
+                       memcpy(buffer, my_digest,
                               AUTH_VECTOR_LEN );
-                       vp->vp_strvalue[AUTH_VECTOR_LEN] = '\0';
-                       vp->length = strlen(vp->vp_strvalue);
+                       buffer[AUTH_VECTOR_LEN] = '\0';
+                       vp->length = strlen(buffer);
                }
                break;
 
@@ -2953,51 +2978,49 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
 
        switch (vp->type) {
        case PW_TYPE_STRING:
+               memcpy(vp->vp_strvalue, buffer, vp->length);
+               vp->vp_strvalue[vp->length] = '\0';
+               break;
+
        case PW_TYPE_OCTETS:
        case PW_TYPE_ABINARY:
-               /* nothing more to do */
+               memcpy(vp->vp_octets, buffer, vp->length);
                break;
 
        case PW_TYPE_BYTE:
                if (vp->length != 1) goto raw;
 
-               vp->vp_integer = vp->vp_octets[0];
+               vp->vp_integer = buffer[0];
                break;
 
 
        case PW_TYPE_SHORT:
                if (vp->length != 2) goto raw;
 
-               vp->vp_integer = (vp->vp_octets[0] << 8) | vp->vp_octets[1];
+               vp->vp_integer = (buffer[0] << 8) | buffer[1];
                break;
 
        case PW_TYPE_INTEGER:
                if (vp->length != 4) goto raw;
 
-               memcpy(&vp->vp_integer, vp->vp_octets, 4);
+               memcpy(&vp->vp_integer, buffer, 4);
                vp->vp_integer = ntohl(vp->vp_integer);
 
                if (vp->flags.has_tag) vp->vp_integer &= 0x00ffffff;
+               break;
 
-               /*
-                *      Try to get named VALUEs
-                */
-               {
-                       DICT_VALUE *dval;
-                       dval = dict_valbyattr(vp->attribute, vp->vendor,
-                                             vp->vp_integer);
-                       if (dval) {
-                               strlcpy(vp->vp_strvalue,
-                                       dval->name,
-                                       sizeof(vp->vp_strvalue));
-                       }
-               }
+       case PW_TYPE_INTEGER64:
+               if (vp->length != 8) goto raw;
+
+               /* vp_integer64 is a union with vp_octets */
+               memcpy(&vp->vp_integer64, buffer, 8);
+               vp->vp_integer64 = ntohll(vp->vp_integer64);
                break;
 
        case PW_TYPE_DATE:
                if (vp->length != 4) goto raw;
 
-               memcpy(&vp->vp_date, vp->vp_octets, 4);
+               memcpy(&vp->vp_date, buffer, 4);
                vp->vp_date = ntohl(vp->vp_date);
                break;
 
@@ -3005,7 +3028,7 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
        case PW_TYPE_IPADDR:
                if (vp->length != 4) goto raw;
 
-               memcpy(&vp->vp_ipaddr, vp->vp_octets, 4);
+               memcpy(&vp->vp_ipaddr, buffer, 4);
                break;
 
                /*
@@ -3013,7 +3036,7 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
                 */
        case PW_TYPE_IFID:
                if (vp->length != 8) goto raw;
-               /* vp->vp_ifid == vp->vp_octets */
+               memcpy(&vp->vp_ifid, buffer, 8);
                break;
 
                /*
@@ -3021,7 +3044,7 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
                 */
        case PW_TYPE_IPV6ADDR:
                if (vp->length != 16) goto raw;
-               /* vp->vp_ipv6addr == vp->vp_octets */
+               memcpy(&vp->vp_ipv6addr, buffer, 16);
                break;
 
                /*
@@ -3035,14 +3058,15 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
                 */
        case PW_TYPE_IPV6PREFIX:
                if (vp->length < 2 || vp->length > 18) goto raw;
-               if (vp->vp_octets[1] > 128) goto raw;
+               if (buffer[1] > 128) goto raw;
 
                /*
                 *      FIXME: double-check that
                 *      (vp->vp_octets[1] >> 3) matches vp->length + 2
                 */
+               memcpy(&vp->vp_ipv6prefix, buffer, vp->length);
                if (vp->length < 18) {
-                       memset(vp->vp_octets + vp->length, 0,
+                       memset(((uint8_t *)vp->vp_ipv6prefix) + vp->length, 0,
                               18 - vp->length);
                }
                break;
@@ -3054,9 +3078,8 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
                 *      Overload vp_integer for ntohl, which takes
                 *      uint32_t, not int32_t
                 */
-               memcpy(&vp->vp_integer, vp->vp_octets, 4);
+               memcpy(&vp->vp_integer, buffer, 4);
                vp->vp_integer = ntohl(vp->vp_integer);
-               memcpy(&vp->vp_signed, &vp->vp_integer, 4);
                break;
 
        case PW_TYPE_TLV:
@@ -3067,12 +3090,12 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
        case PW_TYPE_COMBO_IP:
                if (vp->length == 4) {
                        vp->type = PW_TYPE_IPADDR;
-                       memcpy(&vp->vp_ipaddr, vp->vp_octets, 4);
+                       memcpy(&vp->vp_ipaddr, buffer, 4);
                        break;
 
                } else if (vp->length == 16) {
                        vp->type = PW_TYPE_IPV6ADDR;
-                       /* vp->vp_ipv6addr == vp->vp_octets */
+                       memcpy(&vp->vp_ipv6addr, buffer, 16);
                        break;
 
                }
@@ -3088,8 +3111,8 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Convert a top-level VSA to a VP.
+/**
+ * @brief Convert a top-level VSA to a VP.
  */
 static ssize_t attr2vp_vsa(const RADIUS_PACKET *packet,
                           const RADIUS_PACKET *original,
@@ -3175,8 +3198,8 @@ static ssize_t attr2vp_vsa(const RADIUS_PACKET *packet,
        return dv_type + dv_length + attrlen;
 }
 
-/*
- *     Convert one or more TLVs to VALUE_PAIRs.  This function can
+/**
+ * @brief Convert one or more TLVs to VALUE_PAIRs.  This function can
  *     be called recursively...
  */
 static ssize_t data2vp_tlvs(const RADIUS_PACKET *packet,
@@ -3319,8 +3342,9 @@ static ssize_t data2vp_tlvs(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Group "continued" attributes together, and create VPs from them.
+/**
+ * @brief Group "continued" attributes together, and create VPs from them.
+ *
  *     The caller ensures that the RADIUS packet is OK, and that the
  *     continuations have all been checked.
  */
@@ -3379,8 +3403,8 @@ static ssize_t data2vp_continued(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Create a "raw" VALUE_PAIR from a RADIUS attribute.
+/**
+ * @brief Create a "raw" VALUE_PAIR from a RADIUS attribute.
  */
 ssize_t rad_attr2vp_raw(const RADIUS_PACKET *packet,
                        const RADIUS_PACKET *original,
@@ -3403,10 +3427,10 @@ ssize_t rad_attr2vp_raw(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Get the length of the data portion of all of the contiguous
+/**
+ * @brief Get the length of the data portion of all of the contiguous
  *     continued attributes.
- *
+ * @return
  *     0 for "no continuation"
  *     -1 on malformed packets (continuation followed by non-wimax, etc.)
  */
@@ -3439,11 +3463,12 @@ static ssize_t wimax_attrlen(uint32_t vendor,
 }
 
 
-/*
- *     Get the length of the data portion of all of the contiguous
+/**
+ * @brief Get the length of the data portion of all of the contiguous
  *     continued attributes.
  *
- *     0 for "no continuation"
+ * @return
+ *     0 for "no continuation"
  *     -1 on malformed packets (continuation followed by non-wimax, etc.)
  */
 static ssize_t extended_attrlen(const uint8_t *start, const uint8_t *end)
@@ -3471,8 +3496,8 @@ static ssize_t extended_attrlen(const uint8_t *start, const uint8_t *end)
 }
 
 
-/*
- *     Create WiMAX VALUE_PAIRs from a RADIUS attribute.
+/**
+ * @brief Create WiMAX VALUE_PAIRs from a RADIUS attribute.
  */
 ssize_t rad_attr2vp_wimax(const RADIUS_PACKET *packet,
                          const RADIUS_PACKET *original,
@@ -3552,8 +3577,8 @@ ssize_t rad_attr2vp_wimax(const RADIUS_PACKET *packet,
        return data[1];
 }
 
-/*
- *     Create Vendor-Specifc VALUE_PAIRs from a RADIUS attribute.
+/**
+ * @brief Create Vendor-Specifc VALUE_PAIRs from a RADIUS attribute.
  */
 ssize_t rad_attr2vp_vsa(const RADIUS_PACKET *packet,
                        const RADIUS_PACKET *original,
@@ -3632,8 +3657,8 @@ ssize_t rad_attr2vp_vsa(const RADIUS_PACKET *packet,
        return data[1];
 }
 
-/*
- *     Create an "extended" VALUE_PAIR from a RADIUS attribute.
+/**
+ * @brief Create an "extended" VALUE_PAIR from a RADIUS attribute.
  */
 ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
                             const RADIUS_PACKET *original,
@@ -3766,8 +3791,8 @@ ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Create a "standard" RFC VALUE_PAIR from the given data.
+/**
+ * @brief Create a "standard" RFC VALUE_PAIR from the given data.
  */
 ssize_t rad_attr2vp_rfc(const RADIUS_PACKET *packet,
                        const RADIUS_PACKET *original,
@@ -3788,8 +3813,8 @@ ssize_t rad_attr2vp_rfc(const RADIUS_PACKET *packet,
        return data[1];
 }      
 
-/*
- *     Create a "normal" VALUE_PAIR from the given data.
+/**
+ * @brief Create a "normal" VALUE_PAIR from the given data.
  */
 ssize_t rad_attr2vp(const RADIUS_PACKET *packet,
                    const RADIUS_PACKET *original,
@@ -3822,11 +3847,9 @@ ssize_t rad_attr2vp(const RADIUS_PACKET *packet,
 }
 
 
-/*
- *     Calculate/check digest, and decode radius attributes.
- *     Returns:
- *     -1 on decoding error
- *     0 on success
+/**
+ * @brief Calculate/check digest, and decode radius attributes.
+ * @return -1 on decoding error, 0 on success
  */
 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
               const char *secret)
@@ -3915,8 +3938,8 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 }
 
 
-/*
- *     Encode password.
+/**
+ * @brief Encode password.
  *
  *     We assume that the passwd buffer passed is big enough.
  *     RFC2138 says the password is max 128 chars, so the size
@@ -3988,8 +4011,8 @@ int rad_pwencode(char *passwd, size_t *pwlen, const char *secret,
        return 0;
 }
 
-/*
- *     Decode password.
+/**
+ * @brief Decode password.
  */
 int rad_pwdecode(char *passwd, size_t pwlen, const char *secret,
                 const uint8_t *vector)
@@ -4054,8 +4077,8 @@ int rad_pwdecode(char *passwd, size_t pwlen, const char *secret,
 }
 
 
-/*
- *     Encode Tunnel-Password attributes when sending them out on the wire.
+/**
+ * @brief Encode Tunnel-Password attributes when sending them out on the wire.
  *
  *     int *pwlen is updated to the new length of the encrypted
  *     password - a multiple of 16 bytes.
@@ -4139,8 +4162,8 @@ int rad_tunnel_pwencode(char *passwd, size_t *pwlen, const char *secret,
        return 0;
 }
 
-/*
- *     Decode Tunnel-Password encrypted attributes.
+/**
+ * @brief Decode Tunnel-Password encrypted attributes.
  *
  *      Defined in RFC-2868, this uses a two char SALT along with the
  *      initial intermediate value, to differentiate it from the
@@ -4245,10 +4268,10 @@ int rad_tunnel_pwdecode(uint8_t *passwd, size_t *pwlen, const char *secret,
        return reallen;
 }
 
-/*
- *     Encode a CHAP password
+/**
+ * @brief Encode a CHAP password
  *
- *     FIXME: might not work with Ascend because
+ *     @bug FIXME: might not work with Ascend because
  *     we use vp->length, and Ascend gear likes
  *     to send an extra '\0' in the string!
  */
@@ -4303,8 +4326,8 @@ int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id,
 }
 
 
-/*
- *     Seed the random number generator.
+/**
+ * @brief Seed the random number generator.
  *
  *     May be called any number of times.
  */
@@ -4357,8 +4380,8 @@ void fr_rand_seed(const void *data, size_t size)
 }
 
 
-/*
- *     Return a 32-bit random number.
+/**
+ * @brief Return a 32-bit random number.
  */
 uint32_t fr_rand(void)
 {
@@ -4381,8 +4404,8 @@ uint32_t fr_rand(void)
 }
 
 
-/*
- *     Allocate a new RADIUS_PACKET
+/**
+ * @brief Allocate a new RADIUS_PACKET
  */
 RADIUS_PACKET *rad_alloc(int newvector)
 {
@@ -4444,8 +4467,8 @@ RADIUS_PACKET *rad_alloc_reply(RADIUS_PACKET *packet)
 }
 
 
-/*
- *     Free a RADIUS_PACKET
+/**
+ * @brief Free a RADIUS_PACKET
  */
 void rad_free(RADIUS_PACKET **radius_packet_ptr)
 {