From: Alan T. DeKok Date: Tue, 20 Apr 2021 09:19:59 +0000 (-0400) Subject: Revert "decode VSAs and vendors as nested attributes." X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=83c87d6b4098e4a61798153b89478dd7bb940267;p=thirdparty%2Ffreeradius-server.git Revert "decode VSAs and vendors as nested attributes." This reverts commit e906e3d73ff649d16916405165ed7736fb496372. --- diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 4bfbbdd1c66..c0c4eb1181b 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -490,14 +490,14 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co return data_len; } -/** Convert one VSA to a VP. +/** Convert a top-level VSA to a VP. * * "length" can be LONGER than just this sub-vsa. */ -static ssize_t decode_vsa_single(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict, - fr_dict_attr_t const *parent, - uint8_t const *data, size_t data_len, - fr_radius_ctx_t *packet_ctx, fr_dict_vendor_t const *dv) +static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict, + fr_dict_attr_t const *parent, + uint8_t const *data, size_t data_len, + fr_radius_ctx_t *packet_ctx, fr_dict_vendor_t const *dv) { unsigned int attribute; ssize_t attrlen, my_len; @@ -611,10 +611,11 @@ static ssize_t decode_extended(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t /* * data = Ext-Attr Flag ... */ + if (attr_len < 3) return -1; /* - * No continuation, just decode the attribute in place. + * No continuation, just decode the attributre in place. */ if ((data[1] & 0x80) == 0) { ret = fr_radius_decode_pair_value(ctx, cursor, dict, @@ -686,55 +687,50 @@ static ssize_t decode_extended(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t * * @note Called ONLY for Vendor-Specific */ -static ssize_t decode_wimax(fr_pair_t *parent, fr_dict_t const *dict, +static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict, + fr_dict_attr_t const *parent, uint8_t const *data, size_t attr_len, size_t packet_len, fr_radius_ctx_t *packet_ctx) { ssize_t ret; size_t wimax_len; + bool more; uint8_t *head, *tail; uint8_t const *attr, *end; fr_dict_attr_t const *da; - fr_pair_list_t list; - fr_dcursor_t cursor; #ifdef __clang_analyzer__ if (!packet_ctx->tmp_ctx) return -1; #endif - fr_assert(parent->da->type == FR_TYPE_VENDOR); - fr_assert(parent->da->attr == VENDORPEC_WIMAX); - /* - * We're passed data = WiMAX-Attr WiMAX-Len Continuation ... + * data = VID VID VID VID WiMAX-Attr WiMAX-Len Continuation ... */ - fr_assert(attr_len > 3); + if (attr_len < 8) return -1; - da = fr_dict_attr_child_by_num(parent->da, data[0]); + /* + * WiMAX-Attr WiMAX-Len Continuation + */ + if (data[5] < 3) return -1; /* - * Unknown attribute, or the WiMAX length doesn't match - * the enclosing attribute length, it's an unknown - * attribute. + * The WiMAX-Len + 4 VID must exactly fill the attribute. */ - if (!da || (data[1] != attr_len)) { - da = fr_dict_unknown_attr_afrom_num(packet_ctx->tmp_ctx, parent->da, data[0]); - if (!da) return -1; - } - FR_PROTO_TRACE("decode context changed %s -> %s", da->parent->name, da->name); + if (((size_t) (data[5] + 4)) != attr_len) return -1; - fr_pair_list_init(&list); - fr_dcursor_init(&cursor, &list); + da = fr_dict_attr_child_by_num(parent, data[4]); + if (!da) da = fr_dict_unknown_attr_afrom_num(packet_ctx->tmp_ctx, parent, data[4]); + if (!da) return -1; + FR_PROTO_TRACE("decode context changed %s -> %s", da->parent->name, da->name); /* - * No continuation, just decode the attribute in place. + * No continuation, just decode the attributre in place. */ - if ((data[2] & 0x80) == 0) { - ret = fr_radius_decode_pair_value(parent, &cursor, dict, - da, data + 3, data[1] - 3, data[1] - 3, packet_ctx); + if ((data[6] & 0x80) == 0) { + ret = fr_radius_decode_pair_value(ctx, cursor, dict, + da, data + 7, data[5] - 3, data[5] - 3, packet_ctx); if (ret < 0) return ret; - fr_pair_list_append(&parent->vp_group, &list); return attr_len; } @@ -743,117 +739,117 @@ static ssize_t decode_wimax(fr_pair_t *parent, fr_dict_t const *dict, * now, they MUST be contiguous in the packet, and they * MUST be all of the same VSA, WiMAX, and WiMAX-attr. * - * The first fragment has already been checked, so we - * start off with that. + * The first fragment doesn't have a RADIUS attribute + * header. */ - wimax_len = attr_len - 3; - attr = data + attr_len; + wimax_len = 0; + attr = data + 4; end = data + packet_len; - /* - * Loop over the entire packet. The base RFC format is - * valid, as the packet was already checked for sanity. - */ while (attr < end) { - uint32_t vendor; - uint8_t const *wimax; - /* - * This check shouldn't be necessary, but what - * the heck. + * Not enough room for Attribute + length + + * continuation, it's bad. */ - if ((attr + 2) > end) break; + if ((end - attr) < 3) return -1; /* - * This check shouldn't be necessary, either. + * Must have non-zero data in the attribute. */ - if ((attr + attr[1]) > end) break; + if (attr[1] <= 3) return -1; /* - * The attribute isn't a VSA, stop. + * If the WiMAX attribute overflows the packet, + * it's bad. */ - if (attr[0] != FR_VENDOR_SPECIFIC) break; + if ((attr + attr[1]) > end) return -1; /* - * Not enough room for RFC header + Vendor-ID + - * WiMAX header + Continuation, stop. + * Check the continuation flag. */ - if (attr[1] < 2 + 4 + 2 + 1) break; + more = ((attr[2] & 0x80) != 0); /* - * Not a WiMAX VSA, stop. + * Or, there's no more data, in which case we + * shorten "end" to finish at this attribute. */ - vendor = fr_net_to_uint32(attr + 2); - if (vendor != VENDORPEC_WIMAX) break; - + if (!more) end = attr + attr[1]; /* - * Point to WiMAX-Attr + * There's more data, but we're at the end of the + * packet. The attribute is malformed! */ - wimax = attr + 2 + 4; + if (more && ((attr + attr[1]) == end)) return -1; /* - * Not the same WiMAX attribute. + * Add in the length of the data we need to + * concatenate together. */ - if (data[0] != wimax[0]) break; + wimax_len += attr[1] - 3; /* - * WiMAX attribute does not fill the - * Vendor-Specific attribute, either - * overflow or underflow. + * Go to the next attribute, and stop if there's + * no more. */ - if (attr[1] != (wimax[1] + 6)) break; + attr += attr[1]; + if (!more) break; /* - * Seems OK, add the length in. + * data = VID VID VID VID WiMAX-Attr WimAX-Len Continuation ... + * + * attr = Vendor-Specific VSA-Length VID VID VID VID WiMAX-Attr WimAX-Len Continuation ... + * */ - wimax_len += wimax[1] - 3; /* - * We've successfully included this attribute, so - * point to the next one. + * No room for Vendor-Specific + length + + * Vendor(4) + attr + length + continuation + data */ - attr += attr[1]; + if ((end - attr) < 9) return -1; + + if (attr[0] != FR_VENDOR_SPECIFIC) return -1; + if (attr[1] < 9) return -1; + if ((attr + attr[1]) > end) return -1; + if (memcmp(data, attr + 2, 4) != 0) return -1; /* not WiMAX Vendor ID */ + + if (attr[1] != (attr[7] + 6)) return -1; /* WiMAX attr doesn't exactly fill the VSA */ + + if (data[4] != attr[6]) return -1; /* different WiMAX attribute */ /* - * No more continuation, stop. + * Skip over the Vendor-Specific header, and + * continue with the WiMAX attributes. */ - if ((wimax[2] & 0x80) == 0) break; + attr += 6; } /* - * Remember where the continued WiMAX attributes ended. + * No data in the WiMAX attribute, make a "raw" one. */ - end = attr; + if (!wimax_len) return -1; - head = tail = talloc_array(packet_ctx->tmp_ctx, uint8_t, wimax_len); + head = tail = talloc_array(ctx, uint8_t, wimax_len); if (!head) return -1; /* * Copy the data over, this time trusting the attribute - * contents. When this function is called, 'data' is - * pointing to WiMAX-Attr. So we back up in order to be - * able to point to the Vendor-Specific byte, which - * treats all of the attributes the same. + * contents. */ - attr = data - 6; + attr = data; while (attr < end) { - uint8_t const *wimax = attr + 2 + 4; - - memcpy_bounded(tail, wimax + 3, wimax[1] - 3, end); - tail += wimax[1] - 3; - attr += attr[1]; + memcpy_bounded(tail, attr + 4 + 3, attr[4 + 1] - 3, end); + tail += attr[4 + 1] - 3; + attr += 4 + attr[4 + 1]; /* skip VID+WiMax header */ + attr += 2; /* skip Vendor-Specific header */ } FR_PROTO_HEX_DUMP(head, wimax_len, "Wimax fragments"); - ret = fr_radius_decode_pair_value(parent, &cursor, dict, + ret = fr_radius_decode_pair_value(ctx, cursor, dict, da, head, wimax_len, wimax_len, packet_ctx); talloc_free(head); if (ret < 0) return ret; - fr_pair_list_append(&parent->vp_group, &list); - return end - data; } @@ -867,12 +863,12 @@ static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *curso fr_radius_ctx_t *packet_ctx) { size_t total; + ssize_t ret; uint32_t vendor; fr_dict_vendor_t const *dv; fr_pair_list_t head; fr_dict_vendor_t my_dv; fr_dict_attr_t const *vendor_da; - fr_pair_t *vp; fr_dcursor_t tlv_cursor; fr_pair_list_init(&head); @@ -887,7 +883,8 @@ static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *curso if (!fr_cond_assert(parent->type == FR_TYPE_VSA)) return -1; if (attr_len > packet_len) return -1; - if (attr_len < 4) return -1; /* must have at least a 32-bit vendor ID */ + if (attr_len < 5) return -1; /* vid, value */ + if (data[0] != 0) return -1; /* we require 24-bit VIDs */ FR_PROTO_TRACE("Decoding VSA"); @@ -896,23 +893,30 @@ static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *curso /* * Verify that the parent (which should be a VSA) - * contains a child which represents the vendor. + * contains a fake attribute representing the vendor. + * + * If it doesn't then this vendor is unknown, but + * (unlike DHCP) we know vendor attributes have a + * standard format, so we can decode the data anyway. */ vendor_da = fr_dict_attr_child_by_num(parent, vendor); if (!vendor_da) { fr_dict_attr_t *n; + /* + * RFC format is 1 octet type, 1 octet length + */ + if (fr_radius_decode_tlv_ok(data + 4, attr_len - 4, 1, 1) < 0) { + FR_PROTO_TRACE("Unknown TLVs not OK: %s", fr_strerror()); + return -1; + } n = fr_dict_unknown_vendor_afrom_num(packet_ctx->tmp_ctx, parent, vendor); if (!n) return -1; vendor_da = n; - } - /* - * Create an unknown DV if necessary. If the DV isn't - * known, we default to RFC format. - */ - dv = fr_dict_vendor_by_num(dict, vendor); - if (!dv) { + /* + * Create an unknown DV too... + */ memset(&my_dv, 0, sizeof(my_dv)); my_dv.pen = vendor; @@ -920,107 +924,74 @@ static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *curso my_dv.length = 1; dv = &my_dv; + + goto create_attrs; } /* - * VSAs should be in a TLV format. + * We found an attribute representing the vendor + * so it *MUST* exist in the vendor tree. */ - if (fr_radius_decode_tlv_ok(data + 4, attr_len - 4, dv->type, dv->length) < 0) { - FR_PROTO_TRACE("TLVs not OK: %s", fr_strerror()); - return -1; - } + dv = fr_dict_vendor_by_num(dict, vendor); + if (!fr_cond_assert(dv)) return -1; + FR_PROTO_TRACE("decode context %s -> %s", parent->name, vendor_da->name); /* - * Ensure that Vendor-Specific exists. If it doesn't - * exist, create it and add it to the parent list. - * - * Since fr_radius_decode_tlv_ok() has returned OK, we - * know that any malformed attributes will be created as - * "raw" attributes. The decode functions we call will - * return -1 only on OOM, or other unrecoverable error. + * WiMAX craziness */ - vp = packet_ctx->vendor_specific; - if (!vp) { - vp = fr_pair_afrom_da(ctx, parent); - if (!vp) return -1; - - packet_ctx->vendor_specific = vp; - fr_dcursor_append(cursor, vp); + if ((vendor == VENDORPEC_WIMAX) && dv->flags) { + ret = decode_wimax(ctx, cursor, dict, vendor_da, data, attr_len, packet_len, packet_ctx); + return ret; } /* - * Ensure that a child VP of this vendor exists. + * VSAs should normally be in TLV format. */ - vp = fr_pair_find_by_da(&packet_ctx->vendor_specific->vp_group, vendor_da); - if (!vp) { - vp = fr_pair_afrom_da(packet_ctx->vendor_specific, vendor_da); - if (!vp) return -1; - - fr_pair_append(&packet_ctx->vendor_specific->vp_group, vp); + if (fr_radius_decode_tlv_ok(data + 4, attr_len - 4, dv->type, dv->length) < 0) { + FR_PROTO_TRACE("TLVs not OK: %s", fr_strerror()); + return -1; } + /* + * There may be more than one VSA in the + * Vendor-Specific. If so, loop over them all. + */ +create_attrs: data += 4; attr_len -= 4; packet_len -= 4; total = 4; - /* - * WiMAX craziness. - */ - if (vendor == VENDORPEC_WIMAX) { - ssize_t slen; - - /* - * If there's only Vendor-Attr + Vendor-Length, - * then there's either continuation byte, or only - * a continuation byte. We return zero - * attributes. - * - * Note that we don't bother checking for the - * continuation flag. If it's set, then there's - * no reason to concatenate an empty attribute - * with the next one. - */ - if (attr_len <= 3) return total + attr_len; - - /* - * There's a continuation byte, and some data. - * Let's decode it. - */ - slen = decode_wimax(vp, dict, data, attr_len, packet_len, packet_ctx); - if (slen < 0) return slen; - return total + slen; - } - - FR_PROTO_TRACE("decode context %s -> %s", parent->name, vendor_da->name); - - /* - * There may be many TLVs in the attribute. Loop over - * them all. - */ fr_dcursor_init(&tlv_cursor, &head); while (attr_len > 0) { - ssize_t slen; + ssize_t vsa_len; /* - * Decode this one VSA, which itself might have - * child attributes. + * Vendor attributes can have subattributes (if you hadn't guessed) */ - slen = decode_vsa_single(vp, &tlv_cursor, dict, - vendor_da, data, attr_len, packet_ctx, dv); - if (slen < 0) { + vsa_len = decode_vsa_internal(ctx, &tlv_cursor, dict, + vendor_da, data, attr_len, packet_ctx, dv); + if (vsa_len < 0) { fr_strerror_printf("%s: Internal sanity check %d", __FUNCTION__, __LINE__); fr_pair_list_free(&head); return -1; } - data += slen; - attr_len -= slen; - packet_len -= slen; - total += slen; + data += vsa_len; + attr_len -= vsa_len; + packet_len -= vsa_len; + total += vsa_len; } + fr_dcursor_head(&tlv_cursor); + fr_dcursor_tail(cursor); + fr_dcursor_merge(cursor, &tlv_cursor); - fr_pair_list_append(&vp->vp_group, &head); + /* + * When the unknown attributes were created by + * decode_vsa_internal, the hierachy between that unknown + * attribute and first known attribute was cloned + * meaning we can now free the unknown vendor. + */ return total; } diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 2d6a561f593..96f8b39975c 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -172,7 +172,6 @@ typedef struct { char const *secret; //!< shared secret. MUST be talloc'd fr_fast_rand_t rand_ctx; //!< for tunnel passwords int salt_offset; //!< for tunnel passwords - fr_pair_t *vendor_specific; //!< for decoding VSAs into nested sets bool tunnel_password_zeros; //!< check for trailing zeros on decode bool disallow_tunnel_passwords; //!< not all packets can have tunnel passwords diff --git a/src/tests/unit/protocols/radius/ascend.txt b/src/tests/unit/protocols/radius/ascend.txt index 51866bc9a64..97617f795a5 100644 --- a/src/tests/unit/protocols/radius/ascend.txt +++ b/src/tests/unit/protocols/radius/ascend.txt @@ -5,7 +5,7 @@ encode-pair Vendor-Specific.Ascend.Data-Filter = "ip in drop tcp dstport > 1023" match 1a 28 00 00 02 11 f2 22 01 00 01 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 03 ff 00 03 00 00 00 00 00 00 00 00 00 00 decode-pair - -match Vendor-Specific = { Ascend = { Data-Filter = "ip in drop tcp dstport > 1023" } } +match Vendor-Specific.Ascend.Data-Filter = "ip in drop tcp dstport > 1023" # # We no longer support setting Vendor-Specific.Ascend.Data-Filters as hex strings @@ -17,28 +17,28 @@ encode-pair Vendor-Specific.Ascend.Data-Filter = "ip in forward srcip 1.2.3.4/5 match 1a 28 00 00 02 11 f2 22 01 01 01 00 01 02 03 04 0a 0b 0c 0d 05 20 06 00 00 05 04 d2 02 02 00 00 00 00 00 00 00 00 00 00 decode-pair 1a2800000211f22201010100010203040a0b0c0d05200600000504d2020200000000000000000000 -match Vendor-Specific = { Ascend = { Data-Filter = "ip in forward srcip 1.2.3.4/5 dstip 10.11.12.13/32 tcp srcport = 5 dstport = 1234" } } +match Vendor-Specific.Ascend.Data-Filter = "ip in forward srcip 1.2.3.4/5 dstip 10.11.12.13/32 tcp srcport = 5 dstport = 1234" encode-pair Vendor-Specific.Ascend.Data-Filter = "ipv6 in forward srcip ::1 dstip ::1 tcp srcport = 5 dstport = 1234" match 1a 38 00 00 02 11 f2 32 03 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 80 80 06 00 00 05 04 d2 02 02 00 00 decode-pair - -match Vendor-Specific = { Ascend = { Data-Filter = "ipv6 in forward srcip ::1/128 dstip ::1/128 tcp srcport = 5 dstport = 1234" } } +match Vendor-Specific.Ascend.Data-Filter = "ipv6 in forward srcip ::1/128 dstip ::1/128 tcp srcport = 5 dstport = 1234" # length < 16 gets padded with zeros encode-pair Vendor-Specific.Ascend.Send-Secret = "foo" match 1a 18 00 00 02 11 d6 12 ce 8d bb 09 a0 cd c2 9c ca f1 bd cb 25 41 f7 70 decode-pair - -match Vendor-Specific = { Ascend = { Send-Secret = "foo" } } +match Vendor-Specific.Ascend.Send-Secret = "foo" # length > 16 gets chopped encode-pair Vendor-Specific.Ascend.Send-Secret = "foo 56789abcdef012" match 1a 18 00 00 02 11 d6 12 ce 8d bb 29 95 fb f5 a4 f3 90 df a8 41 24 91 40 decode-pair - -match Vendor-Specific = { Ascend = { Send-Secret = "foo 56789abcdef0" } } +match Vendor-Specific.Ascend.Send-Secret = "foo 56789abcdef0" count match 22 diff --git a/src/tests/unit/protocols/radius/lucent.txt b/src/tests/unit/protocols/radius/lucent.txt index 5f350e6b553..0d17cfcdae2 100644 --- a/src/tests/unit/protocols/radius/lucent.txt +++ b/src/tests/unit/protocols/radius/lucent.txt @@ -5,10 +5,10 @@ encode-pair Vendor-Specific.Lucent.Max-Shared-Users = 1 match 1a 0d 00 00 12 ee 00 02 07 00 00 00 01 decode-pair - -match Vendor-Specific = { Lucent = { Max-Shared-Users = 1 } } +match Vendor-Specific.Lucent.Max-Shared-Users = 1 decode-pair 1a 0d 00 00 12 ee ff 02 07 00 00 00 01 -match Vendor-Specific = { Lucent = { 65282 = 0x00000001 } } +match Vendor-Specific.Lucent.65282 = 0x00000001 encode-pair Vendor-Specific.Lucent.65282 = 0x00000001 match 1a 0d 00 00 12 ee ff 02 07 00 00 00 01 diff --git a/src/tests/unit/protocols/radius/vendor.txt b/src/tests/unit/protocols/radius/vendor.txt index 2587d33ef04..25db8118669 100644 --- a/src/tests/unit/protocols/radius/vendor.txt +++ b/src/tests/unit/protocols/radius/vendor.txt @@ -1,35 +1,38 @@ proto radius proto-dictionary radius +encode-pair Vendor-Specific = { Starent = { VPN-Name = "foo" } } +match 1a 0d 00 00 1f e4 00 02 00 07 66 6f 6f + encode-pair Vendor-Specific.Starent.VPN-Name = "foo" match 1a 0d 00 00 1f e4 00 02 00 07 66 6f 6f decode-pair - -match Vendor-Specific = { Starent = { VPN-Name = "foo" } } +match Vendor-Specific.Starent.VPN-Name = "foo" encode-pair Vendor-Specific.USR.Event-Id = 1234 match 1a 0e 00 00 01 ad 00 00 bf be 00 00 04 d2 decode-pair - -match Vendor-Specific = { USR = { Event-Id = 1234 } } +match Vendor-Specific.USR.Event-Id = 1234 decode-pair 1a 15 00 00 4e 20 01 0f 6c 69 74 68 69 61 73 70 72 69 6e 67 73 -match Vendor-Specific = { 20000 = { = 0x6c6974686961737072696e6773 } } +match Vendor-Specific.20000.1 = 0x6c6974686961737072696e6773 encode-pair Vendor-Specific.3com.User-Access-Level = Visitor, Vendor-Specific.3com.Ip-Host-Addr = "155.4.12.100 00:00:00:00:00:00" match 1a 0c 00 00 00 2b 01 06 00 00 00 00 1a 26 00 00 00 2b 3c 20 31 35 35 2e 34 2e 31 32 2e 31 30 30 20 30 30 3a 30 30 3a 30 30 3a 30 30 3a 30 30 3a 30 30 decode-pair - -match Vendor-Specific = { 3com = { User-Access-Level = Visitor, Ip-Host-Addr = "155.4.12.100 00:00:00:00:00:00" } } +match Vendor-Specific.3com.User-Access-Level = Visitor, Vendor-Specific.3com.Ip-Host-Addr = "155.4.12.100 00:00:00:00:00:00" # # The VSAs could also be packet into one Vendor-Specific # decode-pair 1a 2e 00 00 00 2b 1c 02 01 06 00 00 00 00 3c 20 31 35 35 2e 34 2e 31 32 2e 31 30 30 20 30 30 3a 30 30 3a 30 30 3a 30 30 3a 30 30 3a 30 30 -match Vendor-Specific = { 3com = { User-Access-Level = Visitor, Ip-Host-Addr = "155.4.12.100 00:00:00:00:00:00" } } +match Vendor-Specific.3com.User-Access-Level = Visitor, Vendor-Specific.3com.Ip-Host-Addr = "155.4.12.100 00:00:00:00:00:00" decode-pair 1a 2c 00 00 00 2b 01 06 00 00 00 00 3c 20 31 35 35 2e 34 2e 31 32 2e 31 30 30 20 30 30 3a 30 30 3a 30 30 3a 30 30 3a 30 30 3a 30 30 -match Vendor-Specific = { 3com = { User-Access-Level = Visitor, Ip-Host-Addr = "155.4.12.100 00:00:00:00:00:00" } } +match Vendor-Specific.3com.User-Access-Level = Visitor, Vendor-Specific.3com.Ip-Host-Addr = "155.4.12.100 00:00:00:00:00:00" # # Vendor-Specific is of type "vsa", and therefore cannot be assigned values. @@ -54,7 +57,7 @@ encode-pair Vendor-Specific.Unisphere.ERX-LI-Action = off match 1a 1a 00 00 13 0a 3a 14 8d 31 89 6e 2e 8a f5 fa 78 fb d5 90 d8 1a 15 91 c1 f1 decode-pair - -match Vendor-Specific = { Unisphere = { ERX-LI-Action = off } } +match Vendor-Specific.Unisphere.ERX-LI-Action = off #packet coa_request #original null @@ -66,7 +69,7 @@ match Vendor-Specific = { Unisphere = { ERX-LI-Action = off } } # Unknown vendors get decoded as TLVs with type=1,length=1 # decode-pair 1a12000080000105abcdef02076161616161 -match Vendor-Specific = { 32768 = { = 0xabcdef, = 0x6161616161 } } +match Vendor-Specific.32768.1 = 0xabcdef, Vendor-Specific.32768.2 = 0x6161616161 # # This MUST be 50 octets of data @@ -75,14 +78,14 @@ encode-pair Vendor-Specific.Microsoft.CHAP-Response = "xxxxxxxxxxxxxxxxxxxxxxxxx match 1a 3a 00 00 01 37 01 34 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 58 decode-pair - -match Vendor-Specific = { Microsoft = { CHAP-Response = 0x7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787858 } } +match Vendor-Specific.Microsoft.CHAP-Response = 0x7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787858 # # And now something which *isn't* 50 octets, but instead 49. # Therefore it's an "invalid attribute", as defined in RFC 6929 Section 2.8. # decode-pair 1a 39 00 00 01 37 01 33 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 -match Vendor-Specific = { Microsoft = { raw.CHAP-Response = 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 } } +match raw.Vendor-Specific.Microsoft.CHAP-Response = 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 count -match 40 +match 42 diff --git a/src/tests/unit/protocols/radius/wimax.txt b/src/tests/unit/protocols/radius/wimax.txt index f98a015913b..f490df87659 100644 --- a/src/tests/unit/protocols/radius/wimax.txt +++ b/src/tests/unit/protocols/radius/wimax.txt @@ -8,19 +8,19 @@ encode-pair Vendor-Specific.WiMAX.Capability.Release = "1.0" match 1a 0e 00 00 60 b5 01 08 00 01 05 31 2e 30 decode-pair - -match Vendor-Specific = { WiMAX = { Capability = { Release = "1.0" } } } +match Vendor-Specific.WiMAX.Capability = { Release = "1.0" } encode-pair Vendor-Specific.WiMAX.Capability.Accounting-Capabilities = 1 match 1a 0c 00 00 60 b5 01 06 00 02 03 01 decode-pair - -match Vendor-Specific = { WiMAX = { Capability = { Accounting-Capabilities = IP-Session-Based } } } +match Vendor-Specific.WiMAX.Capability = { Accounting-Capabilities = IP-Session-Based } encode-pair Vendor-Specific.WiMAX.Capability.Release = "1.0", Vendor-Specific.WiMAX.Capability.Accounting-Capabilities = 1 match 1a 11 00 00 60 b5 01 0b 00 01 05 31 2e 30 02 03 01 decode-pair - -match Vendor-Specific = { WiMAX = { Capability = { Release = "1.0", Accounting-Capabilities = IP-Session-Based } } } +match Vendor-Specific.WiMAX.Capability = { Release = "1.0", Accounting-Capabilities = IP-Session-Based } encode-pair - match 1a 11 00 00 60 b5 01 0b 00 01 05 31 2e 30 02 03 01 @@ -87,10 +87,10 @@ encode-pair Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2.Classifier.Direction match 1a 14 00 00 60 b5 54 0e 00 09 0b 04 03 01 05 06 04 04 1a 99 decode-pair - -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Direction = 1, Src-Spec = { Port = 6809 } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Direction = 1, Src-Spec = { Port = 6809 } } } decode-pair 1a 11 00 00 60 b5 54 0b 00 09 08 05 06 04 04 1a 99 -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Src-Spec = { Port = 6809 } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Src-Spec = { Port = 6809 } } } encode-pair - match 1a 11 00 00 60 b5 54 0b 00 09 08 05 06 04 04 1a 99 @@ -99,7 +99,7 @@ match 1a 11 00 00 60 b5 54 0b 00 09 08 05 06 04 04 1a 99 # 26.24757.84.9.5 has the correct length. # 26.24757.84.9.5.4 has the wrong length. decode-pair 1a 14 00 00 60 b5 54 0e 00 09 0b 04 03 01 05 06 04 05 1a 99 -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Direction = 1, raw.Src-Spec = 0x04051a99 } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Direction = 1, raw.Src-Spec = 0x04051a99 } } # The 26.24757.1 has the wrong length decode-pair 1a 11 00 00 60 b5 01 0a 00 01 05 31 2e 30 02 03 01 @@ -116,10 +116,10 @@ match 1a 11 00 00 60 b5 01 0c 00 01 05 31 2e 30 02 03 01 # 26.24757.1.1 has the wrong length decode-pair 1a 11 00 00 60 b5 01 0b 00 01 04 31 2e 30 02 03 01 -match Vendor-Specific = { WiMAX = { raw.Capability = 0x0104312e30020301 } } +match raw.Vendor-Specific.WiMAX.Capability = 0x0104312e30020301 decode-pair 1a 11 00 00 60 b5 01 0b 00 01 06 31 2e 30 02 03 01 -match Vendor-Specific = { WiMAX = { raw.Capability = 0x0106312e30020301 } } +match raw.Vendor-Specific.WiMAX.Capability = 0x0106312e30020301 encode-pair - match 1a 11 00 00 60 b5 01 0b 00 01 06 31 2e 30 02 03 01 @@ -149,7 +149,7 @@ match 1a 11 00 00 60 b5 01 0b 00 01 06 31 2e 30 02 03 01 # 26.24757.1.2 has the wrong length decode-pair 1a 11 00 00 60 b5 01 0b 00 01 05 31 2e 30 02 02 01 -match Vendor-Specific = { WiMAX = { raw.Capability = 0x0105312e30020201 } } +match raw.Vendor-Specific.WiMAX.Capability = 0x0105312e30020201 encode-pair - match 1a 11 00 00 60 b5 01 0b 00 01 05 31 2e 30 02 02 01 @@ -161,7 +161,7 @@ match 1a 11 00 00 60 b5 01 0b 00 01 05 31 2e 30 02 02 01 # 26.24757.1.2 has the wrong length # This means that 26.24757.1 is invalid, and we create a raw attribute. decode-pair 1a 11 00 00 60 b5 01 0b 00 01 05 31 2e 30 02 04 01 -match Vendor-Specific = { WiMAX = { raw.Capability = 0x0105312e30020401 } } +match raw.Vendor-Specific.WiMAX.Capability = 0x0105312e30020401 encode-pair - match 1a 11 00 00 60 b5 01 0b 00 01 05 31 2e 30 02 04 01 @@ -176,35 +176,34 @@ encode-pair Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2.Classifier.Classifie match 1a 15 00 00 60 b5 54 0f 00 09 0c 09 0a 03 08 01 03 37 02 03 54 decode-pair - -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { Eth-Priority-Range = { Low = 55, High = 84 } } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { Eth-Priority-Range = { Low = 55, High = 84 } } } } # A less efficient encoding of the above data decode-pair 1a 17 00 00 60 b5 54 11 00 09 0e 09 0c 03 05 01 03 37 03 05 02 03 54 -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { Eth-Priority-Range = { Low = 55 }, Eth-Priority-Range = { High = 84 } } } } } } - +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { Eth-Priority-Range = { Low = 55 }, Eth-Priority-Range = { High = 84 } } } } # 26.24757.84.9.9.3.1 has the wrong length decode-pair 1a 15 00 00 60 b5 54 0f 00 09 0c 09 0a 03 08 01 04 37 02 03 54 -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { raw.Eth-Priority-Range = 0x010437020354 } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { raw.Eth-Priority-Range = 0x010437020354 } } } # 26.24757.84.9.9.3.2 has the wrong length decode-pair 1a 15 00 00 60 b5 54 0f 00 09 0c 09 0a 03 08 01 03 37 02 04 54 -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { raw.Eth-Priority-Range = 0x010337020454 } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { raw.Eth-Priority-Range = 0x010337020454 } } } # 26.24757.84.9.9.3.2 has the wrong length # This means that the SECOND 26.24757.84.9.9.3 is invalid. decode-pair 1a 17 00 00 60 b5 54 11 00 09 0e 09 0c 03 05 01 03 37 03 05 02 04 54 -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { Eth-Priority-Range = { Low = 55 }, raw.Eth-Priority-Range = 0x020454 } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { Eth-Priority-Range = { Low = 55 }, raw.Eth-Priority-Range = 0x020454 } } } # 26.24757.84.9.9.3.1 has the wrong length # This means that 26.24757.84.9.9.3 is invalid. decode-pair 1a 17 00 00 60 b5 54 11 00 09 0e 09 0c 03 05 01 02 37 03 05 02 03 54 -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { raw.Eth-Priority-Range = 0x010237, Eth-Priority-Range = { High = 84 } } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2 = { Classifier = { Classifier-Eth-Option = { raw.Eth-Priority-Range = 0x010237, Eth-Priority-Range = { High = 84 } } } } # # Simple test for continued attributes # decode-pair 1a 0e 00 00 60 b5 01 08 80 01 05 31 2e 30 1a 0c 00 00 60 b5 01 06 00 02 03 00 -match Vendor-Specific = { WiMAX = { Capability = { Release = "1.0", Accounting-Capabilities = No-Accounting } } } +match Vendor-Specific.WiMAX.Capability = { Release = "1.0", Accounting-Capabilities = No-Accounting } # # See if encoding multiple attributes works @@ -245,7 +244,7 @@ match 1a 1d 00 00 60 b5 1c 17 00 0b 14 05 12 01 06 7f 00 00 01 04 04 08 40 05 06 # Structs not yet decoded into sub-groups # decode-pair - -match Vendor-Specific = { WiMAX = { Packet-Flow-Descriptor = { Classifier = { Src-Spec = { IP-Address = 127.0.0.1, Port = 2112, Port-Range.Start = 2112, Port-Range.End = 6809 } } } } } +match Vendor-Specific.WiMAX.Packet-Flow-Descriptor = { Classifier = { Src-Spec = { IP-Address = 127.0.0.1, Port = 2112, Port-Range.Start = 2112, Port-Range.End = 6809 } } } encode-pair Vendor-Specific.WiMAX.DNS-Server = ::1 match 1a 19 00 00 60 b5 34 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 @@ -260,8 +259,7 @@ encode-pair Vendor-Specific.WiMAX.Capability.Release = "xxxxxxxxxxxxxxxxxxxxxxxx match 1a ff 00 00 60 b5 01 f9 80 01 fd 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 1a 10 00 00 60 b5 01 0a 00 78 78 78 78 78 78 78 decode-pair - -match Vendor-Specific = { WiMAX = { Capability = { Release = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } } - +match Vendor-Specific.WiMAX.Capability = { Release = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } count match 122