X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=epan%2Fdissectors%2Fpacket-xml.c;h=4961f7a47f390ff98a98ae582d38c01f41ddd07f;hb=574e9f8946b241d0de31b775ee9e0d832ecf187d;hp=9faecd793b9ace1f2ecbdd29a19e190733a0ecae;hpb=630c8140c93c5318854def7b10260dffd3cf6f35;p=metze%2Fwireshark%2Fwip.git diff --git a/epan/dissectors/packet-xml.c b/epan/dissectors/packet-xml.c index 9faecd793b..4961f7a47f 100644 --- a/epan/dissectors/packet-xml.c +++ b/epan/dissectors/packet-xml.c @@ -10,35 +10,29 @@ * By Gerald Combs * Copyright 1998 Gerald Combs * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include #include +#include #include #include #include +#include #include #include #include #include +#include #include -#include +#include +#include +#include "packet-kerberos.h" +#include "read_keytab_file.h" #include "packet-xml.h" @@ -59,6 +53,7 @@ static int hf_comment = -1; static int hf_xmlpi = -1; static int hf_dtd_tag = -1; static int hf_doctype = -1; +static int hf_cdatasection = -1; static expert_field ei_xml_closing_unopened_tag = EI_INIT; static expert_field ei_xml_closing_unopened_xmpli_tag = EI_INIT; @@ -66,14 +61,15 @@ static expert_field ei_xml_unrecognized_text = EI_INIT; /* dissector handles */ static dissector_handle_t xml_handle; +static dissector_handle_t gssapi_handle; /* parser definitions */ static tvbparse_wanted_t *want; static tvbparse_wanted_t *want_ignore; static tvbparse_wanted_t *want_heur; -static GHashTable *xmpli_names; -static GHashTable *media_types; +static wmem_map_t *xmpli_names; +static wmem_map_t *media_types; static xml_ns_t xml_ns = {"xml", "/", -1, -1, -1, NULL, NULL, NULL}; static xml_ns_t unknown_ns = {"unknown", "?", -1, -1, -1, NULL, NULL, NULL}; @@ -81,9 +77,6 @@ static xml_ns_t *root_ns; static gboolean pref_heuristic_unicode = FALSE; -static range_t *global_xml_tcp_range = NULL; -static range_t *xml_tcp_range = NULL; - #define XML_CDATA -1000 #define XML_SCOPED_NAME -1001 @@ -99,12 +92,16 @@ static const gchar *default_media_types[] = { "text/vnd.wap.sl", "text/vnd.wap.co", "text/vnd.wap.emn", + "application/3gpp-ims+xml", "application/atom+xml", "application/auth-policy+xml", "application/ccmp+xml", + "application/conference-info+xml", /*RFC4575*/ "application/cpim-pidf+xml", "application/cpl+xml", "application/dds-web+xml", + "application/im-iscomposing+xml", /*RFC3994*/ + "application/load-control+xml", /*RFC7200*/ "application/mathml+xml", "application/media_control+xml", "application/note+xml", @@ -117,8 +114,10 @@ static const gchar *default_media_types[] = { "application/rlmi+xml", "application/rls-services+xml", "application/rss+xml", + "application/rs-metadata+xml", "application/smil", "application/simple-filter+xml", + "application/simple-message-summary+xml", /*RFC3842*/ "application/simservs+xml", "application/soap+xml", "application/vnd.etsi.aoc+xml", @@ -129,14 +128,67 @@ static const gchar *default_media_types[] = { "application/vnd.etsi.iptvsad-bc+xml", "application/vnd.etsi.iptvsad-cod+xml", "application/vnd.etsi.iptvsad-npvr+xml", + "application/vnd.etsi.iptvservice+xml", + "application/vnd.etsi.iptvsync+xml", "application/vnd.etsi.iptvueprofile+xml", "application/vnd.etsi.mcid+xml", + "application/vnd.etsi.overload-control-policy-dataset+xml", + "application/vnd.etsi.pstn+xml", "application/vnd.etsi.sci+xml", "application/vnd.etsi.simservs+xml", + "application/vnd.etsi.tsl+xml", "application/vnd.oma.xdm-apd+xml", + "application/vnd.oma.fnl+xml", + "application/vnd.oma.access-permissions-list+xml", + "application/vnd.oma.alias-principals-list+xml", + "application/upp-directory+xml", /*OMA-ERELD-XDM-V2_2_1-20170124-A*/ + "application/vnd.oma.xdm-hi+xml", + "application/vnd.oma.xdm-rhi+xml", + "application/vnd.oma.xdm-prefs+xml", + "application/vnd.oma.xdcp+xml", + "application/vnd.oma.bcast.associated-procedure-parameter+xml", + "application/vnd.oma.bcast.drm-trigger+xml", + "application/vnd.oma.bcast.imd+xml", + "application/vnd.oma.bcast.notification+xml", + "application/vnd.oma.bcast.sgdd+xml", + "application/vnd.oma.bcast.smartcard-trigger+xml", + "application/vnd.oma.bcast.sprov+xml", + "application/vnd.oma.cab-address-book+xml", + "application/vnd.oma.cab-feature-handler+xml", + "application/vnd.oma.cab-pcc+xml", + "application/vnd.oma.cab-subs-invite+xml", + "application/vnd.oma.cab-user-prefs+xml", + "application/vnd.oma.dd2+xml", + "application/vnd.oma.drm.risd+xml", + "application/vnd.oma.group-usage-list+xml", + "application/vnd.oma.pal+xml", + "application/vnd.oma.poc.detailed-progress-report+xml", + "application/vnd.oma.poc.final-report+xml", + "application/vnd.oma.poc.groups+xml", + "application/vnd.oma.poc.invocation-descriptor+xml", + "application/vnd.oma.poc.optimized-progress-report+xml", + "application/vnd.oma.scidm.messages+xml", + "application/vnd.oma.suppnot+xml", /*OMA-ERELD-Presence_SIMPLE-V2_0-20120710-A*/ + "application/vnd.oma.xcap-directory+xml", + "application/vnd.omads-email+xml", + "application/vnd.omads-file+xml", + "application/vnd.omads-folder+xml", + "application/vnd.3gpp.access-transfer-events+xml", + "application/vnd.3gpp.bsf+xml", + "application/vnd.3gpp.comm-div-info+xml", /*3GPP TS 24.504 version 8.19.0*/ "application/vnd.3gpp.cw+xml", - "application/vnd.3gpp.sms+xml" - "application/vnd.3gpp.SRVCC-info+xml", + "application/vnd.3gpp.iut+xml", /*3GPP TS 24.337*/ + "application/vnc.3gpp.iut-config+xml", /*3GPP TS 24.337*/ + "application/vnd.3gpp.mid-call+xml", + "application/vnd.3gpp-prose-pc3ch+xml", + "application/vnd.3gpp-prose+xml", + "application/vnd.3gpp.replication+xml", /*3GPP TS 24.337*/ + "application/vnd.3gpp.sms+xml", + "application/vnd.3gpp.srvcc-info+xml", + "application/vnd.3gpp.srvcc-ext+xml", + "application/vnd.3gpp.state-and-event-info+xml", + "application/vnd.3gpp.ussd+xml", + "application/vnd.3gpp2.bcmcsinfo+xml", "application/vnd.wv.csp+xml", "application/vnd.wv.csp.xml", "application/watcherinfo+xml", @@ -150,10 +202,12 @@ static const gchar *default_media_types[] = { "application/xml-dtd", "application/xpidf+xml", "application/xslt+xml", + "application/x-crd+xml", "application/x-wms-logconnectstats", "application/x-wms-logplaystats", "application/x-wms-sendevent", "image/svg+xml", + "message/imdn+xml", /*RFC5438*/ }; static void insert_xml_frame(xml_frame_t *parent, xml_frame_t *new_child) @@ -187,7 +241,7 @@ dissect_xml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) g_ptr_array_free(stack, TRUE); stack = g_ptr_array_new(); - current_frame = (xml_frame_t *)wmem_alloc(wmem_packet_scope(), sizeof(xml_frame_t)); + current_frame = wmem_new(wmem_packet_scope(), xml_frame_t); current_frame->type = XML_FRAME_ROOT; current_frame->name = NULL; current_frame->name_orig_case = NULL; @@ -198,18 +252,21 @@ dissect_xml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) tt = tvbparse_init(tvb, 0, -1, stack, want_ignore); current_frame->start_offset = 0; + current_frame->length = tvb_captured_length(tvb); + + current_frame->decryption_keys = wmem_map_new(wmem_packet_scope(), g_str_hash, g_str_equal); root_ns = NULL; if (pinfo->match_string) - root_ns = (xml_ns_t *)g_hash_table_lookup(media_types, pinfo->match_string); + root_ns = (xml_ns_t *)wmem_map_lookup(media_types, pinfo->match_string); if (! root_ns ) { root_ns = &xml_ns; colinfo_str = "/XML"; } else { char *colinfo_str_buf; - colinfo_str_buf = wmem_strdup_printf(wmem_packet_scope(), "/%s", root_ns->name); + colinfo_str_buf = wmem_strconcat(wmem_packet_scope(), "/", root_ns->name, NULL); ascii_strup_inplace(colinfo_str_buf); colinfo_str = colinfo_str_buf; } @@ -237,9 +294,8 @@ static gboolean dissect_xml_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree * return TRUE; } else if (pref_heuristic_unicode) { /* XXX - UCS-2, or UTF-16? */ - const guint8 *data_str = tvb_get_string_enc(NULL, tvb, 0, tvb_captured_length(tvb), ENC_UCS_2|ENC_LITTLE_ENDIAN); + const guint8 *data_str = tvb_get_string_enc(pinfo->pool, tvb, 0, tvb_captured_length(tvb), ENC_UCS_2|ENC_LITTLE_ENDIAN); tvbuff_t *unicode_tvb = tvb_new_child_real_data(tvb, data_str, tvb_captured_length(tvb)/2, tvb_captured_length(tvb)/2); - tvb_set_free_cb(unicode_tvb, g_free); if (tvbparse_peek(tvbparse_init(unicode_tvb, 0, -1, NULL, want_ignore), want_heur)) { add_new_data_source(pinfo, unicode_tvb, "UTF8"); dissect_xml(unicode_tvb, pinfo, tree, data); @@ -310,7 +366,8 @@ static void after_token(void *tvbparse_data, const void *wanted_data _U_, tvbpar int hfid; gboolean is_cdata = FALSE; proto_item *pi; - xml_frame_t *new_frame; + xml_frame_t *new_frame = NULL; + gchar *text = NULL; if (tok->id == XML_CDATA) { hfid = current_frame->ns ? current_frame->ns->hf_cdata : xml_ns.hf_cdata; @@ -323,11 +380,11 @@ static void after_token(void *tvbparse_data, const void *wanted_data _U_, tvbpar pi = proto_tree_add_item(current_frame->tree, hfid, tok->tvb, tok->offset, tok->len, ENC_UTF_8|ENC_NA); - proto_item_set_text(pi, "%s", - tvb_format_text(tok->tvb, tok->offset, tok->len)); + text = tvb_format_text(tok->tvb, tok->offset, tok->len); + proto_item_set_text(pi, "%s", text); if (is_cdata) { - new_frame = (xml_frame_t *)wmem_alloc(wmem_packet_scope(), sizeof(xml_frame_t)); + new_frame = wmem_new(wmem_packet_scope(), xml_frame_t); new_frame->type = XML_FRAME_CDATA; new_frame->name = NULL; new_frame->name_orig_case = NULL; @@ -337,9 +394,74 @@ static void after_token(void *tvbparse_data, const void *wanted_data _U_, tvbpar new_frame->last_item = pi; new_frame->tree = NULL; new_frame->start_offset = tok->offset; + new_frame->length = tok->len; new_frame->ns = NULL; new_frame->pinfo = current_frame->pinfo; } + + if (new_frame != NULL && + strcmp(current_frame->name_orig_case, "BinarySecurityToken") == 0) + { + xml_frame_t *value_type = NULL; + + value_type = xml_get_attrib(current_frame, "ValueType"); + if (value_type != NULL) { + const gchar *s = "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ"; + size_t l = strlen(s); + gint c; + c = tvb_strneql(value_type->value, 0, s, l); + if (c == 0) { + tvbuff_t *ssp_tvb = base64_to_tvb(new_frame->value, text); + add_new_data_source(current_frame->pinfo, ssp_tvb, "GSSAPI Data"); + call_dissector(gssapi_handle, ssp_tvb, + current_frame->pinfo, current_frame->tree); + } + } + } + + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); +#if 0 +#ifdef HAVE_KERBEROS + if (!pinfo->fd->flags.visited && si->status == 0) { + enc_key_t *ek; + + if (krb_decrypt) { + read_keytab_file_from_preferences(); + } + + for (ek=enc_key_list;ek;ek=ek->next) { + if (ek->fd_num == (int)pinfo->num) { + break; + } + } + + if (ek != NULL) { + smb2_sesid_info_t *sesid; + guint8 custom_seskey[NTLMSSP_KEY_LEN] = { 0, }; + const guint8 *session_key; + + sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t); + sesid->sesid = si->sesid; + /* TODO: fill in the correct information */ + sesid->acct_name = NULL; + sesid->domain_name = NULL; + sesid->host_name = NULL; + + if (seskey_find_sid_key(si->sesid, custom_seskey)) { + session_key = custom_seskey; + } else { + session_key = ek->keyvalue; + } + smb2_set_session_keys(sesid, session_key); + sesid->server_port = pinfo->srcport; + sesid->auth_frame = pinfo->num; + sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal); + g_hash_table_insert(si->conv->sesids, sesid, sesid); + } + } +#endif +#endif } static void before_xmpli(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) @@ -350,7 +472,7 @@ static void before_xmpli(void *tvbparse_data, const void *wanted_data _U_, tvbpa proto_tree *pt; tvbparse_elem_t *name_tok = tok->sub->next; gchar *name = tvb_get_string_enc(wmem_packet_scope(), name_tok->tvb, name_tok->offset, name_tok->len, ENC_ASCII); - xml_ns_t *ns = (xml_ns_t *)g_hash_table_lookup(xmpli_names, name); + xml_ns_t *ns = (xml_ns_t *)wmem_map_lookup(xmpli_names, name); xml_frame_t *new_frame; int hf_tag; @@ -371,7 +493,7 @@ static void before_xmpli(void *tvbparse_data, const void *wanted_data _U_, tvbpa pt = proto_item_add_subtree(pi, ett); - new_frame = (xml_frame_t *)wmem_alloc(wmem_packet_scope(), sizeof(xml_frame_t)); + new_frame = wmem_new(wmem_packet_scope(), xml_frame_t); new_frame->type = XML_FRAME_XMPLI; new_frame->name = name; new_frame->name_orig_case = name; @@ -381,11 +503,14 @@ static void before_xmpli(void *tvbparse_data, const void *wanted_data _U_, tvbpa new_frame->last_item = pi; new_frame->tree = pt; new_frame->start_offset = tok->offset; + new_frame->length = tok->len; new_frame->ns = ns; new_frame->pinfo = current_frame->pinfo; g_ptr_array_add(stack, new_frame); + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, new_frame->name_orig_case); + //fflush(stdout); } static void after_xmlpi(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) @@ -401,6 +526,14 @@ static void after_xmlpi(void *tvbparse_data, const void *wanted_data _U_, tvbpar proto_tree_add_expert(current_frame->tree, current_frame->pinfo, &ei_xml_closing_unopened_xmpli_tag, tok->tvb, tok->offset, tok->len); } + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + //fflush(stdout); + //fflush(stdout); + fflush(stdout); + fflush(stdout); + fflush(stdout); + fflush(stdout); + fflush(stdout); } static void before_tag(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) @@ -424,10 +557,10 @@ static void before_tag(void *tvbparse_data, const void *wanted_data _U_, tvbpars name = (gchar *)tvb_get_string_enc(wmem_packet_scope(), leaf_tok->tvb, leaf_tok->offset, leaf_tok->len, ENC_ASCII); name_orig_case = name; - nameroot_ns = (xml_ns_t *)g_hash_table_lookup(xml_ns.elements, root_name); + nameroot_ns = (xml_ns_t *)wmem_map_lookup(xml_ns.elements, root_name); if(nameroot_ns) { - ns = (xml_ns_t *)g_hash_table_lookup(nameroot_ns->elements, name); + ns = (xml_ns_t *)wmem_map_lookup(nameroot_ns->elements, name); if (!ns) { ns = &unknown_ns; } @@ -441,10 +574,10 @@ static void before_tag(void *tvbparse_data, const void *wanted_data _U_, tvbpars ascii_strdown_inplace(name); if(current_frame->ns) { - ns = (xml_ns_t *)g_hash_table_lookup(current_frame->ns->elements, name); + ns = (xml_ns_t *)wmem_map_lookup(current_frame->ns->elements, name); if (!ns) { - if (! ( ns = (xml_ns_t *)g_hash_table_lookup(root_ns->elements, name) ) ) { + if (! ( ns = (xml_ns_t *)wmem_map_lookup(root_ns->elements, name) ) ) { ns = &unknown_ns; } } @@ -460,7 +593,7 @@ static void before_tag(void *tvbparse_data, const void *wanted_data _U_, tvbpars pt = proto_item_add_subtree(pi, ns->ett); - new_frame = (xml_frame_t *)wmem_alloc(wmem_packet_scope(), sizeof(xml_frame_t)); + new_frame = wmem_new(wmem_packet_scope(), xml_frame_t); new_frame->type = XML_FRAME_TAG; new_frame->name = name; new_frame->name_orig_case = name_orig_case; @@ -470,11 +603,14 @@ static void before_tag(void *tvbparse_data, const void *wanted_data _U_, tvbpars new_frame->last_item = pi; new_frame->tree = pt; new_frame->start_offset = tok->offset; + new_frame->length = tok->len; new_frame->ns = ns; new_frame->pinfo = current_frame->pinfo; g_ptr_array_add(stack, new_frame); + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, new_frame->name_orig_case); + fflush(stdout); } static void after_open_tag(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok _U_) @@ -483,6 +619,8 @@ static void after_open_tag(void *tvbparse_data, const void *wanted_data _U_, tvb xml_frame_t *current_frame = (xml_frame_t *)g_ptr_array_index(stack, stack->len - 1); proto_item_append_text(current_frame->last_item, ">"); + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); } static void after_closed_tag(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) @@ -498,14 +636,43 @@ static void after_closed_tag(void *tvbparse_data, const void *wanted_data _U_, t proto_tree_add_expert(current_frame->tree, current_frame->pinfo, &ei_xml_closing_unopened_tag, tok->tvb, tok->offset, tok->len); } + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); +} + +struct decryption_key { + gchar *id; + size_t key_length; + guint8 key[HASH_SHA1_LENGTH]; +}; + +static void P_SHA1(const guint8 *Secret, guint32 Secret_len, + const guint8 *Seed, guint32 Seed_len, + guint8 Result[HASH_SHA1_LENGTH]) +{ + gcry_md_hd_t hd = NULL; + guint8 *digest = NULL; + + /* + * https://social.microsoft.com/Forums/en-US/c485d98b-6e0b-49e7-ab34-8ecf8d694d31/signing-soap-message-request-via-adfs?forum=crmdevelopment#6cee9fa8-dc24-4524-a5a2-c3d17e05d50e + */ + gcry_md_open(&hd, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); + gcry_md_setkey(hd, Secret, Secret_len); + gcry_md_write(hd, Seed, Seed_len); + digest = gcry_md_read(hd, GCRY_MD_SHA1); + memcpy(Result, digest, HASH_SHA1_LENGTH); + + gcry_md_close(hd); } static void after_untag(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) { GPtrArray *stack = (GPtrArray *)tvbparse_data; xml_frame_t *current_frame = (xml_frame_t *)g_ptr_array_index(stack, stack->len - 1); + xml_frame_t *top_frame = (xml_frame_t *)g_ptr_array_index(stack, 0); proto_item_set_len(current_frame->item, (tok->offset - current_frame->start_offset) + tok->len); + current_frame->length = (tok->offset - current_frame->start_offset) + tok->len; proto_tree_add_format_text(current_frame->tree, tok->tvb, tok->offset, tok->len); @@ -515,6 +682,215 @@ static void after_untag(void *tvbparse_data, const void *wanted_data _U_, tvbpar proto_tree_add_expert(current_frame->tree, current_frame->pinfo, &ei_xml_closing_unopened_tag, tok->tvb, tok->offset, tok->len); } + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); + + if (current_frame->name_orig_case == NULL) { + return; + } + +#ifdef HAVE_KERBEROS + if (strcmp(current_frame->name_orig_case, "DerivedKeyToken") == 0) { + xml_frame_t *id_frame = xml_get_attrib(current_frame, "u:Id"); + xml_frame_t *nonce_frame = xml_get_tag(current_frame, "Nonce"); + xml_frame_t *nonce_cdata = NULL; + tvbuff_t *nonce_tvb = NULL; + enc_key_t *ek = NULL; + guint8 seed[64]; + size_t seed_length = 16; // TODO + const size_t key_length = 16; //TODO + + //printf("%s:%s:%u: DerivedKeyToken->Id[%p]\n", __FILE__, G_STRFUNC, __LINE__, id_frame); + //printf("%s:%s:%u: DerivedKeyToken->Nonce[%p]\n", __FILE__, G_STRFUNC, __LINE__, nonce_frame); + fflush(stdout); + if (id_frame != NULL && nonce_frame != NULL) { + nonce_cdata = xml_get_cdata(nonce_frame); + } + if (nonce_cdata != NULL) { + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); + gchar *text = tvb_format_text(nonce_cdata->value, 0, + tvb_reported_length(nonce_cdata->value)); + nonce_tvb = base64_to_tvb(nonce_cdata->value, text); + } + if (nonce_tvb != NULL) { + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); + + seed_length = tvb_reported_length(nonce_tvb); + seed_length = MIN(seed_length, sizeof(seed)); + tvb_memcpy(nonce_tvb, seed, 0, seed_length); + + if (krb_decrypt) { + read_keytab_file_from_preferences(); + } + + for (ek=enc_key_list;ek;ek=ek->next) { + if (ek->fd_num == (int)current_frame->pinfo->num) { + break; + } + } + } + //printf("%s:%s:%u: ek[%p]\n", __FILE__, G_STRFUNC, __LINE__, ek); + fflush(stdout); + if (ek != NULL) { + struct decryption_key *key; + + key = wmem_new0(wmem_packet_scope(), struct decryption_key); + key->id = wmem_strdup_printf(wmem_packet_scope(), "#%s", + tvb_format_text(id_frame->value, 0, tvb_reported_length(id_frame->value))); + P_SHA1(ek->keyvalue, ek->keylength, seed, seed_length, key->key); + key->key_length = key_length; + + wmem_map_insert(top_frame->decryption_keys, key->id, key); + //printf("%s:%s:%u: key_id[%s] (%02x%02x%02x%02x...)\n", __FILE__, G_STRFUNC, __LINE__, key->id, + // key->key[0] & 0xFF, key->key[1] & 0xFF, + // key->key[2] & 0xFF, key->key[3] & 0xFF); + fflush(stdout); + } + //proto_item_append_text(current_frame->last_item, "(ek[%p])", ek); + // printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); + } + if (strcmp(current_frame->name_orig_case, "CipherValue") == 0) { + xml_frame_t *encrypted_frame = current_frame->parent->parent; + xml_frame_t *key_info_frame = NULL; + xml_frame_t *token_frame = NULL; + xml_frame_t *reference_frame = NULL; + xml_frame_t *uri_frame = NULL; + const struct decryption_key *key = NULL; + xml_frame_t *cdata_frame = NULL; + tvbuff_t *crypt_tvb = NULL; + tvbuff_t *plain_tvb = NULL; + + // printf("%s:%s:%u: CipherValue->Parent->Parent[%p]\n", __FILE__, G_STRFUNC, __LINE__, + // encrypted_frame); + // printf("%s:%s:%u: CipherValue->Parent->Parent[%s]\n", __FILE__, G_STRFUNC, __LINE__, + // encrypted_frame->name_orig_case); + + key_info_frame = xml_get_tag(encrypted_frame, "KeyInfo"); + if (key_info_frame != NULL) { + token_frame = xml_get_tag(key_info_frame, "SecurityTokenReference"); + } + if (token_frame != NULL) { + reference_frame = xml_get_tag(token_frame, "Reference"); + } + if (reference_frame != NULL) { + uri_frame = xml_get_attrib(reference_frame, "URI"); + } + + //printf("%s:%s:%u: key_info[%p] token[%p] reference[%p] uri[%p]\n", __FILE__, G_STRFUNC, __LINE__, + // key_info_frame, token_frame, reference_frame, uri_frame); + fflush(stdout); + if (uri_frame != NULL) { + gchar *key_id = tvb_format_text(uri_frame->value, 0, + tvb_reported_length(uri_frame->value)); + + + //printf("%s:%s:%u: URI[%s]\n", __FILE__, G_STRFUNC, __LINE__, key_id); + fflush(stdout); + key = (const struct decryption_key *)wmem_map_lookup(top_frame->decryption_keys, key_id); + } + if (key != NULL) { +// printf("%s:%s:%u: key_id[%s] (%02x%02x%02x%02x...)\n", __FILE__, G_STRFUNC, __LINE__, key->id, +// key->key[0] & 0xFF, key->key[1] & 0xFF, +// key->key[2] & 0xFF, key->key[3] & 0xFF); + fflush(stdout); + cdata_frame = xml_get_cdata(current_frame); + } + if (cdata_frame != NULL) { + gchar *text = tvb_format_text(cdata_frame->value, 0, + tvb_reported_length(cdata_frame->value)); + crypt_tvb = base64_to_tvb(cdata_frame->value, text); + } + if (crypt_tvb != NULL) { + gcry_cipher_hd_t cipher_hd = NULL; + guint8 *data = NULL; + size_t data_length = tvb_reported_length(crypt_tvb); + +// printf("%s:%s:%u: data_length[%zu]\n", __FILE__, G_STRFUNC, __LINE__, data_length); + fflush(stdout); + data = (guint8 *)tvb_memdup(wmem_packet_scope(), + crypt_tvb, 0, data_length); + + /* Open the cipher. */ + gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0); + + gcry_cipher_setkey(cipher_hd, key->key, key->key_length); + //gcry_cipher_setctr(cipher_hd, A_1, NTLMSSP_KEY_LEN); + //gcry_cipher_encrypt(cipher_hd, plain_data, sti->size, NULL, 0); + //gcry_cipher_decrypt(cipher_hd, data, data_length, NULL, 0); + gcry_cipher_encrypt(cipher_hd, data, data_length, NULL, 0); + gcry_cipher_close(cipher_hd); + + plain_tvb = tvb_new_child_real_data(crypt_tvb, data, + data_length, data_length); + add_new_data_source(current_frame->pinfo, plain_tvb, "Decrypted Data"); + } + } +#endif +#if 0 + metze + strcmp(current_frame->name_orig_case, "BinarySecurityToken") == 0) + xml_frame_t *value_type = NULL; + + value_type = xml_get_attrib(current_frame, "ValueType"); + if (value_type != NULL) { + const gchar *s = "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ"; + size_t l = strlen(s); + gint c; + c = tvb_strneql(value_type->value, 0, s, l); + if (c == 0) { + tvbuff_t *ssp_tvb = base64_to_tvb(new_frame->value, text); + add_new_data_source(current_frame->pinfo, ssp_tvb, "GSSAPI Data"); + call_dissector(gssapi_handle, ssp_tvb, + current_frame->pinfo, current_frame->tree); + } + } + } + +#ifdef HAVE_KERBEROS + if (!pinfo->fd->flags.visited && si->status == 0) { + enc_key_t *ek; + + if (krb_decrypt) { + read_keytab_file_from_preferences(); + } + + for (ek=enc_key_list;ek;ek=ek->next) { + if (ek->fd_num == (int)pinfo->num) { + break; + } + } + + if (ek != NULL) { + smb2_sesid_info_t *sesid; + guint8 custom_seskey[NTLMSSP_KEY_LEN] = { 0, }; + const guint8 *session_key; + + sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t); + sesid->sesid = si->sesid; + /* TODO: fill in the correct information */ + sesid->acct_name = NULL; + sesid->domain_name = NULL; + sesid->host_name = NULL; + + if (seskey_find_sid_key(si->sesid, custom_seskey)) { + session_key = custom_seskey; + } else { + session_key = ek->keyvalue; + } + smb2_set_session_keys(sesid, session_key); + sesid->server_port = pinfo->srcport; + sesid->auth_frame = pinfo->num; + sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal); + g_hash_table_insert(si->conv->sesids, sesid, sesid); + } + } +#endif +#endif + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); } static void before_dtd_doctype(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) @@ -529,7 +905,7 @@ static void before_dtd_doctype(void *tvbparse_data, const void *wanted_data _U_, proto_item_set_text(dtd_item, "%s", tvb_format_text(tok->tvb, tok->offset, tok->len)); - new_frame = (xml_frame_t *)wmem_alloc(wmem_packet_scope(), sizeof(xml_frame_t)); + new_frame = wmem_new(wmem_packet_scope(), xml_frame_t); new_frame->type = XML_FRAME_DTD_DOCTYPE; new_frame->name = (gchar *)tvb_get_string_enc(wmem_packet_scope(), name_tok->tvb, name_tok->offset, @@ -541,10 +917,13 @@ static void before_dtd_doctype(void *tvbparse_data, const void *wanted_data _U_, new_frame->last_item = dtd_item; new_frame->tree = proto_item_add_subtree(dtd_item, ett_dtd); new_frame->start_offset = tok->offset; + new_frame->length = tok->len; new_frame->ns = NULL; new_frame->pinfo = current_frame->pinfo; g_ptr_array_add(stack, new_frame); + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, new_frame->name_orig_case); + fflush(stdout); } static void pop_stack(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok _U_) @@ -558,6 +937,8 @@ static void pop_stack(void *tvbparse_data, const void *wanted_data _U_, tvbparse proto_tree_add_expert(current_frame->tree, current_frame->pinfo, &ei_xml_closing_unopened_tag, tok->tvb, tok->offset, tok->len); } + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); } static void after_dtd_close(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) @@ -572,6 +953,8 @@ static void after_dtd_close(void *tvbparse_data, const void *wanted_data _U_, tv proto_tree_add_expert(current_frame->tree, current_frame->pinfo, &ei_xml_closing_unopened_tag, tok->tvb, tok->offset, tok->len); } + //printf("%s:%s:%u: name[%s]\n", __FILE__, G_STRFUNC, __LINE__, current_frame->name_orig_case); + fflush(stdout); } static void get_attrib_value(void *tvbparse_data _U_, const void *wanted_data _U_, tvbparse_elem_t *tok) @@ -595,7 +978,7 @@ static void after_attrib(void *tvbparse_data, const void *wanted_data _U_, tvbpa name_orig_case = wmem_strdup(wmem_packet_scope(), name); ascii_strdown_inplace(name); - if(current_frame->ns && (hfidp = (int *)g_hash_table_lookup(current_frame->ns->attributes, name) )) { + if(current_frame->ns && (hfidp = (int *)wmem_map_lookup(current_frame->ns->attributes, name) )) { hfid = *hfidp; value = value_part; } else { @@ -608,7 +991,7 @@ static void after_attrib(void *tvbparse_data, const void *wanted_data _U_, tvbpa current_frame->last_item = pi; - new_frame = (xml_frame_t *)wmem_alloc(wmem_packet_scope(), sizeof(xml_frame_t)); + new_frame = wmem_new(wmem_packet_scope(), xml_frame_t); new_frame->type = XML_FRAME_ATTRIB; new_frame->name = name; new_frame->name_orig_case = name_orig_case; @@ -619,6 +1002,7 @@ static void after_attrib(void *tvbparse_data, const void *wanted_data _U_, tvbpa new_frame->last_item = pi; new_frame->tree = NULL; new_frame->start_offset = tok->offset; + new_frame->length = tok->len; new_frame->ns = NULL; new_frame->pinfo = current_frame->pinfo; @@ -686,6 +1070,13 @@ static void init_xml_parser(void) TP_UNTIL_INCLUDE), NULL); + tvbparse_wanted_t *want_cdatasection = tvbparse_set_seq(hf_cdatasection, NULL, NULL, after_token, + tvbparse_string(-1, "", NULL, NULL, NULL), + TP_UNTIL_INCLUDE), + NULL); + tvbparse_wanted_t *want_xmlpi = tvbparse_set_seq(hf_xmlpi, NULL, before_xmpli, NULL, tvbparse_string(-1, "name = g_strdup(name); + ns->name = wmem_strdup(wmem_epan_scope(), name); ns->hf_tag = -1; ns->hf_cdata = -1; ns->ett = -1; - ns->attributes = g_hash_table_new(g_str_hash, g_str_equal); - ns->elements = g_hash_table_new(g_str_hash, g_str_equal); + ns->attributes = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); + ns->elements = NULL; va_start(ap, name); while(( attr_name = va_arg(ap, gchar *) )) { - int *hfp = (int *)g_malloc(sizeof(int)); + int *hfp = wmem_new(wmem_epan_scope(), int); *hfp = -1; - g_hash_table_insert(ns->attributes, g_strdup(attr_name), hfp); + wmem_map_insert(ns->attributes, wmem_strdup(wmem_epan_scope(), attr_name), hfp); }; va_end(ap); - g_hash_table_insert(hash, ns->name, ns); + wmem_map_insert(hash, ns->name, ns); return ns; } @@ -819,11 +1212,7 @@ static void add_xml_field(wmem_array_t *hfs, int *p_id, const gchar *name, const hfri.hfinfo.strings = NULL; hfri.hfinfo.bitmask = 0x0; hfri.hfinfo.blurb = NULL; - hfri.hfinfo.id = 0; - hfri.hfinfo.parent = 0; - hfri.hfinfo.ref_type = HF_REF_TYPE_NONE; - hfri.hfinfo.same_name_next = NULL; - hfri.hfinfo.same_name_prev_id = -1; + HFILL_INIT(hfri); wmem_array_append_one(hfs, hfri); } @@ -831,7 +1220,7 @@ static void add_xml_field(wmem_array_t *hfs, int *p_id, const gchar *name, const static void add_xml_attribute_names(gpointer k, gpointer v, gpointer p) { struct _attr_reg_data *d = (struct _attr_reg_data *)p; - const gchar *basename = wmem_strdup_printf(wmem_epan_scope(), "%s.%s", d->basename, (gchar *)k); + const gchar *basename = wmem_strconcat(wmem_epan_scope(), d->basename, ".", (gchar *)k, NULL); add_xml_field(d->hf, (int*) v, (gchar *)k, basename); } @@ -840,7 +1229,7 @@ static void add_xml_attribute_names(gpointer k, gpointer v, gpointer p) static void add_xmlpi_namespace(gpointer k _U_, gpointer v, gpointer p) { xml_ns_t *ns = (xml_ns_t *)v; - const gchar *basename = wmem_strdup_printf(wmem_epan_scope(), "%s.%s", (gchar *)p, ns->name); + const gchar *basename = wmem_strconcat(wmem_epan_scope(), (gchar *)p, ".", ns->name, NULL); gint *ett_p = &(ns->ett); struct _attr_reg_data d; @@ -851,7 +1240,7 @@ static void add_xmlpi_namespace(gpointer k _U_, gpointer v, gpointer p) d.basename = basename; d.hf = hf_arr; - g_hash_table_foreach(ns->attributes, add_xml_attribute_names, &d); + wmem_map_foreach(ns->attributes, add_xml_attribute_names, &d); } @@ -867,6 +1256,7 @@ static void destroy_dtd_data(dtd_build_data_t *dtd_data) while(dtd_data->elements->len) { dtd_named_list_t *nl = (dtd_named_list_t *)g_ptr_array_remove_index_fast(dtd_data->elements, 0); g_ptr_array_free(nl->list, TRUE); + g_free(nl->name); g_free(nl); } @@ -875,6 +1265,7 @@ static void destroy_dtd_data(dtd_build_data_t *dtd_data) while(dtd_data->attributes->len) { dtd_named_list_t *nl = (dtd_named_list_t *)g_ptr_array_remove_index_fast(dtd_data->attributes, 0); g_ptr_array_free(nl->list, TRUE); + g_free(nl->name); g_free(nl); } @@ -885,35 +1276,35 @@ static void destroy_dtd_data(dtd_build_data_t *dtd_data) static void copy_attrib_item(gpointer k, gpointer v _U_, gpointer p) { - gchar *key = (gchar *)g_strdup((const gchar *)k); - int *value = (int *)g_malloc(sizeof(int)); - GHashTable *dst = (GHashTable *)p; + gchar *key = (gchar *)wmem_strdup(wmem_epan_scope(), (const gchar *)k); + int *value = wmem_new(wmem_epan_scope(), int); + wmem_map_t *dst = (wmem_map_t *)p; *value = -1; - g_hash_table_insert(dst, key, value); + wmem_map_insert(dst, key, value); } -static GHashTable *copy_attributes_hash(GHashTable *src) +static wmem_map_t *copy_attributes_hash(wmem_map_t *src) { - GHashTable *dst = g_hash_table_new(g_str_hash, g_str_equal); + wmem_map_t *dst = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); - g_hash_table_foreach(src, copy_attrib_item, dst); + wmem_map_foreach(src, copy_attrib_item, dst); return dst; } static xml_ns_t *duplicate_element(xml_ns_t *orig) { - xml_ns_t *new_item = (xml_ns_t *)g_malloc(sizeof(xml_ns_t)); + xml_ns_t *new_item = wmem_new(wmem_epan_scope(), xml_ns_t); guint i; - new_item->name = g_strdup(orig->name); + new_item->name = wmem_strdup(wmem_epan_scope(), orig->name); new_item->hf_tag = -1; new_item->hf_cdata = -1; new_item->ett = -1; new_item->attributes = copy_attributes_hash(orig->attributes); - new_item->elements = g_hash_table_new(g_str_hash, g_str_equal); + new_item->elements = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); new_item->element_names = g_ptr_array_new(); for(i=0; i < orig->element_names->len; i++) { @@ -927,23 +1318,23 @@ static xml_ns_t *duplicate_element(xml_ns_t *orig) static gchar *fully_qualified_name(GPtrArray *hier, gchar *name, gchar *proto_name) { guint i; - GString *s = g_string_new(proto_name); + wmem_strbuf_t *s = wmem_strbuf_new(wmem_epan_scope(), proto_name); - g_string_append(s, "."); + wmem_strbuf_append(s, "."); for (i = 1; i < hier->len; i++) { - g_string_append_printf(s, "%s.", (gchar *)g_ptr_array_index(hier, i)); + wmem_strbuf_append_printf(s, "%s.", (gchar *)g_ptr_array_index(hier, i)); } - g_string_append(s, name); + wmem_strbuf_append(s, name); - return g_string_free(s, FALSE); + return wmem_strbuf_finalize(s);; } static xml_ns_t *make_xml_hier(gchar *elem_name, xml_ns_t *root, - GHashTable *elements, + wmem_map_t *elements, GPtrArray *hier, GString *error, wmem_array_t *hfs, @@ -962,7 +1353,7 @@ static xml_ns_t *make_xml_hier(gchar *elem_name, return NULL; } - if (! ( orig = (xml_ns_t *)g_hash_table_lookup(elements, elem_name) )) { + if (! ( orig = (xml_ns_t *)wmem_map_lookup(elements, elem_name) )) { g_string_append_printf(error, "element '%s' is not defined\n", elem_name); return NULL; } @@ -991,7 +1382,7 @@ static xml_ns_t *make_xml_hier(gchar *elem_name, d.basename = fqn; d.hf = hfs; - g_hash_table_foreach(fresh->attributes, add_xml_attribute_names, &d); + wmem_map_foreach(fresh->attributes, add_xml_attribute_names, &d); while(fresh->element_names->len) { gchar *child_name = (gchar *)g_ptr_array_remove_index(fresh->element_names, 0); @@ -1002,7 +1393,7 @@ static xml_ns_t *make_xml_hier(gchar *elem_name, g_ptr_array_remove_index_fast(hier, hier->len - 1); if (child_element) { - g_hash_table_insert(fresh->elements, child_element->name, child_element); + wmem_map_insert(fresh->elements, child_element->name, child_element); } } @@ -1011,35 +1402,20 @@ static xml_ns_t *make_xml_hier(gchar *elem_name, return fresh; } -static gboolean free_both(gpointer k, gpointer v, gpointer p _U_) -{ - g_free(k); - g_free(v); - return TRUE; -} - -static gboolean free_elements(gpointer k _U_, gpointer v, gpointer p _U_) +static void free_elements(gpointer k _U_, gpointer v, gpointer p _U_) { xml_ns_t *e = (xml_ns_t *)v; - g_free(e->name); - g_hash_table_foreach_remove(e->attributes, free_both, NULL); - g_hash_table_destroy(e->attributes); - g_hash_table_destroy(e->elements); - while (e->element_names->len) { g_free(g_ptr_array_remove_index(e->element_names, 0)); } g_ptr_array_free(e->element_names, TRUE); - g_free(e); - - return TRUE; } static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) { - GHashTable *elements = g_hash_table_new(g_str_hash, g_str_equal); + wmem_map_t *elements = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); gchar *root_name = NULL; xml_ns_t *root_element = NULL; wmem_array_t *hfs; @@ -1051,44 +1427,45 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) /* we first populate elements with the those coming from the parser */ while(dtd_data->elements->len) { dtd_named_list_t *nl = (dtd_named_list_t *)g_ptr_array_remove_index(dtd_data->elements, 0); - xml_ns_t *element = (xml_ns_t *)g_malloc(sizeof(xml_ns_t)); + xml_ns_t *element = wmem_new(wmem_epan_scope(), xml_ns_t); /* we will use the first element found as root in case no other one was given. */ if (root_name == NULL) - root_name = g_strdup(nl->name); + root_name = wmem_strdup(wmem_epan_scope(), nl->name); - element->name = nl->name; + element->name = wmem_strdup(wmem_epan_scope(), nl->name); element->element_names = nl->list; element->hf_tag = -1; element->hf_cdata = -1; element->ett = -1; - element->attributes = g_hash_table_new(g_str_hash, g_str_equal); - element->elements = g_hash_table_new(g_str_hash, g_str_equal); + element->attributes = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); + element->elements = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); - if( g_hash_table_lookup(elements, element->name) ) { + if( wmem_map_lookup(elements, element->name) ) { g_string_append_printf(errors, "element %s defined more than once\n", element->name); free_elements(NULL, element, NULL); } else { - g_hash_table_insert(elements, (gpointer)element->name, element); - g_ptr_array_add(element_names, g_strdup(element->name)); + wmem_map_insert(elements, element->name, element); + g_ptr_array_add(element_names, wmem_strdup(wmem_epan_scope(), element->name)); } + g_free(nl->name); g_free(nl); } /* then we add the attributes to its relative elements */ while(dtd_data->attributes->len) { dtd_named_list_t *nl = (dtd_named_list_t *)g_ptr_array_remove_index(dtd_data->attributes, 0); - xml_ns_t *element = (xml_ns_t *)g_hash_table_lookup(elements, nl->name); + xml_ns_t *element = (xml_ns_t *)wmem_map_lookup(elements, nl->name); if (element) { while(nl->list->len) { gchar *name = (gchar *)g_ptr_array_remove_index(nl->list, 0); - int *id_p = (int *)g_malloc(sizeof(int)); + int *id_p = wmem_new(wmem_epan_scope(), int); *id_p = -1; - g_hash_table_insert(element->attributes, name, id_p); - } + wmem_map_insert(element->attributes, wmem_strdup(wmem_epan_scope(), name), id_p); + g_free(name); } } else { g_string_append_printf(errors, "element %s is not defined\n", nl->name); @@ -1101,8 +1478,8 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) /* if a proto_root is defined in the dtd we'll use that as root */ if( dtd_data->proto_root ) { - g_free(root_name); - root_name = g_strdup(dtd_data->proto_root); + wmem_free(wmem_epan_scope(), root_name); + root_name = wmem_strdup(wmem_epan_scope(), dtd_data->proto_root); } /* we use a stack with the names to avoid recurring infinitelly */ @@ -1115,7 +1492,7 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) if( ! dtd_data->proto_name ) { hfs = hf_arr; etts = ett_arr; - g_ptr_array_add(hier, g_strdup("xml")); + g_ptr_array_add(hier, wmem_strdup(wmem_epan_scope(), "xml")); } else { /* * if we were given a proto_name the namespace will be registered @@ -1126,13 +1503,13 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) } /* the root element of the dtd's namespace */ - root_element = (xml_ns_t *)g_malloc(sizeof(xml_ns_t)); - root_element->name = g_strdup(root_name); - root_element->fqn = dtd_data->proto_name ? g_strdup(dtd_data->proto_name) : root_element->name; + root_element = wmem_new(wmem_epan_scope(), xml_ns_t); + root_element->name = wmem_strdup(wmem_epan_scope(), root_name); + root_element->fqn = dtd_data->proto_name ? wmem_strdup(wmem_epan_scope(), dtd_data->proto_name) : root_element->name; root_element->hf_tag = -1; root_element->hf_cdata = -1; root_element->ett = -1; - root_element->elements = g_hash_table_new(g_str_hash, g_str_equal); + root_element->elements = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); root_element->element_names = element_names; /* @@ -1145,9 +1522,9 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) make_xml_hier(root_name, root_element, elements, hier, errors, hfs, etts, dtd_data->proto_name); - g_hash_table_insert(root_element->elements, (gpointer)root_element->name, root_element); + wmem_map_insert(root_element->elements, (gpointer)root_element->name, root_element); - orig_root = (xml_ns_t *)g_hash_table_lookup(elements, root_name); + orig_root = (xml_ns_t *)wmem_map_lookup(elements, root_name); /* if the root element was defined copy its attrlist to the child */ if(orig_root) { @@ -1157,9 +1534,9 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) d.hf = hfs; root_element->attributes = copy_attributes_hash(orig_root->attributes); - g_hash_table_foreach(root_element->attributes, add_xml_attribute_names, &d); + wmem_map_foreach(root_element->attributes, add_xml_attribute_names, &d); } else { - root_element->attributes = g_hash_table_new(g_str_hash, g_str_equal); + root_element->attributes = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); } /* we then create all the sub hierarchies to catch the recurred cases */ @@ -1168,20 +1545,18 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) while(root_element->element_names->len) { curr_name = (gchar *)g_ptr_array_remove_index(root_element->element_names, 0); - if( ! g_hash_table_lookup(root_element->elements, curr_name) ) { + if( ! wmem_map_lookup(root_element->elements, curr_name) ) { xml_ns_t *fresh = make_xml_hier(curr_name, root_element, elements, hier, errors, hfs, etts, dtd_data->proto_name); - g_hash_table_insert(root_element->elements, (gpointer)fresh->name, fresh); + wmem_map_insert(root_element->elements, (gpointer)fresh->name, fresh); } - - g_free(curr_name); } } else { /* a flat namespace */ g_ptr_array_add(hier, root_name); - root_element->attributes = g_hash_table_new(g_str_hash, g_str_equal); + root_element->attributes = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); while(root_element->element_names->len) { xml_ns_t *fresh; @@ -1189,7 +1564,7 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) struct _attr_reg_data d; curr_name = (gchar *)g_ptr_array_remove_index(root_element->element_names, 0); - fresh = duplicate_element((xml_ns_t *)g_hash_table_lookup(elements, curr_name)); + fresh = duplicate_element((xml_ns_t *)wmem_map_lookup(elements, curr_name)); fresh->fqn = fully_qualified_name(hier, curr_name, root_name); add_xml_field(hfs, &(fresh->hf_tag), curr_name, fresh->fqn); @@ -1198,14 +1573,14 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) d.basename = fresh->fqn; d.hf = hfs; - g_hash_table_foreach(fresh->attributes, add_xml_attribute_names, &d); + wmem_map_foreach(fresh->attributes, add_xml_attribute_names, &d); ett_p = &fresh->ett; g_array_append_val(etts, ett_p); g_ptr_array_free(fresh->element_names, TRUE); - g_hash_table_insert(root_element->elements, (gpointer)fresh->name, fresh); + wmem_map_insert(root_element->elements, (gpointer)fresh->name, fresh); } } @@ -1219,39 +1594,37 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) */ if( dtd_data->proto_name ) { gint *ett_p; + gchar *full_name, *short_name; - if ( ! dtd_data->description) { - dtd_data->description = wmem_strdup(wmem_epan_scope(), root_name); + if (dtd_data->description) { + full_name = wmem_strdup(wmem_epan_scope(), dtd_data->description); + } else { + full_name = wmem_strdup(wmem_epan_scope(), root_name); } + short_name = wmem_strdup(wmem_epan_scope(), dtd_data->proto_name); ett_p = &root_element->ett; g_array_append_val(etts, ett_p); add_xml_field(hfs, &root_element->hf_cdata, root_element->name, root_element->fqn); - root_element->hf_tag = proto_register_protocol(dtd_data->description, - dtd_data->proto_name, - dtd_data->proto_name); + root_element->hf_tag = proto_register_protocol(full_name, short_name, short_name); proto_register_field_array(root_element->hf_tag, (hf_register_info*)wmem_array_get_raw(hfs), wmem_array_get_count(hfs)); proto_register_subtree_array((gint **)g_array_data(etts), etts->len); if (dtd_data->media_type) { - g_hash_table_insert(media_types, dtd_data->media_type, root_element); - dtd_data->media_type = NULL; + gchar* media_type = wmem_strdup(wmem_epan_scope(), dtd_data->media_type); + wmem_map_insert(media_types, media_type, root_element); } - dtd_data->description = NULL; - dtd_data->proto_name = NULL; g_array_free(etts, TRUE); } - g_hash_table_insert(xml_ns.elements, (gpointer)root_element->name, root_element); - - g_hash_table_foreach_remove(elements, free_elements, NULL); - g_hash_table_destroy(elements); + wmem_map_insert(xml_ns.elements, root_element->name, root_element); + wmem_map_foreach(elements, free_elements, NULL); destroy_dtd_data(dtd_data); - g_free(root_name); + wmem_free(wmem_epan_scope(), root_name); } # define DIRECTORY_T GDir @@ -1263,27 +1636,22 @@ static void register_dtd(dtd_build_data_t *dtd_data, GString *errors) static void init_xml_names(void) { - xml_ns_t *xmlpi_xml_ns; guint i; DIRECTORY_T *dir; const FILE_T *file; const gchar *filename; gchar *dirname; - GError **dummy = (GError **)g_malloc(sizeof(GError *)); + GError **dummy = wmem_new(wmem_epan_scope(), GError *); *dummy = NULL; - xmpli_names = g_hash_table_new(g_str_hash, g_str_equal); - media_types = g_hash_table_new(g_str_hash, g_str_equal); - - unknown_ns.elements = xml_ns.elements = g_hash_table_new(g_str_hash, g_str_equal); - unknown_ns.attributes = xml_ns.attributes = g_hash_table_new(g_str_hash, g_str_equal); - - xmlpi_xml_ns = xml_new_namespace(xmpli_names, "xml", "version", "encoding", "standalone", NULL); + xmpli_names = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); + media_types = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); - g_hash_table_destroy(xmlpi_xml_ns->elements); - xmlpi_xml_ns->elements = NULL; + unknown_ns.elements = xml_ns.elements = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); + unknown_ns.attributes = xml_ns.attributes = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal); + xml_new_namespace(xmpli_names, "xml", "version", "encoding", "standalone", NULL); dirname = get_persconffile_path("dtds", FALSE); @@ -1344,22 +1712,14 @@ static void init_xml_names(void) g_free(dirname); for(i=0;i