From 2e497e105f3d4d535de81dbd6364e23ed6fde6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Thu, 15 Jun 2017 13:38:34 +0100 Subject: [PATCH] RADIUS: Add dictionary support for format= with BEGIN-VENDOR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: 13745 Change-Id: Ibd00ea4818eb4b47a2c46324c1bfc878fef03d1e Reviewed-on: https://code.wireshark.org/review/22155 Petri-Dish: João Valverde Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann Reviewed-by: Anders Broman --- epan/dissectors/packet-radius.c | 30 +++++++++++----- epan/radius_dict.l | 61 ++++++++++++++++++++++++--------- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/epan/dissectors/packet-radius.c b/epan/dissectors/packet-radius.c index 84870f401c..5b61783810 100644 --- a/epan/dissectors/packet-radius.c +++ b/epan/dissectors/packet-radius.c @@ -1518,6 +1518,7 @@ dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo, tvbuff_t *tv vendor_offset += 4; while (offset < max_offset) { + radius_attr_type_t vendor_type; guint32 avp_vsa_type; guint32 avp_vsa_len; guint8 avp_vsa_flags = 0; @@ -1576,8 +1577,15 @@ dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo, tvbuff_t *tv avp_vsa_len -= avp_vsa_header_len; - if (vendor->attrs_by_id && !avp_is_extended) { - dictionary_entry = (radius_attr_info_t *)g_hash_table_lookup(vendor->attrs_by_id, GUINT_TO_POINTER(avp_vsa_type)); + if (avp_is_extended) { + vendor_type.u8_code[0] = avp_type.u8_code[0]; + vendor_type.u8_code[1] = avp_vsa_type; + } else { + vendor_type.u8_code[0] = avp_vsa_type; + vendor_type.u8_code[1] = 0; + } + if (vendor->attrs_by_id) { + dictionary_entry = (radius_attr_info_t *)g_hash_table_lookup(vendor->attrs_by_id, GUINT_TO_POINTER(vendor_type.value)); } else { dictionary_entry = NULL; } @@ -1590,6 +1598,10 @@ dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo, tvbuff_t *tv avp_tree = proto_tree_add_subtree_format(vendor_tree, tvb, offset-avp_vsa_header_len, avp_vsa_len+avp_vsa_header_len, dictionary_entry->ett, &avp_item, "VSA: l=%u t=%s(%u) C=0x%02x", avp_vsa_len+avp_vsa_header_len, dictionary_entry->name, avp_vsa_type, avp_vsa_flags); + } else if (avp_is_extended) { + avp_tree = proto_tree_add_subtree_format(vendor_tree, tvb, offset-avp_vsa_header_len, avp_vsa_len+avp_vsa_header_len, + dictionary_entry->ett, &avp_item, "EVS: l=%u t=%s(%u)", + avp_vsa_len+avp_vsa_header_len, dictionary_entry->name, avp_vsa_type); } else { avp_tree = proto_tree_add_subtree_format(vendor_tree, tvb, offset-avp_vsa_header_len, avp_vsa_len+avp_vsa_header_len, dictionary_entry->ett, &avp_item, "VSA: l=%u t=%s(%u)", @@ -2666,25 +2678,25 @@ register_radius_fields(const char *unused _U_) { "AVP", "radius.avp", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_radius_avp_length, - { "AVP Length", "radius.avp.length", FT_UINT8, BASE_DEC, NULL, 0x0, + { "Length", "radius.avp.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_radius_avp_type, - { "AVP Type", "radius.avp.type", FT_UINT8, BASE_DEC, NULL, 0x0, + { "Type", "radius.avp.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_radius_avp_vendor_id, - { "AVP Vendor ID", "radius.avp.vendor_id", FT_UINT32, BASE_DEC, NULL, 0x0, + { "Vendor ID", "radius.avp.vendor_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_radius_avp_vendor_type, - { "VSA Type", "radius.avp.vendor_type", FT_UINT8, BASE_DEC, NULL, 0x0, + { "Type", "radius.avp.vendor_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_radius_avp_vendor_len, - { "VSA Length", "radius.avp.vendor_len", FT_UINT8, BASE_DEC, NULL, 0x0, + { "Length", "radius.avp.vendor_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_radius_avp_extended_type, - { "AVP Extended Type", "radius.avp.extended_type", FT_UINT8, BASE_DEC, NULL, 0x0, + { "Extended Type", "radius.avp.extended_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_radius_avp_extended_more, - { "AVP Extended More", "radius.avp.extended_more", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x80, + { "Extended More", "radius.avp.extended_more", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x80, NULL, HFILL }}, { &hf_radius_egress_vlanid_tag, { "Tag", "radius.egress_vlanid_tag", FT_UINT32, BASE_HEX, VALS(egress_vlan_tag_vals), 0xFF000000, diff --git a/epan/radius_dict.l b/epan/radius_dict.l index 9e419ad6cd..3652c7f845 100644 --- a/epan/radius_dict.l +++ b/epan/radius_dict.l @@ -112,8 +112,6 @@ * internal, array, concat, and virtual as attribute flags (not * documented in the man page); * - * format= for BEGIN-VENDOR. - * * We should, perhaps, adopt FreeRADIUS's dictionary-parsing code in * src/lib/dict.c and use that, rather than writing our own parser. * See bug 13176. @@ -149,6 +147,7 @@ typedef struct { guint encrypted; gboolean has_tag; gchar* current_vendor; + guint current_vendor_evs_type; gchar* current_attr; gchar* directory; @@ -183,7 +182,7 @@ static void add_value(Radius_scanner_state_t* state, const gchar* attrib_name, c * name types in the FreeRadius dictionaries. */ -%START WS_OUT VENDOR VENDOR_W_NAME ATTR ATTR_W_NAME ATTR_W_ID ATTR_W_TYPE VALUE VALUE_W_ATTR VALUE_W_NAME INCLUDE JUNK BEGIN_VENDOR END_VENDOR VENDOR_W_ID VENDOR_W_FORMAT VENDOR_W_TYPE_OCTETS VENDOR_W_LENGTH_OCTETS VENDOR_W_CONTINUATION BEGIN_TLV END_TLV +%START WS_OUT VENDOR VENDOR_W_NAME ATTR ATTR_W_NAME ATTR_W_ID ATTR_W_TYPE VALUE VALUE_W_ATTR VALUE_W_NAME INCLUDE JUNK BEGIN_VENDOR BEGIN_VENDOR_FORMAT END_VENDOR VENDOR_W_ID VENDOR_W_FORMAT VENDOR_W_TYPE_OCTETS VENDOR_W_LENGTH_OCTETS VENDOR_W_CONTINUATION BEGIN_TLV END_TLV %% [:blank:] ; #[^\n]* ; @@ -204,13 +203,32 @@ static void add_value(Radius_scanner_state_t* state, const gchar* attrib_name, c g_free(yyextra->current_vendor); } yyextra->current_vendor = g_strdup(yytext); + BEGIN BEGIN_VENDOR_FORMAT; +} +format=Extended-Vendor-Specific-[123456] { + if (strcmp(yytext, "format=Extended-Vendor-Specific-1") == 0) { + yyextra->current_vendor_evs_type = 241; + } else if(strcmp(yytext, "format=Extended-Vendor-Specific-2") == 0) { + yyextra->current_vendor_evs_type = 242; + } else if(strcmp(yytext, "format=Extended-Vendor-Specific-3") == 0) { + yyextra->current_vendor_evs_type = 243; + } else if(strcmp(yytext, "format=Extended-Vendor-Specific-4") == 0) { + yyextra->current_vendor_evs_type = 244; + } else if(strcmp(yytext, "format=Extended-Vendor-Specific-5") == 0) { + yyextra->current_vendor_evs_type = 245; + } else if(strcmp(yytext, "format=Extended-Vendor-Specific-6") == 0) { + yyextra->current_vendor_evs_type = 246; + } BEGIN WS_OUT; } +\n {BEGIN WS_OUT;} + [^\n]* { if (yyextra->current_vendor) { g_free(yyextra->current_vendor); yyextra->current_vendor = NULL; } + yyextra->current_vendor_evs_type = 0; BEGIN WS_OUT; } @@ -454,17 +472,33 @@ static gboolean add_attribute(Radius_scanner_state_t* state, const gchar* name, radius_attr_info_t* a; GHashTable* by_id; radius_attr_type_t code; - gchar *dot, *extcodestr = NULL; + guint8 code0 = 0, code1 = 0; + gchar *dot, *buf = NULL; if (attr){ return add_tlv(state, name, codestr, type, attr); } + buf = g_strdup(codestr); + dot = strchr(codestr, '.'); + if (dot) + *dot = '\0'; + code0 = (guint8) strtoul(buf, NULL, 10); + if (dot) + code1 = (guint8) strtoul(dot + 1, NULL, 10); + g_free(buf); + memset(&code, 0, sizeof(code)); if (vendor) { - radius_vendor_info_t* v; - v = (radius_vendor_info_t *)g_hash_table_lookup(state->dict->vendors_by_name,vendor); + if (state->current_vendor_evs_type) { + code.u8_code[0] = (guint8) state->current_vendor_evs_type; + code.u8_code[1] = code0; + } else { + code.u8_code[0] = code0; + code.u8_code[1] = 0; + } + radius_vendor_info_t* v = (radius_vendor_info_t *)g_hash_table_lookup(state->dict->vendors_by_name,vendor); if (! v) { g_string_append_printf(state->error, "Vendor: '%s', does not exist in %s:%i \n", vendor, state->fullpaths[state->include_stack_ptr], state->linenums[state->include_stack_ptr] ); return FALSE; @@ -472,18 +506,10 @@ static gboolean add_attribute(Radius_scanner_state_t* state, const gchar* name, by_id = v->attrs_by_id; } } else { - by_id = state->dict->attrs_by_id; - } + code.u8_code[0] = code0; + code.u8_code[1] = code1; - memset(&code, 0, sizeof(code)); - dot = strchr(codestr, '.'); - if (dot) { - *dot = '\0'; - extcodestr = dot + 1; - } - code.u8_code[0] = (guint8) strtoul(codestr, NULL, 10); - if (extcodestr) { - code.u8_code[1] = (guint8) strtoul(extcodestr, NULL, 10); + by_id = state->dict->attrs_by_id; } a=(radius_attr_info_t*)g_hash_table_lookup(by_id, GUINT_TO_POINTER(code.value)); @@ -708,6 +734,7 @@ gboolean radius_load_dictionary (radius_dictionary_t* d, gchar* dir, const gchar state.encrypted = 0; state.has_tag = FALSE; state.current_vendor = NULL; + state.current_vendor_evs_type = 0; state.current_attr = NULL; state.directory = dir;