25RCSID(
"$Id: 0d7ae46287627fc3fce105bcd71bc836ce7c8a6c $")
27#include <freeradius-devel/util/md5.h>
28#include <freeradius-devel/util/struct.h>
29#include <freeradius-devel/io/test_point.h>
30#include <freeradius-devel/protocol/radius/freeradius.internal.h>
37#include <freeradius-devel/protocol/radius/rfc2869.h>
38#include <freeradius-devel/protocol/radius/rfc5904.h>
39#include <freeradius-devel/protocol/radius/rfc6929.h>
40#include <freeradius-devel/protocol/radius/rfc7268.h>
42static void memcpy_bounded(
void * restrict dst,
const void * restrict src,
size_t n,
const void * restrict end)
57 len = (
uint8_t const * restrict) end - (
uint8_t const * restrict) src;
60 memcpy(dst, src, len);
74 size_t i,
n, encrypted_len, embedded_len;
76 encrypted_len = *pwlen;
81 if (encrypted_len < 2) {
96 if (encrypted_len <= 3) {
127 block_len = *pwlen -
n - 2;
141 embedded_len = passwd[2] ^ digest[0];
142 if (embedded_len > encrypted_len) {
144 "(shared secret is probably incorrect!)");
161 for (i = base; i < block_len; i++) {
162 passwd[
n + i - 1] = passwd[
n + i + 2] ^ digest[i];
173 if (passwd[i] != 0) {
175 "(shared secret is probably incorrect!)");
181 *pwlen = embedded_len;
183 passwd[embedded_len] =
'\0';
207 if (pwlen == 0)
goto done;
243 passwd[pwlen] =
'\0';
244 return strlen(passwd);
254 FR_PROTO_TRACE(
"Checking TLV %u/%u", (
unsigned int) dv_type, (
unsigned int) dv_length);
258 if ((dv_length > 2) || (dv_type == 0) || (dv_type > 4)) {
266 if ((
data + dv_type + dv_length) > end) {
273 if ((
data[0] == 0) && (
data[1] == 0) &&
307 if (
data[dv_type] != 0) {
313 attrlen =
data[dv_type + dv_length - 1];
322 if (attrlen < (dv_type + dv_length)) {
327 if (attrlen > length) {
361 if ((ptr + 2) == end)
break;
362 if ((ptr + 2) > end)
return -1;
363 if (ptr[1] <= 2)
return -1;
364 if ((ptr + ptr[1]) > end)
return -1;
370 if (ptr == end)
break;
375 if (ptr[0] != attr)
break;
387 if (!total)
return 2;
411#define decode_value fr_radius_decode_pair_value
418 uint8_t const *
data,
size_t const data_len,
void *decode_ctx)
426#ifdef STATIC_ANALYZER
435 if ((data_len < 2) || (
data[1] < 2)) {
443 if (
data[1] == 2)
return 2;
447 if (len > data_len) {
449 "Length must be less than %zu bytes, got %zu bytes",
450 __FUNCTION__, data_len - 2, len - 2);
459 if (slen < 0)
return slen;
462 FR_PROTO_TRACE(
"decode context changed %s -> %s",da->parent->name, da->name);
464 if (da->flags.array) {
474 if (slen < 0)
return slen;
503 if ((ptr + 2) == end)
break;
504 if ((ptr + 2) > end)
return -1;
505 if ((ptr[0] != FR_NAS_FILTER_RULE))
break;
506 if (ptr[1] <= 2)
return -1;
507 if ((ptr + ptr[1]) > end)
return -1;
514 FR_PROTO_TRACE(
"Coalesced NAS-Filter-Rule has %lu octets", total);
535 memcpy(p, ptr + 2, ptr[1] - 2);
541 decode_end =
buffer + total;
552 while (
decode < decode_end) {
558 while (p < decode_end) {
559 if (*p == 0x00)
break;
617 if (((
size_t) (p - end) < 2) || (p[1] > (
size_t) (end - p))) {
661 if (data_len < 3)
return -1;
663#ifdef STATIC_ANALYZER
664 if (!packet_ctx->
tmp_ctx)
return -1;
703 if (!child)
goto error;
713 child, p + 2, p[1] - 2,
716 if (tlv_len < 0)
goto error;
735 unsigned int attribute;
739#ifdef STATIC_ANALYZER
740 if (!packet_ctx->
tmp_ctx)
return -1;
763 attribute =
data[1] << 16;
764 attribute |=
data[2] << 8;
765 attribute |=
data[3];
769 attribute =
data[0] << 8;
770 attribute |=
data[1];
807 FR_PROTO_TRACE(
"decode context changed %s -> %s", da->parent->name, da->name);
813 if (my_len < 0)
return my_len;
869 if (attr_len < 3)
return -1;
874 if ((
data[1] & 0x80) == 0) {
877 if (ret < 0)
return -1;
887 fraglen = attr_len - 2;
888 frag =
data + attr_len;
889 end = packet_ctx->
end;
894 if (last_frag || ((end - frag) < 4) ||
895 (frag[0] != attr[0]) ||
897 (frag[2] != attr[2]) ||
898 ((frag + frag[1]) > end)) {
903 last_frag = ((frag[3] & 0x80) == 0);
905 fraglen += frag[1] - 4;
911 if (!
head)
return -1;
913 FR_PROTO_TRACE(
"Fragments %d, total length %d", fragments, (
int) fraglen);
923 while (fragments > 0) {
924 if (frag[1] > 4)
memcpy_bounded(tail, frag + 4, frag[1] - 4, end);
938 packet_ctx->
end =
head + fraglen;
943 packet_ctx->
end = tmp;
947 if (ret < 0)
return ret;
972 if (slen <= 0)
return slen;
984 if (!unknown)
return -1;
997 if (slen < 0 )
return slen;
1012 if (slen < 0)
return slen;
1021 if ((
data[3] & 0x80) == 0) {
1024 if (slen < 0 )
return slen;
1033 if (slen < 0)
return slen;
1054#ifdef STATIC_ANALYZER
1055 if (!packet_ctx->
tmp_ctx)
return -1;
1073 FR_PROTO_TRACE(
"attribute is too small to be WiMAX-Attr-WiMAX-Len Continuation");
1080 if (((
size_t) (
data[5] + 4)) != attr_len) {
1092 FR_PROTO_TRACE(
"decode context changed %s -> %s", da->parent->name, da->name);
1097 if ((
data[6] & 0x80) == 0) {
1100 da,
data + 7,
data[5] - 3, packet_ctx);
1101 if (ret < 0)
return ret;
1116 end = packet_ctx->
end;
1118 while (attr < end) {
1123 if ((end - attr) < 3) {
1140 if ((attr + attr[1]) > end) {
1148 more = ((attr[2] & 0x80) != 0);
1154 if (!more) end = attr + attr[1];
1160 if (more && ((attr + attr[1]) == end)) {
1169 wimax_len += attr[1] - 3;
1189 if ((end - attr) < 9) {
1194 if (attr[0] != FR_VENDOR_SPECIFIC) {
1204 if ((attr + attr[1]) > end) {
1209 if (memcmp(
data, attr + 2, 4) != 0) {
1214 if (attr[1] != (attr[7] + 6)) {
1219 if (
data[4] != attr[6]) {
1239 head = tail = talloc_array(ctx,
uint8_t, wimax_len);
1240 if (!
head)
return -1;
1247 while (attr < end) {
1249 tail += attr[4 + 1] - 3;
1250 attr += 4 + attr[4 + 1];
1262 packet_ctx->
end =
head + wimax_len;
1267 da,
head, wimax_len, packet_ctx);
1269 packet_ctx->
end = tmp;
1273 if (ret < 0)
return ret;
1299#ifdef STATIC_ANALYZER
1300 if (!packet_ctx->
tmp_ctx)
return -1;
1308 if ((
data + attr_len) > packet_ctx->
end)
return -1;
1309 if (attr_len < 5)
return -1;
1310 if (
data[0] != 0)
return -1;
1314 memcpy(&vendor_pen,
data, 4);
1315 vendor_pen = ntohl(vendor_pen);
1340 fr_assert(vendor_da->flags.type_size == 1);
1345 memset(&my_dv, 0,
sizeof(my_dv));
1347 my_dv.
pen = vendor_pen;
1394 while (attr_len > 0) {
1401 vendor_da,
data, attr_len, packet_ctx, dv);
1410 attr_len -= vsa_len;
1449 uint8_t const *
data,
size_t data_len,
void *decode_ctx)
1458 uint8_t const *
data,
size_t data_len,
void *decode_ctx)
1496 if (attr_len > 128 * 1024) {
1501 if ((
data + attr_len) > packet_ctx->
end) {
1510 data_len = attr_len;
1515 if (attr_len == 0)
return 0;
1525 if ((attr_len != 4) || (p[0] >= 0x20)) {
1540 if (data_len >=
sizeof(
buffer))
goto raw;
1543 memcpy(
buffer, p + 1, data_len - 1);
1548 memcpy(
buffer, p, attr_len);
1561 if (!packet_ctx->
tags) {
1573 packet_ctx->
tags = new_tag_ctx;
1578 if (!packet_ctx->
tags[tag]) {
1584 if (new_tag_ctx) TALLOC_FREE(packet_ctx->
tags);
1591 TALLOC_FREE(packet_ctx->
tags[tag]);
1596 if (
unlikely(!group))
goto tag_alloc_error;
1604#ifdef TALLOC_GET_TYPE_ABORT_NOOP
1626 if (attr_len > 253)
goto raw;
1636 if (!packet_ctx->request_authenticator)
goto raw;
1646 if (
parent->flags.length) {
1647 if (data_len >
parent->flags.length) {
1648 data_len =
parent->flags.length;
1661 while ((data_len > 0) && (
buffer[data_len - 1] ==
'\0')) data_len--;
1671 if (!packet_ctx->request_authenticator)
goto raw;
1683 if (!packet_ctx->request_authenticator)
goto raw;
1686 packet_ctx->common->secret, packet_ctx->request_authenticator);
1688 data_len = strlen((
char *)
buffer);
1696 (
parent->flags.length && (data_len >
parent->flags.length))) {
1697 data_len =
parent->flags.length;
1724 if (ret < 0)
goto raw;
1733 if (data_len < 6)
goto raw;
1735 memcpy(&vendor_pen, p, 4);
1736 vendor_pen = ntohl(vendor_pen);
1777 child, p + 5, attr_len - 5,
1779 if (ret < 0)
goto raw;
1790 if (ret < 0)
goto raw;
1801 if (ret < 0)
goto raw;
1817 if (!proto->
decode)
goto raw;
1823 ret = proto->
decode(
vp, &
vp->vp_group, p, attr_len);
1824 if (ret < 0)
goto raw;
1826 vp->vp_tainted =
true;
1847 fr_assert(packet_ctx->tags[tag] != NULL);
1868 if (data_len != 6)
goto raw;
1869 if (p[0] != 0)
goto raw;
1872 p[1], p + 2, 4,
true,
true) < 0) {
1898 if (data_len > 18)
goto raw;
1899 if (data_len < 2)
goto raw;
1900 if (p[0] != 0)
goto raw;
1903 p[1], p + 2, data_len - 2,
false,
true) < 0) {
1921 if (
parent->flags.length && (data_len !=
parent->flags.length))
goto raw;
1932 if (
vp->
da->flags.is_unknown) {
1941 vp->vp_tainted =
true;
1954 [FR_NAS_FILTER_RULE] =
true,
1957 [FR_EAP_MESSAGE] =
true,
1958 [FR_PKM_SS_CERT] =
true,
1959 [FR_PKM_CA_CERT] =
true,
1960 [FR_EAPOL_ANNOUNCEMENT] =
true,
1962 [FR_EXTENDED_ATTRIBUTE_1] =
true,
1963 [FR_EXTENDED_ATTRIBUTE_2] =
true,
1964 [FR_EXTENDED_ATTRIBUTE_3] =
true,
1965 [FR_EXTENDED_ATTRIBUTE_4] =
true,
1966 [FR_EXTENDED_ATTRIBUTE_5] =
true,
1967 [FR_EXTENDED_ATTRIBUTE_6] =
true,
1979 if ((data_len < 2) || (
data[1] < 2) || (
data[1] > data_len)) {
2000 FR_PROTO_TRACE(
"decode context changed %s -> %s",da->parent->name, da->name);
2008 if (
data[0] != FR_CHARGEABLE_USER_IDENTITY) {
2042 if (
data[0] == FR_NAS_FILTER_RULE) {
2081 if (ret < 0)
return ret;
2097 .tmp_ctx = talloc(ctx,
uint8_t),
2098 .end =
data + data_len,
2104 end = decode_ctx.
end;
2106 while (attr < end) {
2126 talloc_free_children(decode_ctx.
tmp_ctx);
2136 TALLOC_FREE(ctx->
tags);
2145 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2146 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2154 common->
secret = talloc_strdup(test_ctx->
common,
"testing123");
2187 uint8_t const *
data,
size_t data_len,
void *proto_ctx)
2192 size_t packet_len = data_len;
2222 test_ctx->
end =
data + packet_len;
2228 uint8_t const *
data,
size_t data_len,
void *decode_ctx)
2234 packet_ctx->
end =
data + data_len;
ssize_t fr_radius_decode_abinary(fr_pair_t *vp, uint8_t const *data, size_t data_len)
Print an Ascend binary filter attribute to a string,.
static int const char char buffer[256]
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define FR_DIGEST_ATTRIBUTES
static fr_dict_attr_t const * attr_packet_type
bool continuation
we only have one flag for now, for WiMAX
size_t type
Length of type data.
fr_dict_attr_decode_func_t decode
for decoding attributes.
static fr_dict_attr_t * fr_dict_attr_unknown_vendor_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int vendor)
fr_dict_protocol_t const * fr_dict_protocol(fr_dict_t const *dict)
Return the protocol descriptor for the dictionary.
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
uint32_t pen
Private enterprise number.
void fr_dict_attr_unknown_free(fr_dict_attr_t const **da)
Free dynamically allocated (unknown attributes)
size_t length
Length of length data.
static fr_dict_attr_t * fr_dict_attr_unknown_typed_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int num, fr_type_t type)
fr_dict_vendor_t const * fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t vendor_pen)
Look up a vendor by its PEN.
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
Protocol-specific callbacks in libfreeradius-PROTOCOL.
static fr_dict_attr_t const * fr_dict_attr_ref(fr_dict_attr_t const *da)
Return the reference associated with a group type attribute.
#define PAIR_DECODE_OOM
Fatal error - Out of memory.
#define PAIR_DECODE_FATAL_ERROR
Fatal error - Failed decoding the packet.
static int _test_ctx_free(UNUSED fr_aka_sim_ctx_t *ctx)
ssize_t fr_pair_tlvs_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, void *decode_ctx, fr_pair_decode_value_t decode_tlv, fr_pair_tlvs_verify_t verify_tlvs, bool nested)
Decode a list of pairs from the network.
ssize_t fr_pair_raw_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *da, uint8_t const *data, size_t data_len)
Create a "raw" pair from malformed network data.
ssize_t fr_pair_array_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_value_t decode_value)
Decode an array of values from the network.
static const uint8_t * zero
void fr_md5_ctx_free_from_list(fr_md5_ctx_t **ctx)
Free function for MD5 digest ctx.
fr_md5_ctx_t * fr_md5_ctx_alloc_from_list(void)
Allocation function for MD5 digest context.
#define fr_md5_final(_out, _ctx)
Finalise the ctx, producing the digest.
#define fr_md5_ctx_copy(_dst, _src)
Copy the contents of a ctx.
#define fr_md5_update(_ctx, _in, _inlen)
Ingest plaintext into the digest.
bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason)
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
static fr_radius_decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, bio_handle_t *h, request_t *request, bio_request_t *u, uint8_t const request_authenticator[static RADIUS_AUTH_VECTOR_LENGTH], uint8_t *data, size_t data_len)
Decode response packet data, extracting relevant information and validating the packet.
#define RADIUS_AUTH_VECTOR_LENGTH
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
int fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
int fr_pair_value_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "octets" type value pair.
fr_pair_t * fr_pair_afrom_da_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da)
Create a pair (and all intermediate parents), and append it to the list.
static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict, UNUSED fr_dict_attr_t const *root_da)
static ssize_t decode_value_trampoline(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, void *decode_ctx)
Handle arrays of DNS labels for fr_struct_from_network()
static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, void *decode_ctx)
RFC 4243 Vendor Specific Suboptions.
static ssize_t decode_tlv_trampoline(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, void *decode_ctx)
static ssize_t decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, NDEBUG_UNUSED fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx)
HIDDEN fr_dict_attr_t const * attr_packet_authentication_vector
ssize_t fr_radius_ascend_secret(fr_dbuff_t *dbuff, uint8_t const *in, size_t inlen, char const *secret, uint8_t const *vector)
Do Ascend-Send / Recv-Secret calculation.
ssize_t fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t *packet, size_t packet_len, fr_radius_decode_ctx_t *decode_ctx)
fr_test_point_proto_decode_t radius_tp_decode_proto
ssize_t fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
static ssize_t decode_concat(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *parent, uint8_t const *data, uint8_t const *end)
Convert a "concatenated" attribute to one long VP.
static ssize_t decode_extended(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *da, uint8_t const *data, UNUSED size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
Fast path for most extended attributes.
static ssize_t decode_digest_attributes(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, fr_radius_decode_ctx_t *packet_ctx)
Decode Digest-Attributes.
static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t attr_len, fr_radius_decode_ctx_t *packet_ctx)
Convert a Vendor-Specific WIMAX to vps.
ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
Convert TLVs to one or more VPs.
static const char * reason_name[DECODE_FAIL_MAX]
fr_test_point_pair_decode_t radius_tp_decode_pair
static void memcpy_bounded(void *restrict dst, const void *restrict src, size_t n, const void *restrict end)
static ssize_t fr_radius_decode_password(char *passwd, size_t pwlen, fr_radius_decode_ctx_t *packet_ctx)
Decode password.
ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const attr_len, void *decode_ctx)
Create any kind of VP from the attribute contents.
static ssize_t decode_extended_fragments(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t attr_len, fr_radius_decode_ctx_t *packet_ctx)
Convert a fragmented extended attr to a VP.
static const bool special[UINT8_MAX+1]
int fr_radius_decode_tlv_ok(uint8_t const *data, size_t length, size_t dv_type, size_t dv_length)
Check if a set of RADIUS formatted TLVs are OK.
ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
Create a "normal" fr_pair_t from the given data.
static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx, fr_dict_vendor_t const *dv)
Convert a top-level VSA to a VP.
static ssize_t decode_rfc(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, void *decode_ctx)
decode an RFC-format TLV
static ssize_t decode_nas_filter_rule(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, fr_radius_decode_ctx_t *packet_ctx)
Decode NAS-Filter-Rule.
static ssize_t fr_radius_decode_tunnel_password(uint8_t *passwd, size_t *pwlen, fr_radius_decode_ctx_t *packet_ctx)
Decode Tunnel-Password encrypted attributes.
static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
static fr_dict_t const * dict_radius
fr_radius_tag_ctx_t ** tags
for decoding tagged attributes
#define fr_radius_flag_concat(_da)
#define fr_radius_flag_has_tag(_da)
uint8_t const * request_authenticator
fr_radius_decode_fail_t
Failure reasons.
@ DECODE_FAIL_INVALID_ATTRIBUTE
@ DECODE_FAIL_ATTRIBUTE_UNDERFLOW
@ DECODE_FAIL_MIN_LENGTH_FIELD
@ DECODE_FAIL_MAX_LENGTH_PACKET
@ DECODE_FAIL_HEADER_OVERFLOW
@ DECODE_FAIL_ATTRIBUTE_TOO_SHORT
@ DECODE_FAIL_ATTRIBUTE_OVERFLOW
@ DECODE_FAIL_TOO_MANY_ATTRIBUTES
@ DECODE_FAIL_MIN_LENGTH_PACKET
@ DECODE_FAIL_MIN_LENGTH_MISMATCH
@ DECODE_FAIL_MA_INVALID_LENGTH
@ DECODE_FAIL_UNKNOWN_PACKET_CODE
uint8_t const * end
end of the packet
#define RADIUS_MAX_STRING_LENGTH
#define fr_radius_flag_encrypted(_da)
static bool fr_radius_flag_extended(fr_dict_attr_t const *da)
TALLOC_CTX * tag_root_ctx
Where to allocate new tag attributes.
#define RADIUS_MAX_PASS_LENGTH
fr_radius_ctx_t const * common
#define fr_radius_flag_long_extended(_da)
fr_radius_attr_flags_encrypt_t
@ RADIUS_FLAG_ENCRYPT_USER_PASSWORD
Encrypt attribute RFC 2865 style.
@ RADIUS_FLAG_ENCRYPT_ASCEND_SECRET
Encrypt attribute ascend style.
@ RADIUS_FLAG_ENCRYPT_TUNNEL_PASSWORD
Encrypt attribute RFC 2868 style.
#define fr_radius_flag_abinary(_da)
bool tunnel_password_zeros
check for trailing zeros on decode
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
fr_pair_list_t * tag_root
Where to insert tag attributes.
static fr_dict_attr_t const * attr_vendor_specific
ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_value_t decode_value, fr_pair_decode_value_t decode_tlv)
Convert a STRUCT to one or more VPs.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Entry point for pair decoders.
Entry point for protocol decoders.
static int fr_pair_find_or_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
#define FR_PROTO_HEX_DUMP(_data, _data_len, _fmt,...)
#define FR_PROTO_TRACE(_fmt,...)
char const * fr_strerror(void)
Get the last library error.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
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, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
ssize_t fr_value_box_ipaddr_from_network(fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, int prefix_len, uint8_t const *data, size_t data_len, bool fixed, bool tainted)
Decode a fr_value_box_t of type IP address / prefix.
static size_t char ** out