forked from osmocom/wireshark
This commit refactors the dcerpc authentication subdissectors for
handling encrypted request/response PDUs. Instead of having dissection function pointers which perform both decryption and dissection, the function pointers now only decrypt the DCERPC fragment payload. Dissection is handled by the dcerpc_try_handoff() function (with DCERPC fragment reassembly if necessary). Details: - Move the dcerpc_auth_info struct into dcerpc.h as it is now used in the function prototype for the decryption function handlers. - decode_encrypted_data() was refactored to take a boolean request parameter instead of passing the DCERPC PDU packet type. - A tvbuff_t * data field was added to dcerpc_auth to hold the verifier. This is passed as an argument to the decryption function handlers. - Dissection of verifiers in request and response PDUs was moved to before the payload. - The dissect_dcerpc_cn_stub() function was refactored to perform the decryption process and hand decrypted data to the reassembly code instead of performing the decryption after reassembly. - Removed references to decrypted_info_t as it's not necessary anymore. Code was tested using encrypted and unencrypted fragmented PDUs. Before this commit ethereal could not dissect unencrypted (!) fragmented PDUs correctly. svn path=/trunk/; revision=8546
This commit is contained in:
parent
6a389c8bd1
commit
2d33b62811
234
packet-dcerpc.c
234
packet-dcerpc.c
|
@ -3,7 +3,7 @@
|
|||
* Copyright 2001, Todd Sabin <tas@webspan.net>
|
||||
* Copyright 2003, Tim Potter <tpot@samba.org>
|
||||
*
|
||||
* $Id: packet-dcerpc.c,v 1.141 2003/09/26 04:43:05 tpot Exp $
|
||||
* $Id: packet-dcerpc.c,v 1.142 2003/09/26 06:30:13 tpot Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -431,14 +431,6 @@ get_next_di(void)
|
|||
return &di[di_counter];
|
||||
}
|
||||
|
||||
|
||||
typedef struct _dcerpc_auth_info {
|
||||
guint8 auth_pad_len;
|
||||
guint8 auth_level;
|
||||
guint8 auth_type;
|
||||
guint32 auth_size;
|
||||
} dcerpc_auth_info;
|
||||
|
||||
/* try to desegment big DCE/RPC packets over TCP? */
|
||||
static gboolean dcerpc_cn_desegment = TRUE;
|
||||
|
||||
|
@ -556,28 +548,23 @@ static void dissect_auth_verf(tvbuff_t *auth_tvb, packet_info *pinfo,
|
|||
|
||||
/* Hand off payload data to a registered dissector */
|
||||
|
||||
static void dissect_encrypted_data(tvbuff_t *enc_tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
dcerpc_auth_subdissector_fns *auth_fns,
|
||||
guint8 ptype, char *drep)
|
||||
static tvbuff_t *decode_encrypted_data(tvbuff_t *enc_tvb,
|
||||
packet_info *pinfo,
|
||||
dcerpc_auth_subdissector_fns *auth_fns,
|
||||
gboolean is_request,
|
||||
dcerpc_auth_info *auth_info)
|
||||
{
|
||||
dcerpc_dissect_fnct_t *fn = NULL;
|
||||
dcerpc_decode_data_fnct_t *fn;
|
||||
|
||||
switch (ptype) {
|
||||
case PDU_REQ:
|
||||
if (is_request)
|
||||
fn = auth_fns->req_data_fn;
|
||||
break;
|
||||
case PDU_RESP:
|
||||
else
|
||||
fn = auth_fns->resp_data_fn;
|
||||
break;
|
||||
default:
|
||||
g_warning("attempt to dissect %s pdu encrypted data",
|
||||
val_to_str(ptype, pckt_vals, "Unknown (%u)"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (fn)
|
||||
fn(enc_tvb, 0, pinfo, tree, drep);
|
||||
return fn(enc_tvb, 0, pinfo, auth_info);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1812,47 +1799,13 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
|
|||
name, info->call_data->opnum);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the authentication level is DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
|
||||
* the stub data is encrypted, and we'd have to decrypt it in
|
||||
* order to dissect it.
|
||||
*/
|
||||
if (auth_info != NULL &&
|
||||
auth_info->auth_level == DCE_C_AUTHN_LEVEL_PKT_PRIVACY) {
|
||||
length = tvb_length_remaining (tvb, offset);
|
||||
|
||||
if (length > 0) {
|
||||
dcerpc_auth_subdissector_fns *auth_fns;
|
||||
decrypted_info_t *dit;
|
||||
tvbuff_t *enc_tvb;
|
||||
|
||||
enc_tvb = tvb_new_subset(tvb, offset, length, length);
|
||||
|
||||
proto_tree_add_text(sub_tree, enc_tvb, 0, length,
|
||||
"Encrypted stub data (%d byte%s)",
|
||||
length, plurality(length, "", "s"));
|
||||
|
||||
pinfo->decrypted_data = NULL;
|
||||
|
||||
if ((auth_fns = get_auth_subdissector_fns(
|
||||
auth_info->auth_level, auth_info->auth_type)))
|
||||
dissect_encrypted_data(
|
||||
enc_tvb, pinfo, sub_tree, auth_fns,
|
||||
info->request ? PDU_REQ : PDU_RESP, drep);
|
||||
|
||||
/* No decrypted data so don't try and call a subdissector */
|
||||
|
||||
if (!pinfo->decrypted_data)
|
||||
goto done;
|
||||
|
||||
dit = (decrypted_info_t *)pinfo->decrypted_data;
|
||||
tvb = dit->decr_tvb;
|
||||
sub_tree = dit->decr_tree;
|
||||
}
|
||||
}
|
||||
|
||||
sub_dissect = info->request ? proc->dissect_rqst : proc->dissect_resp;
|
||||
if (sub_dissect) {
|
||||
|
||||
/* Call subdissector if we have a zero auth_level and no decrypted data,
|
||||
or non-zero auth_level and sucessfully decrypted data. */
|
||||
|
||||
if (sub_dissect && ((!auth_info->auth_level && !pinfo->decrypted_data) ||
|
||||
(auth_info->auth_level && pinfo->decrypted_data))) {
|
||||
saved_proto = pinfo->current_proto;
|
||||
saved_private_data = pinfo->private_data;
|
||||
pinfo->current_proto = sub_proto->name;
|
||||
|
@ -1902,7 +1855,6 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
|
|||
}
|
||||
}
|
||||
|
||||
done:
|
||||
tap_queue_packet(dcerpc_tap, pinfo, info);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1914,6 +1866,8 @@ dissect_dcerpc_verifier (tvbuff_t *tvb, packet_info *pinfo,
|
|||
{
|
||||
int auth_offset;
|
||||
|
||||
auth_info->auth_data = NULL;
|
||||
|
||||
if (auth_info->auth_size != 0) {
|
||||
dcerpc_auth_subdissector_fns *auth_fns;
|
||||
tvbuff_t *auth_tvb;
|
||||
|
@ -1923,6 +1877,8 @@ dissect_dcerpc_verifier (tvbuff_t *tvb, packet_info *pinfo,
|
|||
auth_tvb = tvb_new_subset(tvb, auth_offset, hdr->auth_len,
|
||||
hdr->auth_len);
|
||||
|
||||
auth_info->auth_data = auth_tvb;
|
||||
|
||||
if ((auth_fns = get_auth_subdissector_fns(auth_info->auth_level,
|
||||
auth_info->auth_type)))
|
||||
dissect_auth_verf(auth_tvb, pinfo, dcerpc_tree, auth_fns,
|
||||
|
@ -1957,6 +1913,7 @@ dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
* If the full packet is here, and we've got an auth len, and it's
|
||||
* valid, then dissect the auth info.
|
||||
*/
|
||||
|
||||
if (tvb_length (tvb) >= hdr->frag_len
|
||||
&& hdr->auth_len
|
||||
&& (hdr->auth_len + 8 <= hdr->frag_len)) {
|
||||
|
@ -2368,6 +2325,8 @@ fragment_type(guint8 flags)
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
/* Dissect stub data (payload) of a DCERPC packet. */
|
||||
|
||||
static void
|
||||
dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *dcerpc_tree, proto_tree *tree,
|
||||
|
@ -2375,29 +2334,68 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
dcerpc_auth_info *auth_info, guint32 alloc_hint,
|
||||
guint32 frame)
|
||||
{
|
||||
int length, reported_length, stub_length;
|
||||
gboolean save_fragmented;
|
||||
gboolean save_fragmented, payload_ok;
|
||||
fragment_data *fd_head=NULL;
|
||||
guint32 tot_len;
|
||||
|
||||
|
||||
length = tvb_length_remaining(tvb, offset);
|
||||
reported_length = tvb_reported_length_remaining(tvb, offset);
|
||||
stub_length = hdr->frag_len - offset - auth_info->auth_size;
|
||||
if (length > stub_length)
|
||||
length = stub_length;
|
||||
if (reported_length > stub_length)
|
||||
reported_length = stub_length;
|
||||
tvbuff_t *payload_tvb;
|
||||
|
||||
save_fragmented = pinfo->fragmented;
|
||||
|
||||
payload_tvb = tvb_new_subset(
|
||||
tvb, offset, tvb_length_remaining(tvb, offset) -
|
||||
auth_info->auth_size, tvb_length_remaining(tvb, offset) -
|
||||
auth_info->auth_size);
|
||||
|
||||
payload_ok = TRUE;
|
||||
|
||||
/* Decrypt the PDU if it is encrypted */
|
||||
|
||||
pinfo->decrypted_data = NULL;
|
||||
|
||||
if (auth_info->auth_type) {
|
||||
dcerpc_auth_subdissector_fns *auth_fns;
|
||||
|
||||
if (dcerpc_tree)
|
||||
proto_tree_add_text(
|
||||
dcerpc_tree, payload_tvb, 0, -1,
|
||||
"Encrypted Stub Data (%d byte%s)",
|
||||
tvb_length(payload_tvb),
|
||||
plurality(tvb_length(payload_tvb), "", "s"));
|
||||
|
||||
if ((auth_fns = get_auth_subdissector_fns(
|
||||
auth_info->auth_level, auth_info->auth_type))) {
|
||||
tvbuff_t *result;
|
||||
|
||||
result = decode_encrypted_data(
|
||||
payload_tvb, pinfo, auth_fns,
|
||||
hdr->ptype == PDU_REQ, auth_info);
|
||||
|
||||
if (result) {
|
||||
int len = tvb_length(result);
|
||||
|
||||
add_new_data_source(
|
||||
pinfo, result, "Decrypted Stub Data");
|
||||
|
||||
pinfo->decrypted_data = result;
|
||||
|
||||
proto_tree_add_text(
|
||||
dcerpc_tree, result, 0, len,
|
||||
"Decrypted Stub Data (%d byte%s)",
|
||||
len, plurality(len, "", "s"));
|
||||
} else
|
||||
payload_ok = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* if this packet is not fragmented, just dissect it and exit */
|
||||
if(PFC_NOT_FRAGMENTED(hdr)){
|
||||
pinfo->fragmented = FALSE;
|
||||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
|
||||
tvb_new_subset (tvb, offset, length, reported_length),
|
||||
0, hdr->drep, di, auth_info);
|
||||
|
||||
dcerpc_try_handoff(
|
||||
pinfo, tree, dcerpc_tree,
|
||||
pinfo->decrypted_data ? pinfo->decrypted_data : payload_tvb,
|
||||
0, hdr->drep, di, auth_info);
|
||||
|
||||
pinfo->fragmented = save_fragmented;
|
||||
return;
|
||||
}
|
||||
|
@ -2409,10 +2407,12 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
then just dissect it and exit
|
||||
*/
|
||||
if( (!dcerpc_reassemble) && hdr->flags&PFC_FIRST_FRAG ){
|
||||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
|
||||
tvb_new_subset (tvb, offset, length,
|
||||
reported_length),
|
||||
0, hdr->drep, di, auth_info);
|
||||
|
||||
dcerpc_try_handoff(
|
||||
pinfo, tree, dcerpc_tree,
|
||||
pinfo->decrypted_data ? pinfo->decrypted_data :
|
||||
payload_tvb, 0, hdr->drep, di, auth_info);
|
||||
|
||||
if (check_col(pinfo->cinfo, COL_INFO)) {
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO,
|
||||
" [DCE/RPC %s fragment]", fragment_type(hdr->flags));
|
||||
|
@ -2421,56 +2421,46 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Replace encrypted payload with decrypted version for reassembly. */
|
||||
|
||||
if (pinfo->decrypted_data)
|
||||
payload_tvb = (tvbuff_t *)pinfo->decrypted_data;
|
||||
|
||||
/* if we have already seen this packet, see if it was reassembled
|
||||
and if so dissect the full pdu.
|
||||
then exit
|
||||
*/
|
||||
if(pinfo->fd->flags.visited){
|
||||
fd_head=fragment_get(pinfo, frame, dcerpc_co_reassemble_table);
|
||||
|
||||
goto end_cn_stub;
|
||||
}
|
||||
|
||||
|
||||
/* if we are not doing reassembly and it was neither a complete PDU
|
||||
nor the first fragment then there is nothing more we can do
|
||||
so we just have to exit
|
||||
*/
|
||||
if( !dcerpc_reassemble ){
|
||||
if( !dcerpc_reassemble )
|
||||
goto end_cn_stub;
|
||||
}
|
||||
|
||||
/* if we didnt get 'frame' we dont know where the PDU started and thus
|
||||
it is pointless to continue
|
||||
*/
|
||||
if(!frame){
|
||||
if(!frame)
|
||||
goto end_cn_stub;
|
||||
}
|
||||
|
||||
|
||||
/* from now on we must attempt to reassemble the PDU
|
||||
*/
|
||||
|
||||
|
||||
/* we dont have the full fragment so we just have to abort and exit
|
||||
*/
|
||||
if( !tvb_bytes_exist(tvb, offset, stub_length) ){
|
||||
goto end_cn_stub;
|
||||
}
|
||||
|
||||
|
||||
/* if we get here we know it is the first time we see the packet
|
||||
and we also know it is only a fragment and not a full PDU,
|
||||
thus we must reassemble it.
|
||||
*/
|
||||
|
||||
|
||||
/* if this is the first fragment we need to start reassembly
|
||||
*/
|
||||
if(hdr->flags&PFC_FIRST_FRAG){
|
||||
fragment_add(tvb, offset, pinfo, frame,
|
||||
dcerpc_co_reassemble_table,
|
||||
0, stub_length, TRUE);
|
||||
fragment_add(payload_tvb, 0, pinfo, frame, dcerpc_co_reassemble_table,
|
||||
0, tvb_length(payload_tvb), TRUE);
|
||||
fragment_set_tot_len(pinfo, frame,
|
||||
dcerpc_co_reassemble_table, alloc_hint);
|
||||
|
||||
|
@ -2481,10 +2471,9 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
if(!(hdr->flags&PFC_LAST_FRAG)){
|
||||
tot_len = fragment_get_tot_len(pinfo, frame,
|
||||
dcerpc_co_reassemble_table);
|
||||
fragment_add(tvb, offset, pinfo, frame,
|
||||
fragment_add(payload_tvb, 0, pinfo, frame,
|
||||
dcerpc_co_reassemble_table,
|
||||
tot_len-alloc_hint,
|
||||
stub_length,
|
||||
tot_len-alloc_hint, tvb_length(payload_tvb),
|
||||
TRUE);
|
||||
|
||||
goto end_cn_stub;
|
||||
|
@ -2494,42 +2483,35 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
*/
|
||||
tot_len = fragment_get_tot_len(pinfo, frame,
|
||||
dcerpc_co_reassemble_table);
|
||||
fd_head = fragment_add(tvb, offset, pinfo,
|
||||
fd_head = fragment_add(payload_tvb, 0, pinfo,
|
||||
frame,
|
||||
dcerpc_co_reassemble_table,
|
||||
tot_len-alloc_hint,
|
||||
stub_length,
|
||||
tot_len-alloc_hint, tvb_length(payload_tvb),
|
||||
TRUE);
|
||||
|
||||
end_cn_stub:
|
||||
|
||||
/* Show the fragment data. */
|
||||
if (dcerpc_tree) {
|
||||
if (length > 0) {
|
||||
proto_tree_add_text (dcerpc_tree, tvb, offset, length,
|
||||
"Fragment data (%d byte%s)",
|
||||
stub_length,
|
||||
plurality(stub_length, "", "s"));
|
||||
}
|
||||
}
|
||||
|
||||
/* if reassembly is complete, dissect the full PDU
|
||||
*/
|
||||
if(fd_head && (fd_head->flags&FD_DEFRAGMENTED) ){
|
||||
|
||||
if(pinfo->fd->num==fd_head->reassembled_in){
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen, fd_head->datalen);
|
||||
tvb_set_child_real_data_tvbuff(tvb, next_tvb);
|
||||
tvb_set_child_real_data_tvbuff(payload_tvb, next_tvb);
|
||||
add_new_data_source(pinfo, next_tvb, "Reassembled DCE/RPC");
|
||||
show_fragment_tree(fd_head, &dcerpc_frag_items,
|
||||
dcerpc_tree, pinfo, next_tvb);
|
||||
|
||||
pinfo->fragmented = FALSE;
|
||||
|
||||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, next_tvb,
|
||||
0, hdr->drep, di, auth_info);
|
||||
|
||||
} else {
|
||||
proto_tree_add_uint(dcerpc_tree, hf_dcerpc_reassembled_in, tvb, 0, 0, fd_head->reassembled_in);
|
||||
proto_tree_add_uint(dcerpc_tree, hf_dcerpc_reassembled_in, payload_tvb, 0, 0,
|
||||
fd_head->reassembled_in);
|
||||
if (check_col(pinfo->cinfo, COL_INFO)) {
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO,
|
||||
" [DCE/RPC %s fragment]", fragment_type(hdr->flags));
|
||||
|
@ -2538,6 +2520,7 @@ end_cn_stub:
|
|||
} else {
|
||||
/* Reassembly not complete - some fragments
|
||||
are missing */
|
||||
|
||||
if (check_col(pinfo->cinfo, COL_INFO)) {
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO,
|
||||
" [DCE/RPC %s fragment]", fragment_type(hdr->flags));
|
||||
|
@ -2602,6 +2585,7 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
* and we just have a security context?
|
||||
*/
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, FALSE, &auth_info);
|
||||
dissect_dcerpc_verifier (tvb, pinfo, dcerpc_tree, hdr, &auth_info);
|
||||
|
||||
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||
pinfo->srcport, pinfo->destport, 0);
|
||||
|
@ -2704,9 +2688,6 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
} else
|
||||
show_stub_data (tvb, offset, dcerpc_tree, &auth_info);
|
||||
}
|
||||
|
||||
/* Decrypt the verifier, if present */
|
||||
dissect_dcerpc_verifier (tvb, pinfo, dcerpc_tree, hdr, &auth_info);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2739,9 +2720,11 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
* and we just have a security context?
|
||||
*/
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, FALSE, &auth_info);
|
||||
dissect_dcerpc_verifier (tvb, pinfo, dcerpc_tree, hdr, &auth_info);
|
||||
|
||||
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||
pinfo->srcport, pinfo->destport, 0);
|
||||
|
||||
if (!conv) {
|
||||
/* no point in creating one here, really */
|
||||
show_stub_data (tvb, offset, dcerpc_tree, &auth_info);
|
||||
|
@ -2806,9 +2789,6 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
} else
|
||||
show_stub_data (tvb, offset, dcerpc_tree, &auth_info);
|
||||
}
|
||||
|
||||
/* Decrypt the verifier, if present */
|
||||
dissect_dcerpc_verifier (tvb, pinfo, dcerpc_tree, hdr, &auth_info);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright 2001, Todd Sabin <tas@webspan.net>
|
||||
* Copyright 2003, Tim Potter <tpot@samba.org>
|
||||
*
|
||||
* $Id: packet-dcerpc.h,v 1.34 2003/08/04 02:48:58 tpot Exp $
|
||||
* $Id: packet-dcerpc.h,v 1.35 2003/09/26 06:30:13 tpot Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -76,7 +76,13 @@ typedef struct _e_dce_dg_common_hdr_t {
|
|||
guint8 serial_lo;
|
||||
} e_dce_dg_common_hdr_t;
|
||||
|
||||
|
||||
typedef struct _dcerpc_auth_info {
|
||||
guint8 auth_pad_len;
|
||||
guint8 auth_level;
|
||||
guint8 auth_type;
|
||||
guint32 auth_size;
|
||||
tvbuff_t *auth_data;
|
||||
} dcerpc_auth_info;
|
||||
|
||||
#define PDU_REQ 0
|
||||
#define PDU_PING 1
|
||||
|
@ -282,14 +288,25 @@ typedef struct _dcerpc_uuid_value {
|
|||
|
||||
/* Authenticated pipe registration functions and miscellanea */
|
||||
|
||||
typedef struct _decrpc_auth_subdissector_fns {
|
||||
typedef tvbuff_t *(dcerpc_decode_data_fnct_t)(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo,
|
||||
dcerpc_auth_info *auth_info);
|
||||
|
||||
typedef struct _dcerpc_auth_subdissector_fns {
|
||||
|
||||
/* Dissect credentials and verifiers */
|
||||
|
||||
dcerpc_dissect_fnct_t *bind_fn;
|
||||
dcerpc_dissect_fnct_t *bind_ack_fn;
|
||||
dcerpc_dissect_fnct_t *auth3_fn;
|
||||
dcerpc_dissect_fnct_t *req_verf_fn;
|
||||
dcerpc_dissect_fnct_t *resp_verf_fn;
|
||||
dcerpc_dissect_fnct_t *req_data_fn;
|
||||
dcerpc_dissect_fnct_t *resp_data_fn;
|
||||
|
||||
/* Decrypt encrypted requests/response PDUs */
|
||||
|
||||
dcerpc_decode_data_fnct_t *req_data_fn;
|
||||
dcerpc_decode_data_fnct_t *resp_data_fn;
|
||||
|
||||
} dcerpc_auth_subdissector_fns;
|
||||
|
||||
void register_dcerpc_auth_subdissector(guint8 auth_level, guint8 auth_type,
|
||||
|
@ -312,9 +329,4 @@ void register_dcerpc_auth_subdissector(guint8 auth_level, guint8 auth_type,
|
|||
#define DCE_C_AUTHN_LEVEL_PKT_INTEGRITY 5
|
||||
#define DCE_C_AUTHN_LEVEL_PKT_PRIVACY 6
|
||||
|
||||
typedef struct _decrypted_info_t {
|
||||
tvbuff_t *decr_tvb;
|
||||
proto_tree *decr_tree;
|
||||
} decrypted_info_t;
|
||||
|
||||
#endif /* packet-dcerpc.h */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Devin Heitmueller <dheitmueller@netilla.com>
|
||||
* Copyright 2003, Tim Potter <tpot@samba.org>
|
||||
*
|
||||
* $Id: packet-ntlmssp.c,v 1.44 2003/09/01 00:01:39 guy Exp $
|
||||
* $Id: packet-ntlmssp.c,v 1.45 2003/09/26 06:30:13 tpot Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -179,7 +179,6 @@ static gint ett_ntlmssp_string = -1;
|
|||
static gint ett_ntlmssp_blob = -1;
|
||||
static gint ett_ntlmssp_address_list = -1;
|
||||
static gint ett_ntlmssp_address_list_item = -1;
|
||||
static gint ett_ntlmssp_decrypted_tree = -1;
|
||||
|
||||
/* Configuration variables */
|
||||
static char *nt_password = NULL;
|
||||
|
@ -1209,12 +1208,11 @@ dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
return offset;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
|
||||
packet_info *pinfo, proto_tree *tree)
|
||||
static tvbuff_t *
|
||||
dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo,
|
||||
dcerpc_auth_info *auth_info _U_)
|
||||
{
|
||||
volatile int offset = 0;
|
||||
tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
|
||||
guint8 *peer_block;
|
||||
conversation_t *conversation;
|
||||
|
@ -1223,8 +1221,6 @@ dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
|
|||
rc4_state_struct *rc4_state_peer;
|
||||
ntlmssp_info *conv_ntlmssp_info = NULL;
|
||||
ntlmssp_packet_info *packet_ntlmssp_info = NULL;
|
||||
proto_item *it;
|
||||
static decrypted_info_t ndi;
|
||||
|
||||
encrypted_block_length = tvb_length_remaining (tvb, offset);
|
||||
|
||||
|
@ -1244,14 +1240,14 @@ dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
|
|||
pinfo->destport, 0);
|
||||
if (conversation == NULL) {
|
||||
/* There is no conversation, thus no encryption state */
|
||||
return offset + encrypted_block_length;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conv_ntlmssp_info = conversation_get_proto_data(conversation,
|
||||
proto_ntlmssp);
|
||||
if (conv_ntlmssp_info == NULL) {
|
||||
/* There is no NTLMSSP state tied to the conversation */
|
||||
return offset + encrypted_block_length;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the pair of RC4 state structures. One is used for to decrypt the
|
||||
|
@ -1267,7 +1263,7 @@ dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
|
|||
|
||||
if (rc4_state == NULL || rc4_state_peer == NULL) {
|
||||
/* There is no encryption state, so we cannot decrypt */
|
||||
return offset + encrypted_block_length;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Store the decrypted contents in the packet state struct
|
||||
|
@ -1297,21 +1293,12 @@ dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
|
|||
decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
|
||||
encrypted_block_length,
|
||||
encrypted_block_length);
|
||||
tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
|
||||
add_new_data_source(pinfo, decr_tvb,
|
||||
"Decrypted NTLMSSP block");
|
||||
|
||||
/* Show the decrypted payload in the tree */
|
||||
it=proto_tree_add_text(tree, decr_tvb, 0, -1,
|
||||
"Decrypted stub data (%d byte%s)",
|
||||
encrypted_block_length,
|
||||
plurality(encrypted_block_length, "", "s"));
|
||||
ndi.decr_tree=proto_item_add_subtree(it, ett_ntlmssp_decrypted_tree);
|
||||
ndi.decr_tvb=decr_tvb;
|
||||
pinfo->decrypted_data=&ndi;
|
||||
|
||||
tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
|
||||
|
||||
offset += encrypted_block_length;
|
||||
return offset;
|
||||
|
||||
return decr_tvb;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1522,8 +1509,7 @@ proto_register_ntlmssp(void)
|
|||
&ett_ntlmssp_string,
|
||||
&ett_ntlmssp_blob,
|
||||
&ett_ntlmssp_address_list,
|
||||
&ett_ntlmssp_address_list_item,
|
||||
&ett_ntlmssp_decrypted_tree
|
||||
&ett_ntlmssp_address_list_item
|
||||
};
|
||||
module_t *ntlmssp_module;
|
||||
|
||||
|
@ -1545,8 +1531,6 @@ proto_register_ntlmssp(void)
|
|||
|
||||
register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
|
||||
new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
|
||||
new_register_dissector("ntlmssp_encrypted_payload",
|
||||
dissect_ntlmssp_encrypted_payload, proto_ntlmssp);
|
||||
}
|
||||
|
||||
static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
|
@ -1575,19 +1559,6 @@ static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pin
|
|||
return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
|
||||
}
|
||||
|
||||
static int wrap_dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo,
|
||||
proto_tree *tree, char *drep _U_)
|
||||
{
|
||||
tvbuff_t *auth_tvb;
|
||||
|
||||
auth_tvb = tvb_new_subset(
|
||||
tvb, offset, tvb_length_remaining(tvb, offset),
|
||||
tvb_length_remaining(tvb, offset));
|
||||
|
||||
return dissect_ntlmssp_encrypted_payload(auth_tvb, pinfo, tree);
|
||||
}
|
||||
|
||||
static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
|
||||
wrap_dissect_ntlmssp, /* Bind */
|
||||
wrap_dissect_ntlmssp, /* Bind ACK */
|
||||
|
@ -1604,8 +1575,8 @@ static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
|
|||
wrap_dissect_ntlmssp, /* AUTH3 */
|
||||
wrap_dissect_ntlmssp_verf, /* Request verifier */
|
||||
wrap_dissect_ntlmssp_verf, /* Response verifier */
|
||||
wrap_dissect_ntlmssp_encrypted_payload, /* Request data */
|
||||
wrap_dissect_ntlmssp_encrypted_payload /* Response data */
|
||||
dissect_ntlmssp_encrypted_payload, /* Request data */
|
||||
dissect_ntlmssp_encrypted_payload /* Response data */
|
||||
};
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue