From: Arran Cudbard-Bell Date: Wed, 24 May 2017 20:23:53 +0000 (-0400) Subject: Use common protocol encoder for RADIUS X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98711f11c04ee7cdcd287fd45d7352913600fd6d;p=thirdparty%2Ffreeradius-server.git Use common protocol encoder for RADIUS --- diff --git a/src/lib/util/value.c b/src/lib/util/value.c index a793ca1bf6f..8461209f1f8 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -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: diff --git a/src/main/xlat_func.c b/src/main/xlat_func.c index ad026ffe253..84c589887d0 100644 --- a/src/main/xlat_func.c +++ b/src/main/xlat_func.c @@ -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'); } diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index e5db891100f..f95110bdc7d 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -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; diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index ae07fc2e4b9..523409b6377 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -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); /*