aboutsummaryrefslogtreecommitdiffstats
path: root/packet-spnego.c
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2004-07-18 18:06:47 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2004-07-18 18:06:47 +0000
commit669db206cb1f270046ad400fff7655e20c63e723 (patch)
tree4eff24a2e16c8963e497e1fc575f35e6af59bd26 /packet-spnego.c
parentae46c27a38700af669ef907491081f09df6f6b2c (diff)
Move dissectors to epan/dissectors directory.
Also move ncp222.py, x11-fields, process-x11-fields.pl, make-reg-dotc, and make-reg-dotc.py. Adjust #include lines in files that include packet-*.h files. svn path=/trunk/; revision=11410
Diffstat (limited to 'packet-spnego.c')
-rw-r--r--packet-spnego.c1694
1 files changed, 0 insertions, 1694 deletions
diff --git a/packet-spnego.c b/packet-spnego.c
deleted file mode 100644
index 70eace5ff2..0000000000
--- a/packet-spnego.c
+++ /dev/null
@@ -1,1694 +0,0 @@
-/* packet-spnego.c
- * Routines for the simple and protected GSS-API negotiation mechanism
- * as described in RFC 2478.
- * Copyright 2002, Tim Potter <tpot@samba.org>
- * Copyright 2002, Richard Sharpe <rsharpe@ns.aus.com>
- * Copyright 2003, Richard Sharpe <rsharpe@richardsharpe.com>
- *
- * $Id$
- *
- * 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.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#include <glib.h>
-#include <epan/packet.h>
-
-#include "asn1.h"
-#include "format-oid.h"
-#include "packet-gssapi.h"
-#include "packet-kerberos.h"
-#include <epan/conversation.h>
-
-#define SPNEGO_negTokenInit 0
-#define SPNEGO_negTokenTarg 1
-#define SPNEGO_mechTypes 0
-#define SPNEGO_reqFlags 1
-#define SPNEGO_mechToken 2
-#define SPNEGO_mechListMIC 3
-#define SPNEGO_negResult 0
-#define SPNEGO_supportedMech 1
-#define SPNEGO_responseToken 2
-#define SPNEGO_negResult_accept_completed 0
-#define SPNEGO_negResult_accept_incomplete 1
-#define SPNEGO_negResult_accept_reject 2
-
-static int proto_spnego = -1;
-static int proto_spnego_krb5 = -1;
-
-static int hf_spnego = -1;
-static int hf_spnego_negtokeninit = -1;
-static int hf_spnego_negtokentarg = -1;
-static int hf_spnego_mechtype = -1;
-static int hf_spnego_mechtoken = -1;
-static int hf_spnego_negtokentarg_negresult = -1;
-static int hf_spnego_mechlistmic = -1;
-static int hf_spnego_responsetoken = -1;
-static int hf_spnego_reqflags = -1;
-static int hf_spnego_wraptoken = -1;
-static int hf_spnego_krb5 = -1;
-static int hf_spnego_krb5_tok_id = -1;
-static int hf_spnego_krb5_sgn_alg = -1;
-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_gssapi_reqflags_deleg = -1;
-static int hf_gssapi_reqflags_mutual = -1;
-static int hf_gssapi_reqflags_replay = -1;
-static int hf_gssapi_reqflags_sequence = -1;
-static int hf_gssapi_reqflags_anon = -1;
-static int hf_gssapi_reqflags_conf = -1;
-static int hf_gssapi_reqflags_integ = -1;
-
-static gint ett_spnego = -1;
-static gint ett_spnego_negtokeninit = -1;
-static gint ett_spnego_negtokentarg = -1;
-static gint ett_spnego_mechtype = -1;
-static gint ett_spnego_mechtoken = -1;
-static gint ett_spnego_mechlistmic = -1;
-static gint ett_spnego_responsetoken = -1;
-static gint ett_spnego_wraptoken = -1;
-static gint ett_spnego_krb5 = -1;
-static gint ett_spnego_reqflags = -1;
-
-static const value_string spnego_negResult_vals[] = {
- { SPNEGO_negResult_accept_completed, "Accept Completed" },
- { SPNEGO_negResult_accept_incomplete, "Accept Incomplete" },
- { SPNEGO_negResult_accept_reject, "Accept Reject"},
- { 0, NULL}
-};
-
-/*
- * These should be in the GSSAPI dissector ... XXX
- */
-
-static const true_false_string tfs_reqflags_deleg = {
- "Delegation Requested",
- "Delegation NOT Requested"
-};
-
-static const true_false_string tfs_reqflags_mutual = {
- "Mutual Authentication Requested",
- "Mutual Authentication NOT Requested"
-};
-
-static const true_false_string tfs_reqflags_replay = {
- "Replay Detection Requested",
- "Replay Detection NOT Requested"
-};
-
-static const true_false_string tfs_reqflags_sequence = {
- "Out-of-sequence Detection Requested",
- "Out-of-sequence Detection NOT Requested"
-};
-
-static const true_false_string tfs_reqflags_anon = {
- "Anonymous Authentication Requested",
- "Anonymous Authentication NOT Requested"
-};
-
-static const true_false_string tfs_reqflags_conf = {
- "Per-message Confidentiality Requested",
- "Per-message Confidentiality NOT Requested"
-};
-
-static const true_false_string tfs_reqflags_integ = {
- "Per-message Integrity Requested",
- "Per-message Integrity NOT Requested"
-};
-
-/* Display an ASN1 parse error. Taken from packet-snmp.c */
-
-static dissector_handle_t data_handle;
-
-static dissector_handle_t
-gssapi_dissector_handle(gssapi_oid_value *next_level_value) {
- if (next_level_value == NULL) {
- return NULL;
- }
- return next_level_value->handle;
-}
-
-static void
-dissect_parse_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, const char *field_name, int ret)
-{
- char *errstr;
-
- errstr = asn1_err_to_str(ret);
-
- if (tree != NULL) {
- proto_tree_add_text(tree, tvb, offset, 0,
- "ERROR: Couldn't parse %s: %s", field_name, errstr);
- call_dissector(data_handle,
- tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
- }
-}
-
-/*
- * This is the SPNEGO KRB5 dissector. It is not true KRB5, but some ASN.1
- * wrapped blob with an OID, USHORT token ID, and a Ticket, that is also
- * ASN.1 wrapped by the looks of it. It conforms to RFC1964.
- */
-
-#define KRB_TOKEN_AP_REQ 0x0001
-#define KRB_TOKEN_AP_REP 0x0002
-#define KRB_TOKEN_AP_ERR 0x0003
-#define KRB_TOKEN_GETMIC 0x0101
-#define KRB_TOKEN_WRAP 0x0102
-#define KRB_TOKEN_DELETE_SEC_CONTEXT 0x0201
-
-static const value_string spnego_krb5_tok_id_vals[] = {
- { KRB_TOKEN_AP_REQ, "KRB5_AP_REQ"},
- { KRB_TOKEN_AP_REP, "KRB5_AP_REP"},
- { KRB_TOKEN_AP_ERR, "KRB5_ERROR"},
- { KRB_TOKEN_GETMIC, "KRB5_GSS_GetMIC" },
- { KRB_TOKEN_WRAP, "KRB5_GSS_Wrap" },
- { KRB_TOKEN_DELETE_SEC_CONTEXT, "KRB5_GSS_Delete_sec_context" },
- { 0, NULL}
-};
-
-#define KRB_SGN_ALG_DES_MAC_MD5 0x0000
-#define KRB_SGN_ALG_MD2_5 0x0001
-#define KRB_SGN_ALG_DES_MAC 0x0002
-#define KRB_SGN_ALG_HMAC 0x0011
-
-static const value_string spnego_krb5_sgn_alg_vals[] = {
- { KRB_SGN_ALG_DES_MAC_MD5, "DES MAC MD5"},
- { KRB_SGN_ALG_MD2_5, "MD2.5"},
- { KRB_SGN_ALG_DES_MAC, "DES MAC"},
- { KRB_SGN_ALG_HMAC, "HMAC"},
- { 0, NULL}
-};
-
-#define KRB_SEAL_ALG_DES_CBC 0x0000
-#define KRB_SEAL_ALG_RC4 0x0010
-#define KRB_SEAL_ALG_NONE 0xffff
-
-static const value_string spnego_krb5_seal_alg_vals[] = {
- { KRB_SEAL_ALG_DES_CBC, "DES CBC"},
- { KRB_SEAL_ALG_RC4, "RC4"},
- { KRB_SEAL_ALG_NONE, "None"},
- { 0, NULL}
-};
-
-/*
- * XXX - is this for SPNEGO or just GSS-API?
- * RFC 1964 is "The Kerberos Version 5 GSS-API Mechanism"; presumably one
- * can directly designate Kerberos V5 as a mechanism in GSS-API, rather
- * than designating SPNEGO as the mechanism, offering Kerberos V5, and
- * getting it accepted.
- */
-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);
-
-static void
-dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- proto_item *item;
- proto_tree *subtree;
- int ret, offset = 0;
- ASN1_SCK hnd;
- gboolean def;
- guint len1, cls, con, tag, oid_len, nbytes;
- guint16 token_id;
- subid_t *oid;
- gchar *oid_string;
- gssapi_oid_value *value;
- tvbuff_t *krb5_tvb;
-
- item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset,
- -1, FALSE);
-
- subtree = proto_item_add_subtree(item, ett_spnego_krb5);
-
- /*
- * The KRB5 blob conforms to RFC1964:
- * [APPLICATION 0] {
- * OID,
- * USHORT (0x0001 == AP-REQ, 0x0002 == AP-REP, 0x0003 == ERROR),
- * OCTET STRING }
- *
- * However, for some protocols, the KRB5 blob starts at the SHORT
- * and has no DER encoded header etc.
- *
- * It appears that for some other protocols the KRB5 blob is just
- * a Kerberos message, with no [APPLICATION 0] header, no OID,
- * and no USHORT.
- *
- * So:
- *
- * If we see an [APPLICATION 0] HEADER, we show the OID and
- * the USHORT, and then dissect the rest as a Kerberos message.
- *
- * If we see an [APPLICATION 14] or [APPLICATION 15] header,
- * we assume it's an AP-REQ or AP-REP message, and dissect
- * it all as a Kerberos message.
- *
- * Otherwise, we show the USHORT, and then dissect the rest
- * as a Kerberos message.
- */
-
- asn1_open(&hnd, tvb, offset);
-
- /*
- * Get the first header ...
- */
-
- ret = asn1_header_decode(&hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO KRB5 Header", ret);
- goto done;
- }
-
- if (cls == ASN1_APL && con == ASN1_CON) {
- /*
- * [APPLICATION <tag>]
- */
- switch (tag) {
-
- case 0:
- /*
- * [APPLICATION 0]
- */
-
- offset = hnd.offset;
-
- /* Next, the OID */
-
- ret = asn1_oid_decode(&hnd, &oid, &oid_len, &nbytes);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO supportedMech token", ret);
- goto done;
- }
-
- oid_string = format_oid(oid, oid_len);
-
- value = gssapi_lookup_oid(oid, oid_len);
-
- if (value)
- proto_tree_add_text(subtree, tvb, offset, nbytes,
- "OID: %s (%s)",
- oid_string, value->comment);
- else
- proto_tree_add_text(subtree, tvb, offset, nbytes,
- "OID: %s",
- oid_string);
-
- g_free(oid_string);
-
- offset += nbytes;
-
- /* Next, the token ID ... */
-
- token_id = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
- token_id);
-
- hnd.offset += 2;
-
- offset += 2;
-
- break;
-
- case 14: /* [APPLICATION 14] */
- case 15: /* [APPLICATION 15] */
- /*
- * No token ID - just dissect as a Kerberos message and
- * return.
- */
- krb5_tvb = tvb_new_subset(tvb, offset, -1, -1);
- offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE, NULL);
- return;
-
- default:
- proto_tree_add_text(subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
- } else {
- /* Next, the token ID ... */
-
- token_id = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
- token_id);
-
- hnd.offset += 2;
-
- offset += 2;
- }
-
- switch (token_id) {
-
- case KRB_TOKEN_AP_REQ:
- 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, NULL);
- break;
-
- 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);
- break;
-
- case KRB_TOKEN_DELETE_SEC_CONTEXT:
-
- break;
-
- default:
-
- break;
- }
-
- done:
- return;
-}
-
-/*
- * XXX - This is for GSSAPI Wrap tokens ...
- */
-static int
-dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
-{
- guint16 sgn_alg;
-
- /*
- * The KRB5 blob conforms to RFC1964:
- * USHORT (0x0102 == GSS_Wrap)
- * and so on }
- */
-
- /* Now, the sign and seal algorithms ... */
-
- sgn_alg = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2,
- sgn_alg);
-
- offset += 2;
-
- proto_tree_add_item(tree, hf_spnego_krb5_seal_alg, tvb, offset, 2,
- TRUE);
-
- offset += 2;
-
- /* Skip the filler */
-
- offset += 2;
-
- /* Encrypted sequence number */
-
- proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
- TRUE);
-
- offset += 8;
-
- /* Checksum of plaintext padded data */
-
- proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
- TRUE);
-
- offset += 8;
-
- /*
- * At least according to draft-brezak-win2k-krb-rc4-hmac-04,
- * if the signing algorithm is KRB_SGN_ALG_HMAC, there's an
- * extra 8 bytes of "Random confounder" after the checksum.
- * It certainly confounds code expecting all Kerberos 5
- * GSS_Wrap() tokens to look the same....
- */
- if (sgn_alg == KRB_SGN_ALG_HMAC) {
- proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
- TRUE);
-
- offset += 8;
- }
-
- /*
- * 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 - This is for GSSAPI GetMIC tokens ...
- */
-static int
-dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
-{
- guint16 sgn_alg;
-
- /*
- * The KRB5 blob conforms to RFC1964:
- * USHORT (0x0101 == GSS_GetMIC)
- * and so on }
- */
-
- /* Now, the sign algorithm ... */
-
- sgn_alg = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2,
- sgn_alg);
-
- offset += 2;
-
- /* Skip the filler */
-
- offset += 4;
-
- /* Encrypted sequence number */
-
- proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
- TRUE);
-
- offset += 8;
-
- /* Checksum of plaintext padded data */
-
- proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
- TRUE);
-
- offset += 8;
-
- /*
- * At least according to draft-brezak-win2k-krb-rc4-hmac-04,
- * if the signing algorithm is KRB_SGN_ALG_HMAC, there's an
- * extra 8 bytes of "Random confounder" after the checksum.
- * It certainly confounds code expecting all Kerberos 5
- * GSS_Wrap() tokens to look the same....
- */
- if (sgn_alg == KRB_SGN_ALG_HMAC) {
- proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
- TRUE);
-
- offset += 8;
- }
-
- /*
- * 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
- * can directly designate Kerberos V5 as a mechanism in GSS-API, rather
- * than designating SPNEGO as the mechanism, offering Kerberos V5, and
- * getting it accepted.
- */
-static int
-dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
-{
- proto_item *item;
- proto_tree *subtree;
- int offset = 0;
-
- item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, FALSE);
-
- subtree = proto_item_add_subtree(item, ett_spnego_krb5);
-
- /*
- * The KRB5 blob conforms to RFC1964:
- * USHORT (0x0102 == GSS_Wrap)
- * and so on }
- */
-
- /* First, the token ID ... */
-
- proto_tree_add_item(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
- TRUE);
-
- offset += 2;
-
- offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree);
-
- /*
- * 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.
- */
- proto_item_set_len(item, offset);
- return offset;
-}
-
-/* Spnego stuff from here */
-
-static int
-dissect_spnego_mechTypes(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, ASN1_SCK *hnd,
- gssapi_oid_value **next_level_value_p)
-{
- proto_item *item = NULL;
- proto_tree *subtree = NULL;
- gboolean def;
- guint len1, len, cls, con, tag, nbytes;
- subid_t *oid;
- gchar *oid_string;
- int ret;
- gboolean saw_mechanism = FALSE;
-
- /*
- * MechTypeList ::= SEQUENCE OF MechType
- */
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO last sequence header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_UNI && con == ASN1_CON && tag == ASN1_SEQ)) {
- proto_tree_add_text(
- subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- offset = hnd->offset;
-
- item = proto_tree_add_item(tree, hf_spnego_mechtype, tvb, offset,
- len1, FALSE);
- subtree = proto_item_add_subtree(item, ett_spnego_mechtype);
-
- /*
- * Now, the object IDs ... We should translate them: FIXME
- */
-
- while (len1) {
- gssapi_oid_value *value;
-
- ret = asn1_oid_decode(hnd, &oid, &len, &nbytes);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO mechTypes token", ret);
- goto done;
- }
-
- oid_string = format_oid(oid, len);
- value = gssapi_lookup_oid(oid, len);
- if (value)
- proto_tree_add_text(subtree, tvb, offset, nbytes, "OID: %s (%s)",
- oid_string, value->comment);
- else
- proto_tree_add_text(subtree, tvb, offset, nbytes, "OID: %s",
- oid_string);
-
- g_free(oid_string);
-
- /*
- * Tell our caller the first mechanism we see, so that if
- * this is a negTokenInit with a mechToken, it can interpret
- * the mechToken according to the first mechType. (There
- * might not have been any indication of the mechType
- * in prior frames, so we can't necessarily use the
- * mechanism from the conversation; i.e., a negTokenInit
- * can contain the initial security token for the desired
- * mechanism of the initiator - that's the first mechanism
- * in the list.)
- */
- if (!saw_mechanism) {
- if (value)
- *next_level_value_p = value;
- saw_mechanism = TRUE;
- }
-
- offset += nbytes;
- len1 -= nbytes;
-
- }
-
- done:
-
- return offset;
-
-}
-
-static int
-dissect_spnego_reqFlags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd)
-{
- gboolean def;
- guint len1, cls, con, tag, flags;
- int ret;
- proto_item *item;
- proto_tree *subtree;
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, tree,
- "SPNEGO reqFlags header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_BTS)) {
- proto_tree_add_text(
- tree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- /* We must have a Bit String ... insert it */
-
- offset = hnd->offset;
-
- flags = tvb_get_guint8(tvb, offset);
-
- item = proto_tree_add_item(tree, hf_spnego_reqflags, tvb, offset, len1,
- FALSE);
-
- subtree = proto_item_add_subtree(item, ett_spnego_reqflags);
-
- /*
- * Now, the bits. XXX: Assume 8 bits. FIXME.
- */
-
- proto_tree_add_boolean(subtree, hf_gssapi_reqflags_deleg, tvb, offset, len1, flags);
- proto_tree_add_boolean(subtree, hf_gssapi_reqflags_mutual, tvb, offset, len1, flags);
- proto_tree_add_boolean(subtree, hf_gssapi_reqflags_replay, tvb, offset, len1, flags);
- proto_tree_add_boolean(subtree, hf_gssapi_reqflags_sequence, tvb, offset, len1, flags);
- proto_tree_add_boolean(subtree, hf_gssapi_reqflags_anon, tvb, offset, len1, flags);
- proto_tree_add_boolean(subtree, hf_gssapi_reqflags_conf, tvb, offset, len1, flags);
- proto_tree_add_boolean(subtree, hf_gssapi_reqflags_integ, tvb, offset, len1, flags);
-
- hnd->offset += len1;
-
- done:
- return offset + len1;
-
-}
-
-static int
-dissect_spnego_mechToken(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd,
- dissector_handle_t next_level_dissector)
-{
- proto_item *item;
- proto_tree *subtree;
- gboolean def;
- int ret;
- guint cls, con, tag, nbytes;
- gint length_remaining, reported_length_remaining;
- tvbuff_t *token_tvb;
-
- /*
- * This appears to be a simple octet string ...
- */
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &nbytes);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, tree,
- "SPNEGO sequence header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS)) {
- proto_tree_add_text(
- tree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- offset = hnd->offset;
-
-
- /* Dont try to create an item with more bytes than remains in the
- * frame or we will not even attempt to dissect those bytes we
- * do have. (since there will be an exception)
- *
- * We use "tvb_ensure_length_remaining()" so that we throw
- * an exception if there's nothing to dissect.
- */
- length_remaining = tvb_ensure_length_remaining(tvb,offset);
- reported_length_remaining = tvb_reported_length_remaining(tvb,offset);
- if ((guint)length_remaining > nbytes)
- length_remaining = nbytes;
- if ((guint)reported_length_remaining > nbytes)
- reported_length_remaining = nbytes;
- item = proto_tree_add_item(tree, hf_spnego_mechtoken, tvb, offset,
- length_remaining, FALSE);
- subtree = proto_item_add_subtree(item, ett_spnego_mechtoken);
-
- /*
- * Now, we should be able to dispatch after creating a new TVB.
- */
-
- token_tvb = tvb_new_subset(tvb, offset, length_remaining,
- reported_length_remaining);
- if (next_level_dissector)
- call_dissector(next_level_dissector, token_tvb, pinfo, subtree);
-
- hnd->offset += nbytes; /* Update this ... */
-
-done:
- return offset + nbytes;
-}
-
-static int
-dissect_spnego_mechListMIC(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd,
- dissector_handle_t next_level_dissector)
-{
- guint len1, cls, con, tag;
- int ret;
- gboolean def;
- proto_tree *subtree = NULL;
-
- /*
- * Add the mechListMIC [3] Octet String or General String ...
- */
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO sequence header", ret);
- goto done;
- }
-
- offset = hnd->offset;
-
- if (cls == ASN1_UNI && con == ASN1_CON && tag == ASN1_SEQ) {
-
- /*
- * There seems to be two different forms this can take
- * One as an Octet string, and one as a general string in a
- * sequence ... We will have to dissect this later
- */
-
- proto_tree_add_text(tree, tvb, offset + 4, len1 - 4,
- "mechListMIC: %s",
- tvb_format_text(tvb, offset + 4, len1 - 4));
-
- /* Naughty ... but we have to adjust for what we never took */
-
- hnd->offset += len1;
- offset += len1;
-
- }
- else if (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS) {
- tvbuff_t *token_tvb;
- proto_item *item;
- proto_tree *subtree;
-
- item = proto_tree_add_item(tree, hf_spnego_mechlistmic, tvb, offset,
- len1, FALSE);
- subtree = proto_item_add_subtree(item, ett_spnego_mechlistmic);
-
- /*
- * Now, we should be able to dispatch after creating a new TVB.
- */
-
- token_tvb = tvb_new_subset(tvb, offset, len1, -1);
- if (next_level_dissector)
- call_dissector(next_level_dissector, token_tvb, pinfo, subtree);
-
- hnd->offset += len1; /* Update this ... */
- offset += len1;
-
- }
- else {
-
- proto_tree_add_text(subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- done:
-
- return offset;
-
-}
-
-static int
-dissect_spnego_negTokenInit(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd,
- gssapi_oid_value **next_level_value_p)
-{
- proto_item *item;
- proto_tree *subtree;
- gboolean def;
- guint len1, len, cls, con, tag;
- int ret;
-
- item = proto_tree_add_item( tree, hf_spnego_negtokeninit, tvb, offset,
- -1, FALSE);
- subtree = proto_item_add_subtree(item, ett_spnego_negtokeninit);
-
- /*
- * Here is what we need to get ...
- * NegTokenInit ::= SEQUENCE {
- * mechTypes [0] MechTypeList OPTIONAL,
- * reqFlags [1] ContextFlags OPTIONAL,
- * mechToken [2] OCTET STRING OPTIONAL,
- * mechListMIC [3] OCTET STRING OPTIONAL }
-
- */
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO sequence header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_UNI && con == ASN1_CON && tag == ASN1_SEQ)) {
- proto_tree_add_text(
- subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- offset = hnd->offset;
-
- while (len1) {
- int hdr_ofs;
-
- hdr_ofs = hnd->offset;
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO context header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_CTX && con == ASN1_CON)) {
- proto_tree_add_text(subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- /* Adjust for the length of the header */
-
- len1 -= (hnd->offset - hdr_ofs);
-
- /* Should be one of the fields */
-
- switch (tag) {
-
- case SPNEGO_mechTypes:
-
- offset = dissect_spnego_mechTypes(tvb, offset, pinfo,
- subtree, hnd,
- next_level_value_p);
-
- break;
-
- case SPNEGO_reqFlags:
-
- offset = dissect_spnego_reqFlags(tvb, offset, pinfo, subtree, hnd);
-
- break;
-
- case SPNEGO_mechToken:
-
- offset = dissect_spnego_mechToken(tvb, offset, pinfo, subtree,
- hnd, gssapi_dissector_handle(*next_level_value_p));
- break;
-
- case SPNEGO_mechListMIC:
-
- offset = dissect_spnego_mechListMIC(tvb, offset, pinfo, subtree,
- hnd, gssapi_dissector_handle(*next_level_value_p));
- break;
-
- default:
-
- break;
- }
-
- len1 -= len;
-
- }
-
- done:
-
- return offset; /* Not sure this is right */
-}
-
-static int
-dissect_spnego_negResult(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd)
-{
- gboolean def;
- int ret;
- guint len, cls, con, tag, val;
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, tree,
- "SPNEGO context header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_ENUM)) {
- proto_tree_add_text(
- tree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d) xxx",
- cls, con, tag);
- goto done;
- }
-
- offset = hnd->offset;
-
- /* Now, get the value */
-
- ret = asn1_uint32_value_decode(hnd, len, &val);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, tree,
- "SPNEGO negResult value", ret);
- goto done;
- }
-
- proto_tree_add_item(tree, hf_spnego_negtokentarg_negresult, tvb,
- offset, 1, FALSE);
-
- offset = hnd->offset;
-
- done:
- return offset;
-}
-
-static int
-dissect_spnego_supportedMech(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd,
- gssapi_oid_value **next_level_value_p)
-{
- int ret;
- guint oid_len, nbytes;
- subid_t *oid;
- gchar *oid_string;
- gssapi_oid_value *value;
- conversation_t *conversation;
-
- /*
- * Now, get the OID, and find the handle, if any
- */
-
- offset = hnd->offset;
-
- ret = asn1_oid_decode(hnd, &oid, &oid_len, &nbytes);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, tree,
- "SPNEGO supportedMech token", ret);
- goto done;
- }
-
- oid_string = format_oid(oid, oid_len);
- value = gssapi_lookup_oid(oid, oid_len);
-
- if (value)
- proto_tree_add_text(tree, tvb, offset, nbytes,
- "supportedMech: %s (%s)",
- oid_string, value->comment);
- else
- proto_tree_add_text(tree, tvb, offset, nbytes, "supportedMech: %s",
- oid_string);
-
- g_free(oid_string);
-
- offset += nbytes;
-
- /* Should check for an unrecognized OID ... */
-
- if (value)
- *next_level_value_p = value;
-
- /*
- * Now, we need to save this in per proto info in the
- * conversation if it exists. We also should create a
- * conversation if one does not exist. FIXME!
- * Hmmm, might need to be smarter, because there can be
- * multiple mechTypes in a negTokenInit with one being the
- * default used in the Token if present. Then the negTokenTarg
- * could override that. :-(
- */
-
- if ((conversation = find_conversation(&pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0))) {
-
-
- conversation_add_proto_data(conversation, proto_spnego,
- *next_level_value_p);
- }
- else {
-
- }
-
- done:
- return offset;
-}
-
-static int
-dissect_spnego_responseToken(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd,
- dissector_handle_t next_level_dissector)
-{
- gboolean def;
- int ret;
- guint cls, con, tag, nbytes;
- tvbuff_t *token_tvb;
- proto_item *item;
- proto_tree *subtree;
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &nbytes);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, tree,
- "SPNEGO sequence header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS)) {
- proto_tree_add_text(
- tree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- offset = hnd->offset;
-
- item = proto_tree_add_item(tree, hf_spnego_responsetoken, tvb, offset -2 ,
- nbytes + 2, FALSE);
-
- subtree = proto_item_add_subtree(item, ett_spnego_responsetoken);
-
-
- /*
- * Now, we should be able to dispatch after creating a new TVB.
- * However, we should make sure that there is something in the
- * response token ...
- */
-
- if (nbytes) {
- token_tvb = tvb_new_subset(tvb, offset, nbytes, -1);
- if (next_level_dissector)
- call_dissector(next_level_dissector, token_tvb, pinfo, subtree);
- }
- else {
- proto_tree_add_text(subtree, tvb, offset-2, 2, "<Empty String>");
- }
- hnd->offset += nbytes; /* Update this ... */
-
- done:
- return offset + nbytes;
-}
-
-static int
-dissect_spnego_negTokenTarg(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, ASN1_SCK *hnd,
- gssapi_oid_value **next_level_value_p)
-
-{
- proto_item *item;
- proto_tree *subtree;
- gboolean def;
- int ret;
- guint len1, len, cls, con, tag;
-
- item = proto_tree_add_item( tree, hf_spnego_negtokentarg, tvb, offset,
- -1, FALSE);
- subtree = proto_item_add_subtree(item, ett_spnego_negtokentarg);
-
- /*
- * Here is what we need to get ...
- * NegTokenTarg ::= SEQUENCE {
- * negResult [0] ENUMERATED {
- * accept_completed (0),
- * accept_incomplete (1),
- * reject (2) } OPTIONAL,
- * supportedMech [1] MechType OPTIONAL,
- * responseToken [2] OCTET STRING OPTIONAL,
- * mechListMIC [3] OCTET STRING OPTIONAL }
- */
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO sequence header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_UNI && con == ASN1_CON && tag == ASN1_SEQ)) {
- proto_tree_add_text(
- subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- offset = hnd->offset;
-
- while (len1) {
- int hdr_ofs;
-
- hdr_ofs = hnd->offset;
-
- ret = asn1_header_decode(hnd, &cls, &con, &tag, &def, &len);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO context header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_CTX && con == ASN1_CON)) {
- proto_tree_add_text(
- subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- /* Adjust for the length of the header */
-
- len1 -= (hnd->offset - hdr_ofs);
-
- /* Should be one of the fields */
-
- switch (tag) {
-
- case SPNEGO_negResult:
-
- offset = dissect_spnego_negResult(tvb, offset, pinfo, subtree,
- hnd);
- break;
-
- case SPNEGO_supportedMech:
-
- offset = dissect_spnego_supportedMech(tvb, offset, pinfo, subtree,
- hnd, next_level_value_p);
-
- break;
-
- case SPNEGO_responseToken:
-
- offset = dissect_spnego_responseToken(tvb, offset, pinfo, subtree,
- hnd, gssapi_dissector_handle(*next_level_value_p));
- break;
-
- case SPNEGO_mechListMIC:
-
- offset = dissect_spnego_mechListMIC(tvb, offset, pinfo, subtree,
- hnd, gssapi_dissector_handle(*next_level_value_p));
- break;
-
- default:
-
- break;
- }
-
- len1 -= len;
-
- }
-
- done:
- return offset;
-
-}
-
-static void
-dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- proto_item *item;
- proto_tree *subtree;
- int ret, offset = 0;
- ASN1_SCK hnd;
- gboolean def;
- guint len1, cls, con, tag;
- conversation_t *conversation;
- gssapi_oid_value *next_level_value;
-
- /*
- * We need this later, so lets get it now ...
- * It has to be per-frame as there can be more than one GSS-API
- * negotiation in a conversation.
- */
-
- next_level_value = p_get_proto_data(pinfo->fd, proto_spnego);
- if (!next_level_value && !pinfo->fd->flags.visited) {
- /*
- * No handle attached to this frame, but it's the first
- * pass, so it'd be attached to the conversation.
- * If we have a conversation, try to get the handle,
- * and if we get one, attach it to the frame.
- */
- conversation = find_conversation(&pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
-
- if (conversation) {
- next_level_value = conversation_get_proto_data(conversation,
- proto_spnego);
- if (next_level_value)
- p_add_proto_data(pinfo->fd, proto_spnego, next_level_value);
- }
- }
-
- item = proto_tree_add_item(tree, hf_spnego, tvb, offset,
- -1, FALSE);
-
- subtree = proto_item_add_subtree(item, ett_spnego);
-
- /*
- * The TVB contains a [0] header and a sequence that consists of an
- * object ID and a blob containing the data ...
- * Actually, it contains, according to RFC2478:
- * NegotiationToken ::= CHOICE {
- * negTokenInit [0] NegTokenInit,
- * negTokenTarg [1] NegTokenTarg }
- * NegTokenInit ::= SEQUENCE {
- * mechTypes [0] MechTypeList OPTIONAL,
- * reqFlags [1] ContextFlags OPTIONAL,
- * mechToken [2] OCTET STRING OPTIONAL,
- * mechListMIC [3] OCTET STRING OPTIONAL }
- * NegTokenTarg ::= SEQUENCE {
- * negResult [0] ENUMERATED {
- * accept_completed (0),
- * accept_incomplete (1),
- * reject (2) } OPTIONAL,
- * supportedMech [1] MechType OPTIONAL,
- * responseToken [2] OCTET STRING OPTIONAL,
- * mechListMIC [3] OCTET STRING OPTIONAL }
- *
- * Windows typically includes mechTypes and mechListMic ('NONE'
- * in the case of NTLMSSP only).
- * It seems to duplicate the responseToken into the mechListMic field
- * as well. Naughty, naughty.
- *
- */
-
- asn1_open(&hnd, tvb, offset);
-
- /*
- * Get the first header ...
- */
-
- ret = asn1_header_decode(&hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO context header", ret);
- goto done;
- }
-
- if (!(cls == ASN1_CTX && con == ASN1_CON)) {
- proto_tree_add_text(
- subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- goto done;
- }
-
- offset = hnd.offset;
-
- /*
- * The Tag is one of negTokenInit or negTokenTarg
- */
-
- switch (tag) {
-
- case SPNEGO_negTokenInit:
-
- offset = dissect_spnego_negTokenInit(tvb, offset, pinfo,
- subtree, &hnd,
- &next_level_value);
-
- break;
-
- case SPNEGO_negTokenTarg:
-
- offset = dissect_spnego_negTokenTarg(tvb, offset, pinfo,
- subtree, &hnd,
- &next_level_value);
- break;
-
- default: /* Broken, what to do? */
-
- break;
- }
-
-
- done:
- asn1_close(&hnd, &offset);
-
-}
-
-static int
-dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- proto_item *item;
- proto_tree *subtree;
- int ret, offset = 0;
- int return_offset;
- ASN1_SCK hnd;
- gboolean def;
- guint len1, cls, con, tag, nbytes;
- guint oid_len;
- subid_t *oid;
- gchar *oid_string;
- conversation_t *conversation;
- gssapi_oid_value *next_level_value;
- tvbuff_t *token_tvb;
- int len;
-
- /*
- * We need this later, so lets get it now ...
- * It has to be per-frame as there can be more than one GSS-API
- * negotiation in a conversation.
- */
-
- next_level_value = p_get_proto_data(pinfo->fd, proto_spnego);
- if (!next_level_value && !pinfo->fd->flags.visited) {
- /*
- * No handle attached to this frame, but it's the first
- * pass, so it'd be attached to the conversation.
- * If we have a conversation, try to get the handle,
- * and if we get one, attach it to the frame.
- */
- conversation = find_conversation(&pinfo->src, &pinfo->dst,
- pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
-
- if (conversation) {
- next_level_value = conversation_get_proto_data(conversation,
- proto_spnego);
- if (next_level_value)
- p_add_proto_data(pinfo->fd, proto_spnego, next_level_value);
- }
- }
-
- item = proto_tree_add_item(tree, hf_spnego, tvb, offset,
- -1, FALSE);
-
- subtree = proto_item_add_subtree(item, ett_spnego);
-
- /*
- * The TVB contains a [0] header and a sequence that consists of an
- * object ID and a blob containing the data ...
- * XXX - is this RFC 2743's "Mechanism-Independent Token Format",
- * with the "optional" "use in non-initial tokens" being chosen.
- */
-
- asn1_open(&hnd, tvb, offset);
-
- /*
- * Get the first header ...
- */
-
- ret = asn1_header_decode(&hnd, &cls, &con, &tag, &def, &len1);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, subtree,
- "SPNEGO context header", ret);
- return_offset = tvb_length(tvb);
- goto done;
- }
-
- if (!(cls == ASN1_APL && con == ASN1_CON && tag == 0)) {
- proto_tree_add_text(
- subtree, tvb, offset, 0,
- "Unknown header (cls=%d, con=%d, tag=%d)",
- cls, con, tag);
- return_offset = tvb_length(tvb);
- goto done;
- }
-
- offset = hnd.offset;
-
- /*
- * Get the OID, and find the handle, if any
- */
-
- ret = asn1_oid_decode(&hnd, &oid, &oid_len, &nbytes);
-
- if (ret != ASN1_ERR_NOERROR) {
- dissect_parse_error(tvb, offset, pinfo, tree,
- "SPNEGO wrap token", ret);
- return_offset = tvb_length(tvb);
- goto done;
- }
-
- oid_string = format_oid(oid, oid_len);
- next_level_value = gssapi_lookup_oid(oid, oid_len);
-
- /*
- * XXX - what should we do if this doesn't match the value
- * attached to the frame or conversation? (That would be
- * bogus, but that's not impossible - some broken implementation
- * might negotiate some security mechanism but put the OID
- * for some other security mechanism in GSS_Wrap tokens.)
- */
- if (next_level_value)
- proto_tree_add_text(tree, tvb, offset, nbytes,
- "thisMech: %s (%s)",
- oid_string, next_level_value->comment);
- else
- proto_tree_add_text(tree, tvb, offset, nbytes, "thisMech: %s",
- oid_string);
-
- g_free(oid_string);
-
- offset += nbytes;
-
- /*
- * Now dissect the GSS_Wrap token; it's assumed to be in the
- * rest of the tvbuff.
- */
- item = proto_tree_add_item(tree, hf_spnego_wraptoken, tvb, offset,
- -1, FALSE);
-
- subtree = proto_item_add_subtree(item, ett_spnego_wraptoken);
-
- /*
- * Now, we should be able to dispatch after creating a new TVB.
- * The subdissector must return the length of the part of the
- * token it dissected, so we can return the length of the part
- * we (and it) dissected.
- */
-
- token_tvb = tvb_new_subset(tvb, offset, -1, -1);
- if (next_level_value->wrap_handle) {
- len = call_dissector(next_level_value->wrap_handle, token_tvb, pinfo, subtree);
- if (len == 0)
- return_offset = tvb_length(tvb);
- else
- return_offset = offset + len;
- } else
- return_offset = tvb_length(tvb);
- done:
- asn1_close(&hnd, &offset);
-
- return return_offset;
-}
-
-void
-proto_register_spnego(void)
-{
- static hf_register_info hf[] = {
- { &hf_spnego,
- { "SPNEGO", "spnego", FT_NONE, BASE_NONE, NULL, 0x0,
- "SPNEGO", HFILL }},
- { &hf_spnego_negtokeninit,
- { "negTokenInit", "spnego.negtokeninit", FT_NONE, BASE_NONE,
- NULL, 0x0, "SPNEGO negTokenInit", HFILL}},
- { &hf_spnego_negtokentarg,
- { "negTokenTarg", "spnego.negtokentarg", FT_NONE, BASE_NONE,
- NULL, 0x0, "SPNEGO negTokenTarg", HFILL}},
- { &hf_spnego_mechtype,
- { "mechType", "spnego.negtokeninit.mechtype", FT_NONE,
- BASE_NONE, NULL, 0x0, "SPNEGO negTokenInit mechTypes", HFILL}},
- { &hf_spnego_mechtoken,
- { "mechToken", "spnego.negtokeninit.mechtoken", FT_NONE,
- BASE_NONE, NULL, 0x0, "SPNEGO negTokenInit mechToken", HFILL}},
- { &hf_spnego_mechlistmic,
- { "mechListMIC", "spnego.mechlistmic", FT_NONE,
- BASE_NONE, NULL, 0x0, "SPNEGO mechListMIC", HFILL}},
- { &hf_spnego_responsetoken,
- { "responseToken", "spnego.negtokentarg.responsetoken",
- FT_NONE, BASE_NONE, NULL, 0x0, "SPNEGO responseToken",
- HFILL}},
- { &hf_spnego_negtokentarg_negresult,
- { "negResult", "spnego.negtokeninit.negresult", FT_UINT16,
- BASE_HEX, VALS(spnego_negResult_vals), 0, "negResult", HFILL}},
- { &hf_spnego_reqflags,
- { "reqFlags", "spnego.negtokeninit.reqflags", FT_BYTES,
- BASE_HEX, NULL, 0, "reqFlags", HFILL }},
- { &hf_gssapi_reqflags_deleg,
- { "Delegation", "gssapi.reqflags.deleg", FT_BOOLEAN, 8,
- TFS(&tfs_reqflags_deleg), 0x01, "Delegation", HFILL }},
- { &hf_gssapi_reqflags_mutual,
- { "Mutual Authentication", "gssapi.reqflags.mutual", FT_BOOLEAN,
- 8, TFS(&tfs_reqflags_mutual), 0x02, "Mutual Authentication", HFILL}},
- { &hf_gssapi_reqflags_replay,
- { "Replay Detection", "gssapi.reqflags.replay", FT_BOOLEAN,
- 8, TFS(&tfs_reqflags_replay), 0x04, "Replay Detection", HFILL}},
- { &hf_gssapi_reqflags_sequence,
- { "Out-of-sequence Detection", "gssapi.reqflags.sequence",
- FT_BOOLEAN, 8, TFS(&tfs_reqflags_sequence), 0x08,
- "Out-of-sequence Detection", HFILL}},
- { &hf_gssapi_reqflags_anon,
- { "Anonymous Authentication", "gssapi.reqflags.anon",
- FT_BOOLEAN, 8, TFS(&tfs_reqflags_anon), 0x10,
- "Anonymous Authentication", HFILL}},
- { &hf_gssapi_reqflags_conf,
- { "Per-message Confidentiality", "gssapi.reqflags.conf",
- FT_BOOLEAN, 8, TFS(&tfs_reqflags_conf), 0x20,
- "Per-message Confidentiality", HFILL}},
- { &hf_gssapi_reqflags_integ,
- { "Per-message Integrity", "gssapi.reqflags.integ",
- FT_BOOLEAN, 8, TFS(&tfs_reqflags_integ), 0x40,
- "Per-message Integrity", HFILL}},
- { &hf_spnego_wraptoken,
- { "wrapToken", "spnego.wraptoken",
- FT_NONE, BASE_NONE, NULL, 0x0, "SPNEGO wrapToken",
- HFILL}},
- { &hf_spnego_krb5,
- { "krb5_blob", "spnego.krb5.blob", FT_BYTES,
- BASE_NONE, NULL, 0, "krb5_blob", HFILL }},
- { &hf_spnego_krb5_tok_id,
- { "krb5_tok_id", "spnego.krb5.tok_id", FT_UINT16, BASE_HEX,
- VALS(spnego_krb5_tok_id_vals), 0, "KRB5 Token Id", HFILL}},
- { &hf_spnego_krb5_sgn_alg,
- { "krb5_sgn_alg", "spnego.krb5.sgn_alg", FT_UINT16, BASE_HEX,
- VALS(spnego_krb5_sgn_alg_vals), 0, "KRB5 Signing Algorithm", HFILL}},
- { &hf_spnego_krb5_seal_alg,
- { "krb5_seal_alg", "spnego.krb5.seal_alg", FT_UINT16, BASE_HEX,
- VALS(spnego_krb5_seal_alg_vals), 0, "KRB5 Sealing Algorithm", HFILL}},
- { &hf_spnego_krb5_snd_seq,
- { "krb5_snd_seq", "spnego.krb5.snd_seq", FT_BYTES, BASE_NONE,
- NULL, 0, "KRB5 Encrypted Sequence Number", HFILL}},
- { &hf_spnego_krb5_sgn_cksum,
- { "krb5_sgn_cksum", "spnego.krb5.sgn_cksum", FT_BYTES, BASE_NONE,
- NULL, 0, "KRB5 Data Checksum", HFILL}},
- { &hf_spnego_krb5_confounder,
- { "krb5_confounder", "spnego.krb5.confounder", FT_BYTES, BASE_NONE,
- NULL, 0, "KRB5 Confounder", HFILL}},
- };
-
- static gint *ett[] = {
- &ett_spnego,
- &ett_spnego_negtokeninit,
- &ett_spnego_negtokentarg,
- &ett_spnego_mechtype,
- &ett_spnego_mechtoken,
- &ett_spnego_mechlistmic,
- &ett_spnego_responsetoken,
- &ett_spnego_wraptoken,
- &ett_spnego_krb5,
- };
-
- proto_spnego = proto_register_protocol(
- "Spnego", "Spnego", "spnego");
- proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5",
- "SPNEGO-KRB5",
- "spnego-krb5");
-
- proto_register_field_array(proto_spnego, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
-}
-
-void
-proto_reg_handoff_spnego(void)
-{
- dissector_handle_t spnego_handle, spnego_wrap_handle;
- dissector_handle_t spnego_krb5_handle, spnego_krb5_wrap_handle;
-
- /* Register protocol with GSS-API module */
-
- spnego_handle = create_dissector_handle(dissect_spnego, proto_spnego);
- spnego_wrap_handle = new_create_dissector_handle(dissect_spnego_wrap,
- proto_spnego);
- gssapi_init_oid("1.3.6.1.5.5.2", proto_spnego, ett_spnego,
- spnego_handle, spnego_wrap_handle,
- "SPNEGO - Simple Protected Negotiation");
-
- /* Register both the one MS created and the real one */
- /*
- * Thanks to Jean-Baptiste Marchand and Richard B Ward, the
- * mystery of the MS KRB5 OID is cleared up. It was due to a library
- * that did not handle OID components greater than 16 bits, and was
- * fixed in Win2K SP2 as well as WinXP.
- * See the archive of <ietf-krb-wg@anl.gov> for the thread topic
- * SPNEGO implementation issues. 3-Dec-2002.
- */
- spnego_krb5_handle = create_dissector_handle(dissect_spnego_krb5,
- proto_spnego_krb5);
- spnego_krb5_wrap_handle = new_create_dissector_handle(dissect_spnego_krb5_wrap,
- proto_spnego_krb5);
- gssapi_init_oid("1.2.840.48018.1.2.2", proto_spnego_krb5, ett_spnego_krb5,
- spnego_krb5_handle, spnego_krb5_wrap_handle,
- "MS KRB5 - Microsoft Kerberos 5");
- gssapi_init_oid("1.2.840.113554.1.2.2", proto_spnego_krb5, ett_spnego_krb5,
- spnego_krb5_handle, spnego_krb5_wrap_handle,
- "KRB5 - Kerberos 5");
- gssapi_init_oid("1.2.840.113554.1.2.2.3", proto_spnego_krb5, ett_spnego_krb5,
- spnego_krb5_handle, spnego_krb5_wrap_handle,
- "KRB5 - Kerberos 5 - User to User");
-
- /*
- * Find the data handle for some calls
- */
- data_handle = find_dissector("data");
-}