]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
move "check packet" to fr_vqp_ok()
authorAlan T. DeKok <aland@freeradius.org>
Wed, 28 Jun 2017 19:42:57 +0000 (15:42 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 29 Jun 2017 12:34:36 +0000 (08:34 -0400)
src/modules/proto_vmps/vqp.c
src/modules/proto_vmps/vqp.h

index 31e42f29962eaffbd756fcce4dc479907f766d99..72ed6a1b0f1ec82b289ae1c15328e9e0ce45ea0d 100644 (file)
@@ -122,12 +122,68 @@ static ssize_t vqp_recv_header(int sockfd)
        return (12 * (4 + 4 + MAX_VMPS_LEN));
 }
 
+bool fr_vqp_ok(uint8_t const *packet, size_t *packet_len)
+{
+       uint8_t const   *ptr;
+       ssize_t         data_len;
+       int             attrlen;
+
+       if (*packet_len == VQP_HDR_LEN) return true;
+
+       /*
+        *      Skip the header.
+        */
+       ptr = packet + VQP_HDR_LEN;
+       data_len = *packet_len - VQP_HDR_LEN;
+
+       while (data_len > 0) {
+               if (data_len < 7) {
+                       fr_strerror_printf("Packet contains malformed attribute");
+                       false;
+               }
+
+               /*
+                *      Attributes are 4 bytes
+                *      0x00000c01 ... 0x00000c08
+                */
+               if ((ptr[0] != 0) || (ptr[1] != 0) ||
+                   (ptr[2] != 0x0c) || (ptr[3] < 1) || (ptr[3] > 8)) {
+                       fr_strerror_printf("Packet contains invalid attribute");
+                       return false;
+               }
+
+               /*
+                *      Length is 2 bytes
+                *
+                *      We support short lengths, as there's no reason
+                *      for bigger lengths to exist... admins won't be
+                *      typing in a 32K vlan name.
+                *
+                *      It's OK for ethernet frames to be longer.
+                */
+               if ((ptr[3] != 5) &&
+                   ((ptr[4] != 0) || (ptr[5] > MAX_VMPS_LEN))) {
+                       fr_strerror_printf("Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);
+                       return false;
+               }
+
+               attrlen = (ptr[4] << 8) | ptr[5];
+               ptr += 6 + attrlen;
+               data_len -= (6 + attrlen);
+       }
+
+       /*
+        *      UDP reads may return too much data, so we truncate it.
+        */
+       *packet_len = ptr - packet;
+
+       return true;
+}
+
 RADIUS_PACKET *vqp_recv(TALLOC_CTX *ctx, int sockfd)
 {
-       uint8_t         *ptr;
        ssize_t         data_len;
        uint32_t        id;
-       int             attrlen;
        RADIUS_PACKET   *packet;
 
        data_len = vqp_recv_header(sockfd);
@@ -176,53 +232,9 @@ RADIUS_PACKET *vqp_recv(TALLOC_CTX *ctx, int sockfd)
        memcpy(&id, packet->data + 4, 4);
        packet->id = ntohl(id);
 
-       if (packet->data_len == VQP_HDR_LEN) {
-               return packet;
-       }
-
-       /*
-        *      Skip the header.
-        */
-       ptr = packet->data + VQP_HDR_LEN;
-       data_len = packet->data_len - VQP_HDR_LEN;
-
-       while (data_len > 0) {
-               if (data_len < 7) {
-                       fr_strerror_printf("Packet contains malformed attribute");
-                       fr_radius_free(&packet);
-                       return NULL;
-               }
-
-               /*
-                *      Attributes are 4 bytes
-                *      0x00000c01 ... 0x00000c08
-                */
-               if ((ptr[0] != 0) || (ptr[1] != 0) ||
-                   (ptr[2] != 0x0c) || (ptr[3] < 1) || (ptr[3] > 8)) {
-                       fr_strerror_printf("Packet contains invalid attribute");
-                       fr_radius_free(&packet);
-                       return NULL;
-               }
-
-               /*
-                *      Length is 2 bytes
-                *
-                *      We support short lengths, as there's no reason
-                *      for bigger lengths to exist... admins won't be
-                *      typing in a 32K vlan name.
-                *
-                *      It's OK for ethernet frames to be longer.
-                */
-               if ((ptr[3] != 5) &&
-                   ((ptr[4] != 0) || (ptr[5] > MAX_VMPS_LEN))) {
-                       fr_strerror_printf("Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);
-                       fr_radius_free(&packet);
-                       return NULL;
-               }
-
-               attrlen = (ptr[4] << 8) | ptr[5];
-               ptr += 6 + attrlen;
-               data_len -= (6 + attrlen);
+       if (!fr_vqp_ok(packet->data, &packet->data_len)) {
+               fr_radius_free(&packet);
+               return NULL;
        }
 
        return packet;
index 84bd4321ec1b765e8b87110a8a38702f01c0b545..d1832be9bbbbb5dd412018f9d2d8f8496673b458 100644 (file)
@@ -33,6 +33,7 @@ extern "C" {
 #endif
 
 RADIUS_PACKET *vqp_recv(TALLOC_CTX *ctx, int sockfd);
+bool fr_vqp_ok(uint8_t const *packet, size_t *packet_len);
 int vqp_send(RADIUS_PACKET *packet);
 int vqp_decode(RADIUS_PACKET *packet);
 int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original);