Add a mechanism where one can provide callbacks to the kerbgeros dissector

to pass back dissection of application specific fields (octet strings)

This can later be used to pick up session keys by dcerpc and similar.
Currently it will initially be used by packetcable.

PacketCable additions by Thomas Anders

svn path=/trunk/; revision=11101
This commit is contained in:
Ronnie Sahlberg 2004-06-04 01:56:25 +00:00
parent aa3aec2d95
commit 6ff0cf2828
7 changed files with 142 additions and 29 deletions

View File

@ -5,7 +5,7 @@
* This information is based off the released idl files from opengroup.
* ftp://ftp.opengroup.org/pub/dce122/dce/src/security.tar.gz security/idl/krb5rpc.idl
*
* $Id: packet-dcerpc-krb5rpc.c,v 1.8 2004/01/27 04:15:48 guy Exp $
* $Id: packet-dcerpc-krb5rpc.c,v 1.9 2004/06/04 01:56:25 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -94,7 +94,7 @@ krb5rpc_dissect_sendto_kdc_rqst (tvbuff_t * tvb, int offset,
remain = tvb_length_remaining(tvb, offset);
krb5_tvb = tvb_new_subset (tvb, offset, remain, remain);
offset = dissect_kerberos_main (krb5_tvb, pinfo, subtree, TRUE);
offset = dissect_kerberos_main (krb5_tvb, pinfo, subtree, TRUE, NULL);
return offset;
@ -140,7 +140,7 @@ krb5rpc_dissect_sendto_kdc_resp (tvbuff_t * tvb, int offset,
remain = tvb_length_remaining(tvb, offset);
krb5_tvb = tvb_new_subset (tvb, offset, remain, remain);
offset = dissect_kerberos_main (krb5_tvb, pinfo, subtree, TRUE);
offset = dissect_kerberos_main (krb5_tvb, pinfo, subtree, TRUE, NULL);
offset += 16; /* no idea what this is, probably just extended encrypted text. */
return offset;

View File

@ -23,7 +23,7 @@
*
* Some structures from RFC2630
*
* $Id: packet-kerberos.c,v 1.67 2004/05/27 08:22:04 sahlberg Exp $
* $Id: packet-kerberos.c,v 1.68 2004/06/04 01:56:25 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -58,6 +58,7 @@
#include <epan/strutil.h>
#include "packet-kerberos.h"
#include "packet-netbios.h"
#include "packet-tcp.h"
#include "prefs.h"
@ -260,7 +261,24 @@ guint32 krb5_errorcode;
static int do_col_info;
static void
call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag)
{
kerberos_callbacks *cb=(kerberos_callbacks *)pinfo->private_data;
if(!cb){
return;
}
while(cb->tag){
if(cb->tag==tag){
cb->callback(pinfo, tvb, tree);
return;
}
cb++;
}
return;
}
@ -2488,7 +2506,9 @@ dissect_krb5_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offse
static int
dissect_krb5_SAFE_BODY_user_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
{
offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_user_data, NULL);
tvbuff_t *new_tvb;
offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_user_data, &new_tvb);
call_kerberos_callbacks(pinfo, tree, new_tvb, KRB_CBTAG_SAFE_USER_DATA);
return offset;
}
static int
@ -3167,7 +3187,8 @@ static void dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree);
static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree, int do_col_info,
gboolean have_rm);
gboolean have_rm,
kerberos_callbacks *cb);
static gint kerberos_rm_to_reclen(guint krb_rm);
static void dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree);
@ -3176,9 +3197,9 @@ static guint get_krb_pdu_len(tvbuff_t *tvb, int offset);
gint
dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info)
dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
{
return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE));
return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, cb));
}
static void
@ -3187,7 +3208,7 @@ dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
(void)dissect_kerberos_common(tvb, pinfo, tree, TRUE, FALSE);
(void)dissect_kerberos_common(tvb, pinfo, tree, TRUE, FALSE, NULL);
}
static gint
@ -3211,7 +3232,7 @@ static void
dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
pinfo->fragmented = TRUE;
if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE) < 0) {
if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, NULL) < 0) {
/*
* The dissector failed to recognize this as a valid
* Kerberos message. Mark it as a continuation packet.
@ -3256,16 +3277,19 @@ show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
static gint
dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int dci, gboolean have_rm)
int dci, gboolean have_rm, kerberos_callbacks *cb)
{
int offset = 0;
proto_tree *kerberos_tree = NULL;
proto_item *item = NULL;
void *saved_private_data;
/* TCP record mark and length */
guint32 krb_rm = 0;
gint krb_reclen = 0;
saved_private_data=pinfo->private_data;
pinfo->private_data=cb;
do_col_info=dci;
if (tree) {
@ -3280,6 +3304,7 @@ dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
* What is a reasonable size limit?
*/
if (krb_reclen > 10 * 1024 * 1024) {
pinfo->private_data=saved_private_data;
return (-1);
}
show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
@ -3289,6 +3314,7 @@ dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
offset=dissect_ber_choice(pinfo, kerberos_tree, tvb, offset, kerberos_applications_choice, -1, -1);
proto_item_set_len(item, offset);
pinfo->private_data=saved_private_data;
return offset;
}

View File

@ -1,6 +1,6 @@
/* packet-kerberos.h
*
* $Id: packet-kerberos.h,v 1.7 2003/04/25 21:29:19 guy Exp $
* $Id: packet-kerberos.h,v 1.8 2004/06/04 01:56:25 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -24,9 +24,23 @@
#ifndef __PACKET_KERBEROS_H
#define __PACKET_KERBEROS_H
/* This is a list of callback functions a caller can use to specify that
octet strings in kerberos to be passed back to application specific
dissectors, outside of kerberos.
This is used for dissection of application specific data for PacketCable
KRB_SAFE user data and eventually to pass kerberos session keys
to future DCERPC decryption and other uses.
The list is terminated by {0, NULL }
*/
#define KRB_CBTAG_SAFE_USER_DATA 1
typedef struct _kerberos_callbacks {
int tag;
int (*callback)(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree);
} kerberos_callbacks;
/* Function prototypes */
gint
dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info);
dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb);
#endif /* __PACKET_KERBEROS_H */

View File

@ -4,7 +4,7 @@
*
* See RFC 3244
*
* $Id: packet-kpasswd.c,v 1.2 2004/02/16 09:42:10 sahlberg Exp $
* $Id: packet-kpasswd.c,v 1.3 2004/06/04 01:56:25 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -66,7 +66,7 @@ dissect_kpasswd_ap_req_data(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *p
it=proto_tree_add_item(parent_tree, hf_kpasswd_ap_req_data, tvb, 0, -1, FALSE);
tree=proto_item_add_subtree(it, ett_ap_req_data);
}
dissect_kerberos_main(tvb, pinfo, tree, FALSE);
dissect_kerberos_main(tvb, pinfo, tree, FALSE, NULL);
}
static void
@ -79,7 +79,7 @@ dissect_kpasswd_krb_priv_message(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tr
it=proto_tree_add_item(parent_tree, hf_kpasswd_krb_priv_message, tvb, 0, -1, FALSE);
tree=proto_item_add_subtree(it, ett_krb_priv_message);
}
dissect_kerberos_main(tvb, pinfo, tree, FALSE);
dissect_kerberos_main(tvb, pinfo, tree, FALSE, NULL);
}

View File

@ -8,7 +8,7 @@
* Ronnie Sahlberg 2004
* Thomas Anders 2004
*
* $Id: packet-pktc.c,v 1.5 2004/05/25 09:41:03 guy Exp $
* $Id: packet-pktc.c,v 1.6 2004/06/04 01:56:25 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -38,6 +38,7 @@
#include "packet-kerberos.h"
#define PKTC_PORT 1293
#define PKTC_MTAFQDNMAP_PORT 2246
static int proto_pktc = -1;
static gint hf_pktc_app_spec_data = -1;
@ -66,10 +67,12 @@ static gint hf_pktc_ack_required_flag = -1;
static gint hf_pktc_sha1_hmac = -1;
static gint hf_pktc_sec_param_lifetime = -1;
static gint hf_pktc_grace_period = -1;
static gint hf_pktc_mtafqdnmap = -1;
static gint ett_pktc = -1;
static gint ett_pktc_app_spec_data = -1;
static gint ett_pktc_list_of_ciphersuites = -1;
static gint ett_pktc_mtafqdnmap = -1;
#define KMMID_WAKEUP 0x01
#define KMMID_AP_REQUEST 0x02
@ -189,7 +192,7 @@ dissect_pktc_app_specific_data(packet_info *pinfo _U_, proto_tree *parent_tree,
break;
default:
proto_tree_add_text(tree, tvb, offset, 1, "Dont know how to parse this type of KMMID yet");
proto_tree_add_text(tree, tvb, offset, 1, "Unknown KMMID");
tvb_get_guint8(tvb, 9999); /* bail out and inform user we cant dissect the packet */
};
break;
@ -207,7 +210,7 @@ dissect_pktc_app_specific_data(packet_info *pinfo _U_, proto_tree *parent_tree,
break;
default:
proto_tree_add_text(tree, tvb, offset, 1, "Dont know how to parse this type of KMMID yet");
proto_tree_add_text(tree, tvb, offset, 1, "Unknown KMMID");
tvb_get_guint8(tvb, 9999); /* bail out and inform user we cant dissect the packet */
};
break;
@ -263,7 +266,7 @@ dissect_pktc_list_of_ciphersuites(packet_info *pinfo _U_, proto_tree *parent_tre
}
break;
default:
proto_tree_add_text(tree, tvb, offset, 1, "Dont know how to parse this type of Algorithm Identifier yet");
proto_tree_add_text(tree, tvb, offset, 1, "Unknown DOI");
tvb_get_guint8(tvb, 9999); /* bail out and inform user we cant dissect the packet */
}
@ -298,7 +301,7 @@ dissect_pktc_ap_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int
/* AP Request kerberos blob */
pktc_tvb = tvb_new_subset(tvb, offset, -1, -1);
offset += dissect_kerberos_main(pktc_tvb, pinfo, tree, FALSE);
offset += dissect_kerberos_main(pktc_tvb, pinfo, tree, FALSE, NULL);
/* Server Nonce */
snonce=tvb_get_ntohl(tvb, offset);
@ -329,7 +332,7 @@ dissect_pktc_ap_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int o
/* AP Reply kerberos blob */
pktc_tvb = tvb_new_subset(tvb, offset, -1, -1);
offset += dissect_kerberos_main(pktc_tvb, pinfo, tree, FALSE);
offset += dissect_kerberos_main(pktc_tvb, pinfo, tree, FALSE, NULL);
/* app specific data */
offset=dissect_pktc_app_specific_data(pinfo, tree, tvb, offset, doi, KMMID_AP_REPLY);
@ -427,11 +430,56 @@ dissect_pktc_error_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, in
/* KRB_ERROR */
pktc_tvb = tvb_new_subset(tvb, offset, -1, -1);
offset += dissect_kerberos_main(pktc_tvb, pinfo, tree, FALSE);
offset += dissect_kerberos_main(pktc_tvb, pinfo, tree, FALSE, NULL);
return offset;
}
static int
dissect_pktc_appspecificdata(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree)
{
int offset=0;
/*XXX add dissection of the app specific data here */
return offset;
}
static kerberos_callbacks cb[] = {
{ KRB_CBTAG_SAFE_USER_DATA, dissect_pktc_appspecificdata },
{ 0, NULL }
};
static void
dissect_pktc_mtafqdnmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset=0;
proto_tree *pktc_mtafqdnmap_tree = NULL;
proto_item *item = NULL;
tvbuff_t *pktc_mtafqdnmap_tvb;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PKTC");
if (tree) {
item = proto_tree_add_item(tree, proto_pktc, tvb, 0, 0, FALSE);
pktc_mtafqdnmap_tree = proto_item_add_subtree(item, ett_pktc_mtafqdnmap);
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_fstr(pinfo->cinfo, COL_INFO, "MTAFQDNMAP %s",
pinfo->srcport == pinfo->match_port ? "Reply":"Request");
}
/* KRB_AP_RE[QP] */
pktc_mtafqdnmap_tvb = tvb_new_subset(tvb, offset, -1, -1);
offset += dissect_kerberos_main(pktc_mtafqdnmap_tvb, pinfo, pktc_mtafqdnmap_tree, FALSE, NULL);
/* KRB_SAFE */
pktc_mtafqdnmap_tvb = tvb_new_subset(tvb, offset, -1, -1);
offset += dissect_kerberos_main(pktc_mtafqdnmap_tvb, pinfo, pktc_mtafqdnmap_tree, FALSE, cb);
proto_item_set_len(item, offset);
}
static void
dissect_pktc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
@ -599,3 +647,28 @@ proto_reg_handoff_pktc(void)
pktc_handle = create_dissector_handle(dissect_pktc, proto_pktc);
dissector_add("udp.port", PKTC_PORT, pktc_handle);
}
void
proto_register_pktc_mtafqdnmap(void)
{
static hf_register_info hf[] = {
{ &hf_pktc_mtafqdnmap, {
"MTAFQDNMAP", "pktc.mtafqdnmap", FT_BOOLEAN, BASE_NONE,
NULL, 0, "MTAFQDNMAP Message", HFILL }},
};
static gint *ett[] = {
&ett_pktc_mtafqdnmap,
};
proto_register_field_array(proto_pktc, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_pktc_mtafqdnmap(void)
{
dissector_handle_t pktc_mtafqdnmap_handle;
pktc_mtafqdnmap_handle = create_dissector_handle(dissect_pktc_mtafqdnmap, proto_pktc);
dissector_add("udp.port", PKTC_MTAFQDNMAP_PORT, pktc_mtafqdnmap_handle);
}

View File

@ -5,7 +5,7 @@
* Copyright 2002, Richard Sharpe <rsharpe@ns.aus.com>
* Copyright 2003, Richard Sharpe <rsharpe@richardsharpe.com>
*
* $Id: packet-spnego.c,v 1.55 2004/05/11 02:02:44 gerald Exp $
* $Id: packet-spnego.c,v 1.56 2004/06/04 01:56:25 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -348,7 +348,7 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* return.
*/
krb5_tvb = tvb_new_subset(tvb, offset, -1, -1);
offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE);
offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE, NULL);
return;
default:
@ -375,7 +375,7 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case KRB_TOKEN_AP_REP:
case KRB_TOKEN_AP_ERR:
krb5_tvb = tvb_new_subset(tvb, offset, -1, -1);
offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE);
offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE, NULL);
break;
case KRB_TOKEN_GETMIC:

View File

@ -2,7 +2,7 @@
* Routines for Telnet packet dissection; see RFC 854 and RFC 855
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
* $Id: packet-telnet.c,v 1.45 2004/02/25 09:31:07 guy Exp $
* $Id: packet-telnet.c,v 1.46 2004/06/04 01:56:25 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -756,7 +756,7 @@ dissect_krb5_authentication_data(packet_info *pinfo, tvbuff_t *tvb, int offset,
if((acmd==TN_AC_IS)&&(krb5_cmd==TN_KRB5_TYPE_AUTH)){
krb5_tvb=unescape_and_tvbuffify_telnet_option(pinfo, tvb, offset, len);
if(krb5_tvb)
dissect_kerberos_main(krb5_tvb, pinfo, tree, FALSE);
dissect_kerberos_main(krb5_tvb, pinfo, tree, FALSE, NULL);
else
proto_tree_add_text(tree, tvb, offset, len, "Kerberos blob (too long to dissect - length %u > %u",
len, MAX_KRB5_BLOB_LEN);
@ -776,7 +776,7 @@ dissect_krb5_authentication_data(packet_info *pinfo, tvbuff_t *tvb, int offset,
/* IAC SB AUTHENTICATION REPLY <authentication-type-pair> RESPONSE <KRB_AP_REP message> IAC SE */
if((acmd==TN_AC_REPLY)&&(krb5_cmd==TN_KRB5_TYPE_RESPONSE)){
krb5_tvb=unescape_and_tvbuffify_telnet_option(pinfo, tvb, offset, len);
dissect_kerberos_main(krb5_tvb, pinfo, tree, FALSE);
dissect_kerberos_main(krb5_tvb, pinfo, tree, FALSE, NULL);
}