25 RCSID(
"$Id: 67c5e6783e2f09af107ed6d24b111f44ddbfead6 $")
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>
42 static 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;
410 #define decode_value fr_radius_decode_pair_value
417 uint8_t const *
data,
size_t const data_len,
void *decode_ctx)
425 #ifdef STATIC_ANALYZER
434 if ((data_len < 2) || (
data[1] < 2)) {
442 if (
data[1] == 2)
return 2;
446 if (len > data_len) {
448 "Length must be less than %zu bytes, got %zu bytes",
449 __FUNCTION__, data_len - 2, len - 2);
458 if (slen < 0)
return slen;
461 FR_PROTO_TRACE(
"decode context changed %s -> %s",da->parent->name, da->name);
463 if (da->flags.array) {
473 if (slen < 0)
return slen;
502 if ((ptr + 2) == end)
break;
503 if ((ptr + 2) > end)
return -1;
504 if ((ptr[0] != FR_NAS_FILTER_RULE))
break;
505 if (ptr[1] <= 2)
return -1;
506 if ((ptr + ptr[1]) > end)
return -1;
513 FR_PROTO_TRACE(
"Coalesced NAS-Filter-Rule has %lu octets", total);
534 memcpy(p, ptr + 2, ptr[1] - 2);
540 decode_end =
buffer + total;
551 while (
decode < decode_end) {
557 while (p < decode_end) {
558 if (*p == 0x00)
break;
614 if (((
size_t) (p - end) < 2) || (p[1] > (
size_t) (end - p))) {
658 if (data_len < 3)
return -1;
660 #ifdef STATIC_ANALYZER
661 if (!packet_ctx->
tmp_ctx)
return -1;
699 if (!child)
goto error;
709 child, p + 2, p[1] - 2,
712 if (tlv_len < 0)
goto error;
731 unsigned int attribute;
735 #ifdef STATIC_ANALYZER
736 if (!packet_ctx->
tmp_ctx)
return -1;
759 attribute =
data[1] << 16;
760 attribute |=
data[2] << 8;
761 attribute |=
data[3];
765 attribute =
data[0] << 8;
766 attribute |=
data[1];
803 FR_PROTO_TRACE(
"decode context changed %s -> %s", da->parent->name, da->name);
809 if (my_len < 0)
return my_len;
865 if (attr_len < 3)
return -1;
870 if ((
data[1] & 0x80) == 0) {
873 if (ret < 0)
return -1;
883 fraglen = attr_len - 2;
884 frag =
data + attr_len;
885 end = packet_ctx->
end;
890 if (last_frag || ((end - frag) < 4) ||
891 (frag[0] != attr[0]) ||
893 (frag[2] != attr[2]) ||
894 ((frag + frag[1]) > end)) {
899 last_frag = ((frag[3] & 0x80) == 0);
901 fraglen += frag[1] - 4;
907 if (!
head)
return -1;
909 FR_PROTO_TRACE(
"Fragments %d, total length %d", fragments, (
int) fraglen);
919 while (fragments > 0) {
920 if (frag[1] > 4)
memcpy_bounded(tail, frag + 4, frag[1] - 4, end);
934 packet_ctx->
end =
head + fraglen;
939 packet_ctx->
end = tmp;
943 if (ret < 0)
return ret;
968 if (slen <= 0)
return slen;
980 if (!unknown)
return -1;
993 if (slen < 0 )
return slen;
1006 if (slen < 0)
return slen;
1015 if ((
data[3] & 0x80) == 0) {
1018 if (slen < 0 )
return slen;
1027 if (slen < 0)
return slen;
1048 #ifdef STATIC_ANALYZER
1049 if (!packet_ctx->
tmp_ctx)
return -1;
1067 FR_PROTO_TRACE(
"attribute is too small to be WiMAX-Attr-WiMAX-Len Continuation");
1074 if (((
size_t) (
data[5] + 4)) != attr_len) {
1086 FR_PROTO_TRACE(
"decode context changed %s -> %s", da->parent->name, da->name);
1091 if ((
data[6] & 0x80) == 0) {
1094 da,
data + 7,
data[5] - 3, packet_ctx);
1095 if (ret < 0)
return ret;
1110 end = packet_ctx->
end;
1112 while (attr < end) {
1117 if ((end - attr) < 3) {
1134 if ((attr + attr[1]) > end) {
1142 more = ((attr[2] & 0x80) != 0);
1148 if (!more) end = attr + attr[1];
1154 if (more && ((attr + attr[1]) == end)) {
1163 wimax_len += attr[1] - 3;
1183 if ((end - attr) < 9) {
1188 if (attr[0] != FR_VENDOR_SPECIFIC) {
1198 if ((attr + attr[1]) > end) {
1203 if (memcmp(
data, attr + 2, 4) != 0) {
1208 if (attr[1] != (attr[7] + 6)) {
1213 if (
data[4] != attr[6]) {
1233 head = tail = talloc_array(ctx,
uint8_t, wimax_len);
1234 if (!
head)
return -1;
1241 while (attr < end) {
1243 tail += attr[4 + 1] - 3;
1244 attr += 4 + attr[4 + 1];
1256 packet_ctx->
end =
head + wimax_len;
1261 da,
head, wimax_len, packet_ctx);
1263 packet_ctx->
end = tmp;
1267 if (ret < 0)
return ret;
1293 #ifdef STATIC_ANALYZER
1294 if (!packet_ctx->
tmp_ctx)
return -1;
1302 if ((
data + attr_len) > packet_ctx->
end)
return -1;
1303 if (attr_len < 5)
return -1;
1304 if (
data[0] != 0)
return -1;
1308 memcpy(&vendor_pen,
data, 4);
1309 vendor_pen = ntohl(vendor_pen);
1334 fr_assert(vendor_da->flags.type_size == 1);
1339 memset(&my_dv, 0,
sizeof(my_dv));
1341 my_dv.
pen = vendor_pen;
1388 while (attr_len > 0) {
1395 vendor_da,
data, attr_len, packet_ctx, dv);
1404 attr_len -= vsa_len;
1443 uint8_t const *
data,
size_t data_len,
void *decode_ctx)
1452 uint8_t const *
data,
size_t data_len,
void *decode_ctx)
1490 if (attr_len > 128 * 1024) {
1495 if ((
data + attr_len) > packet_ctx->
end) {
1504 data_len = attr_len;
1509 if (attr_len == 0)
return 0;
1519 if ((attr_len != 4) || (p[0] >= 0x20)) {
1534 if (data_len >=
sizeof(
buffer))
goto raw;
1537 memcpy(
buffer, p + 1, data_len - 1);
1542 memcpy(
buffer, p, attr_len);
1555 if (!packet_ctx->
tags) {
1567 packet_ctx->
tags = new_tag_ctx;
1572 if (!packet_ctx->
tags[tag]) {
1578 if (new_tag_ctx) TALLOC_FREE(packet_ctx->
tags);
1585 TALLOC_FREE(packet_ctx->
tags[tag]);
1590 if (
unlikely(!group))
goto tag_alloc_error;
1597 #ifdef TALLOC_GET_TYPE_ABORT_NOOP
1619 if (attr_len > 253)
goto raw;
1629 if (!packet_ctx->request_authenticator)
goto raw;
1639 if (
parent->flags.length) {
1640 if (data_len >
parent->flags.length) {
1641 data_len =
parent->flags.length;
1654 while ((data_len > 0) && (
buffer[data_len - 1] ==
'\0')) data_len--;
1664 if (!packet_ctx->request_authenticator)
goto raw;
1676 if (!packet_ctx->request_authenticator)
goto raw;
1679 packet_ctx->common->secret, packet_ctx->request_authenticator);
1681 data_len = strlen((
char *)
buffer);
1689 (
parent->flags.length && (data_len >
parent->flags.length))) {
1690 data_len =
parent->flags.length;
1717 if (ret < 0)
goto raw;
1726 if (data_len < 6)
goto raw;
1728 memcpy(&vendor_pen, p, 4);
1729 vendor_pen = ntohl(vendor_pen);
1770 child, p + 5, attr_len - 5,
1772 if (ret < 0)
goto raw;
1783 if (ret < 0)
goto raw;
1794 if (ret < 0)
goto raw;
1810 if (!
proto->decode)
goto raw;
1815 ret =
proto->decode(
vp, &
vp->vp_group, p, attr_len);
1816 if (ret < 0)
goto raw;
1818 vp->vp_tainted =
true;
1839 fr_assert(packet_ctx->tags[tag] != NULL);
1859 if (data_len != 6)
goto raw;
1860 if (p[0] != 0)
goto raw;
1861 if ((p[1] & 0x3f) > 32)
goto raw;
1863 vp->vp_ip.af = AF_INET;
1864 vp->vp_ip.scope_id = 0;
1865 vp->vp_ip.prefix = p[1] & 0x3f;
1866 memcpy((
uint8_t *)&
vp->vp_ipv4addr, p + 2, data_len - 2);
1891 if (data_len > 18)
goto raw;
1892 if (data_len < 2)
goto raw;
1893 if (p[0] != 0)
goto raw;
1894 if (p[1] > 128)
goto raw;
1905 vp->vp_ip.af = AF_INET6;
1906 vp->vp_ip.scope_id = 0;
1907 vp->vp_ip.prefix = p[1];
1909 memcpy((
uint8_t *)&
vp->vp_ipv6addr, p + 2, data_len - 2);
1916 if (memcmp(p + 2, (
uint8_t *)&
vp->vp_ipv6addr, data_len - 2) != 0)
goto raw;
1931 if (
parent->flags.length && (data_len !=
parent->flags.length))
goto raw;
1942 if (
vp->
da->flags.is_unknown) {
1951 vp->vp_tainted =
true;
1964 [FR_NAS_FILTER_RULE] =
true,
1967 [FR_EAP_MESSAGE] =
true,
1968 [FR_PKM_SS_CERT] =
true,
1969 [FR_PKM_CA_CERT] =
true,
1970 [FR_EAPOL_ANNOUNCEMENT] =
true,
1972 [FR_EXTENDED_ATTRIBUTE_1] =
true,
1973 [FR_EXTENDED_ATTRIBUTE_2] =
true,
1974 [FR_EXTENDED_ATTRIBUTE_3] =
true,
1975 [FR_EXTENDED_ATTRIBUTE_4] =
true,
1976 [FR_EXTENDED_ATTRIBUTE_5] =
true,
1977 [FR_EXTENDED_ATTRIBUTE_6] =
true,
1989 if ((data_len < 2) || (
data[1] < 2) || (
data[1] > data_len)) {
2010 FR_PROTO_TRACE(
"decode context changed %s -> %s",da->parent->name, da->name);
2018 if (
data[0] != FR_CHARGEABLE_USER_IDENTITY) {
2035 vp->vp_tainted =
true;
2044 if (
data[0] == FR_NAS_FILTER_RULE) {
2083 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);
2144 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2145 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2153 common->
secret = talloc_strdup(test_ctx->
common,
"testing123");
2184 uint8_t const *
data,
size_t data_len,
void *proto_ctx)
2189 size_t packet_len = data_len;
2215 test_ctx->
end =
data + packet_len;
2221 uint8_t const *
data,
size_t data_len,
void *decode_ctx)
2227 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_vendor_t const * fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t vendor_pen)
Look up a vendor by its PEN.
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_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)
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
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_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.
fr_dict_protocol_t const * fr_dict_protocol(fr_dict_t const *dict)
Return the protocol descriptor for the dictionary.
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.
void fr_ipaddr_mask(fr_ipaddr_t *addr, uint8_t prefix)
Zeroes out the host portion of an fr_ipaddr_t.
#define PAIR_DECODE_OOM
Fatal error - Out of memory.
#define PAIR_DECODE_FATAL_ERROR
Fatal error - Failed decoding the packet.
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_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.
ssize_t fr_pair_raw_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len)
Create a "raw" pair from the network data.
static const uint8_t * zero
fr_md5_update_t fr_md5_update
fr_md5_final_t fr_md5_final
void fr_md5_ctx_free_from_list(fr_md5_ctx_t **ctx)
fr_md5_ctx_t * fr_md5_ctx_alloc_from_list(void)
fr_md5_ctx_copy_t fr_md5_ctx_copy
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 unsigned int fr_bytes_from_bits(unsigned int bits)
Convert bits (as in prefix length) to bytes, rounding up.
#define RADIUS_AUTH_VECTOR_LENGTH
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.
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.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
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.
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.
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_tlv_trampoline(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)
Wrapper called by fr_struct_from_network()
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.
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 data_len, void *decode_ctx)
Wrapper called by fr_struct_from_network()
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.
static int decode_test_ctx(void **out, TALLOC_CTX *ctx)
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]
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 attr_len, fr_radius_decode_ctx_t *packet_ctx)
Convert a top-level VSA to one or more VPs.
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 int _test_ctx_free(fr_radius_decode_ctx_t *ctx)
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 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)
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
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
static char const * proto(int id, int porttype)
#define check(_handle, _len_p)
static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, udp_handle_t *h, request_t *request, udp_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.
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.
@ DECODE_FAIL_INVALID_ATTRIBUTE
@ DECODE_FAIL_ATTRIBUTE_UNDERFLOW
@ DECODE_FAIL_MIN_LENGTH_FIELD
@ 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
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.
static size_t char ** out