]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add fr_value_box_from_network_dbuff() (#3738)
authorJames Jones <jejones3141@gmail.com>
Tue, 5 Jan 2021 17:01:17 +0000 (11:01 -0600)
committerGitHub <noreply@github.com>
Tue, 5 Jan 2021 17:01:17 +0000 (17:01 +0000)
With this change, fr_value_box_from_network() is made a wrapper
around fr_value_box_from_network_dbuff()

src/lib/util/value.c
src/lib/util/value.h

index e7ad5f3062f3af10bfd5b81b5bd8091c22c54902..421a03758efc3b54b9e31efa57bfbd8710c3495d 100644 (file)
@@ -1457,9 +1457,16 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
                                  uint8_t const *src, size_t len,
                                  bool tainted)
 {
-       uint8_t const *p = src;
-       uint8_t const *end = p + len;
-       size_t  min, max;
+       return fr_value_box_from_network_dbuff(ctx, dst, type, enumv, &FR_DBUFF_TMP(src, len), len, tainted);
+}
+
+ssize_t fr_value_box_from_network_dbuff(TALLOC_CTX *ctx,
+                                       fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv,
+                                       fr_dbuff_t *dbuff, size_t len,
+                                       bool tainted)
+{
+       size_t          min, max;
+       fr_dbuff_t      work_dbuff = FR_DBUFF_NO_ADVANCE(dbuff);
 
        min = fr_value_box_network_sizes[type][0];
        max = fr_value_box_network_sizes[type][1];
@@ -1481,14 +1488,16 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
 
        switch (type) {
        case FR_TYPE_STRING:
-               if (fr_value_box_bstrndup(ctx, dst, enumv, (char const *)src, len, tainted) < 0) {
+               if (fr_value_box_bstrndup_dbuff(ctx, dst, enumv, &work_dbuff, len, tainted) < 0) {
                        return FR_VALUE_BOX_NET_OOM;
                }
-               return len;
+               return fr_dbuff_set(dbuff, &work_dbuff);
 
        case FR_TYPE_OCTETS:
-               if (fr_value_box_memdup(ctx, dst, enumv, src, len, tainted) < 0) return FR_VALUE_BOX_NET_OOM;
-               return len;
+               if (fr_value_box_memdup_dbuff(ctx, dst, enumv, &work_dbuff, len, tainted) < 0) {
+                       return FR_VALUE_BOX_NET_OOM;
+               }
+               return fr_dbuff_set(dbuff, &work_dbuff);
        default:
                break;
        }
@@ -1506,65 +1515,101 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
                        .af = AF_INET,
                        .prefix = 32,
                };
-               memcpy(&dst->vb_ip.addr.v4, p, (end - p));
+               FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *)&dst->vb_ip.addr.v4, &work_dbuff, len);
                break;
 
        case FR_TYPE_IPV4_PREFIX:
                dst->vb_ip = (fr_ipaddr_t){
                        .af = AF_INET,
-                       .prefix = *p++,
                };
-               memcpy(&dst->vb_ip.addr.v4, p, (end - p));
+               FR_DBUFF_OUT_RETURN(&dst->vb_ip.prefix, &work_dbuff);
+               FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *)&dst->vb_ip.addr.v4, &work_dbuff, len - 1);
                break;
 
        case FR_TYPE_IPV6_ADDR:
                dst->vb_ip = (fr_ipaddr_t){
                        .af = AF_INET6,
-                       .scope_id = len == max ? *p++ : 0, /* optional */
+                       .scope_id = 0,
                        .prefix = 128
                };
-               memcpy(&dst->vb_ip.addr.v6, p, (end - p));
+               if (len == max) {
+                       uint8_t scope_id = 0;
+
+                       FR_DBUFF_OUT_RETURN(&scope_id, &work_dbuff);
+                       dst->vb_ip.scope_id = scope_id;
+                       len--;
+               }
+               FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *)&dst->vb_ip.addr.v6, &work_dbuff, len);
                break;
 
        case FR_TYPE_IPV6_PREFIX:
                dst->vb_ip = (fr_ipaddr_t){
                        .af = AF_INET6,
-                       .scope_id = len == max ? *p++ : 0,
+                       .scope_id = 0,
                };
+               if (len == max) {
+                       uint8_t scope_id = 0;
 
-               /*
-                *      Can't increment p multiple times
-                *      in an initialiser because the operations
-                *      aren't explicitly ordered.
-                */
-               dst->vb_ip.prefix = *p++;
-               memcpy(&dst->vb_ip.addr.v6, p, (end - p));
+                       FR_DBUFF_OUT_RETURN(&scope_id, &work_dbuff);
+                       dst->vb_ip.scope_id = scope_id;
+                       len--;
+               }
+               FR_DBUFF_OUT_RETURN(&dst->vb_ip.prefix, &work_dbuff);
+               FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *)&dst->vb_ip.addr.v6, &work_dbuff, len - 1);
                break;
 
        case FR_TYPE_BOOL:
-               dst->datum.boolean = src[0] > 0 ? true : false;
+               {
+                       uint8_t val = 0;
+
+                       FR_DBUFF_OUT_RETURN(&val, &work_dbuff);
+                       dst->datum.boolean = (val != 0);
+               }
                break;
 
        case FR_TYPE_IFID:
        case FR_TYPE_ETHERNET:
-       case FR_TYPE_UINT8:
+               FR_DBUFF_OUT_MEMCPY_RETURN(((uint8_t *)&dst->datum) + fr_value_box_offsets[type], &work_dbuff, len);
+               break;
+
        case FR_TYPE_INT8:
-               memcpy(((uint8_t *)&dst->datum) + fr_value_box_offsets[type], src, len);
+               FR_DBUFF_OUT_RETURN(&dst->vb_int8, &work_dbuff);
+               break;
+
+       case FR_TYPE_UINT8:
+               FR_DBUFF_OUT_RETURN(&dst->vb_uint8, &work_dbuff);
                break;
 
-       /*
-        *      Needs a bytesex operation
-        */
-       case FR_TYPE_UINT16:
-       case FR_TYPE_UINT32:
-       case FR_TYPE_UINT64:
        case FR_TYPE_INT16:
+               FR_DBUFF_OUT_RETURN(&dst->vb_int16, &work_dbuff);
+               break;
+
+       case FR_TYPE_UINT16:
+               FR_DBUFF_OUT_RETURN(&dst->vb_uint16, &work_dbuff);
+               break;
+
        case FR_TYPE_INT32:
+               FR_DBUFF_OUT_RETURN(&dst->vb_int32, &work_dbuff);
+               break;
+
+       case FR_TYPE_UINT32:
+               FR_DBUFF_OUT_RETURN(&dst->vb_uint32, &work_dbuff);
+               break;
+
        case FR_TYPE_INT64:
+               FR_DBUFF_OUT_RETURN(&dst->vb_int64, &work_dbuff);
+               break;
+
+       case FR_TYPE_UINT64:
+               FR_DBUFF_OUT_RETURN(&dst->vb_uint64, &work_dbuff);
+               break;
+
        case FR_TYPE_FLOAT32:
+               FR_DBUFF_OUT_RETURN(&dst->vb_float32, &work_dbuff);
+               break;
+
        case FR_TYPE_FLOAT64:
-               memcpy(((uint8_t *)&dst->datum) + fr_value_box_offsets[type], src, len);
-               fr_value_box_hton(dst, dst);    /* Operate in-place */
+               FR_DBUFF_OUT_RETURN(&dst->vb_float64, &work_dbuff);
                break;
 
        /*
@@ -1576,7 +1621,7 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
         */
        case FR_TYPE_DATE:
        {
-               size_t i, length = 4;
+               size_t length = 4;
                fr_time_res_t precision = FR_TIME_RES_SEC;
                uint64_t date;
 
@@ -1589,21 +1634,11 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
                 *      Input data doesn't match what we were told we
                 *      need.
                 */
-               if (len != length) return (len > length) ? -(length) : -(len);
+               if (len > length) return -(length);
 
-               /*
-                *      Just loop over the input data until we reach
-                *      the end.  Shifting it every time.
-                */
-               date = 0;
                dst->enumv = enumv;
 
-               i = 0;
-               do {
-                       date <<= 8;
-                       date |= *(p++);
-                       i++;
-               } while (i < length);
+               FR_DBUFF_OUT_UINT64V_RETURN(&date, &work_dbuff, length);
 
                switch (precision) {
                default:
@@ -1629,7 +1664,7 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
 
        case FR_TYPE_TIME_DELTA:
        {
-               size_t i, length = 4;
+               size_t length = 4;
                fr_time_res_t precision = FR_TIME_RES_SEC;
                uint64_t date;
 
@@ -1642,21 +1677,11 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
                 *      Input data doesn't match what we were told we
                 *      need.
                 */
-               if (len != length) return (len > length) ? -(length) : -(len);
+               if (len > length) return -(length);
 
-               /*
-                *      Just loop over the input data until we reach
-                *      the end.  Shifting it every time.
-                */
-               date = 0;
                dst->enumv = enumv;
 
-               i = 0;
-               do {
-                       date <<= 8;
-                       date |= *(p++);
-                       i++;
-               } while (i < length);
+               FR_DBUFF_OUT_UINT64V_RETURN(&date, &work_dbuff, length);
 
                switch (precision) {
                default:
@@ -1691,7 +1716,7 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx,
                break;
        }
 
-       return len;
+       return fr_dbuff_set(dbuff, &work_dbuff);
 }
 
 /** Convert octets to a fixed size value box value
@@ -3521,6 +3546,27 @@ int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t c
        return 0;
 }
 
+int fr_value_box_bstrndup_dbuff(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
+                               fr_dbuff_t *dbuff, size_t len, bool tainted)
+{
+       char    *str;
+
+       str = talloc_array(ctx, char, len + 1);
+       if (!str) {
+               fr_strerror_printf("Failed allocating string buffer");
+               return -1;
+       }
+
+       if (fr_dbuff_out_memcpy((uint8_t *)str, dbuff, len) < 0) return -1;
+       str[len] = '\0';
+
+       fr_value_box_init(dst, FR_TYPE_STRING, enumv, tainted);
+       dst->vb_strvalue = str;
+       dst->vb_length = len;
+
+       return 0;
+}
+
 /** Copy a nul terminated talloced buffer to a #fr_value_box_t
  *
  * Copy a talloced nul terminated buffer, setting fields in the dst value box appropriately.
@@ -3800,6 +3846,26 @@ int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t con
        return 0;
 }
 
+int fr_value_box_memdup_dbuff(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
+                             fr_dbuff_t *dbuff, size_t len, bool tainted)
+{
+       uint8_t *bin;
+
+       bin = talloc_size(ctx, len);
+       if (!bin) {
+               fr_strerror_printf("Failed allocating octets buffer");
+               return -1;
+       }
+       if (fr_dbuff_out_memcpy(bin, dbuff, len) < (ssize_t) len) return -1;
+       talloc_set_type(bin, uint8_t);
+
+       fr_value_box_init(dst, FR_TYPE_OCTETS, enumv, tainted);
+       dst->vb_octets = bin;
+       dst->vb_length = len;
+
+       return 0;
+}
+
 /** Copy a talloced buffer to a fr_value_box_t
  *
  * Copy a buffer containing binary data, setting fields in the dst value box appropriately.
index 8b22249df721ca3d3bd43dc8891574da8a13a25b..e8ba4c5a4a5f1714fb13bf361ac119c8e7337985 100644 (file)
@@ -601,6 +601,9 @@ ssize_t             fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value)
 ssize_t                fr_value_box_from_network(TALLOC_CTX *ctx,
                                          fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv,
                                          uint8_t const *src, size_t len, bool tainted);
+ssize_t                fr_value_box_from_network_dbuff(TALLOC_CTX *ctx,
+                                               fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv,
+                                               fr_dbuff_t *dbuff, size_t len, bool tainted);
 
 int            fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst,
                                  fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
@@ -663,6 +666,9 @@ int         fr_value_box_bstr_realloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst,
 int            fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
                                      char const *src, size_t len, bool tainted);
 
+int            fr_value_box_bstrndup_dbuff(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
+                                           fr_dbuff_t *dbuff, size_t len, bool tainted);
+
 int            fr_value_box_bstrdup_buffer(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
                                           char const *src, bool tainted);
 
@@ -689,6 +695,9 @@ int         fr_value_box_mem_realloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *ds
 int            fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
                                    uint8_t const *src, size_t len, bool tainted);
 
+int            fr_value_box_memdup_dbuff(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
+                                         fr_dbuff_t *dbuff, size_t len, bool tainted);
+
 int            fr_value_box_memdup_buffer(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv,
                                           uint8_t const *src, bool tainted);