diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | packet-dcerpc-netlogon.c | 123 | ||||
-rw-r--r-- | packet-dcerpc-netlogon.h | 16 | ||||
-rw-r--r-- | packet-dcerpc.c | 380 | ||||
-rw-r--r-- | packet-dcerpc.h | 39 | ||||
-rw-r--r-- | packet-gssapi.c | 49 | ||||
-rw-r--r-- | packet-ntlmssp.c | 76 | ||||
-rw-r--r-- | packet-ntlmssp.h | 27 |
8 files changed, 409 insertions, 304 deletions
diff --git a/Makefile.am b/Makefile.am index f729600313..ab2e7b89fe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/packet-dcerpc-netlogon.c b/packet-dcerpc-netlogon.c index 102334c199..2ccf12fccb 100644 --- a/packet-dcerpc-netlogon.c +++ b/packet-dcerpc-netlogon.c @@ -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); } diff --git a/packet-dcerpc-netlogon.h b/packet-dcerpc-netlogon.h index 266bf95769..94bec6a643 100644 --- a/packet-dcerpc-netlogon.h +++ b/packet-dcerpc-netlogon.h @@ -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 */ diff --git a/packet-dcerpc.c b/packet-dcerpc.c index 2dfa8b26e6..752561a69b 100644 --- a/packet-dcerpc.c +++ b/packet-dcerpc.c @@ -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, @@ -464,6 +441,125 @@ dcerpc_reassemble_init(void) } /* + * 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) { - - 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; - - call_dissector(ntlmssp_enc_payload_handle, ntlmssp_tvb, pinfo, - sub_tree); - - if(pinfo->decrypted_data){ - ntlmssp_decrypted_info_t *ndi=pinfo->decrypted_data; - - - 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, 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; - } + 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; } - } - } 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); - - proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_sig, tvb, - auth_offset, 8, FALSE); - - proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_unk, tvb, - auth_offset + 8, 8, FALSE); + dcerpc_auth_subdissector_fns *auth_fns; + tvbuff_t *auth_tvb; - proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_seq, tvb, - auth_offset + 16, 8, FALSE); + auth_offset = hdr->frag_len - hdr->auth_len; - proto_tree_add_item(sec_chan_tree, hf_dcerpc_sec_chan_nonce, tvb, - auth_offset + 24, 8, FALSE); + auth_tvb = tvb_new_subset(tvb, auth_offset, hdr->auth_len, + hdr->auth_len); - 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) { - - case DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP: { - /* NTLMSSP */ - tvbuff_t *ntlmssp_tvb; - - 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"); - } + tvbuff_t *auth_tvb; + dcerpc_auth_subdissector_fns *auth_fns; + + auth_tvb = tvb_new_subset( + tvb, offset, hdr->auth_len, hdr->auth_len); + + 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); } diff --git a/packet-dcerpc.h b/packet-dcerpc.h index 789a384a3d..c12579d680 100644 --- a/packet-dcerpc.h +++ b/packet-dcerpc.h @@ -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 */ diff --git a/packet-gssapi.c b/packet-gssapi.c index 49cfb15bfe..3be922300b 100644 --- a/packet-gssapi.c +++ b/packet-gssapi.c @@ -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); } diff --git a/packet-ntlmssp.c b/packet-ntlmssp.c index 3cdd3d72bf..6257c0a379 100644 --- a/packet-ntlmssp.c +++ b/packet-ntlmssp.c @@ -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); } diff --git a/packet-ntlmssp.h b/packet-ntlmssp.h deleted file mode 100644 index 7fa2ad96af..0000000000 --- a/packet-ntlmssp.h +++ /dev/null @@ -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; |