On Sun, Dec 29, 2002 at 04:16:32PM -0500, dheitmueller wrote:
> Attached is a patch to decrypt DCE/RPC conversations that make use of
> NTLMSSP version 1.
Checked in, with a number of bug fixes.
> Here is what is still outstanding:
...
> * The ability to dissect the decrypted payload. I need to be able to
> hand the TVB with the decrypted buffer back to the calling dissector.
> Not quite sure what the best approach for this is this yet.
That's the stuff in "dcerpc_try_handoff()" (which I fixed to call the
NTLMSSP dissector only if it's actually NTLMSSP)?
One way to do that would be to set "pinfo->private_data" to point to a
"tvbuff_t *", have payload dissectors all assume that
"pinfo->private_data" points to a "tvbuff_t *" and set the "tvbuff_t *"
to which it points to the new tvb, and then do something such as
gboolean is_encrypted;
tvbuff_t *stub_tvb;
int stub_offset;
...
saved_proto = pinfo->current_proto;
saved_private_data = pinfo->private_data;
if (auth_info != NULL &&
auth_info->auth_level == DCE_C_AUTHN_LEVEL_PKT_PRIVACY) {
is_encrypted = TRUE;
stub_tvb = NULL;
stub_offset = 0;
length = tvb_length_remaining (tvb, offset);
if (length > 0) {
proto_tree_add_text(sub_tree, tvb, offset, length,
"Encrypted stub data (%d byte%s)",
length, plurality(length, "", "s"));
switch (auth_info->auth_type) {
case DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP: {
/* NTLMSSP */
tvbuff_t *ntlmssp_tvb;
ntlmssp_tvb = tvb_new_subset(tvb, offset, length, length);
pinfo->private_data = (void *)&stub_tvb;
call_dissector(ntlmssp_enc_payload_handle, ntlmssp_tvb, pinfo,
sub_tree);
break;
}
}
}
} else {
is_encrypted = FALSE;
stub_tvb = tvb;
stub_offset = 0;
}
if (stub_tvb != NULL) {
sub_dissect = info->request ? proc->dissect_rqst : proc->dissect_resp;
if (sub_dissect) {
pinfo->current_proto = sub_proto->name;
pinfo->private_data = (void *)info;
init_ndr_pointer_list(pinfo);
offset = sub_dissect (stub_tvb, stub_offset, pinfo, sub_tree, drep);
pinfo->current_proto = saved_proto;
pinfo->private_data = saved_private_data;
} else {
length = tvb_length_remaining (stub_tvb, stub_offset);
if (length > 0) {
proto_tree_add_text (sub_tree, stub_tvb, stub_offset, length,
"Stub data (%d byte%s)", length,
plurality(length, "", "s"));
}
}
}
and then don't have the decrypting dissector put anything into the
protocol tree (yes, one might argue that this slightly abuses the
dissector-handle mechanism to call functions that aren't, strictly
speaking, dissectors, but that's life).
> Please email with comments, problems, etc.
Well, I fixed a number of bugs that showed up when doing regressions.
However, a problem that a regression wouldn't show up is that it appears
that you never free the ntlmssp_info structures allocated by the NTLMSSP
dissector. You should probably allocate them from a GMemChunk (which is
a little quicker and, if there are a lot of them, a little more
memory-efficient than allocating them with "g_malloc()), and then have
"ntlmssp_init_protocol()" destroy that GMemChunk if it exists and then
create it regardless of whether it existed or not.