]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Use common protocol encoder for RADIUS
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 24 May 2017 20:23:53 +0000 (16:23 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 24 May 2017 20:23:58 +0000 (16:23 -0400)
src/lib/util/value.c
src/main/xlat_func.c
src/protocols/radius/encode.c
src/protocols/radius/radius.h

index a793ca1bf6f8abbafcd014889576aeac0e253591..8461209f1f8df07cc4c2a3a8ef095cc82b2a38ba 100644 (file)
@@ -1059,6 +1059,9 @@ ssize_t fr_value_box_to_network(size_t *need, uint8_t *dst, size_t dst_len, fr_v
        }
 
        switch (value->type) {
+       case FR_TYPE_IPV4_ADDR:
+               memcpy(dst, (uint8_t const *)&value->vb_ip.addr.v4.s_addr, sizeof(value->vb_ip.addr.v4.s_addr));
+               break;
        /*
         *      Needs special mangling
         */
@@ -1086,7 +1089,7 @@ ssize_t fr_value_box_to_network(size_t *need, uint8_t *dst, size_t dst_len, fr_v
        /*
         *      Already in network byte-order
         */
-       case FR_TYPE_IPV4_ADDR:
+
        case FR_TYPE_IFID:
        case FR_TYPE_ETHERNET:
        case FR_TYPE_UINT8:
index ad026ffe2530757854ac1968ef8c61d2e45c1638..84c589887d00a2714ade4c0c10269e053a83ff80 100644 (file)
@@ -529,9 +529,9 @@ static ssize_t xlat_string(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
                           UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
                           REQUEST *request, char const *fmt)
 {
-       ssize_t ret;
-       VALUE_PAIR *vp;
-       uint8_t buffer[64];
+       ssize_t         ret;
+       VALUE_PAIR      *vp;
+       uint8_t         buffer[64];
 
        while (isspace((int) *fmt)) fmt++;
 
@@ -560,10 +560,8 @@ static ssize_t xlat_string(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
                break;
        }
 
-       ret = fr_radius_encode_value_hton(buffer, sizeof(buffer), vp);
-       if (ret < 0) {
-               return ret;
-       }
+       ret = fr_value_box_to_network(NULL, buffer, sizeof(buffer), &vp->data);
+       if (ret < 0) return ret;
 
        return fr_snprint(*out, outlen, (char const *) buffer, ret, '\0');
 }
index e5db891100f272f5c6e45d91b3799f29a69baf96..f95110bdc7d5db9daae886fea9fbf6aa8d05c871 100644 (file)
@@ -409,94 +409,6 @@ static void encode_tunnel_password(uint8_t *out, ssize_t *outlen,
        }
 }
 
-
-/** Converts vp_data to network byte order
- *
- *  ONLY for simple data types.  Complex data types are not allowed.
- *
- * @param out where to write the pointer to the value.
- * @param outlen length of the output buffer
- * @param vp to get the value from.
- * @return
- *     - The length of the value.
- *     - -1 on failure.
- */
-ssize_t fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR const *vp)
-{
-       size_t          len;
-
-       VERIFY_VP(vp);
-
-       len = fr_radius_attr_len(vp);
-
-       /*
-        *      Mash outlen down to size.
-        */
-       if (outlen > len) outlen = len;
-
-       switch (vp->vp_type) {
-       case FR_TYPE_STRING:
-       case FR_TYPE_OCTETS:
-               memcpy(out, vp->vp_ptr, outlen);
-               return outlen;
-
-       /*
-        *      All of these values are at the same location.
-        */
-       case FR_TYPE_IFID:
-       case FR_TYPE_IPV4_ADDR:
-       case FR_TYPE_IPV6_ADDR:
-       case FR_TYPE_IPV6_PREFIX:
-       case FR_TYPE_IPV4_PREFIX:
-       case FR_TYPE_ABINARY:
-       case FR_TYPE_ETHERNET:
-               memcpy(out, &vp->data.datum, outlen);
-               break;
-
-       case FR_TYPE_BOOL:
-               out[0] = vp->vp_bool ? 1 : 0;
-               break;
-
-       case FR_TYPE_UINT8:
-               out[0] = vp->vp_uint8;
-               break;
-
-       case FR_TYPE_INT8:
-               out[0] = vp->vp_int8;
-               break;
-
-       case FR_TYPE_UINT16:
-       case FR_TYPE_UINT32:
-       case FR_TYPE_UINT64:
-       case FR_TYPE_INT16:
-       case FR_TYPE_INT32:
-       case FR_TYPE_INT64:
-       case FR_TYPE_DATE:
-       {
-               fr_value_box_t network;
-
-               fr_value_box_hton(&network, &vp->data);
-               memcpy(out, (uint8_t *)&network.datum, len);
-       }
-               break;
-
-       case FR_TYPE_TIMEVAL:
-       case FR_TYPE_FLOAT32:
-       case FR_TYPE_FLOAT64:
-       case FR_TYPE_DATE_MILLISECONDS:
-       case FR_TYPE_DATE_MICROSECONDS:
-       case FR_TYPE_DATE_NANOSECONDS:
-       case FR_TYPE_SIZE:
-       case FR_TYPE_NON_VALUES:
-               fr_strerror_printf("Cannot encode data for VALUE_PAIR type %i", vp->vp_type);
-               return -1;
-
-       /* Don't add default */
-       }
-
-       return outlen;
-}
-
 static ssize_t encode_struct(uint8_t *out, size_t outlen,
                              fr_dict_attr_t const **tlv_stack, unsigned int depth,
                              vp_cursor_t *cursor, void *encoder_ctx)
@@ -754,21 +666,45 @@ static ssize_t encode_value(uint8_t *out, size_t outlen,
 
        case FR_TYPE_STRING:
                data = vp->vp_ptr;
-               if (!data) {
-                       fr_strerror_printf("ERROR: Cannot encode NULL data");
-                       return -1;
-               }
                break;
 
-               /*
-                *      Simple data types use the common encoder.
-                */
-       case FR_TYPE_IFID:
-       case FR_TYPE_IPV4_ADDR:
+       case FR_TYPE_ABINARY:
+               data = vp->vp_filter;
+               break;
+
+       /*
+        *      Common encoder might add scope byte
+        */
        case FR_TYPE_IPV6_ADDR:
+               memcpy(buffer, vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
+               data = buffer;
+               break;
+
+       /*
+        *      Common encoder doesn't add reserved byte
+        */
        case FR_TYPE_IPV6_PREFIX:
+               buffer[0] = 0;
+               buffer[1] = vp->vp_ip.prefix;
+               len = vp->vp_ip.prefix >> 3;            /* Convert bits to whole bytes */
+               memcpy(buffer, vp->vp_ipv6addr, len);   /* Only copy the minimum number of address bytes required */
+               len += 2;                               /* Reserved and prefix bytes */
+               break;
+
+       /*
+        *      Common encoder doesn't add reserved byte
+        */
        case FR_TYPE_IPV4_PREFIX:
-       case FR_TYPE_ABINARY:
+               buffer[0] = 0;
+               buffer[1] = vp->vp_ip.prefix;
+               memcpy(buffer, &vp->vp_ipv4addr, sizeof(vp->vp_ipv4addr));
+               break;
+
+       /*
+        *      Simple data types use the common encoder.
+        */
+       case FR_TYPE_IPV4_ADDR:
+       case FR_TYPE_IFID:
        case FR_TYPE_ETHERNET:  /* just in case */
        case FR_TYPE_BOOL:
        case FR_TYPE_UINT8:
@@ -780,7 +716,7 @@ static ssize_t encode_value(uint8_t *out, size_t outlen,
        case FR_TYPE_INT32:
        case FR_TYPE_INT64:
        case FR_TYPE_DATE:
-               len = fr_radius_encode_value_hton(buffer, sizeof(buffer), vp);
+               len = fr_value_box_to_network(NULL, buffer, sizeof(buffer), &vp->data);
                if (len < 0) return -1;
                data = buffer;
                break;
index ae07fc2e4b94b3d97ca1fb8a499d49cd80090df1..523409b6377baffc4ce491792b6f9b493e224afb 100644 (file)
@@ -129,8 +129,6 @@ int         fr_radius_encode_tunnel_password(char *encpw, size_t *len, char const *secr
 
 int            fr_radius_encode_chap_password(uint8_t *output, RADIUS_PACKET *packet, int id, VALUE_PAIR *password);
 
-ssize_t                fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR const *vp);
-
 ssize_t                fr_radius_encode_pair(uint8_t *out, size_t outlen, vp_cursor_t *cursor, void *encoder_ctx);
 
 /*