aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packet-dcerpc.c172
1 files changed, 137 insertions, 35 deletions
diff --git a/packet-dcerpc.c b/packet-dcerpc.c
index 439762ba69..8fb15ca83d 100644
--- a/packet-dcerpc.c
+++ b/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,