aboutsummaryrefslogtreecommitdiffstats
path: root/asn1
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2008-09-29 18:44:10 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2008-09-29 18:44:10 +0000
commit687b0422d33e189a613114104c19a183a4e5e398 (patch)
treecfa047be7d70e60b4111975e8ba74c649f77b617 /asn1
parent7d3592fed28e7073a72fd8eba2c5bd5888f200c7 (diff)
from Metze
add dissection of RFC4121 krb5 blobs svn path=/trunk/; revision=26294
Diffstat (limited to 'asn1')
-rw-r--r--asn1/spnego/packet-spnego-template.c263
1 files changed, 262 insertions, 1 deletions
diff --git a/asn1/spnego/packet-spnego-template.c b/asn1/spnego/packet-spnego-template.c
index 6cf5e5c442..62d60b937d 100644
--- a/asn1/spnego/packet-spnego-template.c
+++ b/asn1/spnego/packet-spnego-template.c
@@ -71,6 +71,14 @@ static int hf_spnego_krb5_seal_alg = -1;
static int hf_spnego_krb5_snd_seq = -1;
static int hf_spnego_krb5_sgn_cksum = -1;
static int hf_spnego_krb5_confounder = -1;
+static int hf_spnego_krb5_filler = -1;
+static int hf_spnego_krb5_cfx_flags = -1;
+static int hf_spnego_krb5_cfx_flags_01 = -1;
+static int hf_spnego_krb5_cfx_flags_02 = -1;
+static int hf_spnego_krb5_cfx_flags_04 = -1;
+static int hf_spnego_krb5_cfx_ec = -1;
+static int hf_spnego_krb5_cfx_rrc = -1;
+static int hf_spnego_krb5_cfx_seq = -1;
#include "packet-spnego-hf.c"
@@ -84,6 +92,7 @@ gboolean saw_mechanism = FALSE;
static gint ett_spnego;
static gint ett_spnego_wraptoken;
static gint ett_spnego_krb5 = -1;
+static gint ett_spnego_krb5_cfx_flags = -1;
#include "packet-spnego-ett.c"
@@ -111,6 +120,8 @@ static int dissect_spnego_PrincipalSeq(gboolean implicit_tag, tvbuff_t *tvb,
#define KRB_TOKEN_GETMIC 0x0101
#define KRB_TOKEN_WRAP 0x0102
#define KRB_TOKEN_DELETE_SEC_CONTEXT 0x0201
+#define KRB_TOKEN_CFX_GETMIC 0x0404
+#define KRB_TOKEN_CFX_WRAP 0x0405
static const value_string spnego_krb5_tok_id_vals[] = {
{ KRB_TOKEN_AP_REQ, "KRB5_AP_REQ"},
@@ -119,6 +130,8 @@ static const value_string spnego_krb5_tok_id_vals[] = {
{ KRB_TOKEN_GETMIC, "KRB5_GSS_GetMIC" },
{ KRB_TOKEN_WRAP, "KRB5_GSS_Wrap" },
{ KRB_TOKEN_DELETE_SEC_CONTEXT, "KRB5_GSS_Delete_sec_context" },
+ { KRB_TOKEN_CFX_GETMIC, "KRB_TOKEN_CFX_GetMic" },
+ { KRB_TOKEN_CFX_WRAP, "KRB_TOKEN_CFX_WRAP" },
{ 0, NULL}
};
@@ -157,6 +170,10 @@ static int
dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
static int
dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 token_id);
+static int
+dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
+static int
+dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 token_id);
static void
dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -284,12 +301,21 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
+ case KRB_TOKEN_CFX_GETMIC:
+ offset = dissect_spnego_krb5_cfx_getmic_base(tvb, offset, pinfo, subtree);
+ break;
+
+ case KRB_TOKEN_CFX_WRAP:
+ offset = dissect_spnego_krb5_cfx_wrap_base(tvb, offset, pinfo, subtree, token_id);
+ break;
+
default:
break;
}
done:
+ proto_item_set_len(item, offset);
return;
}
@@ -825,6 +851,192 @@ dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U
return offset;
}
+static int
+dissect_spnego_krb5_cfx_flags(tvbuff_t *tvb, int offset,
+ proto_tree *spnego_krb5_tree,
+ guint8 cfx_flags)
+{
+ proto_tree *cfx_flags_tree = NULL;
+ proto_item *tf = NULL;
+
+ if (spnego_krb5_tree) {
+ tf = proto_tree_add_uint(spnego_krb5_tree,
+ hf_spnego_krb5_cfx_flags,
+ tvb, offset, 1, cfx_flags);
+ cfx_flags_tree = proto_item_add_subtree(tf, ett_spnego_krb5_cfx_flags);
+ }
+
+ proto_tree_add_boolean(cfx_flags_tree,
+ hf_spnego_krb5_cfx_flags_04,
+ tvb, offset, 1, cfx_flags);
+ proto_tree_add_boolean(cfx_flags_tree,
+ hf_spnego_krb5_cfx_flags_02,
+ tvb, offset, 1, cfx_flags);
+ proto_tree_add_boolean(cfx_flags_tree,
+ hf_spnego_krb5_cfx_flags_01,
+ tvb, offset, 1, cfx_flags);
+
+ return (offset + 1);
+}
+
+/*
+ * XXX - This is for GSSAPI CFX Wrap tokens ...
+ */
+static int
+dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
+#ifndef HAVE_KERBEROS
+ _U_
+#endif
+ , proto_tree *tree, guint16 token_id _U_
+ )
+{
+ guint8 flags;
+ guint16 ec;
+ guint16 rrc;
+ int checksum_size;
+#ifdef HAVE_KERBEROS
+ int start_offset=offset;
+#endif
+
+ /*
+ * The KRB5 blob conforms to RFC4121:
+ * USHORT (0x0504)
+ * and so on }
+ */
+
+ /* Now, the sign and seal algorithms ... */
+
+ flags = tvb_get_guint8(tvb, offset);
+ offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags);
+
+ pinfo->gssapi_data_encrypted=(flags & 2);
+
+ /* Skip the filler */
+
+ proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 1,
+ FALSE);
+ offset += 1;
+
+ /* EC */
+ ec = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(tree, hf_spnego_krb5_cfx_ec, tvb, offset, 2,
+ FALSE);
+ offset += 2;
+
+ /* RRC */
+ rrc = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(tree, hf_spnego_krb5_cfx_rrc, tvb, offset, 2,
+ FALSE);
+ offset += 2;
+
+ /* sequence number */
+
+ proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8,
+ FALSE);
+ offset += 8;
+
+ /* Checksum of plaintext padded data */
+
+ if (pinfo->gssapi_data_encrypted) {
+ checksum_size = 44 + ec;
+ } else {
+ checksum_size = 12;
+ }
+
+ proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
+ checksum_size, FALSE);
+ offset += checksum_size;
+
+ if(pinfo->decrypt_gssapi_tvb){
+ /* if the caller did not provide a tvb, then we just use
+ whatever is left of our current tvb.
+ */
+ if(!pinfo->gssapi_encrypted_tvb){
+ int len;
+ len=tvb_reported_length_remaining(tvb,offset);
+ if(len>tvb_length_remaining(tvb, offset)){
+ /* no point in trying to decrypt,
+ we dont have the full pdu.
+ */
+ return offset;
+ }
+ pinfo->gssapi_encrypted_tvb = tvb_new_subset(
+ tvb, offset, len, len);
+ }
+
+ if (pinfo->gssapi_data_encrypted) {
+ /* do we need to create a tvb for the wrapper
+ as well ?
+ */
+ if(!pinfo->gssapi_wrap_tvb){
+ pinfo->gssapi_wrap_tvb = tvb_new_subset(
+ tvb, start_offset-2,
+ offset - (start_offset-2),
+ offset - (start_offset-2));
+ }
+ }
+ }
+
+ /*
+ * Return the offset past the checksum, so that we know where
+ * the data we're wrapped around starts. Also, set the length
+ * of our top-level item to that offset, so it doesn't cover
+ * the data we're wrapped around.
+ *
+ * Note that for DCERPC the GSSAPI blobs comes after the data it wraps,
+ * not before.
+ */
+ return offset;
+}
+
+/*
+ * XXX - This is for GSSAPI CFX GetMIC tokens ...
+ */
+static int
+dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint8 flags;
+ int checksum_size;
+
+ /*
+ * The KRB5 blob conforms to RFC4121:
+ * USHORT (0x0404 == GSS_GetMIC)
+ * and so on }
+ */
+
+ flags = tvb_get_guint8(tvb, offset);
+ offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags);
+
+ /* Skip the filler */
+
+ proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 5,
+ FALSE);
+ offset += 5;
+
+ /* sequence number */
+
+ proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8,
+ FALSE);
+ offset += 8;
+
+ /* Checksum of plaintext padded data */
+
+ checksum_size = tvb_length_remaining(tvb, offset);
+
+ proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
+ checksum_size, FALSE);
+ offset += checksum_size;
+
+ /*
+ * Return the offset past the checksum, so that we know where
+ * the data we're wrapped around starts. Also, set the length
+ * of our top-level item to that offset, so it doesn't cover
+ * the data we're wrapped around.
+ */
+
+ return offset;
+}
+
/*
* XXX - is this for SPNEGO or just GSS-API?
* RFC 1964 is "The Kerberos Version 5 GSS-API Mechanism"; presumably one
@@ -858,7 +1070,27 @@ dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
offset += 2;
- offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id);
+ switch (token_id) {
+ case KRB_TOKEN_GETMIC:
+ offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree);
+ break;
+
+ case KRB_TOKEN_WRAP:
+ offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id);
+ break;
+
+ case KRB_TOKEN_CFX_GETMIC:
+ offset = dissect_spnego_krb5_cfx_getmic_base(tvb, offset, pinfo, subtree);
+ break;
+
+ case KRB_TOKEN_CFX_WRAP:
+ offset = dissect_spnego_krb5_cfx_wrap_base(tvb, offset, pinfo, subtree, token_id);
+ break;
+
+ default:
+
+ break;
+ }
/*
* Return the offset past the checksum, so that we know where
@@ -1015,6 +1247,30 @@ void proto_register_spnego(void) {
{ &hf_spnego_krb5_confounder,
{ "krb5_confounder", "spnego.krb5.confounder", FT_BYTES, BASE_NONE,
NULL, 0, "KRB5 Confounder", HFILL}},
+ { &hf_spnego_krb5_filler,
+ { "krb5_filler", "spnego.krb5.filler", FT_BYTES, BASE_HEX,
+ NULL, 0, "KRB5 Filler", HFILL}},
+ { &hf_spnego_krb5_cfx_flags,
+ { "krb5_cfx_flags", "spnego.krb5.cfx_flags", FT_UINT8, BASE_HEX,
+ NULL, 0, "KRB5 CFX Flags", HFILL}},
+ { &hf_spnego_krb5_cfx_flags_01,
+ { "SendByAcceptor", "spnego.krb5.send_by_acceptor", FT_BOOLEAN, 8,
+ TFS (&flags_set_truth), 0x01, "", HFILL}},
+ { &hf_spnego_krb5_cfx_flags_02,
+ { "Sealed", "spnego.krb5.sealed", FT_BOOLEAN, 8,
+ TFS (&flags_set_truth), 0x02, "", HFILL}},
+ { &hf_spnego_krb5_cfx_flags_04,
+ { "AcceptorSubkey", "spnego.krb5.acceptor_subkey", FT_BOOLEAN, 8,
+ TFS (&flags_set_truth), 0x04, "", HFILL}},
+ { &hf_spnego_krb5_cfx_ec,
+ { "krb5_cfx_ec", "spnego.krb5.cfx_ec", FT_UINT16, BASE_DEC,
+ NULL, 0, "KRB5 CFX Extra Count", HFILL}},
+ { &hf_spnego_krb5_cfx_rrc,
+ { "krb5_cfx_rrc", "spnego.krb5.cfx_rrc", FT_UINT16, BASE_DEC,
+ NULL, 0, "KRB5 CFX Right Rotation Count", HFILL}},
+ { &hf_spnego_krb5_cfx_seq,
+ { "krb5_cfx_seq", "spnego.krb5.cfx_seq", FT_UINT64, BASE_DEC,
+ NULL, 0, "KRB5 Sequence Number", HFILL}},
#include "packet-spnego-hfarr.c"
};
@@ -1024,6 +1280,7 @@ void proto_register_spnego(void) {
&ett_spnego,
&ett_spnego_wraptoken,
&ett_spnego_krb5,
+ &ett_spnego_krb5_cfx_flags,
#include "packet-spnego-ettarr.c"
};
@@ -1036,6 +1293,10 @@ void proto_register_spnego(void) {
proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5",
"SPNEGO-KRB5",
"spnego-krb5");
+
+ register_dissector("spnego-krb5", dissect_spnego_krb5, proto_spnego_krb5);
+ new_register_dissector("spnego-krb5-wrap", dissect_spnego_krb5_wrap, proto_spnego_krb5);
+
/* Register fields and subtrees */
proto_register_field_array(proto_spnego, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));