Move all DCERPC authentication/encryption dissection code from packet-dcerpc.c

to the dissector that handles the particular authentication flavour.  This
gets rid of a couple of ugly switch statements and allows other authentication
modules to be written easily.

svn path=/trunk/; revision=8026
This commit is contained in:
Tim Potter 2003-07-16 04:20:33 +00:00
parent 83665ca82b
commit 8b89bd76ee
8 changed files with 402 additions and 297 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.598 2003/07/12 22:35:20 sahlberg Exp $
# $Id: Makefile.am,v 1.599 2003/07/16 04:20:33 tpot Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@ -622,7 +622,6 @@ noinst_HEADERS = \
packet-nfs.h \
packet-nisplus.h \
packet-nlm.h \
packet-ntlmssp.h \
packet-ntp.h \
packet-null.h \
packet-osi-options.h \

View File

@ -3,7 +3,7 @@
* Copyright 2001,2003 Tim Potter <tpot@samba.org>
* 2002 structure and command dissectors by Ronnie Sahlberg
*
* $Id: packet-dcerpc-netlogon.c,v 1.83 2003/06/26 04:30:28 tpot Exp $
* $Id: packet-dcerpc-netlogon.c,v 1.84 2003/07/16 04:20:33 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -5941,22 +5941,21 @@ static int hf_netlogon_secchan_bind_ack_unknown1 = -1;
static int hf_netlogon_secchan_bind_ack_unknown2 = -1;
static int hf_netlogon_secchan_bind_ack_unknown3 = -1;
static gint ett_secchan = -1;
static gint ett_secchan_verf = -1;
static gint ett_secchan_bind_creds = -1;
static gint ett_secchan_bind_ack_creds = -1;
int netlogon_dissect_secchan_bind_creds(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
char *drep)
static int dissect_secchan_bind_creds(tvbuff_t *tvb, int offset,
packet_info *pinfo,
proto_tree *tree, char *drep)
{
int start_offset = offset;
proto_item *item = NULL;
proto_tree *subtree = NULL;
int len;
if (tree) {
item = proto_tree_add_text(
tree, tvb, offset, 0,
tree, tvb, offset, tvb_length(tvb),
"Secure Channel Bind Credentials");
subtree = proto_item_add_subtree(
item, ett_secchan_bind_creds);
@ -5988,14 +5987,12 @@ int netlogon_dissect_secchan_bind_creds(tvbuff_t *tvb, int offset,
offset += len;
proto_item_set_len(item, offset - start_offset);
return offset;
}
int netlogon_dissect_secchan_bind_ack_creds(tvbuff_t *tvb, int offset,
packet_info *pinfo,
proto_tree *tree, char *drep)
static int dissect_secchan_bind_ack_creds(tvbuff_t *tvb, int offset,
packet_info *pinfo,
proto_tree *tree, char *drep)
{
proto_item *item = NULL;
proto_tree *subtree = NULL;
@ -6025,40 +6022,6 @@ int netlogon_dissect_secchan_bind_ack_creds(tvbuff_t *tvb, int offset,
return offset;
}
static int hf_netlogon_secchan = -1;
static int hf_netlogon_secchan_sig = -1;
static int hf_netlogon_secchan_unk = -1;
static int hf_netlogon_secchan_seq = -1;
static int hf_netlogon_secchan_nonce = -1;
int netlogon_dissect_secchan_verf(tvbuff_t *tvb, int offset,
packet_info *pinfo _U_, proto_tree *tree,
char *drep _U_)
{
proto_item *vf;
proto_tree *sec_chan_tree;
/*
* Create a new tree, and split into 4 components ...
*/
vf = proto_tree_add_item(tree, hf_netlogon_secchan, tvb,
offset, -1, FALSE);
sec_chan_tree = proto_item_add_subtree(vf, ett_secchan);
proto_tree_add_item(sec_chan_tree, hf_netlogon_secchan_sig, tvb,
offset, 8, FALSE);
proto_tree_add_item(sec_chan_tree, hf_netlogon_secchan_unk, tvb,
offset + 8, 8, FALSE);
proto_tree_add_item(sec_chan_tree, hf_netlogon_secchan_seq, tvb,
offset + 16, 8, FALSE);
proto_tree_add_item(sec_chan_tree, hf_netlogon_secchan_nonce, tvb,
offset + 24, 8, FALSE);
return offset;
}
/* Subdissectors */
static dcerpc_sub_dissector dcerpc_netlogon_dissectors[] = {
@ -6191,6 +6154,45 @@ static dcerpc_sub_dissector dcerpc_netlogon_dissectors[] = {
{0, NULL, NULL, NULL }
};
static int hf_netlogon_secchan_verf = -1;
static int hf_netlogon_secchan_verf_sig = -1;
static int hf_netlogon_secchan_verf_unk = -1;
static int hf_netlogon_secchan_verf_seq = -1;
static int hf_netlogon_secchan_verf_nonce = -1;
static int
dissect_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
proto_tree *tree, char *drep _U_)
{
proto_item *vf = NULL;
proto_tree *subtree = NULL;
/*
* Create a new tree, and split into 4 components ...
*/
vf = proto_tree_add_item(tree, hf_netlogon_secchan_verf, tvb,
offset, -1, FALSE);
subtree = proto_item_add_subtree(vf, ett_secchan_verf);
proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sig, tvb,
offset, 8, FALSE);
offset += 8;
proto_tree_add_item(subtree, hf_netlogon_secchan_verf_unk, tvb,
offset, 8, FALSE);
offset += 8;
proto_tree_add_item(subtree, hf_netlogon_secchan_verf_seq, tvb,
offset, 8, FALSE);
offset += 8;
proto_tree_add_item(subtree, hf_netlogon_secchan_verf_nonce, tvb,
offset, 8, FALSE);
offset += 8;
return offset;
}
/* Secure channel types */
static const value_string sec_chan_type_vals[] = {
@ -7008,26 +7010,25 @@ static hf_register_info hf[] = {
{ "Unknown3", "netlogon.secchan.bind_ack.unknown3", FT_UINT32,
BASE_HEX, NULL, 0x0, "", HFILL }},
{ &hf_netlogon_secchan,
{ "Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE,
{ &hf_netlogon_secchan_verf,
{ "Secure channel Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE,
NULL, 0x0, "Verifier", HFILL }},
{ &hf_netlogon_secchan_sig,
{ &hf_netlogon_secchan_verf_sig,
{ "Signature", "netlogon.secchan.sig", FT_BYTES, BASE_HEX, NULL,
0x0, "Signature", HFILL }},
{ &hf_netlogon_secchan_unk,
{ &hf_netlogon_secchan_verf_unk,
{ "Unknown", "netlogon.secchan.unk", FT_BYTES, BASE_HEX, NULL,
0x0, "Unknown", HFILL }},
{ &hf_netlogon_secchan_seq,
{ &hf_netlogon_secchan_verf_seq,
{ "Sequence No", "netlogon.secchan.seq", FT_BYTES, BASE_HEX, NULL,
0x0, "Sequence No", HFILL }},
{ &hf_netlogon_secchan_nonce,
{ &hf_netlogon_secchan_verf_nonce,
{ "Nonce", "netlogon.secchan.nonce", FT_BYTES, BASE_HEX, NULL,
0x0, "Nonce", HFILL }},
};
static gint *ett[] = {
@ -7055,7 +7056,7 @@ static hf_register_info hf[] = {
&ett_dc_flags,
&ett_secchan_bind_creds,
&ett_secchan_bind_ack_creds,
&ett_secchan,
&ett_secchan_verf
};
proto_dcerpc_netlogon = proto_register_protocol(
@ -7066,6 +7067,16 @@ static hf_register_info hf[] = {
proto_register_subtree_array(ett, array_length(ett));
}
static dcerpc_auth_subdissector_fns secchan_auth_fns = {
dissect_secchan_bind_creds, /* Bind */
dissect_secchan_bind_ack_creds, /* Bind ACK */
NULL, /* AUTH3 */
dissect_secchan_verf, /* Request verifier */
dissect_secchan_verf, /* Response verifier */
NULL, /* Request data */
NULL /* Response data */
};
void
proto_reg_handoff_dcerpc_netlogon(void)
{
@ -7082,4 +7093,8 @@ proto_reg_handoff_dcerpc_netlogon(void)
hf_info = proto_registrar_get_nth(hf_netlogon_opnum);
hf_info->strings = value_string_from_subdissectors(
dcerpc_netlogon_dissectors, array_length(dcerpc_netlogon_dissectors));
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN,
&secchan_auth_fns);
}

View File

@ -2,7 +2,7 @@
* Routines for SMB \PIPE\NETLOGON packet disassembly
* Copyright 2001,2003 Tim Potter <tpot@samba.org>
*
* $Id: packet-dcerpc-netlogon.h,v 1.13 2003/05/15 04:58:53 tpot Exp $
* $Id: packet-dcerpc-netlogon.h,v 1.14 2003/07/16 04:20:33 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -75,18 +75,4 @@
#define SEC_CHAN_DOMAIN 4
#define SEC_CHAN_BDC 6
/* Function prototypes */
int netlogon_dissect_secchan_bind_creds(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
char *drep);
int netlogon_dissect_secchan_bind_ack_creds(tvbuff_t *tvb, int offset,
packet_info *pinfo,
proto_tree *tree, char *drep);
int netlogon_dissect_secchan_verf(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
char *drep);
#endif /* packet-dcerpc-netlogon.h */

View File

@ -1,8 +1,9 @@
/* packet-dcerpc.c
* Routines for DCERPC packet disassembly
* Copyright 2001, Todd Sabin <tas@webspan.net>
* Copyright 2003, Tim Potter <tpot@samba.org>
*
* $Id: packet-dcerpc.c,v 1.133 2003/06/26 04:30:31 tpot Exp $
* $Id: packet-dcerpc.c,v 1.134 2003/07/16 04:20:33 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -38,7 +39,6 @@
#include "reassemble.h"
#include "tap.h"
#include "packet-frame.h"
#include "packet-ntlmssp.h"
#include "packet-dcerpc-nt.h"
static int dcerpc_tap = -1;
@ -95,12 +95,6 @@ static const value_string drep_fp_vals[] = {
/*
* Authentication services.
*/
#define DCE_C_RPC_AUTHN_PROTOCOL_NONE 0
#define DCE_C_RPC_AUTHN_PROTOCOL_KRB5 1
#define DCE_C_RPC_AUTHN_PROTOCOL_SPNEGO 9
#define DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP 10
#define DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN 68
static const value_string authn_protocol_vals[] = {
{ DCE_C_RPC_AUTHN_PROTOCOL_NONE, "None" },
{ DCE_C_RPC_AUTHN_PROTOCOL_KRB5, "Kerberos 5" },
@ -113,13 +107,6 @@ static const value_string authn_protocol_vals[] = {
/*
* 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" },
@ -398,11 +385,6 @@ static int hf_dcerpc_fragment_multiple_tails = -1;
static int hf_dcerpc_fragment_too_long_fragment = -1;
static int hf_dcerpc_fragment_error = -1;
static int hf_dcerpc_reassembled_in = -1;
static int hf_dcerpc_sec_chan = -1;
static int hf_dcerpc_sec_chan_sig = -1;
static int hf_dcerpc_sec_chan_unk = -1;
static int hf_dcerpc_sec_chan_seq = -1;
static int hf_dcerpc_sec_chan_nonce = -1;
static gint ett_dcerpc = -1;
static gint ett_dcerpc_cn_flags = -1;
@ -414,11 +396,6 @@ static gint ett_dcerpc_string = -1;
static gint ett_dcerpc_fragments = -1;
static gint ett_dcerpc_fragment = -1;
static gint ett_dcerpc_krb5_auth_verf = -1;
static gint ett_sec_chan = -1;
static dissector_handle_t ntlmssp_handle, ntlmssp_verf_handle,
ntlmssp_enc_payload_handle;
static dissector_handle_t gssapi_handle, gssapi_verf_handle;
static const fragment_items dcerpc_frag_items = {
&ett_dcerpc_fragments,
@ -463,6 +440,125 @@ dcerpc_reassemble_init(void)
fragment_table_init(&dcerpc_cl_reassemble_table);
}
/*
* Authentication subdissectors. Used to dissect authentication blobs in
* DCERPC binds, requests and responses.
*/
typedef struct _dcerpc_auth_subdissector {
guint8 auth_level;
guint8 auth_type;
dcerpc_auth_subdissector_fns auth_fns;
} dcerpc_auth_subdissector;
static GSList *dcerpc_auth_subdissector_list;
static dcerpc_auth_subdissector_fns *get_auth_subdissector_fns(
guint8 auth_level, guint8 auth_type)
{
gpointer data;
int i;
for (i = 0; (data = g_slist_nth_data(dcerpc_auth_subdissector_list, i)); i++) {
dcerpc_auth_subdissector *asd = (dcerpc_auth_subdissector *)data;
if (asd->auth_level == auth_level &&
asd->auth_type == auth_type)
return &asd->auth_fns;
}
return NULL;
}
void register_dcerpc_auth_subdissector(guint8 auth_level, guint8 auth_type,
dcerpc_auth_subdissector_fns *fns)
{
dcerpc_auth_subdissector *d;
if (get_auth_subdissector_fns(auth_level, auth_type))
return;
d = (dcerpc_auth_subdissector *)g_malloc(sizeof(dcerpc_auth_subdissector));
d->auth_level = auth_level;
d->auth_type = auth_type;
memcpy(&d->auth_fns, fns, sizeof(dcerpc_auth_subdissector_fns));
dcerpc_auth_subdissector_list = g_slist_append(dcerpc_auth_subdissector_list, d);
}
/* Hand off verifier data to a registered dissector */
static void dissect_auth_verf(tvbuff_t *auth_tvb, packet_info *pinfo,
proto_tree *tree,
dcerpc_auth_subdissector_fns *auth_fns,
e_dce_cn_common_hdr_t *hdr,
dcerpc_auth_info *auth_info)
{
dcerpc_dissect_fnct_t *fn = NULL;
switch (hdr->ptype) {
case PDU_BIND:
fn = auth_fns->bind_fn;
break;
case PDU_BIND_ACK:
fn = auth_fns->bind_ack_fn;
break;
case PDU_AUTH3:
fn = auth_fns->auth3_fn;
break;
case PDU_REQ:
fn = auth_fns->req_verf_fn;
break;
case PDU_RESP:
fn = auth_fns->resp_verf_fn;
break;
/* Don't know how to handle authentication data in this
pdu type. */
default:
g_warning("attempt to dissect %s pdu authentication data",
val_to_str(hdr->ptype, pckt_vals, "Unknown (%u)"));
break;
}
if (fn)
fn(auth_tvb, 0, pinfo, tree, hdr->drep);
else
proto_tree_add_text(tree, auth_tvb, 0, hdr->auth_len,
"%s Verifier",
val_to_str(auth_info->auth_type,
authn_protocol_vals,
"Unknown (%u)"));
}
/* 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)
{
dcerpc_dissect_fnct_t *fn = NULL;
switch (ptype) {
case PDU_REQ:
fn = auth_fns->req_data_fn;
break;
case PDU_RESP:
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);
}
/*
* Subdissectors
*/
@ -1692,66 +1788,45 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
*/
if (auth_info != NULL &&
auth_info->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,
"Encrypted stub data (%d byte%s)",
length, plurality(length, "", "s"));
length = tvb_length_remaining (tvb, offset);
switch (auth_info->auth_type) {
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);
case DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP: {
/* NTLMSSP */
tvbuff_t *ntlmssp_tvb;
ntlmssp_tvb = tvb_new_subset(tvb, offset, length, length);
pinfo->decrypted_data=NULL;
proto_tree_add_text(sub_tree, enc_tvb, 0, length,
"Encrypted stub data (%d byte%s)",
length, plurality(length, "", "s"));
pinfo->decrypted_data = NULL;
call_dissector(ntlmssp_enc_payload_handle, ntlmssp_tvb, pinfo,
sub_tree);
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);
if(pinfo->decrypted_data){
ntlmssp_decrypted_info_t *ndi=pinfo->decrypted_data;
/* No decrypted data so don't try and call a subdissector */
sub_dissect = info->request ? 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;
if (!pinfo->decrypted_data)
goto done;
init_ndr_pointer_list(pinfo);
/*
* Catch ReportedBoundsError, as that could
* be due to the decryption being bad,
* and doesn't mean that the tvbuff we were
* handed has a malformed packet.
*/
TRY {
offset = sub_dissect (ndi->decr_tvb, 0, pinfo, ndi->decr_tree, drep);
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
pinfo->current_proto = saved_proto;
pinfo->private_data = saved_private_data;
}
}
break;
dit = (decrypted_info_t *)pinfo->decrypted_data;
tvb = dit->decr_tvb;
sub_tree = dit->decr_tree;
}
}
}
} else {
sub_dissect = info->request ? proc->dissect_rqst : proc->dissect_resp;
if (sub_dissect) {
}
sub_dissect = info->request ? 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);
/*
* Catch ReportedBoundsError, so that even if the stub
@ -1786,7 +1861,8 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
plurality(length, "", "s"));
}
}
}
done:
tap_queue_packet(dcerpc_tap, pinfo, info);
return 0;
}
@ -1799,63 +1875,21 @@ dissect_dcerpc_verifier (tvbuff_t *tvb, packet_info *pinfo,
int auth_offset;
if (auth_info->auth_size != 0) {
auth_offset = hdr->frag_len - hdr->auth_len;
switch (auth_info->auth_type) {
case DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP: {
/* NTLMSSP */
tvbuff_t *ntlmssp_tvb;
ntlmssp_tvb = tvb_new_subset(tvb, auth_offset, hdr->auth_len,
hdr->auth_len);
call_dissector(ntlmssp_verf_handle, ntlmssp_tvb, pinfo,
dcerpc_tree);
break;
}
case DCE_C_RPC_AUTHN_PROTOCOL_SPNEGO: {
/* SPNEGO (rfc2478) */
tvbuff_t *gssapi_tvb;
gssapi_tvb = tvb_new_subset(tvb, auth_offset, hdr->auth_len,
hdr->auth_len);
call_dissector(gssapi_verf_handle, gssapi_tvb, pinfo, dcerpc_tree);
break;
}
case DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN: {
proto_item *vf = NULL;
proto_tree *volatile sec_chan_tree = NULL;
/*
* Create a new tree, and split into 4 components ...
*/
vf = proto_tree_add_item(dcerpc_tree, hf_dcerpc_sec_chan, tvb,
auth_offset, -1, FALSE);
sec_chan_tree = proto_item_add_subtree(vf, ett_sec_chan);
dcerpc_auth_subdissector_fns *auth_fns;
tvbuff_t *auth_tvb;
proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_sig, tvb,
auth_offset, 8, FALSE);
auth_offset = hdr->frag_len - hdr->auth_len;
proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_unk, tvb,
auth_offset + 8, 8, FALSE);
auth_tvb = tvb_new_subset(tvb, auth_offset, hdr->auth_len,
hdr->auth_len);
proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_seq, tvb,
auth_offset + 16, 8, FALSE);
proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_nonce, tvb,
auth_offset + 24, 8, FALSE);
break;
}
default:
proto_tree_add_text (dcerpc_tree, tvb, auth_offset, hdr->auth_len,
"Auth Verifier");
}
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,
hdr, auth_info);
else
proto_tree_add_text (dcerpc_tree, auth_tvb, 0, hdr->auth_len,
"Auth Verifier");
}
return hdr->auth_len;
@ -1907,49 +1941,19 @@ dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
* Dissect the authentication data.
*/
if (are_credentials) {
/*
* The authentication data are credentials.
*/
switch (auth_info->auth_type) {
tvbuff_t *auth_tvb;
dcerpc_auth_subdissector_fns *auth_fns;
case DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP: {
/* NTLMSSP */
tvbuff_t *ntlmssp_tvb;
auth_tvb = tvb_new_subset(
tvb, offset, hdr->auth_len, hdr->auth_len);
ntlmssp_tvb = tvb_new_subset(tvb, offset, hdr->auth_len,
hdr->auth_len);
call_dissector(ntlmssp_handle, ntlmssp_tvb, pinfo,
dcerpc_tree);
break;
}
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_handle, gssapi_tvb, pinfo, dcerpc_tree);
break;
}
case DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN: {
/* TODO: Fill me in when we know what goes here */
proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len,
"Secure Channel Auth Credentials");
break;
}
default:
proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len,
"Auth Credentials");
}
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,
hdr, auth_info);
else
proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len,
"Auth Credentials");
}
/* figure out where the auth padding starts */
@ -4297,22 +4301,6 @@ proto_register_dcerpc (void)
{ "Time from request", "dcerpc.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0, "Time between Request and Reply for DCE-RPC calls", HFILL }},
{ &hf_dcerpc_reassembled_in,
{ "This PDU is reassembled in", "dcerpc.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }},
{ &hf_dcerpc_sec_chan,
{ "Verifier", "verifier", FT_NONE, BASE_NONE, NULL, 0x0, "Verifier",
HFILL }},
{ &hf_dcerpc_sec_chan_sig,
{ "Signature", "dcerpc.sec_chan.sig", FT_BYTES, BASE_HEX, NULL,
0x0, "Signature", HFILL }},
{ &hf_dcerpc_sec_chan_unk,
{ "Unknown", "dcerpc.sec_chan.unk", FT_BYTES, BASE_HEX, NULL,
0x0, "Unknown", HFILL }},
{ &hf_dcerpc_sec_chan_seq,
{ "Sequence No", "dcerpc.sec_chan.seq", FT_BYTES, BASE_HEX, NULL,
0x0, "Sequence No", HFILL }},
{ &hf_dcerpc_sec_chan_nonce,
{ "Nonce", "dcerpc.sec_chan.nonce", FT_BYTES, BASE_HEX, NULL,
0x0, "Nonce", HFILL }},
};
static gint *ett[] = {
&ett_dcerpc,
@ -4325,7 +4313,6 @@ proto_register_dcerpc (void)
&ett_dcerpc_fragments,
&ett_dcerpc_fragment,
&ett_dcerpc_krb5_auth_verf,
&ett_sec_chan,
};
module_t *dcerpc_module;
@ -4356,10 +4343,5 @@ proto_reg_handoff_dcerpc (void)
heur_dissector_add ("netbios", dissect_dcerpc_cn_pk, proto_dcerpc);
heur_dissector_add ("udp", dissect_dcerpc_dg, proto_dcerpc);
heur_dissector_add ("smb_transact", dissect_dcerpc_cn_bs, proto_dcerpc);
ntlmssp_handle = find_dissector("ntlmssp");
ntlmssp_verf_handle = find_dissector("ntlmssp_verf");
ntlmssp_enc_payload_handle = find_dissector("ntlmssp_encrypted_payload");
gssapi_handle = find_dissector("gssapi");
gssapi_verf_handle = find_dissector("gssapi_verf");
dcerpc_smb_init(proto_dcerpc);
}

View File

@ -1,7 +1,8 @@
/* packet-dcerpc.h
* Copyright 2001, Todd Sabin <tas@webspan.net>
* Copyright 2003, Tim Potter <tpot@samba.org>
*
* $Id: packet-dcerpc.h,v 1.32 2003/06/26 04:30:31 tpot Exp $
* $Id: packet-dcerpc.h,v 1.33 2003/07/16 04:20:32 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -279,5 +280,41 @@ typedef struct _dcerpc_uuid_value {
int opnum_hf;
} dcerpc_uuid_value;
/* Authenticated pipe registration functions and miscellanea */
typedef struct _decrpc_auth_subdissector_fns {
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;
} dcerpc_auth_subdissector_fns;
void register_dcerpc_auth_subdissector(guint8 auth_level, guint8 auth_type,
dcerpc_auth_subdissector_fns *fns);
/* Authentication services */
#define DCE_C_RPC_AUTHN_PROTOCOL_NONE 0
#define DCE_C_RPC_AUTHN_PROTOCOL_KRB5 1
#define DCE_C_RPC_AUTHN_PROTOCOL_SPNEGO 9
#define DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP 10
#define DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN 68
/* 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
typedef struct _decrypted_info_t {
tvbuff_t *decr_tvb;
proto_tree *decr_tree;
} decrypted_info_t;
#endif /* packet-dcerpc.h */

View File

@ -4,7 +4,7 @@
* Copyright 2002, Richard Sharpe <rsharpe@samba.org> Added a few
* bits and pieces ...
*
* $Id: packet-gssapi.c,v 1.26 2002/12/02 20:04:07 guy Exp $
* $Id: packet-gssapi.c,v 1.27 2003/07/16 04:20:32 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -40,6 +40,7 @@
#include "asn1.h"
#include "format-oid.h"
#include "packet-dcerpc.h"
#include "packet-gssapi.h"
#include "packet-frame.h"
#include "epan/conversation.h"
@ -402,7 +403,7 @@ dissect_gssapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
static int
dissect_gssapi_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
dissect_gssapi_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
return dissect_gssapi_work(tvb, pinfo, tree, TRUE);
}
@ -428,13 +429,55 @@ proto_register_gssapi(void)
proto_register_subtree_array(ett, array_length(ett));
register_dissector("gssapi", dissect_gssapi, proto_gssapi);
new_register_dissector("gssapi_verf", dissect_gssapi_wrap, proto_gssapi);
new_register_dissector("gssapi_verf", dissect_gssapi_verf, proto_gssapi);
gssapi_oids = g_hash_table_new(gssapi_oid_hash, gssapi_oid_equal);
}
static int wrap_dissect_gssapi(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));
dissect_gssapi(auth_tvb, pinfo, tree);
return tvb_length_remaining(tvb, offset);
}
static int wrap_dissect_gssapi_verf(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_gssapi_verf(auth_tvb, pinfo, tree);
}
static dcerpc_auth_subdissector_fns gssapi_auth_fns = {
wrap_dissect_gssapi, /* Bind */
wrap_dissect_gssapi, /* Bind ACK */
wrap_dissect_gssapi, /* AUTH3 */
wrap_dissect_gssapi_verf, /* Request verifier */
wrap_dissect_gssapi_verf, /* Response verifier */
NULL, /* Request data */
NULL /* Response data */
};
void
proto_reg_handoff_gssapi(void)
{
data_handle = find_dissector("data");
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
DCE_C_RPC_AUTHN_PROTOCOL_SPNEGO,
&gssapi_auth_fns);
}

View File

@ -1,8 +1,9 @@
/* packet-ntlmssp.c
* Routines for NTLM Secure Service Provider
* Devin Heitmueller <dheitmueller@netilla.com>
* Copyright 2003, Tim Potter <tpot@samba.org>
*
* $Id: packet-ntlmssp.c,v 1.40 2003/05/09 01:41:28 tpot Exp $
* $Id: packet-ntlmssp.c,v 1.41 2003/07/16 04:20:32 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -38,7 +39,7 @@
#include "crypt-rc4.h"
#include "crypt-md4.h"
#include "crypt-des.h"
#include "packet-ntlmssp.h"
#include "packet-dcerpc.h"
/* Message types */
@ -1186,7 +1187,7 @@ dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
ntlmssp_info *conv_ntlmssp_info = NULL;
ntlmssp_packet_info *packet_ntlmssp_info = NULL;
proto_item *it;
static ntlmssp_decrypted_info_t ndi;
static decrypted_info_t ndi;
encrypted_block_length = tvb_length_remaining (tvb, offset);
@ -1503,6 +1504,65 @@ proto_register_ntlmssp(void)
dissect_ntlmssp_encrypted_payload, proto_ntlmssp);
}
static int wrap_dissect_ntlmssp(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));
dissect_ntlmssp(auth_tvb, pinfo, tree);
return tvb_length_remaining(tvb, offset);
}
static int wrap_dissect_ntlmssp_verf(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_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 */
wrap_dissect_ntlmssp, /* AUTH3 */
wrap_dissect_ntlmssp_verf, /* Request verifier */
wrap_dissect_ntlmssp_verf, /* Response verifier */
NULL, /* Request data */
NULL /* Response data */
};
static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
wrap_dissect_ntlmssp, /* Bind */
wrap_dissect_ntlmssp, /* Bind ACK */
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 */
};
void
proto_reg_handoff_ntlmssp(void)
{
@ -1515,4 +1575,14 @@ proto_reg_handoff_ntlmssp(void)
gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
ntlmssp_handle, ntlmssp_wrap_handle,
"NTLMSSP - Microsoft NTLM Security Support Provider");
/* Register authenticated pipe dissector */
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
&ntlmssp_sign_fns);
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
&ntlmssp_seal_fns);
}

View File

@ -1,27 +0,0 @@
/* packet-ntlmssp.h
*
* $Id: packet-ntlmssp.h,v 1.1 2003/01/06 11:28:02 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
typedef struct _ntlmssp_decrypted_info_t {
tvbuff_t *decr_tvb;
proto_tree *decr_tree;
} ntlmssp_decrypted_info_t;