In connection-oriented DCE RPC, the authentication data are credentials
only in bind, bind_ack, alter_context, alter_context_response, and auth3 PDUs; they're a verifier of some sort in other PDUs. The verifier appears to start with an OID for the real authentication mechanism if the authentication type is SPNEGO. svn path=/trunk/; revision=6563
This commit is contained in:
parent
e914e4fa6a
commit
3b71004a61
|
@ -2,7 +2,7 @@
|
||||||
* Routines for DCERPC packet disassembly
|
* Routines for DCERPC packet disassembly
|
||||||
* Copyright 2001, Todd Sabin <tas@webspan.net>
|
* Copyright 2001, Todd Sabin <tas@webspan.net>
|
||||||
*
|
*
|
||||||
* $Id: packet-dcerpc.c,v 1.85 2002/11/03 20:34:54 guy Exp $
|
* $Id: packet-dcerpc.c,v 1.86 2002/11/05 21:41:26 guy Exp $
|
||||||
*
|
*
|
||||||
* Ethereal - Network traffic analyzer
|
* Ethereal - Network traffic analyzer
|
||||||
* By Gerald Combs <gerald@ethereal.com>
|
* By Gerald Combs <gerald@ethereal.com>
|
||||||
|
@ -404,7 +404,9 @@ static gint ett_dcerpc_fragments = -1;
|
||||||
static gint ett_dcerpc_fragment = -1;
|
static gint ett_dcerpc_fragment = -1;
|
||||||
static gint ett_decrpc_krb5_auth_verf = -1;
|
static gint ett_decrpc_krb5_auth_verf = -1;
|
||||||
|
|
||||||
static dissector_handle_t ntlmssp_handle, gssapi_handle;
|
static dissector_handle_t ntlmssp_handle;
|
||||||
|
static dissector_handle_t gssapi_handle;
|
||||||
|
static dissector_handle_t gssapi_verf_handle;
|
||||||
|
|
||||||
static const fragment_items dcerpc_frag_items = {
|
static const fragment_items dcerpc_frag_items = {
|
||||||
&ett_dcerpc_fragments,
|
&ett_dcerpc_fragments,
|
||||||
|
@ -1429,7 +1431,8 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree,
|
dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree,
|
||||||
e_dce_cn_common_hdr_t *hdr, int *auth_level_p)
|
e_dce_cn_common_hdr_t *hdr, int *auth_level_p,
|
||||||
|
gboolean are_credentials)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
guint8 auth_pad_len;
|
guint8 auth_pad_len;
|
||||||
|
@ -1470,13 +1473,17 @@ dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
||||||
offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
|
||||||
hf_dcerpc_auth_ctx_id, NULL);
|
hf_dcerpc_auth_ctx_id, NULL);
|
||||||
|
|
||||||
/* Dissect the authentication data */
|
/*
|
||||||
|
* Dissect the authentication data.
|
||||||
switch(auth_type) {
|
*/
|
||||||
|
if (are_credentials) {
|
||||||
|
/*
|
||||||
|
* The authentication data are credentials.
|
||||||
|
*/
|
||||||
|
switch (auth_type) {
|
||||||
|
|
||||||
|
case DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP: {
|
||||||
/* NTLMSSP */
|
/* NTLMSSP */
|
||||||
|
|
||||||
case DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP: {
|
|
||||||
tvbuff_t *ntlmssp_tvb;
|
tvbuff_t *ntlmssp_tvb;
|
||||||
|
|
||||||
ntlmssp_tvb = tvb_new_subset(tvb, offset, hdr->auth_len,
|
ntlmssp_tvb = tvb_new_subset(tvb, offset, hdr->auth_len,
|
||||||
|
@ -1486,11 +1493,10 @@ dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
||||||
dcerpc_tree);
|
dcerpc_tree);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DCE_C_RPC_AUTHN_PROTOCOL_SPNEGO: {
|
||||||
/* SPNEGO (rfc2478) */
|
/* SPNEGO (rfc2478) */
|
||||||
|
|
||||||
case DCE_C_RPC_AUTHN_PROTOCOL_SPNEGO: {
|
|
||||||
tvbuff_t *gssapi_tvb;
|
tvbuff_t *gssapi_tvb;
|
||||||
|
|
||||||
gssapi_tvb = tvb_new_subset(tvb, offset, hdr->auth_len,
|
gssapi_tvb = tvb_new_subset(tvb, offset, hdr->auth_len,
|
||||||
|
@ -1499,11 +1505,34 @@ dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
||||||
call_dissector(gssapi_handle, gssapi_tvb, pinfo, dcerpc_tree);
|
call_dissector(gssapi_handle, gssapi_tvb, pinfo, dcerpc_tree);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len,
|
proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len,
|
||||||
"Auth Data");
|
"Auth Credentials");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The authentication data are a verifier.
|
||||||
|
*/
|
||||||
|
switch (auth_type) {
|
||||||
|
|
||||||
|
case DCE_C_RPC_AUTHN_PROTOCOL_SPNEGO: {
|
||||||
|
/* SPNEGO (rfc2478) */
|
||||||
|
tvbuff_t *gssapi_tvb;
|
||||||
|
|
||||||
|
gssapi_tvb = tvb_new_subset(tvb, offset, hdr->auth_len,
|
||||||
|
hdr->auth_len);
|
||||||
|
|
||||||
|
call_dissector(gssapi_verf_handle, gssapi_tvb, pinfo, dcerpc_tree);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len,
|
||||||
|
"Auth Verifier");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* figure out where the auth padding starts */
|
/* figure out where the auth padding starts */
|
||||||
|
@ -1700,7 +1729,7 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
||||||
* an authentication header, and associate it with an authentication
|
* an authentication header, and associate it with an authentication
|
||||||
* context, so subsequent PDUs can use that context.
|
* context, so subsequent PDUs can use that context.
|
||||||
*/
|
*/
|
||||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, NULL);
|
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1788,7 +1817,7 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerp
|
||||||
* XXX - do we need to do anything with the authentication level
|
* XXX - do we need to do anything with the authentication level
|
||||||
* we get back from this?
|
* we get back from this?
|
||||||
*/
|
*/
|
||||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, NULL);
|
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr, NULL, TRUE);
|
||||||
|
|
||||||
if (check_col (pinfo->cinfo, COL_INFO)) {
|
if (check_col (pinfo->cinfo, COL_INFO)) {
|
||||||
if (num_results != 0 && result == 0) {
|
if (num_results != 0 && result == 0) {
|
||||||
|
@ -2030,7 +2059,7 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
||||||
* and we just have a security context?
|
* and we just have a security context?
|
||||||
*/
|
*/
|
||||||
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
||||||
&auth_level);
|
&auth_level, FALSE);
|
||||||
|
|
||||||
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||||
pinfo->srcport, pinfo->destport, 0);
|
pinfo->srcport, pinfo->destport, 0);
|
||||||
|
@ -2150,7 +2179,7 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
|
||||||
* and we just have a security context?
|
* and we just have a security context?
|
||||||
*/
|
*/
|
||||||
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
||||||
&auth_level);
|
&auth_level, FALSE);
|
||||||
|
|
||||||
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||||
pinfo->srcport, pinfo->destport, 0);
|
pinfo->srcport, pinfo->destport, 0);
|
||||||
|
@ -2262,7 +2291,7 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, packet_info *pinfo,
|
||||||
* and we just have a security context?
|
* and we just have a security context?
|
||||||
*/
|
*/
|
||||||
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr,
|
||||||
&auth_level);
|
&auth_level, FALSE);
|
||||||
|
|
||||||
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
|
||||||
pinfo->srcport, pinfo->destport, 0);
|
pinfo->srcport, pinfo->destport, 0);
|
||||||
|
@ -2599,6 +2628,13 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
dissect_dcerpc_cn_bind_ack (tvb, pinfo, dcerpc_tree, &hdr);
|
dissect_dcerpc_cn_bind_ack (tvb, pinfo, dcerpc_tree, &hdr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PDU_AUTH3:
|
||||||
|
/*
|
||||||
|
* Nothing after the common header other than credentials.
|
||||||
|
*/
|
||||||
|
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr, NULL, TRUE);
|
||||||
|
break;
|
||||||
|
|
||||||
case PDU_REQ:
|
case PDU_REQ:
|
||||||
dissect_dcerpc_cn_rqst (tvb, pinfo, dcerpc_tree, tree, &hdr);
|
dissect_dcerpc_cn_rqst (tvb, pinfo, dcerpc_tree, tree, &hdr);
|
||||||
break;
|
break;
|
||||||
|
@ -2621,7 +2657,7 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
* Nothing after the common header other than an authentication
|
* Nothing after the common header other than an authentication
|
||||||
* verifier.
|
* verifier.
|
||||||
*/
|
*/
|
||||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr, NULL);
|
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr, NULL, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDU_SHUTDOWN:
|
case PDU_SHUTDOWN:
|
||||||
|
@ -2633,7 +2669,7 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* might as well dissect the auth info */
|
/* might as well dissect the auth info */
|
||||||
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr, NULL);
|
dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr, NULL, FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return hdr.frag_len + padding;
|
return hdr.frag_len + padding;
|
||||||
|
@ -3771,4 +3807,5 @@ proto_reg_handoff_dcerpc (void)
|
||||||
heur_dissector_add ("smb_transact", dissect_dcerpc_cn_bs, proto_dcerpc);
|
heur_dissector_add ("smb_transact", dissect_dcerpc_cn_bs, proto_dcerpc);
|
||||||
ntlmssp_handle = find_dissector("ntlmssp");
|
ntlmssp_handle = find_dissector("ntlmssp");
|
||||||
gssapi_handle = find_dissector("gssapi");
|
gssapi_handle = find_dissector("gssapi");
|
||||||
|
gssapi_verf_handle = find_dissector("gssapi_verf");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Copyright 2002, Richard Sharpe <rsharpe@samba.org> Added a few
|
* Copyright 2002, Richard Sharpe <rsharpe@samba.org> Added a few
|
||||||
* bits and pieces ...
|
* bits and pieces ...
|
||||||
*
|
*
|
||||||
* $Id: packet-gssapi.c,v 1.20 2002/09/29 18:58:56 gerald Exp $
|
* $Id: packet-gssapi.c,v 1.21 2002/11/05 21:41:27 guy Exp $
|
||||||
*
|
*
|
||||||
* Ethereal - Network traffic analyzer
|
* Ethereal - Network traffic analyzer
|
||||||
* By Gerald Combs <gerald@ethereal.com>
|
* By Gerald Combs <gerald@ethereal.com>
|
||||||
|
@ -143,7 +143,8 @@ dissect_parse_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_gssapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
dissect_gssapi_work(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||||
|
gboolean is_verifier)
|
||||||
{
|
{
|
||||||
proto_item *item;
|
proto_item *item;
|
||||||
proto_tree *subtree;
|
proto_tree *subtree;
|
||||||
|
@ -156,6 +157,7 @@ dissect_gssapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
gssapi_oid_value *value;
|
gssapi_oid_value *value;
|
||||||
volatile dissector_handle_t handle = NULL;
|
volatile dissector_handle_t handle = NULL;
|
||||||
conversation_t *volatile conversation;
|
conversation_t *volatile conversation;
|
||||||
|
tvbuff_t *oid_tvb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need this later, so lets get it now ...
|
* We need this later, so lets get it now ...
|
||||||
|
@ -289,39 +291,42 @@ dissect_gssapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
|
|
||||||
handle = value->handle;
|
handle = value->handle;
|
||||||
|
|
||||||
if (handle) {
|
/*
|
||||||
tvbuff_t *oid_tvb;
|
* Here we should create a conversation if needed and
|
||||||
|
* save the OID and dissector handle in it for the
|
||||||
|
* GSSAPI protocol.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
if (!conversation) { /* Create one */
|
||||||
* Here we should create a conversation if needed and
|
conversation = conversation_new(&pinfo->src,
|
||||||
* save the OID and dissector handle in it for the
|
&pinfo->dst,
|
||||||
* GSSAPI protocol.
|
pinfo->ptype,
|
||||||
*/
|
pinfo->srcport,
|
||||||
|
pinfo->destport, 0);
|
||||||
if (!conversation) { /* Create one */
|
|
||||||
conversation = conversation_new(&pinfo->src,
|
|
||||||
&pinfo->dst,
|
|
||||||
pinfo->ptype,
|
|
||||||
pinfo->srcport,
|
|
||||||
pinfo->destport, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now add the proto data ...
|
|
||||||
* but only if it is not already there.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!conversation_get_proto_data(conversation,
|
|
||||||
proto_gssapi)) {
|
|
||||||
conversation_add_proto_data(conversation,
|
|
||||||
proto_gssapi, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
oid_tvb = tvb_new_subset(tvb, offset, -1, -1);
|
|
||||||
call_dissector(handle, oid_tvb, pinfo, subtree);
|
|
||||||
}
|
}
|
||||||
else { /* FIXME, do something if handle not found */
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now add the proto data ...
|
||||||
|
* but only if it is not already there.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!conversation_get_proto_data(conversation,
|
||||||
|
proto_gssapi)) {
|
||||||
|
conversation_add_proto_data(conversation,
|
||||||
|
proto_gssapi, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_verifier) {
|
||||||
|
proto_tree_add_text(subtree, tvb, offset, -1,
|
||||||
|
"Authentication verifier");
|
||||||
|
} else {
|
||||||
|
if (handle != NULL) {
|
||||||
|
oid_tvb = tvb_new_subset(tvb, offset, -1, -1);
|
||||||
|
call_dissector(handle, oid_tvb, pinfo, subtree);
|
||||||
|
} else {
|
||||||
|
proto_tree_add_text(subtree, tvb, offset, -1,
|
||||||
|
"Authentication credentials");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -333,6 +338,18 @@ dissect_gssapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
} ENDTRY;
|
} ENDTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dissect_gssapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
|
{
|
||||||
|
dissect_gssapi_work(tvb, pinfo, tree, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dissect_gssapi_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||||
|
{
|
||||||
|
dissect_gssapi_work(tvb, pinfo, tree, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
proto_register_gssapi(void)
|
proto_register_gssapi(void)
|
||||||
{
|
{
|
||||||
|
@ -354,6 +371,7 @@ proto_register_gssapi(void)
|
||||||
proto_register_subtree_array(ett, array_length(ett));
|
proto_register_subtree_array(ett, array_length(ett));
|
||||||
|
|
||||||
register_dissector("gssapi", dissect_gssapi, proto_gssapi);
|
register_dissector("gssapi", dissect_gssapi, proto_gssapi);
|
||||||
|
register_dissector("gssapi_verf", dissect_gssapi_verf, proto_gssapi);
|
||||||
|
|
||||||
gssapi_oids = g_hash_table_new(gssapi_oid_hash, gssapi_oid_equal);
|
gssapi_oids = g_hash_table_new(gssapi_oid_hash, gssapi_oid_equal);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue