From Todd Sabin: set the tvbuff length of the stub data for
connectionless calls to the fragment length. Add value_string tables for authentication protocol and level values. Show the authentication protocol in decimal in connectionless PDUs, just as we do in connection-oriented PDUs. Get the authentication level from connection-oriented request and reply PDUs and, if it's DCE_C_AUTHN_LEVEL_PKT_PRIVACY, don't hand the stub data to subdissectors, just show it as encrypted stub data. svn path=/trunk/; revision=4998
This commit is contained in:
parent
c3881d8a9d
commit
030cea2057
172
packet-dcerpc.c
172
packet-dcerpc.c
|
@ -2,7 +2,7 @@
|
|||
* Routines for DCERPC packet disassembly
|
||||
* Copyright 2001, Todd Sabin <tas@webspan.net>
|
||||
*
|
||||
* $Id: packet-dcerpc.c,v 1.41 2002/03/19 11:10:40 guy Exp $
|
||||
* $Id: packet-dcerpc.c,v 1.42 2002/03/21 09:35:52 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -89,6 +89,35 @@ static const true_false_string flags_set_truth = {
|
|||
"Not set"
|
||||
};
|
||||
|
||||
/*
|
||||
* Authentication services.
|
||||
*/
|
||||
static const value_string authn_protocol_vals[] = {
|
||||
{ 0, "None" },
|
||||
{ 1, "Kerberos 5" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* Protection levels.
|
||||
*/
|
||||
#define DCE_C_AUTHN_LEVEL_NONE 1
|
||||
#define DCE_C_AUTHN_LEVEL_CONNECT 2
|
||||
#define DCE_C_AUTHN_LEVEL_CALL 3
|
||||
#define DCE_C_AUTHN_LEVEL_PKT 4
|
||||
#define DCE_C_AUTHN_LEVEL_PKT_INTEGRITY 5
|
||||
#define DCE_C_AUTHN_LEVEL_PKT_PRIVACY 6
|
||||
|
||||
static const value_string authn_level_vals[] = {
|
||||
{ DCE_C_AUTHN_LEVEL_NONE, "None" },
|
||||
{ DCE_C_AUTHN_LEVEL_CONNECT, "Connect" },
|
||||
{ DCE_C_AUTHN_LEVEL_CALL, "Call" },
|
||||
{ DCE_C_AUTHN_LEVEL_PKT, "Packet" },
|
||||
{ DCE_C_AUTHN_LEVEL_PKT_INTEGRITY, "Packet integrity" },
|
||||
{ DCE_C_AUTHN_LEVEL_PKT_PRIVACY, "Packet privacy" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static int proto_dcerpc = -1;
|
||||
|
||||
/* field defines */
|
||||
|
@ -873,7 +902,8 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
|
|||
proto_tree *dcerpc_tree,
|
||||
tvbuff_t *tvb, gint offset,
|
||||
guint16 opnum, gboolean is_rqst,
|
||||
char *drep, dcerpc_info *info)
|
||||
char *drep, dcerpc_info *info,
|
||||
int auth_level)
|
||||
{
|
||||
dcerpc_uuid_key key;
|
||||
dcerpc_uuid_value *sub_proto;
|
||||
|
@ -933,24 +963,37 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
|
|||
col_set_str (pinfo->cinfo, COL_PROTOCOL, sub_proto->name);
|
||||
}
|
||||
|
||||
sub_dissect = is_rqst ? proc->dissect_rqst : proc->dissect_resp;
|
||||
if (sub_dissect) {
|
||||
saved_proto = pinfo->current_proto;
|
||||
saved_private_data = pinfo->private_data;
|
||||
pinfo->current_proto = sub_proto->name;
|
||||
pinfo->private_data = (void *)info;
|
||||
|
||||
init_ndr_pointer_list(pinfo);
|
||||
offset = sub_dissect (tvb, offset, pinfo, sub_tree, drep);
|
||||
|
||||
pinfo->current_proto = saved_proto;
|
||||
pinfo->private_data = saved_private_data;
|
||||
} else {
|
||||
/*
|
||||
* If the authentication level is DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
|
||||
* the stub data is encrypted, and we can't dissect it.
|
||||
*/
|
||||
if (auth_level == DCE_C_AUTHN_LEVEL_PKT_PRIVACY) {
|
||||
length = tvb_length_remaining (tvb, offset);
|
||||
if (length > 0) {
|
||||
proto_tree_add_text (sub_tree, tvb, offset, length,
|
||||
"Stub data (%d byte%s)", length,
|
||||
plurality(length, "", "s"));
|
||||
proto_tree_add_text(sub_tree, tvb, offset, length,
|
||||
"Encrypted stub data (%d byte%s)",
|
||||
length, plurality(length, "", "s"));
|
||||
}
|
||||
} else {
|
||||
sub_dissect = is_rqst ? proc->dissect_rqst : proc->dissect_resp;
|
||||
if (sub_dissect) {
|
||||
saved_proto = pinfo->current_proto;
|
||||
saved_private_data = pinfo->private_data;
|
||||
pinfo->current_proto = sub_proto->name;
|
||||
pinfo->private_data = (void *)info;
|
||||
|
||||
init_ndr_pointer_list(pinfo);
|
||||
offset = sub_dissect (tvb, offset, pinfo, sub_tree, drep);
|
||||
|
||||
pinfo->current_proto = saved_proto;
|
||||
pinfo->private_data = saved_private_data;
|
||||
} else {
|
||||
length = tvb_length_remaining (tvb, offset);
|
||||
if (length > 0) {
|
||||
proto_tree_add_text (sub_tree, tvb, offset, length,
|
||||
"Stub data (%d byte%s)", length,
|
||||
plurality(length, "", "s"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -958,10 +1001,18 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
|
|||
|
||||
static int
|
||||
dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree,
|
||||
e_dce_cn_common_hdr_t *hdr)
|
||||
e_dce_cn_common_hdr_t *hdr, int *auth_level_p)
|
||||
{
|
||||
int offset;
|
||||
guint8 auth_pad_len;
|
||||
guint8 auth_level;
|
||||
|
||||
/*
|
||||
* Initially set "*auth_level_p" to -1 to indicate that we haven't
|
||||
* yet seen any authentication level information.
|
||||
*/
|
||||
if (auth_level_p != NULL)
|
||||
*auth_level_p = -1;
|
||||
|
||||
/*
|
||||
* The authentication information is at the *end* of the PDU; in
|
||||
|
@ -969,7 +1020,7 @@ dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
* come before it.
|
||||
*
|
||||
* If the full packet is here, and we've got an auth len, and it's
|
||||
* valid, then dissect the auth info
|
||||
* valid, then dissect the auth info.
|
||||
*/
|
||||
if (tvb_length (tvb) >= hdr->frag_len
|
||||
&& hdr->auth_len
|
||||
|
@ -980,7 +1031,9 @@ dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
||||
hf_dcerpc_auth_type, NULL);
|
||||
offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
||||
hf_dcerpc_auth_level, NULL);
|
||||
hf_dcerpc_auth_level, &auth_level);
|
||||
if (auth_level_p != NULL)
|
||||
*auth_level_p = auth_level;
|
||||
offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
||||
hf_dcerpc_auth_pad_len, &auth_pad_len);
|
||||
offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
||||
|
@ -1161,7 +1214,12 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
}
|
||||
}
|
||||
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr);
|
||||
/*
|
||||
* XXX - we should save the authentication type *if* we have
|
||||
* an authentication header, and associate it with an authentication
|
||||
* context, so subsequent PDUs can use that context.
|
||||
*/
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1231,7 +1289,11 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerp
|
|||
hf_dcerpc_cn_ack_trans_ver, &trans_ver);
|
||||
}
|
||||
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr);
|
||||
/*
|
||||
* XXX - do we need to do anything with the authentication level
|
||||
* we get back from this?
|
||||
*/
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, NULL);
|
||||
|
||||
if (check_col (pinfo->cinfo, COL_INFO)) {
|
||||
if (num_results != 0 && result == 0) {
|
||||
|
@ -1258,6 +1320,7 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
guint16 opnum;
|
||||
e_uuid_t obj_id;
|
||||
int auth_sz = 0;
|
||||
int auth_level;
|
||||
int offset = 16;
|
||||
|
||||
offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
||||
|
@ -1293,7 +1356,12 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
offset += 16;
|
||||
}
|
||||
|
||||
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr);
|
||||
/*
|
||||
* XXX - what if this was set when the connection was set up,
|
||||
* and we just have a security context?
|
||||
*/
|
||||
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
||||
&auth_level);
|
||||
|
||||
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||
pinfo->srcport, pinfo->destport, 0);
|
||||
|
@ -1376,7 +1444,7 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
|
||||
tvb_new_subset (tvb, offset, length,
|
||||
reported_length),
|
||||
0, opnum, TRUE, hdr->drep, &di);
|
||||
0, opnum, TRUE, hdr->drep, &di, auth_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1390,6 +1458,7 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
guint16 ctx_id;
|
||||
int auth_sz = 0;
|
||||
int offset = 16;
|
||||
int auth_level;
|
||||
|
||||
offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
||||
hf_dcerpc_cn_alloc_hint, NULL);
|
||||
|
@ -1407,7 +1476,12 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
/* padding */
|
||||
offset++;
|
||||
|
||||
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr);
|
||||
/*
|
||||
* XXX - what if this was set when the connection was set up,
|
||||
* and we just have a security context?
|
||||
*/
|
||||
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
||||
&auth_level);
|
||||
|
||||
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||
pinfo->srcport, pinfo->destport, 0);
|
||||
|
@ -1466,7 +1540,8 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
|||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
|
||||
tvb_new_subset (tvb, offset, length,
|
||||
reported_length),
|
||||
0, value->opnum, FALSE, hdr->drep, &di);
|
||||
0, value->opnum, FALSE, hdr->drep, &di,
|
||||
auth_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1614,7 +1689,7 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
|
||||
default:
|
||||
/* might as well dissect the auth info */
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr);
|
||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr, NULL);
|
||||
break;
|
||||
}
|
||||
return hdr.frag_len + padding;
|
||||
|
@ -1899,6 +1974,7 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
*/
|
||||
|
||||
switch (hdr.ptype) {
|
||||
int length, reported_length, stub_length;
|
||||
dcerpc_info di;
|
||||
dcerpc_call_value *value, v;
|
||||
|
||||
|
@ -1938,14 +2014,27 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
value = &v;
|
||||
}
|
||||
|
||||
length = tvb_length_remaining (tvb, offset);
|
||||
reported_length = tvb_reported_length_remaining (tvb, offset);
|
||||
stub_length = hdr.frag_len;
|
||||
if (length > stub_length)
|
||||
length = stub_length;
|
||||
if (reported_length > stub_length)
|
||||
reported_length = stub_length;
|
||||
|
||||
di.conv = conv;
|
||||
di.call_id = hdr.seqnum;
|
||||
di.smb_fid = -1;
|
||||
di.request = TRUE;
|
||||
di.call_data = value;
|
||||
|
||||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, tvb, offset,
|
||||
hdr.opnum, TRUE, hdr.drep, &di);
|
||||
/*
|
||||
* XXX - authentication level?
|
||||
*/
|
||||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
|
||||
tvb_new_subset (tvb, offset, length,
|
||||
reported_length),
|
||||
0, hdr.opnum, TRUE, hdr.drep, &di, 0);
|
||||
break;
|
||||
case PDU_RESP:
|
||||
if(!(pinfo->fd->flags.visited)){
|
||||
|
@ -1975,14 +2064,27 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
value = &v;
|
||||
}
|
||||
|
||||
length = tvb_length_remaining (tvb, offset);
|
||||
reported_length = tvb_reported_length_remaining (tvb, offset);
|
||||
stub_length = hdr.frag_len;
|
||||
if (length > stub_length)
|
||||
length = stub_length;
|
||||
if (reported_length > stub_length)
|
||||
reported_length = stub_length;
|
||||
|
||||
di.conv = conv;
|
||||
di.call_id = 0;
|
||||
di.smb_fid = -1;
|
||||
di.request = FALSE;
|
||||
di.call_data = value;
|
||||
|
||||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, tvb, offset,
|
||||
value->opnum, FALSE, hdr.drep, &di);
|
||||
/*
|
||||
* XXX - authentication level?
|
||||
*/
|
||||
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
|
||||
tvb_new_subset (tvb, offset, length,
|
||||
reported_length),
|
||||
0, value->opnum, FALSE, hdr.drep, &di, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2132,9 +2234,9 @@ proto_register_dcerpc (void)
|
|||
{ &hf_dcerpc_cn_cancel_count,
|
||||
{ "Cancel count", "dcerpc.cn_cancel_count", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_dcerpc_auth_type,
|
||||
{ "Auth type", "dcerpc.auth_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
|
||||
{ "Auth type", "dcerpc.auth_type", FT_UINT8, BASE_DEC, VALS (authn_protocol_vals), 0x0, "", HFILL }},
|
||||
{ &hf_dcerpc_auth_level,
|
||||
{ "Auth level", "dcerpc.auth_level", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
|
||||
{ "Auth level", "dcerpc.auth_level", FT_UINT8, BASE_DEC, VALS (authn_level_vals), 0x0, "", HFILL }},
|
||||
{ &hf_dcerpc_auth_pad_len,
|
||||
{ "Auth pad len", "dcerpc.auth_pad_len", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_dcerpc_auth_rsrvd,
|
||||
|
@ -2190,7 +2292,7 @@ proto_register_dcerpc (void)
|
|||
{ &hf_dcerpc_dg_frag_num,
|
||||
{ "Fragment num", "dcerpc.dg_frag_num", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_dcerpc_dg_auth_proto,
|
||||
{ "Auth proto", "dcerpc.dg_auth_proto", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
|
||||
{ "Auth proto", "dcerpc.dg_auth_proto", FT_UINT8, BASE_DEC, VALS (authn_protocol_vals), 0x0, "", HFILL }},
|
||||
{ &hf_dcerpc_dg_seqnum,
|
||||
{ "Sequence num", "dcerpc.dg_seqnum", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_dcerpc_dg_server_boot,
|
||||
|
|
Loading…
Reference in New Issue