diff options
author | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2016-10-02 21:07:24 +0200 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2016-10-04 23:13:59 +0000 |
commit | 257abd91217c8f5512689be5cc568a500fda3b54 (patch) | |
tree | 0fb527f9dc9cc3cec78807342f75aaf5acc6807b | |
parent | d6635e8dc873dcf46b3808ad4c61d2c598e4d725 (diff) | |
download | wireshark-257abd91217c8f5512689be5cc568a500fda3b54.tar.gz |
spnego: fix indent (use 2 spaces) and modelines
Change-Id: I077c21eb213435e7ed0e9ac0b9a8f95aa9dd6f3d
Reviewed-on: https://code.wireshark.org/review/18075
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r-- | epan/dissectors/asn1/spnego/packet-spnego-template.c | 1991 | ||||
-rw-r--r-- | epan/dissectors/asn1/spnego/spnego.cnf | 13 | ||||
-rw-r--r-- | epan/dissectors/packet-spnego.c | 1971 |
3 files changed, 1951 insertions, 2024 deletions
diff --git a/epan/dissectors/asn1/spnego/packet-spnego-template.c b/epan/dissectors/asn1/spnego/packet-spnego-template.c index 9bb8788521..9f4e1986f1 100644 --- a/epan/dissectors/asn1/spnego/packet-spnego-template.c +++ b/epan/dissectors/asn1/spnego/packet-spnego-template.c @@ -114,14 +114,14 @@ static int dissect_spnego_NegTokenInit2(gboolean implicit_tag, tvbuff_t *tvb, * 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 -#define KRB_TOKEN_CFX_GETMIC 0x0404 -#define KRB_TOKEN_CFX_WRAP 0x0405 +#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 +#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"}, @@ -131,14 +131,14 @@ static const value_string spnego_krb5_tok_id_vals[] = { { 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" }, + { KRB_TOKEN_CFX_WRAP, "KRB_TOKEN_CFX_WRAP" }, { 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 +#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"}, @@ -148,9 +148,9 @@ static const value_string spnego_krb5_sgn_alg_vals[] = { { 0, NULL} }; -#define KRB_SEAL_ALG_DES_CBC 0x0000 -#define KRB_SEAL_ALG_RC4 0x0010 -#define KRB_SEAL_ALG_NONE 0xffff +#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"}, @@ -178,143 +178,139 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo, static int dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - guint16 token_id; - const char *oid; - tvbuff_t *krb5_tvb; - gint8 ber_class; - gboolean pc, ind = 0; - gint32 tag; - guint32 len; - gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; - asn1_ctx_t asn1_ctx; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - - item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset, - -1, ENC_NA); - - 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. - */ - - /* - * Get the first header ... - */ - get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - if (ber_class == BER_CLASS_APP && pc) { - /* - * [APPLICATION <tag>] - */ - offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &ber_class, &pc, &tag); - offset = dissect_ber_length(pinfo, subtree, tvb, offset, &len, &ind); - - switch (tag) { - - case 0: - /* - * [APPLICATION 0] - */ - - /* Next, the OID */ - offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, tvb, offset, hf_spnego_krb5_oid, &oid); - - token_id = tvb_get_letohs(tvb, offset); - proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2, - token_id); - - offset += 2; - - break; - - case 14: /* [APPLICATION 14] */ - case 15: /* [APPLICATION 15] */ - /* - * No token ID - just dissect as a Kerberos message and - * return. - */ - dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL); - return tvb_captured_length(tvb); - - default: - proto_tree_add_expert_format(subtree, pinfo, &ei_spnego_unknown_header, tvb, offset, 0, - "Unknown header (class=%d, pc=%d, tag=%d)", - ber_class, pc, 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); - - 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_remaining(tvb, offset); - 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, token_id, encrypt_info); - break; - - case KRB_TOKEN_DELETE_SEC_CONTEXT: - - 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, encrypt_info); - break; - - default: - - break; - } - - done: - proto_item_set_len(item, offset); - return tvb_captured_length(tvb); + proto_item *item; + proto_tree *subtree; + int offset = 0; + guint16 token_id; + const char *oid; + tvbuff_t *krb5_tvb; + gint8 ber_class; + gboolean pc, ind = 0; + gint32 tag; + guint32 len; + gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset, -1, ENC_NA); + + 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. + */ + + /* + * Get the first header ... + */ + get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + if (ber_class == BER_CLASS_APP && pc) { + /* + * [APPLICATION <tag>] + */ + offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &ber_class, &pc, &tag); + offset = dissect_ber_length(pinfo, subtree, tvb, offset, &len, &ind); + + switch (tag) { + + case 0: + /* + * [APPLICATION 0] + */ + + /* Next, the OID */ + offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, tvb, offset, hf_spnego_krb5_oid, &oid); + + token_id = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2, token_id); + + offset += 2; + + break; + + case 14: /* [APPLICATION 14] */ + case 15: /* [APPLICATION 15] */ + /* + * No token ID - just dissect as a Kerberos message and + * return. + */ + dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL); + return tvb_captured_length(tvb); + + default: + proto_tree_add_expert_format(subtree, pinfo, &ei_spnego_unknown_header, tvb, offset, 0, + "Unknown header (class=%d, pc=%d, tag=%d)", ber_class, pc, 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); + + 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_remaining(tvb, offset); + 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, token_id, encrypt_info); + break; + + case KRB_TOKEN_DELETE_SEC_CONTEXT: + + 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, encrypt_info); + break; + + default: + + break; + } + + done: + proto_item_set_len(item, offset); + return tvb_captured_length(tvb); } #ifdef HAVE_KERBEROS @@ -333,94 +329,80 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d static int arcfour_mic_key(const guint8 *key_data, size_t key_size, int key_type, - const guint8 *cksum_data, size_t cksum_size, - guint8 *key6_data) + const guint8 *cksum_data, size_t cksum_size, + guint8 *key6_data) { - guint8 k5_data[16]; - guint8 T[4]; - - memset(T, 0, 4); - - if (key_type == KEYTYPE_ARCFOUR_56) { - guint8 L40[14] = "fortybits"; - - memcpy(L40 + 10, T, sizeof(T)); - md5_hmac( - L40, 14, - key_data, - key_size, - k5_data); - memset(&k5_data[7], 0xAB, 9); - } else { - md5_hmac( - T, 4, - key_data, - key_size, - k5_data); - } + guint8 k5_data[16]; + guint8 T[4]; - md5_hmac( - cksum_data, cksum_size, - k5_data, - 16, - key6_data); + memset(T, 0, 4); - return 0; + if (key_type == KEYTYPE_ARCFOUR_56) { + guint8 L40[14] = "fortybits"; + + memcpy(L40 + 10, T, sizeof(T)); + md5_hmac(L40, 14, key_data, key_size, k5_data); + memset(&k5_data[7], 0xAB, 9); + } else { + md5_hmac(T, 4, key_data, key_size, k5_data); + } + + md5_hmac(cksum_data, cksum_size, k5_data, 16, key6_data); + + return 0; } static int usage2arcfour(int usage) { - switch (usage) { + switch (usage) { case 3: /*KRB5_KU_AS_REP_ENC_PART 3 */ case 9: /*KRB5_KU_TGS_REP_ENC_PART_SUB_KEY 9 */ - return 8; + return 8; case 22: /*KRB5_KU_USAGE_SEAL 22 */ - return 13; + return 13; case 23: /*KRB5_KU_USAGE_SIGN 23 */ return 15; case 24: /*KRB5_KU_USAGE_SEQ 24 */ - return 0; + return 0; default : - return 0; - } + return 0; + } } static int arcfour_mic_cksum(guint8 *key_data, int key_length, - unsigned int usage, - guint8 sgn_cksum[8], - const guint8 *v1, size_t l1, - const guint8 *v2, size_t l2, - const guint8 *v3, size_t l3) + unsigned int usage, + guint8 sgn_cksum[8], + const guint8 *v1, size_t l1, + const guint8 *v2, size_t l2, + const guint8 *v3, size_t l3) { - static const guint8 signature[] = "signaturekey"; - guint8 ksign_c[16]; - guint8 t[4]; - md5_state_t ms; - guint8 digest[16]; - int rc4_usage; - guint8 cksum[16]; - - rc4_usage=usage2arcfour(usage); - md5_hmac(signature, sizeof(signature), - key_data, key_length, - ksign_c); - md5_init(&ms); - t[0] = (rc4_usage >> 0) & 0xFF; - t[1] = (rc4_usage >> 8) & 0xFF; - t[2] = (rc4_usage >> 16) & 0xFF; - t[3] = (rc4_usage >> 24) & 0xFF; - md5_append(&ms, t, 4); - md5_append(&ms, v1, l1); - md5_append(&ms, v2, l2); - md5_append(&ms, v3, l3); - md5_finish(&ms, digest); - md5_hmac(digest, 16, ksign_c, 16, cksum); - - memcpy(sgn_cksum, cksum, 8); - - return 0; + static const guint8 signature[] = "signaturekey"; + guint8 ksign_c[16]; + guint8 t[4]; + md5_state_t ms; + guint8 digest[16]; + int rc4_usage; + guint8 cksum[16]; + + rc4_usage=usage2arcfour(usage); + md5_hmac(signature, sizeof(signature), key_data, key_length, ksign_c); + md5_init(&ms); + t[0] = (rc4_usage >> 0) & 0xFF; + t[1] = (rc4_usage >> 8) & 0xFF; + t[2] = (rc4_usage >> 16) & 0xFF; + t[3] = (rc4_usage >> 24) & 0xFF; + md5_append(&ms, t, 4); + md5_append(&ms, v1, l1); + md5_append(&ms, v2, l2); + md5_append(&ms, v3, l3); + md5_finish(&ms, digest); + md5_hmac(digest, 16, ksign_c, 16, cksum); + + memcpy(sgn_cksum, cksum, 8); + + return 0; } /* @@ -428,140 +410,131 @@ arcfour_mic_cksum(guint8 *key_data, int key_length, */ static int gssapi_verify_pad(guint8 *wrapped_data, int wrapped_length, - int datalen, - int *padlen) + int datalen, + int *padlen) { - guint8 *pad; - int padlength; - int i; + guint8 *pad; + int padlength; + int i; - pad = wrapped_data + wrapped_length - 1; - padlength = *pad; + pad = wrapped_data + wrapped_length - 1; + padlength = *pad; - if (padlength > datalen) - return 1; + if (padlength > datalen) + return 1; - for (i = padlength; i > 0 && *pad == padlength; i--, pad--) - ; - if (i != 0) - return 2; + for (i = padlength; i > 0 && *pad == padlength; i--, pad--); + if (i != 0) + return 2; - *padlen = padlength; + *padlen = padlength; - return 0; + return 0; } static int decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buffer, guint8 *output_message_buffer, - guint8 *key_value, int key_size, int key_type) + guint8 *key_value, int key_size, int key_type) { - guint8 Klocaldata[16]; - int ret; - int datalen; - guint8 k6_data[16]; - guint32 SND_SEQ[2]; - guint8 Confounder[8]; - guint8 cksum_data[8]; - int cmp; - int conf_flag; - int padlen = 0; - - datalen = tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); - - if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0x1000){ - conf_flag=1; - } else if (tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0xffff){ - conf_flag=0; - } else { - return -3; - } - - if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 6)!=0xffff){ - return -4; - } - - ret = arcfour_mic_key(key_value, key_size, key_type, - tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 16, 8), - 8, /* SGN_CKSUM */ - k6_data); + guint8 Klocaldata[16]; + int ret; + int datalen; + guint8 k6_data[16]; + guint32 SND_SEQ[2]; + guint8 Confounder[8]; + guint8 cksum_data[8]; + int cmp; + int conf_flag; + int padlen = 0; + rc4_state_struct rc4_state; + int i; + + datalen = tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); + + if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0x1000){ + conf_flag=1; + } else if (tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0xffff){ + conf_flag=0; + } else { + return -3; + } + + if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 6)!=0xffff){ + return -4; + } + + ret = arcfour_mic_key(key_value, key_size, key_type, + tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 16, 8), + 8, /* SGN_CKSUM */ + k6_data); + if (ret) { + return -5; + } + + crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); + tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, SND_SEQ, 8, 8); + crypt_rc4(&rc4_state, (guint8 *)SND_SEQ, 8); + + memset(k6_data, 0, sizeof(k6_data)); + + + + if (SND_SEQ[1] != 0xFFFFFFFF && SND_SEQ[1] != 0x00000000) { + return -6; + } + + + for (i = 0; i < 16; i++) + Klocaldata[i] = ((guint8 *)key_value)[i] ^ 0xF0; + + ret = arcfour_mic_key(Klocaldata,sizeof(Klocaldata),key_type, + (const guint8 *)SND_SEQ, 4, + k6_data); + memset(Klocaldata, 0, sizeof(Klocaldata)); + if (ret) { + return -7; + } + + if(conf_flag) { + + crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); + tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); + crypt_rc4(&rc4_state, Confounder, 8); + memcpy(output_message_buffer, input_message_buffer, datalen); + crypt_rc4(&rc4_state, output_message_buffer, datalen); + } else { + tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); + memcpy(output_message_buffer, input_message_buffer, datalen); + } + memset(k6_data, 0, sizeof(k6_data)); + + /* only normal (i.e. non DCE style wrapping use padding ? */ + if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ + ret = gssapi_verify_pad(output_message_buffer,datalen,datalen, &padlen); if (ret) { - return -5; - } - - { - rc4_state_struct rc4_state; - - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); - tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, SND_SEQ, 8, 8); - crypt_rc4(&rc4_state, (guint8 *)SND_SEQ, 8); - - memset(k6_data, 0, sizeof(k6_data)); + return -9; } - - - if (SND_SEQ[1] != 0xFFFFFFFF && SND_SEQ[1] != 0x00000000) { - return -6; - } - - { - int i; - - for (i = 0; i < 16; i++) - Klocaldata[i] = ((guint8 *)key_value)[i] ^ 0xF0; - } - ret = arcfour_mic_key(Klocaldata,sizeof(Klocaldata),key_type, - (const guint8 *)SND_SEQ, 4, - k6_data); - memset(Klocaldata, 0, sizeof(Klocaldata)); + datalen -= padlen; + } + + /* don't know what the checksum looks like for dce style gssapi */ + if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ + ret = arcfour_mic_cksum(key_value, key_size, KRB5_KU_USAGE_SEAL, + cksum_data, + tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 0, 8), 8, + Confounder, sizeof(Confounder), output_message_buffer, + datalen + padlen); if (ret) { - return -7; - } - - if(conf_flag) { - rc4_state_struct rc4_state; - - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); - tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); - crypt_rc4(&rc4_state, Confounder, 8); - memcpy(output_message_buffer, input_message_buffer, datalen); - crypt_rc4(&rc4_state, output_message_buffer, datalen); - } else { - tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); - memcpy(output_message_buffer, - input_message_buffer, - datalen); - } - memset(k6_data, 0, sizeof(k6_data)); - - /* only normal (i.e. non DCE style wrapping use padding ? */ - if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ - ret = gssapi_verify_pad(output_message_buffer,datalen,datalen, &padlen); - if (ret) { - return -9; - } - datalen -= padlen; + return -10; } - /* don't know what the checksum looks like for dce style gssapi */ - if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ - ret = arcfour_mic_cksum(key_value, key_size, - KRB5_KU_USAGE_SEAL, - cksum_data, - tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 0, 8), 8, - Confounder, sizeof(Confounder), - output_message_buffer, - datalen + padlen); - if (ret) { - return -10; - } - - cmp = tvb_memeql(gssapi_encrypt->gssapi_wrap_tvb, 16, cksum_data, 8); /* SGN_CKSUM */ - if (cmp) { - return -11; - } + cmp = tvb_memeql(gssapi_encrypt->gssapi_wrap_tvb, 16, cksum_data, 8); /* SGN_CKSUM */ + if (cmp) { + return -11; } + } - return datalen; + return datalen; } @@ -571,162 +544,158 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf static void decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb, int keytype, gssapi_encrypt_info_t* gssapi_encrypt) { - int ret; - enc_key_t *ek; - int length; - const guint8 *original_data; + int ret; + enc_key_t *ek; + int length; + const guint8 *original_data; - guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */ - guint8 *output_message_buffer; + guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */ + guint8 *output_message_buffer; - length=tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); - original_data=tvb_get_ptr(gssapi_encrypt->gssapi_encrypted_tvb, 0, length); + length=tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); + original_data=tvb_get_ptr(gssapi_encrypt->gssapi_encrypted_tvb, 0, length); - /* don't do anything if we are not attempting to decrypt data */ + /* don't do anything if we are not attempting to decrypt data */ /* - if(!krb_decrypt){ - return; - } + if(!krb_decrypt){ + return; + } */ - /* XXX we should only do this for first time, then store somewhere */ - /* XXX We also need to re-read the keytab when the preference changes */ - - cryptocopy=(guint8 *)wmem_alloc(wmem_packet_scope(), length); - output_message_buffer=(guint8 *)wmem_alloc(pinfo->pool, length); - - for(ek=enc_key_list;ek;ek=ek->next){ - /* shortcircuit and bail out if enctypes are not matching */ - if(ek->keytype!=keytype){ - continue; - } - - /* pre-0.6.1 versions of Heimdal would sometimes change - the cryptotext data even when the decryption failed. - This would obviously not work since we iterate over the - keys. So just give it a copy of the crypto data instead. - This has been seen for RC4-HMAC blobs. - */ - memcpy(cryptocopy, original_data, length); - ret=decrypt_arcfour(gssapi_encrypt, - cryptocopy, - output_message_buffer, - ek->keyvalue, - ek->keylength, - ek->keytype); - if (ret >= 0) { - expert_add_info_format(pinfo, NULL, &ei_spnego_decrypted_keytype, - "Decrypted keytype %d in frame %u using %s", - ek->keytype, pinfo->num, ek->key_origin); - - gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb, - output_message_buffer, - ret, ret); - add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); - return; - } - } + /* XXX we should only do this for first time, then store somewhere */ + /* XXX We also need to re-read the keytab when the preference changes */ + + cryptocopy=(guint8 *)wmem_alloc(wmem_packet_scope(), length); + output_message_buffer=(guint8 *)wmem_alloc(pinfo->pool, length); + + for(ek=enc_key_list;ek;ek=ek->next){ + /* shortcircuit and bail out if enctypes are not matching */ + if(ek->keytype!=keytype){ + continue; + } + + /* pre-0.6.1 versions of Heimdal would sometimes change + the cryptotext data even when the decryption failed. + This would obviously not work since we iterate over the + keys. So just give it a copy of the crypto data instead. + This has been seen for RC4-HMAC blobs. + */ + memcpy(cryptocopy, original_data, length); + ret=decrypt_arcfour(gssapi_encrypt, + cryptocopy, + output_message_buffer, + ek->keyvalue, + ek->keylength, + ek->keytype); + if (ret >= 0) { + expert_add_info_format(pinfo, NULL, &ei_spnego_decrypted_keytype, + "Decrypted keytype %d in frame %u using %s", + ek->keytype, pinfo->num, ek->key_origin); + + gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb, output_message_buffer, ret, ret); + add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); + return; + } + } } /* borrowed from heimdal */ static int rrc_rotate(guint8 *data, int len, guint16 rrc, int unrotate) { - guint8 *tmp, buf[256]; - size_t left; + guint8 *tmp, buf[256]; + size_t left; - if (len == 0) - return 0; - - rrc %= len; - - if (rrc == 0) - return 0; - - left = len - rrc; - - if (rrc <= sizeof(buf)) { - tmp = buf; - } else { - tmp = (guint8 *)g_malloc(rrc); - if (tmp == NULL) - return -1; - } + if (len == 0) + return 0; - if (unrotate) { - memcpy(tmp, data, rrc); - memmove(data, data + rrc, left); - memcpy(data + left, tmp, rrc); - } else { - memcpy(tmp, data + left, rrc); - memmove(data + rrc, data, left); - memcpy(data, tmp, rrc); - } + rrc %= len; - if (rrc > sizeof(buf)) - g_free(tmp); + if (rrc == 0) + return 0; - return 0; + left = len - rrc; + + if (rrc <= sizeof(buf)) { + tmp = buf; + } else { + tmp = (guint8 *)g_malloc(rrc); + if (tmp == NULL) + return -1; + } + + if (unrotate) { + memcpy(tmp, data, rrc); + memmove(data, data + rrc, left); + memcpy(data + left, tmp, rrc); + } else { + memcpy(tmp, data + left, rrc); + memmove(data + rrc, data, left); + memcpy(data, tmp, rrc); + } + + if (rrc > sizeof(buf)) + g_free(tmp); + + return 0; } -#define KRB5_KU_USAGE_ACCEPTOR_SEAL 22 -#define KRB5_KU_USAGE_ACCEPTOR_SIGN 23 -#define KRB5_KU_USAGE_INITIATOR_SEAL 24 -#define KRB5_KU_USAGE_INITIATOR_SIGN 25 +#define KRB5_KU_USAGE_ACCEPTOR_SEAL 22 +#define KRB5_KU_USAGE_ACCEPTOR_SIGN 23 +#define KRB5_KU_USAGE_INITIATOR_SEAL 24 +#define KRB5_KU_USAGE_INITIATOR_SIGN 25 static void decrypt_gssapi_krb_cfx_wrap(proto_tree *tree, - packet_info *pinfo, - tvbuff_t *checksum_tvb, - gssapi_encrypt_info_t* gssapi_encrypt, - guint16 ec, - guint16 rrc, - int keytype, - unsigned int usage) + packet_info *pinfo, + tvbuff_t *checksum_tvb, + gssapi_encrypt_info_t* gssapi_encrypt, + guint16 ec, + guint16 rrc, + int keytype, + unsigned int usage) { - guint8 *rotated; - guint8 *output; - int datalen; - tvbuff_t *next_tvb; + guint8 *rotated; + guint8 *output; + int datalen; + tvbuff_t *next_tvb; - /* don't do anything if we are not attempting to decrypt data */ - if(!krb_decrypt){ - return; - } + /* don't do anything if we are not attempting to decrypt data */ + if(!krb_decrypt){ + return; + } - datalen = tvb_captured_length(checksum_tvb) + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); + datalen = tvb_captured_length(checksum_tvb) + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); - rotated = (guint8 *)wmem_alloc(pinfo->pool, datalen); + rotated = (guint8 *)wmem_alloc(pinfo->pool, datalen); - tvb_memcpy(checksum_tvb, rotated, - 0, tvb_captured_length(checksum_tvb)); - tvb_memcpy(gssapi_encrypt->gssapi_encrypted_tvb, rotated + tvb_captured_length(checksum_tvb), - 0, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); + tvb_memcpy(checksum_tvb, rotated, 0, tvb_captured_length(checksum_tvb)); + tvb_memcpy(gssapi_encrypt->gssapi_encrypted_tvb, rotated + tvb_captured_length(checksum_tvb), + 0, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); - if (gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE) { - rrc += ec; - } + if (gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE) { + rrc += ec; + } - rrc_rotate(rotated, datalen, rrc, TRUE); + rrc_rotate(rotated, datalen, rrc, TRUE); - next_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, rotated, - datalen, datalen); - add_new_data_source(pinfo, next_tvb, "GSSAPI CFX"); + next_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, rotated, + datalen, datalen); + add_new_data_source(pinfo, next_tvb, "GSSAPI CFX"); - output = decrypt_krb5_data(tree, pinfo, usage, next_tvb, - keytype, &datalen); + output = decrypt_krb5_data(tree, pinfo, usage, next_tvb, keytype, &datalen); - if (output) { - guint8 *outdata; + if (output) { + guint8 *outdata; - outdata = (guint8 *)wmem_memdup(pinfo->pool, output, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); + outdata = (guint8 *)wmem_memdup(pinfo->pool, output, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); - gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, - outdata, - tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb), - tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); - add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); - } + gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, + outdata, + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb), + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); + add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); + } } #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */ @@ -740,130 +709,125 @@ decrypt_gssapi_krb_cfx_wrap(proto_tree *tree, static int dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo #ifndef HAVE_KERBEROS - _U_ + _U_ #endif , proto_tree *tree, guint16 token_id #ifndef HAVE_KERBEROS - _U_ + _U_ #endif - , gssapi_encrypt_info_t* gssapi_encrypt - ) + , gssapi_encrypt_info_t* gssapi_encrypt + ) { - guint16 sgn_alg, seal_alg; + guint16 sgn_alg, seal_alg; #ifdef HAVE_KERBEROS - int start_offset=offset; + int start_offset=offset; #endif - /* - * The KRB5 blob conforms to RFC1964: - * USHORT (0x0102 == GSS_Wrap) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC1964: + * USHORT (0x0102 == GSS_Wrap) + * and so on } + */ - /* Now, the sign and seal algorithms ... */ + /* 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); + sgn_alg = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2, sgn_alg); - offset += 2; + offset += 2; - seal_alg = tvb_get_letohs(tvb, offset); - proto_tree_add_uint(tree, hf_spnego_krb5_seal_alg, tvb, offset, 2, - seal_alg); + seal_alg = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_spnego_krb5_seal_alg, tvb, offset, 2, seal_alg); - offset += 2; + offset += 2; - /* Skip the filler */ + /* Skip the filler */ - offset += 2; + offset += 2; - /* Encrypted sequence number */ + /* Encrypted sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, ENC_NA); - offset += 8; + offset += 8; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, ENC_NA); - offset += 8; + 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) || - /* there also seems to be a confounder for DES MAC MD5 - certainly seen when using with - SASL with LDAP between a Java client and Active Directory. If this breaks other things - we may need to make this an option. gal 17/2/06 */ - (sgn_alg == KRB_SGN_ALG_DES_MAC_MD5)) { - proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, - ENC_NA); - 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) || + /* there also seems to be a confounder for DES MAC MD5 - certainly seen when using with + SASL with LDAP between a Java client and Active Directory. If this breaks other things + we may need to make this an option. gal 17/2/06 */ + (sgn_alg == KRB_SGN_ALG_DES_MAC_MD5)) { + proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, ENC_NA); + offset += 8; + } - /* Is the data encrypted? */ - if (gssapi_encrypt != NULL) - gssapi_encrypt->gssapi_data_encrypted=(seal_alg!=KRB_SEAL_ALG_NONE); + /* Is the data encrypted? */ + if (gssapi_encrypt != NULL) + gssapi_encrypt->gssapi_data_encrypted=(seal_alg!=KRB_SEAL_ALG_NONE); #ifdef HAVE_KERBEROS #define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32 - if(gssapi_encrypt && gssapi_encrypt->decrypt_gssapi_tvb){ - /* if the caller did not provide a tvb, then we just use - whatever is left of our current tvb. - */ - if(!gssapi_encrypt->gssapi_encrypted_tvb){ - int len; - len=tvb_reported_length_remaining(tvb,offset); - if(len>tvb_captured_length_remaining(tvb, offset)){ - /* no point in trying to decrypt, - we don't have the full pdu. - */ - return offset; - } - gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset_length( - tvb, offset, len); - } - - /* if this is KRB5 wrapped rc4-hmac */ - if((token_id==KRB_TOKEN_WRAP) - &&(sgn_alg==KRB_SGN_ALG_HMAC) - &&(seal_alg==KRB_SEAL_ALG_RC4)){ - /* do we need to create a tvb for the wrapper - as well ? - */ - if(!gssapi_encrypt->gssapi_wrap_tvb){ - gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( - tvb, start_offset-2, - GSS_ARCFOUR_WRAP_TOKEN_SIZE); - } + if(gssapi_encrypt && gssapi_encrypt->decrypt_gssapi_tvb){ + /* if the caller did not provide a tvb, then we just use + whatever is left of our current tvb. + */ + if(!gssapi_encrypt->gssapi_encrypted_tvb){ + int len; + len=tvb_reported_length_remaining(tvb,offset); + if(len>tvb_captured_length_remaining(tvb, offset)){ + /* no point in trying to decrypt, + we don't have the full pdu. + */ + return offset; + } + gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset_length( + tvb, offset, len); + } + + /* if this is KRB5 wrapped rc4-hmac */ + if((token_id==KRB_TOKEN_WRAP) + &&(sgn_alg==KRB_SGN_ALG_HMAC) + &&(seal_alg==KRB_SEAL_ALG_RC4)){ + /* do we need to create a tvb for the wrapper + as well ? + */ + if(!gssapi_encrypt->gssapi_wrap_tvb){ + gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( + tvb, start_offset-2, + GSS_ARCFOUR_WRAP_TOKEN_SIZE); + } #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - decrypt_gssapi_krb_arcfour_wrap(tree, - pinfo, - tvb, - KEYTYPE_ARCFOUR_HMAC, - gssapi_encrypt); + decrypt_gssapi_krb_arcfour_wrap(tree, + pinfo, + tvb, + KEYTYPE_ARCFOUR_HMAC, + gssapi_encrypt); #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */ - } - } + } + } #endif - /* - * 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; + /* + * 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; } /* @@ -872,84 +836,80 @@ dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo static int dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { - guint16 sgn_alg; + guint16 sgn_alg; - /* - * The KRB5 blob conforms to RFC1964: - * USHORT (0x0101 == GSS_GetMIC) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC1964: + * USHORT (0x0101 == GSS_GetMIC) + * and so on } + */ - /* Now, the sign algorithm ... */ + /* 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); + sgn_alg = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2, sgn_alg); - offset += 2; + offset += 2; - /* Skip the filler */ + /* Skip the filler */ - offset += 4; + offset += 4; - /* Encrypted sequence number */ + /* Encrypted sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, ENC_NA); - offset += 8; + offset += 8; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, ENC_NA); - offset += 8; + 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.... - * - * The exception is DNS/TSIG where there is no such confounder - * so we need to test here if there are more bytes in our tvb or not. - * -- ronnie - */ - if (tvb_reported_length_remaining(tvb, offset)) { - if (sgn_alg == KRB_SGN_ALG_HMAC) { - proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, - ENC_NA); + /* + * 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.... + * + * The exception is DNS/TSIG where there is no such confounder + * so we need to test here if there are more bytes in our tvb or not. + * -- ronnie + */ + if (tvb_reported_length_remaining(tvb, offset)) { + if (sgn_alg == KRB_SGN_ALG_HMAC) { + proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, ENC_NA); - offset += 8; - } - } + 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 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; + return offset; } static int dissect_spnego_krb5_cfx_flags(tvbuff_t *tvb, int offset, - proto_tree *spnego_krb5_tree, - guint8 cfx_flags _U_) + proto_tree *spnego_krb5_tree, + guint8 cfx_flags _U_) { - static const int * flags[] = { - &hf_spnego_krb5_cfx_flags_04, - &hf_spnego_krb5_cfx_flags_02, - &hf_spnego_krb5_cfx_flags_01, - NULL - }; - - proto_tree_add_bitmask(spnego_krb5_tree, tvb, offset, hf_spnego_krb5_cfx_flags, ett_spnego_krb5_cfx_flags, flags, ENC_NA); - return (offset + 1); + static const int * flags[] = { + &hf_spnego_krb5_cfx_flags_04, + &hf_spnego_krb5_cfx_flags_02, + &hf_spnego_krb5_cfx_flags_01, + NULL + }; + + proto_tree_add_bitmask(spnego_krb5_tree, tvb, offset, hf_spnego_krb5_cfx_flags, ett_spnego_krb5_cfx_flags, flags, ENC_NA); + return (offset + 1); } /* @@ -958,183 +918,176 @@ dissect_spnego_krb5_cfx_flags(tvbuff_t *tvb, int offset, static int dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo #ifndef HAVE_KERBEROS - _U_ + _U_ #endif - , proto_tree *tree, guint16 token_id _U_ - , gssapi_encrypt_info_t* gssapi_encrypt - ) + , proto_tree *tree, guint16 token_id _U_ + , gssapi_encrypt_info_t* gssapi_encrypt + ) { - guint8 flags; - guint16 ec; + guint8 flags; + guint16 ec; #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - guint16 rrc; + guint16 rrc; #endif - int checksum_size; - int start_offset=offset; + int checksum_size; + int start_offset=offset; - /* - * The KRB5 blob conforms to RFC4121: - * USHORT (0x0504) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC4121: + * USHORT (0x0504) + * and so on } + */ - /* Now, the sign and seal algorithms ... */ + /* Now, the sign and seal algorithms ... */ - flags = tvb_get_guint8(tvb, offset); - offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags); + flags = tvb_get_guint8(tvb, offset); + offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags); - if (gssapi_encrypt != NULL) - gssapi_encrypt->gssapi_data_encrypted=(flags & 2); + if (gssapi_encrypt != NULL) + gssapi_encrypt->gssapi_data_encrypted=(flags & 2); - /* Skip the filler */ + /* Skip the filler */ - proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 1, - ENC_NA); - offset += 1; + proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 1, ENC_NA); + offset += 1; - /* EC */ - ec = tvb_get_ntohs(tvb, offset); - proto_tree_add_item(tree, hf_spnego_krb5_cfx_ec, tvb, offset, 2, - ENC_BIG_ENDIAN); - offset += 2; + /* EC */ + ec = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_spnego_krb5_cfx_ec, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; - /* RRC */ + /* RRC */ #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - rrc = tvb_get_ntohs(tvb, offset); + rrc = tvb_get_ntohs(tvb, offset); #endif - proto_tree_add_item(tree, hf_spnego_krb5_cfx_rrc, tvb, offset, 2, - ENC_BIG_ENDIAN); - offset += 2; + proto_tree_add_item(tree, hf_spnego_krb5_cfx_rrc, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; - /* sequence number */ + /* sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, - ENC_BIG_ENDIAN); - offset += 8; + proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, ENC_BIG_ENDIAN); + offset += 8; - if (gssapi_encrypt == NULL) /* Probably shoudn't happen, but just protect ourselves */ - return offset; + if (gssapi_encrypt == NULL) /* Probably shoudn't happen, but just protect ourselves */ + return offset; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - if (gssapi_encrypt->gssapi_data_encrypted) { - checksum_size = 44 + ec; + if (gssapi_encrypt->gssapi_data_encrypted) { + checksum_size = 44 + ec; - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, - checksum_size, ENC_NA); - offset += checksum_size; + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + offset += checksum_size; - } else { - int returned_offset; - int inner_token_len = 0; + } else { + int returned_offset; + int inner_token_len = 0; - /* - * We know we have a wrap token, but we have to let the proto - * above us decode that, so hand it back in gssapi_wrap_tvb - * and put the checksum in the tree. - */ + /* + * We know we have a wrap token, but we have to let the proto + * above us decode that, so hand it back in gssapi_wrap_tvb + * and put the checksum in the tree. + */ - checksum_size = ec; + checksum_size = ec; - inner_token_len = tvb_reported_length_remaining(tvb, offset); - if (inner_token_len > ec) { - inner_token_len -= ec; - } + inner_token_len = tvb_reported_length_remaining(tvb, offset); + if (inner_token_len > ec) { + inner_token_len -= ec; + } - /* - * We handle only the two common cases for now - * (rrc == 0 and rrc == ec) - */ + /* + * We handle only the two common cases for now + * (rrc == 0 and rrc == ec) + */ #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - if (rrc == ec) { - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, - tvb, offset, checksum_size, ENC_NA); - offset += checksum_size; - } + if (rrc == ec) { + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + offset += checksum_size; + } #endif - returned_offset = offset; - gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset, - inner_token_len); + returned_offset = offset; + gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset, + inner_token_len); - offset += inner_token_len; + offset += inner_token_len; #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - if (rrc == 0) + if (rrc == 0) #endif - { - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, - tvb, offset, checksum_size, ENC_NA); - } - - /* - * Return an offset that puts our caller before the inner - * token. This is better than before, but we still see the - * checksum included in the LDAP query at times. - */ - return returned_offset; - } - - if(gssapi_encrypt->decrypt_gssapi_tvb){ - /* if the caller did not provide a tvb, then we just use - whatever is left of our current tvb. - */ - if(!gssapi_encrypt->gssapi_encrypted_tvb){ - int len; - len=tvb_reported_length_remaining(tvb,offset); - if(len>tvb_captured_length_remaining(tvb, offset)){ - /* no point in trying to decrypt, - we don't have the full pdu. - */ - return offset; - } - gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset( - tvb, offset, len, len); - } - - if (gssapi_encrypt->gssapi_data_encrypted) { - /* do we need to create a tvb for the wrapper - as well ? - */ - if(!gssapi_encrypt->gssapi_wrap_tvb){ - gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( - tvb, start_offset-2, - offset - (start_offset-2)); - } - } - } + { + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + } + + /* + * Return an offset that puts our caller before the inner + * token. This is better than before, but we still see the + * checksum included in the LDAP query at times. + */ + return returned_offset; + } + + if(gssapi_encrypt->decrypt_gssapi_tvb){ + /* if the caller did not provide a tvb, then we just use + whatever is left of our current tvb. + */ + if(!gssapi_encrypt->gssapi_encrypted_tvb){ + int len; + len=tvb_reported_length_remaining(tvb,offset); + if(len>tvb_captured_length_remaining(tvb, offset)){ + /* no point in trying to decrypt, + we don't have the full pdu. + */ + return offset; + } + gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset( + tvb, offset, len, len); + } + + if (gssapi_encrypt->gssapi_data_encrypted) { + /* do we need to create a tvb for the wrapper + as well ? + */ + if(!gssapi_encrypt->gssapi_wrap_tvb){ + gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( + tvb, start_offset-2, + offset - (start_offset-2)); + } + } + } #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) { - tvbuff_t *checksum_tvb = tvb_new_subset_length(tvb, 16, checksum_size); - - if (gssapi_encrypt->gssapi_data_encrypted) { - if(gssapi_encrypt->gssapi_encrypted_tvb){ - decrypt_gssapi_krb_cfx_wrap(tree, - pinfo, - checksum_tvb, - gssapi_encrypt, - ec, - rrc, - -1, - (flags & 0x0001)? - KRB5_KU_USAGE_ACCEPTOR_SEAL: - KRB5_KU_USAGE_INITIATOR_SEAL); - } - } + tvbuff_t *checksum_tvb = tvb_new_subset_length(tvb, 16, checksum_size); + + if (gssapi_encrypt->gssapi_data_encrypted) { + if(gssapi_encrypt->gssapi_encrypted_tvb){ + decrypt_gssapi_krb_cfx_wrap(tree, + pinfo, + checksum_tvb, + gssapi_encrypt, + ec, + rrc, + -1, + (flags & 0x0001)? + KRB5_KU_USAGE_ACCEPTOR_SEAL: + KRB5_KU_USAGE_INITIATOR_SEAL); + } + } } #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */ - /* - * 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; + /* + * 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; } /* @@ -1143,46 +1096,43 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo 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; + guint8 flags; + int checksum_size; - /* - * The KRB5 blob conforms to RFC4121: - * USHORT (0x0404 == GSS_GetMIC) - * and so on } - */ + /* + * 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); + flags = tvb_get_guint8(tvb, offset); + offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags); - /* Skip the filler */ + /* Skip the filler */ - proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 5, - ENC_NA); - offset += 5; + proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 5, ENC_NA); + offset += 5; - /* sequence number */ + /* sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, - ENC_BIG_ENDIAN); - offset += 8; + proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, ENC_BIG_ENDIAN); + offset += 8; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - checksum_size = tvb_captured_length_remaining(tvb, offset); + checksum_size = tvb_captured_length_remaining(tvb, offset); - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, - checksum_size, ENC_NA); - offset += checksum_size; + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + 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 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; + return offset; } /* @@ -1195,60 +1145,59 @@ dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinf static int dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - guint16 token_id; - gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; + proto_item *item; + proto_tree *subtree; + int offset = 0; + guint16 token_id; + gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; - item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, ENC_NA); + item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, ENC_NA); - subtree = proto_item_add_subtree(item, ett_spnego_krb5); + subtree = proto_item_add_subtree(item, ett_spnego_krb5); - /* - * The KRB5 blob conforms to RFC1964: - * USHORT (0x0102 == GSS_Wrap) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC1964: + * USHORT (0x0102 == GSS_Wrap) + * and so on } + */ - /* First, the token ID ... */ + /* First, 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); + token_id = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2, token_id); - offset += 2; + offset += 2; - switch (token_id) { - case KRB_TOKEN_GETMIC: - offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree); - break; + 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, encrypt_info); - break; + case KRB_TOKEN_WRAP: + offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id, encrypt_info); + break; - case KRB_TOKEN_CFX_GETMIC: - offset = dissect_spnego_krb5_cfx_getmic_base(tvb, offset, pinfo, subtree); - 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, encrypt_info); - break; + case KRB_TOKEN_CFX_WRAP: + offset = dissect_spnego_krb5_cfx_wrap_base(tvb, offset, pinfo, subtree, token_id, encrypt_info); + break; - default: + default: - break; - } + break; + } - /* - * 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; + /* + * 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 */ @@ -1256,237 +1205,245 @@ dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree static int dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - asn1_ctx_t asn1_ctx; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + proto_item *item; + proto_tree *subtree; + int offset = 0; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - MechType_oid = NULL; + MechType_oid = NULL; - /* - * 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. - */ + /* + * 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. + */ - item = proto_tree_add_item(tree, proto_spnego, tvb, offset, - -1, ENC_NA); + item = proto_tree_add_item(tree, proto_spnego, tvb, offset, -1, ENC_NA); - 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 code addet to spnego.asn to handle this. - */ + 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 code addet to spnego.asn to handle this. + */ - offset = dissect_spnego_InitialContextToken(FALSE, tvb, offset, &asn1_ctx , subtree, -1); + offset = dissect_spnego_InitialContextToken(FALSE, tvb, offset, &asn1_ctx , subtree, -1); - return offset; + return offset; } static int dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - conversation_t *conversation; - asn1_ctx_t asn1_ctx; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - - /* - * 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 = (gssapi_oid_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0); - 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->num, &pinfo->src, &pinfo->dst, - pinfo->ptype, pinfo->srcport, - pinfo->destport, 0); - - if (conversation) { - next_level_value = (gssapi_oid_value *)conversation_get_proto_data(conversation, - proto_spnego); - if (next_level_value) - p_add_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0, next_level_value); - } - } - - item = proto_tree_add_item(parent_tree, proto_spnego, tvb, offset, - -1, ENC_NA); - - 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. - * - */ - dissect_spnego_NegotiationToken(FALSE, tvb, offset, &asn1_ctx, subtree, -1); - return tvb_captured_length(tvb); + proto_item *item; + proto_tree *subtree; + int offset = 0; + conversation_t *conversation; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + /* + * 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 = (gssapi_oid_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0); + 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->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + + if (conversation) { + next_level_value = (gssapi_oid_value *)conversation_get_proto_data(conversation, proto_spnego); + if (next_level_value) + p_add_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0, next_level_value); + } + } + + item = proto_tree_add_item(parent_tree, proto_spnego, tvb, offset, -1, ENC_NA); + + 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. + * + */ + dissect_spnego_NegotiationToken(FALSE, tvb, offset, &asn1_ctx, subtree, -1); + return tvb_captured_length(tvb); } /*--- proto_register_spnego -------------------------------------------*/ void proto_register_spnego(void) { - /* List of fields */ - static hf_register_info hf[] = { - { &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, NULL, HFILL }}, - { &hf_spnego_krb5_oid, - { "KRB5 OID", "spnego.krb5_oid", FT_STRING, - BASE_NONE, NULL, 0, NULL, 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}}, - { &hf_spnego_krb5_filler, - { "krb5_filler", "spnego.krb5.filler", FT_BYTES, BASE_NONE, - 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 (&tfs_set_notset), 0x01, NULL, HFILL}}, - { &hf_spnego_krb5_cfx_flags_02, - { "Sealed", "spnego.krb5.sealed", FT_BOOLEAN, 8, - TFS (&tfs_set_notset), 0x02, NULL, HFILL}}, - { &hf_spnego_krb5_cfx_flags_04, - { "AcceptorSubkey", "spnego.krb5.acceptor_subkey", FT_BOOLEAN, 8, - TFS (&tfs_set_notset), 0x04, NULL, 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}}, + /* List of fields */ + static hf_register_info hf[] = { + { &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, NULL, HFILL }}, + { &hf_spnego_krb5_oid, + { "KRB5 OID", "spnego.krb5_oid", FT_STRING, + BASE_NONE, NULL, 0, NULL, 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}}, + { &hf_spnego_krb5_filler, + { "krb5_filler", "spnego.krb5.filler", FT_BYTES, BASE_NONE, + 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 (&tfs_set_notset), 0x01, NULL, HFILL}}, + { &hf_spnego_krb5_cfx_flags_02, + { "Sealed", "spnego.krb5.sealed", FT_BOOLEAN, 8, + TFS (&tfs_set_notset), 0x02, NULL, HFILL}}, + { &hf_spnego_krb5_cfx_flags_04, + { "AcceptorSubkey", "spnego.krb5.acceptor_subkey", FT_BOOLEAN, 8, + TFS (&tfs_set_notset), 0x04, NULL, 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" - }; + }; - /* List of subtrees */ - static gint *ett[] = { - &ett_spnego, - &ett_spnego_wraptoken, - &ett_spnego_krb5, - &ett_spnego_krb5_cfx_flags, + /* List of subtrees */ + static gint *ett[] = { + &ett_spnego, + &ett_spnego_wraptoken, + &ett_spnego_krb5, + &ett_spnego_krb5_cfx_flags, #include "packet-spnego-ettarr.c" - }; + }; - static ei_register_info ei[] = { - { &ei_spnego_decrypted_keytype, { "spnego.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }}, - { &ei_spnego_unknown_header, { "spnego.unknown_header", PI_PROTOCOL, PI_WARN, "Unknown header", EXPFILL }}, - }; + static ei_register_info ei[] = { + { &ei_spnego_decrypted_keytype, { "spnego.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }}, + { &ei_spnego_unknown_header, { "spnego.unknown_header", PI_PROTOCOL, PI_WARN, "Unknown header", EXPFILL }}, + }; - expert_module_t* expert_spnego; + expert_module_t* expert_spnego; - /* Register protocol */ - proto_spnego = proto_register_protocol(PNAME, PSNAME, PFNAME); + /* Register protocol */ + proto_spnego = proto_register_protocol(PNAME, PSNAME, PFNAME); - spnego_handle = register_dissector("spnego", dissect_spnego, proto_spnego); + spnego_handle = register_dissector("spnego", dissect_spnego, proto_spnego); - proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5", - "SPNEGO-KRB5", - "spnego-krb5"); + proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5", "SPNEGO-KRB5", "spnego-krb5"); - spnego_krb5_handle = register_dissector("spnego-krb5", dissect_spnego_krb5, proto_spnego_krb5); - spnego_krb5_wrap_handle = register_dissector("spnego-krb5-wrap", dissect_spnego_krb5_wrap, proto_spnego_krb5); + spnego_krb5_handle = register_dissector("spnego-krb5", dissect_spnego_krb5, proto_spnego_krb5); + spnego_krb5_wrap_handle = 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)); - expert_spnego = expert_register_protocol(proto_spnego); - expert_register_field_array(expert_spnego, ei, array_length(ei)); + /* Register fields and subtrees */ + proto_register_field_array(proto_spnego, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + expert_spnego = expert_register_protocol(proto_spnego); + expert_register_field_array(expert_spnego, ei, array_length(ei)); } /*--- proto_reg_handoff_spnego ---------------------------------------*/ void proto_reg_handoff_spnego(void) { - dissector_handle_t spnego_wrap_handle; - - /* Register protocol with GSS-API module */ - - spnego_wrap_handle = 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. - */ - 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"); + dissector_handle_t spnego_wrap_handle; + + /* Register protocol with GSS-API module */ + + spnego_wrap_handle = 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. + */ + 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"); } + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 2 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=2 tabstop=8 expandtab: + * :indentSize=2:tabSize=8:noTabs=true: + */ diff --git a/epan/dissectors/asn1/spnego/spnego.cnf b/epan/dissectors/asn1/spnego/spnego.cnf index 04ce792d02..9df7afd365 100644 --- a/epan/dissectors/asn1/spnego/spnego.cnf +++ b/epan/dissectors/asn1/spnego/spnego.cnf @@ -177,3 +177,16 @@ NegotiationToken } #.END + +# +# Editor modelines - http://www.wireshark.org/tools/modelines.html +# +# Local variables: +# c-basic-offset: 2 +# tab-width: 8 +# indent-tabs-mode: nil +# End: +# +# vi: set shiftwidth=2 tabstop=8 expandtab: +# :indentSize=2:tabSize=8:noTabs=true: +# diff --git a/epan/dissectors/packet-spnego.c b/epan/dissectors/packet-spnego.c index 063dd2b800..306a6ad315 100644 --- a/epan/dissectors/packet-spnego.c +++ b/epan/dissectors/packet-spnego.c @@ -566,14 +566,14 @@ dissect_spnego_InitialContextToken(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, * 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 -#define KRB_TOKEN_CFX_GETMIC 0x0404 -#define KRB_TOKEN_CFX_WRAP 0x0405 +#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 +#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"}, @@ -583,14 +583,14 @@ static const value_string spnego_krb5_tok_id_vals[] = { { 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" }, + { KRB_TOKEN_CFX_WRAP, "KRB_TOKEN_CFX_WRAP" }, { 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 +#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"}, @@ -600,9 +600,9 @@ static const value_string spnego_krb5_sgn_alg_vals[] = { { 0, NULL} }; -#define KRB_SEAL_ALG_DES_CBC 0x0000 -#define KRB_SEAL_ALG_RC4 0x0010 -#define KRB_SEAL_ALG_NONE 0xffff +#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"}, @@ -630,143 +630,139 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo, static int dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - guint16 token_id; - const char *oid; - tvbuff_t *krb5_tvb; - gint8 ber_class; - gboolean pc, ind = 0; - gint32 tag; - guint32 len; - gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; - asn1_ctx_t asn1_ctx; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - - item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset, - -1, ENC_NA); - - 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. - */ - - /* - * Get the first header ... - */ - get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - if (ber_class == BER_CLASS_APP && pc) { - /* - * [APPLICATION <tag>] - */ - offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &ber_class, &pc, &tag); - offset = dissect_ber_length(pinfo, subtree, tvb, offset, &len, &ind); - - switch (tag) { - - case 0: - /* - * [APPLICATION 0] - */ - - /* Next, the OID */ - offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, tvb, offset, hf_spnego_krb5_oid, &oid); - - token_id = tvb_get_letohs(tvb, offset); - proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2, - token_id); - - offset += 2; - - break; - - case 14: /* [APPLICATION 14] */ - case 15: /* [APPLICATION 15] */ - /* - * No token ID - just dissect as a Kerberos message and - * return. - */ - dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL); - return tvb_captured_length(tvb); - - default: - proto_tree_add_expert_format(subtree, pinfo, &ei_spnego_unknown_header, tvb, offset, 0, - "Unknown header (class=%d, pc=%d, tag=%d)", - ber_class, pc, 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); - - 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_remaining(tvb, offset); - 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, token_id, encrypt_info); - break; - - case KRB_TOKEN_DELETE_SEC_CONTEXT: - - 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, encrypt_info); - break; - - default: - - break; - } - - done: - proto_item_set_len(item, offset); - return tvb_captured_length(tvb); + proto_item *item; + proto_tree *subtree; + int offset = 0; + guint16 token_id; + const char *oid; + tvbuff_t *krb5_tvb; + gint8 ber_class; + gboolean pc, ind = 0; + gint32 tag; + guint32 len; + gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset, -1, ENC_NA); + + 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. + */ + + /* + * Get the first header ... + */ + get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + if (ber_class == BER_CLASS_APP && pc) { + /* + * [APPLICATION <tag>] + */ + offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &ber_class, &pc, &tag); + offset = dissect_ber_length(pinfo, subtree, tvb, offset, &len, &ind); + + switch (tag) { + + case 0: + /* + * [APPLICATION 0] + */ + + /* Next, the OID */ + offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, tvb, offset, hf_spnego_krb5_oid, &oid); + + token_id = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2, token_id); + + offset += 2; + + break; + + case 14: /* [APPLICATION 14] */ + case 15: /* [APPLICATION 15] */ + /* + * No token ID - just dissect as a Kerberos message and + * return. + */ + dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL); + return tvb_captured_length(tvb); + + default: + proto_tree_add_expert_format(subtree, pinfo, &ei_spnego_unknown_header, tvb, offset, 0, + "Unknown header (class=%d, pc=%d, tag=%d)", ber_class, pc, 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); + + 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_remaining(tvb, offset); + 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, token_id, encrypt_info); + break; + + case KRB_TOKEN_DELETE_SEC_CONTEXT: + + 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, encrypt_info); + break; + + default: + + break; + } + + done: + proto_item_set_len(item, offset); + return tvb_captured_length(tvb); } #ifdef HAVE_KERBEROS @@ -785,94 +781,80 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d static int arcfour_mic_key(const guint8 *key_data, size_t key_size, int key_type, - const guint8 *cksum_data, size_t cksum_size, - guint8 *key6_data) + const guint8 *cksum_data, size_t cksum_size, + guint8 *key6_data) { - guint8 k5_data[16]; - guint8 T[4]; - - memset(T, 0, 4); - - if (key_type == KEYTYPE_ARCFOUR_56) { - guint8 L40[14] = "fortybits"; - - memcpy(L40 + 10, T, sizeof(T)); - md5_hmac( - L40, 14, - key_data, - key_size, - k5_data); - memset(&k5_data[7], 0xAB, 9); - } else { - md5_hmac( - T, 4, - key_data, - key_size, - k5_data); - } + guint8 k5_data[16]; + guint8 T[4]; - md5_hmac( - cksum_data, cksum_size, - k5_data, - 16, - key6_data); + memset(T, 0, 4); - return 0; + if (key_type == KEYTYPE_ARCFOUR_56) { + guint8 L40[14] = "fortybits"; + + memcpy(L40 + 10, T, sizeof(T)); + md5_hmac(L40, 14, key_data, key_size, k5_data); + memset(&k5_data[7], 0xAB, 9); + } else { + md5_hmac(T, 4, key_data, key_size, k5_data); + } + + md5_hmac(cksum_data, cksum_size, k5_data, 16, key6_data); + + return 0; } static int usage2arcfour(int usage) { - switch (usage) { + switch (usage) { case 3: /*KRB5_KU_AS_REP_ENC_PART 3 */ case 9: /*KRB5_KU_TGS_REP_ENC_PART_SUB_KEY 9 */ - return 8; + return 8; case 22: /*KRB5_KU_USAGE_SEAL 22 */ - return 13; + return 13; case 23: /*KRB5_KU_USAGE_SIGN 23 */ return 15; case 24: /*KRB5_KU_USAGE_SEQ 24 */ - return 0; + return 0; default : - return 0; - } + return 0; + } } static int arcfour_mic_cksum(guint8 *key_data, int key_length, - unsigned int usage, - guint8 sgn_cksum[8], - const guint8 *v1, size_t l1, - const guint8 *v2, size_t l2, - const guint8 *v3, size_t l3) + unsigned int usage, + guint8 sgn_cksum[8], + const guint8 *v1, size_t l1, + const guint8 *v2, size_t l2, + const guint8 *v3, size_t l3) { - static const guint8 signature[] = "signaturekey"; - guint8 ksign_c[16]; - guint8 t[4]; - md5_state_t ms; - guint8 digest[16]; - int rc4_usage; - guint8 cksum[16]; - - rc4_usage=usage2arcfour(usage); - md5_hmac(signature, sizeof(signature), - key_data, key_length, - ksign_c); - md5_init(&ms); - t[0] = (rc4_usage >> 0) & 0xFF; - t[1] = (rc4_usage >> 8) & 0xFF; - t[2] = (rc4_usage >> 16) & 0xFF; - t[3] = (rc4_usage >> 24) & 0xFF; - md5_append(&ms, t, 4); - md5_append(&ms, v1, l1); - md5_append(&ms, v2, l2); - md5_append(&ms, v3, l3); - md5_finish(&ms, digest); - md5_hmac(digest, 16, ksign_c, 16, cksum); - - memcpy(sgn_cksum, cksum, 8); - - return 0; + static const guint8 signature[] = "signaturekey"; + guint8 ksign_c[16]; + guint8 t[4]; + md5_state_t ms; + guint8 digest[16]; + int rc4_usage; + guint8 cksum[16]; + + rc4_usage=usage2arcfour(usage); + md5_hmac(signature, sizeof(signature), key_data, key_length, ksign_c); + md5_init(&ms); + t[0] = (rc4_usage >> 0) & 0xFF; + t[1] = (rc4_usage >> 8) & 0xFF; + t[2] = (rc4_usage >> 16) & 0xFF; + t[3] = (rc4_usage >> 24) & 0xFF; + md5_append(&ms, t, 4); + md5_append(&ms, v1, l1); + md5_append(&ms, v2, l2); + md5_append(&ms, v3, l3); + md5_finish(&ms, digest); + md5_hmac(digest, 16, ksign_c, 16, cksum); + + memcpy(sgn_cksum, cksum, 8); + + return 0; } /* @@ -880,140 +862,131 @@ arcfour_mic_cksum(guint8 *key_data, int key_length, */ static int gssapi_verify_pad(guint8 *wrapped_data, int wrapped_length, - int datalen, - int *padlen) + int datalen, + int *padlen) { - guint8 *pad; - int padlength; - int i; + guint8 *pad; + int padlength; + int i; - pad = wrapped_data + wrapped_length - 1; - padlength = *pad; + pad = wrapped_data + wrapped_length - 1; + padlength = *pad; - if (padlength > datalen) - return 1; + if (padlength > datalen) + return 1; - for (i = padlength; i > 0 && *pad == padlength; i--, pad--) - ; - if (i != 0) - return 2; + for (i = padlength; i > 0 && *pad == padlength; i--, pad--); + if (i != 0) + return 2; - *padlen = padlength; + *padlen = padlength; - return 0; + return 0; } static int decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buffer, guint8 *output_message_buffer, - guint8 *key_value, int key_size, int key_type) + guint8 *key_value, int key_size, int key_type) { - guint8 Klocaldata[16]; - int ret; - int datalen; - guint8 k6_data[16]; - guint32 SND_SEQ[2]; - guint8 Confounder[8]; - guint8 cksum_data[8]; - int cmp; - int conf_flag; - int padlen = 0; - - datalen = tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); - - if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0x1000){ - conf_flag=1; - } else if (tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0xffff){ - conf_flag=0; - } else { - return -3; - } + guint8 Klocaldata[16]; + int ret; + int datalen; + guint8 k6_data[16]; + guint32 SND_SEQ[2]; + guint8 Confounder[8]; + guint8 cksum_data[8]; + int cmp; + int conf_flag; + int padlen = 0; + rc4_state_struct rc4_state; + int i; + + datalen = tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); + + if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0x1000){ + conf_flag=1; + } else if (tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 4)==0xffff){ + conf_flag=0; + } else { + return -3; + } - if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 6)!=0xffff){ - return -4; - } + if(tvb_get_ntohs(gssapi_encrypt->gssapi_wrap_tvb, 6)!=0xffff){ + return -4; + } - ret = arcfour_mic_key(key_value, key_size, key_type, - tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 16, 8), - 8, /* SGN_CKSUM */ - k6_data); - if (ret) { - return -5; - } + ret = arcfour_mic_key(key_value, key_size, key_type, + tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 16, 8), + 8, /* SGN_CKSUM */ + k6_data); + if (ret) { + return -5; + } - { - rc4_state_struct rc4_state; + crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); + tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, SND_SEQ, 8, 8); + crypt_rc4(&rc4_state, (guint8 *)SND_SEQ, 8); - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); - tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, SND_SEQ, 8, 8); - crypt_rc4(&rc4_state, (guint8 *)SND_SEQ, 8); + memset(k6_data, 0, sizeof(k6_data)); - memset(k6_data, 0, sizeof(k6_data)); - } - if (SND_SEQ[1] != 0xFFFFFFFF && SND_SEQ[1] != 0x00000000) { - return -6; - } + if (SND_SEQ[1] != 0xFFFFFFFF && SND_SEQ[1] != 0x00000000) { + return -6; + } - { - int i; - for (i = 0; i < 16; i++) - Klocaldata[i] = ((guint8 *)key_value)[i] ^ 0xF0; - } - ret = arcfour_mic_key(Klocaldata,sizeof(Klocaldata),key_type, - (const guint8 *)SND_SEQ, 4, - k6_data); - memset(Klocaldata, 0, sizeof(Klocaldata)); + for (i = 0; i < 16; i++) + Klocaldata[i] = ((guint8 *)key_value)[i] ^ 0xF0; + + ret = arcfour_mic_key(Klocaldata,sizeof(Klocaldata),key_type, + (const guint8 *)SND_SEQ, 4, + k6_data); + memset(Klocaldata, 0, sizeof(Klocaldata)); + if (ret) { + return -7; + } + + if(conf_flag) { + + crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); + tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); + crypt_rc4(&rc4_state, Confounder, 8); + memcpy(output_message_buffer, input_message_buffer, datalen); + crypt_rc4(&rc4_state, output_message_buffer, datalen); + } else { + tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); + memcpy(output_message_buffer, input_message_buffer, datalen); + } + memset(k6_data, 0, sizeof(k6_data)); + + /* only normal (i.e. non DCE style wrapping use padding ? */ + if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ + ret = gssapi_verify_pad(output_message_buffer,datalen,datalen, &padlen); if (ret) { - return -7; + return -9; } + datalen -= padlen; + } - if(conf_flag) { - rc4_state_struct rc4_state; - - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); - tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); - crypt_rc4(&rc4_state, Confounder, 8); - memcpy(output_message_buffer, input_message_buffer, datalen); - crypt_rc4(&rc4_state, output_message_buffer, datalen); - } else { - tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); - memcpy(output_message_buffer, - input_message_buffer, - datalen); - } - memset(k6_data, 0, sizeof(k6_data)); - - /* only normal (i.e. non DCE style wrapping use padding ? */ - if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ - ret = gssapi_verify_pad(output_message_buffer,datalen,datalen, &padlen); - if (ret) { - return -9; - } - datalen -= padlen; + /* don't know what the checksum looks like for dce style gssapi */ + if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ + ret = arcfour_mic_cksum(key_value, key_size, KRB5_KU_USAGE_SEAL, + cksum_data, + tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 0, 8), 8, + Confounder, sizeof(Confounder), output_message_buffer, + datalen + padlen); + if (ret) { + return -10; } - /* don't know what the checksum looks like for dce style gssapi */ - if(gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){ - ret = arcfour_mic_cksum(key_value, key_size, - KRB5_KU_USAGE_SEAL, - cksum_data, - tvb_get_ptr(gssapi_encrypt->gssapi_wrap_tvb, 0, 8), 8, - Confounder, sizeof(Confounder), - output_message_buffer, - datalen + padlen); - if (ret) { - return -10; - } - - cmp = tvb_memeql(gssapi_encrypt->gssapi_wrap_tvb, 16, cksum_data, 8); /* SGN_CKSUM */ - if (cmp) { - return -11; - } + cmp = tvb_memeql(gssapi_encrypt->gssapi_wrap_tvb, 16, cksum_data, 8); /* SGN_CKSUM */ + if (cmp) { + return -11; } + } - return datalen; + return datalen; } @@ -1023,162 +996,158 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf static void decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb, int keytype, gssapi_encrypt_info_t* gssapi_encrypt) { - int ret; - enc_key_t *ek; - int length; - const guint8 *original_data; + int ret; + enc_key_t *ek; + int length; + const guint8 *original_data; - guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */ - guint8 *output_message_buffer; + guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */ + guint8 *output_message_buffer; - length=tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); - original_data=tvb_get_ptr(gssapi_encrypt->gssapi_encrypted_tvb, 0, length); + length=tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); + original_data=tvb_get_ptr(gssapi_encrypt->gssapi_encrypted_tvb, 0, length); - /* don't do anything if we are not attempting to decrypt data */ + /* don't do anything if we are not attempting to decrypt data */ /* - if(!krb_decrypt){ - return; - } + if(!krb_decrypt){ + return; + } */ - /* XXX we should only do this for first time, then store somewhere */ - /* XXX We also need to re-read the keytab when the preference changes */ - - cryptocopy=(guint8 *)wmem_alloc(wmem_packet_scope(), length); - output_message_buffer=(guint8 *)wmem_alloc(pinfo->pool, length); - - for(ek=enc_key_list;ek;ek=ek->next){ - /* shortcircuit and bail out if enctypes are not matching */ - if(ek->keytype!=keytype){ - continue; - } - - /* pre-0.6.1 versions of Heimdal would sometimes change - the cryptotext data even when the decryption failed. - This would obviously not work since we iterate over the - keys. So just give it a copy of the crypto data instead. - This has been seen for RC4-HMAC blobs. - */ - memcpy(cryptocopy, original_data, length); - ret=decrypt_arcfour(gssapi_encrypt, - cryptocopy, - output_message_buffer, - ek->keyvalue, - ek->keylength, - ek->keytype); - if (ret >= 0) { - expert_add_info_format(pinfo, NULL, &ei_spnego_decrypted_keytype, - "Decrypted keytype %d in frame %u using %s", - ek->keytype, pinfo->num, ek->key_origin); - - gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb, - output_message_buffer, - ret, ret); - add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); - return; - } - } + /* XXX we should only do this for first time, then store somewhere */ + /* XXX We also need to re-read the keytab when the preference changes */ + + cryptocopy=(guint8 *)wmem_alloc(wmem_packet_scope(), length); + output_message_buffer=(guint8 *)wmem_alloc(pinfo->pool, length); + + for(ek=enc_key_list;ek;ek=ek->next){ + /* shortcircuit and bail out if enctypes are not matching */ + if(ek->keytype!=keytype){ + continue; + } + + /* pre-0.6.1 versions of Heimdal would sometimes change + the cryptotext data even when the decryption failed. + This would obviously not work since we iterate over the + keys. So just give it a copy of the crypto data instead. + This has been seen for RC4-HMAC blobs. + */ + memcpy(cryptocopy, original_data, length); + ret=decrypt_arcfour(gssapi_encrypt, + cryptocopy, + output_message_buffer, + ek->keyvalue, + ek->keylength, + ek->keytype); + if (ret >= 0) { + expert_add_info_format(pinfo, NULL, &ei_spnego_decrypted_keytype, + "Decrypted keytype %d in frame %u using %s", + ek->keytype, pinfo->num, ek->key_origin); + + gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb, output_message_buffer, ret, ret); + add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); + return; + } + } } /* borrowed from heimdal */ static int rrc_rotate(guint8 *data, int len, guint16 rrc, int unrotate) { - guint8 *tmp, buf[256]; - size_t left; + guint8 *tmp, buf[256]; + size_t left; - if (len == 0) - return 0; + if (len == 0) + return 0; - rrc %= len; + rrc %= len; - if (rrc == 0) - return 0; + if (rrc == 0) + return 0; - left = len - rrc; + left = len - rrc; - if (rrc <= sizeof(buf)) { - tmp = buf; - } else { - tmp = (guint8 *)g_malloc(rrc); - if (tmp == NULL) - return -1; - } + if (rrc <= sizeof(buf)) { + tmp = buf; + } else { + tmp = (guint8 *)g_malloc(rrc); + if (tmp == NULL) + return -1; + } - if (unrotate) { - memcpy(tmp, data, rrc); - memmove(data, data + rrc, left); - memcpy(data + left, tmp, rrc); - } else { - memcpy(tmp, data + left, rrc); - memmove(data + rrc, data, left); - memcpy(data, tmp, rrc); - } + if (unrotate) { + memcpy(tmp, data, rrc); + memmove(data, data + rrc, left); + memcpy(data + left, tmp, rrc); + } else { + memcpy(tmp, data + left, rrc); + memmove(data + rrc, data, left); + memcpy(data, tmp, rrc); + } - if (rrc > sizeof(buf)) - g_free(tmp); + if (rrc > sizeof(buf)) + g_free(tmp); - return 0; + return 0; } -#define KRB5_KU_USAGE_ACCEPTOR_SEAL 22 -#define KRB5_KU_USAGE_ACCEPTOR_SIGN 23 -#define KRB5_KU_USAGE_INITIATOR_SEAL 24 -#define KRB5_KU_USAGE_INITIATOR_SIGN 25 +#define KRB5_KU_USAGE_ACCEPTOR_SEAL 22 +#define KRB5_KU_USAGE_ACCEPTOR_SIGN 23 +#define KRB5_KU_USAGE_INITIATOR_SEAL 24 +#define KRB5_KU_USAGE_INITIATOR_SIGN 25 static void decrypt_gssapi_krb_cfx_wrap(proto_tree *tree, - packet_info *pinfo, - tvbuff_t *checksum_tvb, - gssapi_encrypt_info_t* gssapi_encrypt, - guint16 ec, - guint16 rrc, - int keytype, - unsigned int usage) + packet_info *pinfo, + tvbuff_t *checksum_tvb, + gssapi_encrypt_info_t* gssapi_encrypt, + guint16 ec, + guint16 rrc, + int keytype, + unsigned int usage) { - guint8 *rotated; - guint8 *output; - int datalen; - tvbuff_t *next_tvb; - - /* don't do anything if we are not attempting to decrypt data */ - if(!krb_decrypt){ - return; - } + guint8 *rotated; + guint8 *output; + int datalen; + tvbuff_t *next_tvb; + + /* don't do anything if we are not attempting to decrypt data */ + if(!krb_decrypt){ + return; + } - datalen = tvb_captured_length(checksum_tvb) + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); + datalen = tvb_captured_length(checksum_tvb) + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); - rotated = (guint8 *)wmem_alloc(pinfo->pool, datalen); + rotated = (guint8 *)wmem_alloc(pinfo->pool, datalen); - tvb_memcpy(checksum_tvb, rotated, - 0, tvb_captured_length(checksum_tvb)); - tvb_memcpy(gssapi_encrypt->gssapi_encrypted_tvb, rotated + tvb_captured_length(checksum_tvb), - 0, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); + tvb_memcpy(checksum_tvb, rotated, 0, tvb_captured_length(checksum_tvb)); + tvb_memcpy(gssapi_encrypt->gssapi_encrypted_tvb, rotated + tvb_captured_length(checksum_tvb), + 0, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); - if (gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE) { - rrc += ec; - } + if (gssapi_encrypt->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE) { + rrc += ec; + } - rrc_rotate(rotated, datalen, rrc, TRUE); + rrc_rotate(rotated, datalen, rrc, TRUE); - next_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, rotated, - datalen, datalen); - add_new_data_source(pinfo, next_tvb, "GSSAPI CFX"); + next_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, rotated, + datalen, datalen); + add_new_data_source(pinfo, next_tvb, "GSSAPI CFX"); - output = decrypt_krb5_data(tree, pinfo, usage, next_tvb, - keytype, &datalen); + output = decrypt_krb5_data(tree, pinfo, usage, next_tvb, keytype, &datalen); - if (output) { - guint8 *outdata; + if (output) { + guint8 *outdata; - outdata = (guint8 *)wmem_memdup(pinfo->pool, output, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); + outdata = (guint8 *)wmem_memdup(pinfo->pool, output, tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); - gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, - outdata, - tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb), - tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); - add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); - } + gssapi_encrypt->gssapi_decrypted_tvb=tvb_new_child_real_data(gssapi_encrypt->gssapi_encrypted_tvb, + outdata, + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb), + tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb)); + add_new_data_source(pinfo, gssapi_encrypt->gssapi_decrypted_tvb, "Decrypted GSS-Krb5"); + } } #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */ @@ -1192,130 +1161,125 @@ decrypt_gssapi_krb_cfx_wrap(proto_tree *tree, static int dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo #ifndef HAVE_KERBEROS - _U_ + _U_ #endif , proto_tree *tree, guint16 token_id #ifndef HAVE_KERBEROS - _U_ + _U_ #endif - , gssapi_encrypt_info_t* gssapi_encrypt - ) + , gssapi_encrypt_info_t* gssapi_encrypt + ) { - guint16 sgn_alg, seal_alg; + guint16 sgn_alg, seal_alg; #ifdef HAVE_KERBEROS - int start_offset=offset; + int start_offset=offset; #endif - /* - * The KRB5 blob conforms to RFC1964: - * USHORT (0x0102 == GSS_Wrap) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC1964: + * USHORT (0x0102 == GSS_Wrap) + * and so on } + */ - /* Now, the sign and seal algorithms ... */ + /* 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); + sgn_alg = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2, sgn_alg); - offset += 2; + offset += 2; - seal_alg = tvb_get_letohs(tvb, offset); - proto_tree_add_uint(tree, hf_spnego_krb5_seal_alg, tvb, offset, 2, - seal_alg); + seal_alg = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_spnego_krb5_seal_alg, tvb, offset, 2, seal_alg); - offset += 2; + offset += 2; - /* Skip the filler */ + /* Skip the filler */ - offset += 2; + offset += 2; - /* Encrypted sequence number */ + /* Encrypted sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, ENC_NA); - offset += 8; + offset += 8; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, ENC_NA); - offset += 8; + 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) || - /* there also seems to be a confounder for DES MAC MD5 - certainly seen when using with - SASL with LDAP between a Java client and Active Directory. If this breaks other things - we may need to make this an option. gal 17/2/06 */ - (sgn_alg == KRB_SGN_ALG_DES_MAC_MD5)) { - proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, - ENC_NA); - 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) || + /* there also seems to be a confounder for DES MAC MD5 - certainly seen when using with + SASL with LDAP between a Java client and Active Directory. If this breaks other things + we may need to make this an option. gal 17/2/06 */ + (sgn_alg == KRB_SGN_ALG_DES_MAC_MD5)) { + proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, ENC_NA); + offset += 8; + } - /* Is the data encrypted? */ - if (gssapi_encrypt != NULL) - gssapi_encrypt->gssapi_data_encrypted=(seal_alg!=KRB_SEAL_ALG_NONE); + /* Is the data encrypted? */ + if (gssapi_encrypt != NULL) + gssapi_encrypt->gssapi_data_encrypted=(seal_alg!=KRB_SEAL_ALG_NONE); #ifdef HAVE_KERBEROS #define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32 - if(gssapi_encrypt && gssapi_encrypt->decrypt_gssapi_tvb){ - /* if the caller did not provide a tvb, then we just use - whatever is left of our current tvb. - */ - if(!gssapi_encrypt->gssapi_encrypted_tvb){ - int len; - len=tvb_reported_length_remaining(tvb,offset); - if(len>tvb_captured_length_remaining(tvb, offset)){ - /* no point in trying to decrypt, - we don't have the full pdu. - */ - return offset; - } - gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset_length( - tvb, offset, len); - } - - /* if this is KRB5 wrapped rc4-hmac */ - if((token_id==KRB_TOKEN_WRAP) - &&(sgn_alg==KRB_SGN_ALG_HMAC) - &&(seal_alg==KRB_SEAL_ALG_RC4)){ - /* do we need to create a tvb for the wrapper - as well ? - */ - if(!gssapi_encrypt->gssapi_wrap_tvb){ - gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( - tvb, start_offset-2, - GSS_ARCFOUR_WRAP_TOKEN_SIZE); - } + if(gssapi_encrypt && gssapi_encrypt->decrypt_gssapi_tvb){ + /* if the caller did not provide a tvb, then we just use + whatever is left of our current tvb. + */ + if(!gssapi_encrypt->gssapi_encrypted_tvb){ + int len; + len=tvb_reported_length_remaining(tvb,offset); + if(len>tvb_captured_length_remaining(tvb, offset)){ + /* no point in trying to decrypt, + we don't have the full pdu. + */ + return offset; + } + gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset_length( + tvb, offset, len); + } + + /* if this is KRB5 wrapped rc4-hmac */ + if((token_id==KRB_TOKEN_WRAP) + &&(sgn_alg==KRB_SGN_ALG_HMAC) + &&(seal_alg==KRB_SEAL_ALG_RC4)){ + /* do we need to create a tvb for the wrapper + as well ? + */ + if(!gssapi_encrypt->gssapi_wrap_tvb){ + gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( + tvb, start_offset-2, + GSS_ARCFOUR_WRAP_TOKEN_SIZE); + } #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - decrypt_gssapi_krb_arcfour_wrap(tree, - pinfo, - tvb, - KEYTYPE_ARCFOUR_HMAC, - gssapi_encrypt); + decrypt_gssapi_krb_arcfour_wrap(tree, + pinfo, + tvb, + KEYTYPE_ARCFOUR_HMAC, + gssapi_encrypt); #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */ - } - } + } + } #endif - /* - * 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; + /* + * 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; } /* @@ -1324,84 +1288,80 @@ dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo static int dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { - guint16 sgn_alg; + guint16 sgn_alg; - /* - * The KRB5 blob conforms to RFC1964: - * USHORT (0x0101 == GSS_GetMIC) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC1964: + * USHORT (0x0101 == GSS_GetMIC) + * and so on } + */ - /* Now, the sign algorithm ... */ + /* 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); + sgn_alg = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2, sgn_alg); - offset += 2; + offset += 2; - /* Skip the filler */ + /* Skip the filler */ - offset += 4; + offset += 4; - /* Encrypted sequence number */ + /* Encrypted sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8, ENC_NA); - offset += 8; + offset += 8; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, - ENC_NA); + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8, ENC_NA); - offset += 8; + 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.... - * - * The exception is DNS/TSIG where there is no such confounder - * so we need to test here if there are more bytes in our tvb or not. - * -- ronnie - */ - if (tvb_reported_length_remaining(tvb, offset)) { - if (sgn_alg == KRB_SGN_ALG_HMAC) { - proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, - ENC_NA); + /* + * 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.... + * + * The exception is DNS/TSIG where there is no such confounder + * so we need to test here if there are more bytes in our tvb or not. + * -- ronnie + */ + if (tvb_reported_length_remaining(tvb, offset)) { + if (sgn_alg == KRB_SGN_ALG_HMAC) { + proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8, ENC_NA); - offset += 8; - } - } + 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 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; + return offset; } static int dissect_spnego_krb5_cfx_flags(tvbuff_t *tvb, int offset, - proto_tree *spnego_krb5_tree, - guint8 cfx_flags _U_) + proto_tree *spnego_krb5_tree, + guint8 cfx_flags _U_) { - static const int * flags[] = { - &hf_spnego_krb5_cfx_flags_04, - &hf_spnego_krb5_cfx_flags_02, - &hf_spnego_krb5_cfx_flags_01, - NULL - }; - - proto_tree_add_bitmask(spnego_krb5_tree, tvb, offset, hf_spnego_krb5_cfx_flags, ett_spnego_krb5_cfx_flags, flags, ENC_NA); - return (offset + 1); + static const int * flags[] = { + &hf_spnego_krb5_cfx_flags_04, + &hf_spnego_krb5_cfx_flags_02, + &hf_spnego_krb5_cfx_flags_01, + NULL + }; + + proto_tree_add_bitmask(spnego_krb5_tree, tvb, offset, hf_spnego_krb5_cfx_flags, ett_spnego_krb5_cfx_flags, flags, ENC_NA); + return (offset + 1); } /* @@ -1410,183 +1370,176 @@ dissect_spnego_krb5_cfx_flags(tvbuff_t *tvb, int offset, static int dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo #ifndef HAVE_KERBEROS - _U_ + _U_ #endif - , proto_tree *tree, guint16 token_id _U_ - , gssapi_encrypt_info_t* gssapi_encrypt - ) + , proto_tree *tree, guint16 token_id _U_ + , gssapi_encrypt_info_t* gssapi_encrypt + ) { - guint8 flags; - guint16 ec; + guint8 flags; + guint16 ec; #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - guint16 rrc; + guint16 rrc; #endif - int checksum_size; - int start_offset=offset; + int checksum_size; + int start_offset=offset; - /* - * The KRB5 blob conforms to RFC4121: - * USHORT (0x0504) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC4121: + * USHORT (0x0504) + * and so on } + */ - /* Now, the sign and seal algorithms ... */ + /* Now, the sign and seal algorithms ... */ - flags = tvb_get_guint8(tvb, offset); - offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags); + flags = tvb_get_guint8(tvb, offset); + offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags); - if (gssapi_encrypt != NULL) - gssapi_encrypt->gssapi_data_encrypted=(flags & 2); + if (gssapi_encrypt != NULL) + gssapi_encrypt->gssapi_data_encrypted=(flags & 2); - /* Skip the filler */ + /* Skip the filler */ - proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 1, - ENC_NA); - offset += 1; + proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 1, ENC_NA); + offset += 1; - /* EC */ - ec = tvb_get_ntohs(tvb, offset); - proto_tree_add_item(tree, hf_spnego_krb5_cfx_ec, tvb, offset, 2, - ENC_BIG_ENDIAN); - offset += 2; + /* EC */ + ec = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_spnego_krb5_cfx_ec, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; - /* RRC */ + /* RRC */ #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - rrc = tvb_get_ntohs(tvb, offset); + rrc = tvb_get_ntohs(tvb, offset); #endif - proto_tree_add_item(tree, hf_spnego_krb5_cfx_rrc, tvb, offset, 2, - ENC_BIG_ENDIAN); - offset += 2; + proto_tree_add_item(tree, hf_spnego_krb5_cfx_rrc, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; - /* sequence number */ + /* sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, - ENC_BIG_ENDIAN); - offset += 8; + proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, ENC_BIG_ENDIAN); + offset += 8; - if (gssapi_encrypt == NULL) /* Probably shoudn't happen, but just protect ourselves */ - return offset; + if (gssapi_encrypt == NULL) /* Probably shoudn't happen, but just protect ourselves */ + return offset; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - if (gssapi_encrypt->gssapi_data_encrypted) { - checksum_size = 44 + ec; + if (gssapi_encrypt->gssapi_data_encrypted) { + checksum_size = 44 + ec; - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, - checksum_size, ENC_NA); - offset += checksum_size; + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + offset += checksum_size; - } else { - int returned_offset; - int inner_token_len = 0; + } else { + int returned_offset; + int inner_token_len = 0; - /* - * We know we have a wrap token, but we have to let the proto - * above us decode that, so hand it back in gssapi_wrap_tvb - * and put the checksum in the tree. - */ + /* + * We know we have a wrap token, but we have to let the proto + * above us decode that, so hand it back in gssapi_wrap_tvb + * and put the checksum in the tree. + */ - checksum_size = ec; + checksum_size = ec; - inner_token_len = tvb_reported_length_remaining(tvb, offset); - if (inner_token_len > ec) { - inner_token_len -= ec; - } + inner_token_len = tvb_reported_length_remaining(tvb, offset); + if (inner_token_len > ec) { + inner_token_len -= ec; + } - /* - * We handle only the two common cases for now - * (rrc == 0 and rrc == ec) - */ + /* + * We handle only the two common cases for now + * (rrc == 0 and rrc == ec) + */ #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - if (rrc == ec) { - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, - tvb, offset, checksum_size, ENC_NA); - offset += checksum_size; - } + if (rrc == ec) { + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + offset += checksum_size; + } #endif - returned_offset = offset; - gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset, - inner_token_len); + returned_offset = offset; + gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset, + inner_token_len); - offset += inner_token_len; + offset += inner_token_len; #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) - if (rrc == 0) + if (rrc == 0) #endif - { - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, - tvb, offset, checksum_size, ENC_NA); - } - - /* - * Return an offset that puts our caller before the inner - * token. This is better than before, but we still see the - * checksum included in the LDAP query at times. - */ - return returned_offset; - } - - if(gssapi_encrypt->decrypt_gssapi_tvb){ - /* if the caller did not provide a tvb, then we just use - whatever is left of our current tvb. - */ - if(!gssapi_encrypt->gssapi_encrypted_tvb){ - int len; - len=tvb_reported_length_remaining(tvb,offset); - if(len>tvb_captured_length_remaining(tvb, offset)){ - /* no point in trying to decrypt, - we don't have the full pdu. - */ - return offset; - } - gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset( - tvb, offset, len, len); - } - - if (gssapi_encrypt->gssapi_data_encrypted) { - /* do we need to create a tvb for the wrapper - as well ? - */ - if(!gssapi_encrypt->gssapi_wrap_tvb){ - gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( - tvb, start_offset-2, - offset - (start_offset-2)); - } - } - } + { + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + } + + /* + * Return an offset that puts our caller before the inner + * token. This is better than before, but we still see the + * checksum included in the LDAP query at times. + */ + return returned_offset; + } + + if(gssapi_encrypt->decrypt_gssapi_tvb){ + /* if the caller did not provide a tvb, then we just use + whatever is left of our current tvb. + */ + if(!gssapi_encrypt->gssapi_encrypted_tvb){ + int len; + len=tvb_reported_length_remaining(tvb,offset); + if(len>tvb_captured_length_remaining(tvb, offset)){ + /* no point in trying to decrypt, + we don't have the full pdu. + */ + return offset; + } + gssapi_encrypt->gssapi_encrypted_tvb = tvb_new_subset( + tvb, offset, len, len); + } + + if (gssapi_encrypt->gssapi_data_encrypted) { + /* do we need to create a tvb for the wrapper + as well ? + */ + if(!gssapi_encrypt->gssapi_wrap_tvb){ + gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length( + tvb, start_offset-2, + offset - (start_offset-2)); + } + } + } #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) { - tvbuff_t *checksum_tvb = tvb_new_subset_length(tvb, 16, checksum_size); - - if (gssapi_encrypt->gssapi_data_encrypted) { - if(gssapi_encrypt->gssapi_encrypted_tvb){ - decrypt_gssapi_krb_cfx_wrap(tree, - pinfo, - checksum_tvb, - gssapi_encrypt, - ec, - rrc, - -1, - (flags & 0x0001)? - KRB5_KU_USAGE_ACCEPTOR_SEAL: - KRB5_KU_USAGE_INITIATOR_SEAL); - } - } + tvbuff_t *checksum_tvb = tvb_new_subset_length(tvb, 16, checksum_size); + + if (gssapi_encrypt->gssapi_data_encrypted) { + if(gssapi_encrypt->gssapi_encrypted_tvb){ + decrypt_gssapi_krb_cfx_wrap(tree, + pinfo, + checksum_tvb, + gssapi_encrypt, + ec, + rrc, + -1, + (flags & 0x0001)? + KRB5_KU_USAGE_ACCEPTOR_SEAL: + KRB5_KU_USAGE_INITIATOR_SEAL); + } + } } #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */ - /* - * 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; + /* + * 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; } /* @@ -1595,46 +1548,43 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo 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; + guint8 flags; + int checksum_size; - /* - * The KRB5 blob conforms to RFC4121: - * USHORT (0x0404 == GSS_GetMIC) - * and so on } - */ + /* + * 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); + flags = tvb_get_guint8(tvb, offset); + offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags); - /* Skip the filler */ + /* Skip the filler */ - proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 5, - ENC_NA); - offset += 5; + proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 5, ENC_NA); + offset += 5; - /* sequence number */ + /* sequence number */ - proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, - ENC_BIG_ENDIAN); - offset += 8; + proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8, ENC_BIG_ENDIAN); + offset += 8; - /* Checksum of plaintext padded data */ + /* Checksum of plaintext padded data */ - checksum_size = tvb_captured_length_remaining(tvb, offset); + checksum_size = tvb_captured_length_remaining(tvb, offset); - proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, - checksum_size, ENC_NA); - offset += checksum_size; + proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, checksum_size, ENC_NA); + 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 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; + return offset; } /* @@ -1647,60 +1597,59 @@ dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinf static int dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - guint16 token_id; - gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; + proto_item *item; + proto_tree *subtree; + int offset = 0; + guint16 token_id; + gssapi_encrypt_info_t* encrypt_info = (gssapi_encrypt_info_t*)data; - item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, ENC_NA); + item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, ENC_NA); - subtree = proto_item_add_subtree(item, ett_spnego_krb5); + subtree = proto_item_add_subtree(item, ett_spnego_krb5); - /* - * The KRB5 blob conforms to RFC1964: - * USHORT (0x0102 == GSS_Wrap) - * and so on } - */ + /* + * The KRB5 blob conforms to RFC1964: + * USHORT (0x0102 == GSS_Wrap) + * and so on } + */ - /* First, the token ID ... */ + /* First, 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); + token_id = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2, token_id); - offset += 2; + offset += 2; - switch (token_id) { - case KRB_TOKEN_GETMIC: - offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree); - break; + 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, encrypt_info); - break; + case KRB_TOKEN_WRAP: + offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id, encrypt_info); + break; - case KRB_TOKEN_CFX_GETMIC: - offset = dissect_spnego_krb5_cfx_getmic_base(tvb, offset, pinfo, subtree); - 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, encrypt_info); - break; + case KRB_TOKEN_CFX_WRAP: + offset = dissect_spnego_krb5_cfx_wrap_base(tvb, offset, pinfo, subtree, token_id, encrypt_info); + break; - default: + default: - break; - } + break; + } - /* - * 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; + /* + * 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 */ @@ -1708,167 +1657,164 @@ dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree static int dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - asn1_ctx_t asn1_ctx; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + proto_item *item; + proto_tree *subtree; + int offset = 0; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - MechType_oid = NULL; + MechType_oid = NULL; - /* - * 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. - */ + /* + * 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. + */ - item = proto_tree_add_item(tree, proto_spnego, tvb, offset, - -1, ENC_NA); + item = proto_tree_add_item(tree, proto_spnego, tvb, offset, -1, ENC_NA); - 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 code addet to spnego.asn to handle this. - */ + 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 code addet to spnego.asn to handle this. + */ - offset = dissect_spnego_InitialContextToken(FALSE, tvb, offset, &asn1_ctx , subtree, -1); + offset = dissect_spnego_InitialContextToken(FALSE, tvb, offset, &asn1_ctx , subtree, -1); - return offset; + return offset; } static int dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_) { - proto_item *item; - proto_tree *subtree; - int offset = 0; - conversation_t *conversation; - asn1_ctx_t asn1_ctx; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - - /* - * 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 = (gssapi_oid_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0); - 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->num, &pinfo->src, &pinfo->dst, - pinfo->ptype, pinfo->srcport, - pinfo->destport, 0); - - if (conversation) { - next_level_value = (gssapi_oid_value *)conversation_get_proto_data(conversation, - proto_spnego); - if (next_level_value) - p_add_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0, next_level_value); - } - } - - item = proto_tree_add_item(parent_tree, proto_spnego, tvb, offset, - -1, ENC_NA); - - 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. - * - */ - dissect_spnego_NegotiationToken(FALSE, tvb, offset, &asn1_ctx, subtree, -1); - return tvb_captured_length(tvb); + proto_item *item; + proto_tree *subtree; + int offset = 0; + conversation_t *conversation; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + /* + * 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 = (gssapi_oid_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0); + 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->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + + if (conversation) { + next_level_value = (gssapi_oid_value *)conversation_get_proto_data(conversation, proto_spnego); + if (next_level_value) + p_add_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0, next_level_value); + } + } + + item = proto_tree_add_item(parent_tree, proto_spnego, tvb, offset, -1, ENC_NA); + + 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. + * + */ + dissect_spnego_NegotiationToken(FALSE, tvb, offset, &asn1_ctx, subtree, -1); + return tvb_captured_length(tvb); } /*--- proto_register_spnego -------------------------------------------*/ void proto_register_spnego(void) { - /* List of fields */ - static hf_register_info hf[] = { - { &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, NULL, HFILL }}, - { &hf_spnego_krb5_oid, - { "KRB5 OID", "spnego.krb5_oid", FT_STRING, - BASE_NONE, NULL, 0, NULL, 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}}, - { &hf_spnego_krb5_filler, - { "krb5_filler", "spnego.krb5.filler", FT_BYTES, BASE_NONE, - 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 (&tfs_set_notset), 0x01, NULL, HFILL}}, - { &hf_spnego_krb5_cfx_flags_02, - { "Sealed", "spnego.krb5.sealed", FT_BOOLEAN, 8, - TFS (&tfs_set_notset), 0x02, NULL, HFILL}}, - { &hf_spnego_krb5_cfx_flags_04, - { "AcceptorSubkey", "spnego.krb5.acceptor_subkey", FT_BOOLEAN, 8, - TFS (&tfs_set_notset), 0x04, NULL, 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}}, + /* List of fields */ + static hf_register_info hf[] = { + { &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, NULL, HFILL }}, + { &hf_spnego_krb5_oid, + { "KRB5 OID", "spnego.krb5_oid", FT_STRING, + BASE_NONE, NULL, 0, NULL, 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}}, + { &hf_spnego_krb5_filler, + { "krb5_filler", "spnego.krb5.filler", FT_BYTES, BASE_NONE, + 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 (&tfs_set_notset), 0x01, NULL, HFILL}}, + { &hf_spnego_krb5_cfx_flags_02, + { "Sealed", "spnego.krb5.sealed", FT_BOOLEAN, 8, + TFS (&tfs_set_notset), 0x02, NULL, HFILL}}, + { &hf_spnego_krb5_cfx_flags_04, + { "AcceptorSubkey", "spnego.krb5.acceptor_subkey", FT_BOOLEAN, 8, + TFS (&tfs_set_notset), 0x04, NULL, 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}}, /*--- Included file: packet-spnego-hfarr.c ---*/ @@ -1967,15 +1913,15 @@ void proto_register_spnego(void) { NULL, HFILL }}, /*--- End of included file: packet-spnego-hfarr.c ---*/ -#line 1422 "./asn1/spnego/packet-spnego-template.c" - }; +#line 1368 "./asn1/spnego/packet-spnego-template.c" + }; - /* List of subtrees */ - static gint *ett[] = { - &ett_spnego, - &ett_spnego_wraptoken, - &ett_spnego_krb5, - &ett_spnego_krb5_cfx_flags, + /* List of subtrees */ + static gint *ett[] = { + &ett_spnego, + &ett_spnego_wraptoken, + &ett_spnego_krb5, + &ett_spnego_krb5_cfx_flags, /*--- Included file: packet-spnego-ettarr.c ---*/ @@ -1990,65 +1936,76 @@ void proto_register_spnego(void) { &ett_spnego_InitialContextToken_U, /*--- End of included file: packet-spnego-ettarr.c ---*/ -#line 1432 "./asn1/spnego/packet-spnego-template.c" - }; +#line 1378 "./asn1/spnego/packet-spnego-template.c" + }; - static ei_register_info ei[] = { - { &ei_spnego_decrypted_keytype, { "spnego.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }}, - { &ei_spnego_unknown_header, { "spnego.unknown_header", PI_PROTOCOL, PI_WARN, "Unknown header", EXPFILL }}, - }; + static ei_register_info ei[] = { + { &ei_spnego_decrypted_keytype, { "spnego.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }}, + { &ei_spnego_unknown_header, { "spnego.unknown_header", PI_PROTOCOL, PI_WARN, "Unknown header", EXPFILL }}, + }; - expert_module_t* expert_spnego; + expert_module_t* expert_spnego; - /* Register protocol */ - proto_spnego = proto_register_protocol(PNAME, PSNAME, PFNAME); + /* Register protocol */ + proto_spnego = proto_register_protocol(PNAME, PSNAME, PFNAME); - spnego_handle = register_dissector("spnego", dissect_spnego, proto_spnego); + spnego_handle = register_dissector("spnego", dissect_spnego, proto_spnego); - proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5", - "SPNEGO-KRB5", - "spnego-krb5"); + proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5", "SPNEGO-KRB5", "spnego-krb5"); - spnego_krb5_handle = register_dissector("spnego-krb5", dissect_spnego_krb5, proto_spnego_krb5); - spnego_krb5_wrap_handle = register_dissector("spnego-krb5-wrap", dissect_spnego_krb5_wrap, proto_spnego_krb5); + spnego_krb5_handle = register_dissector("spnego-krb5", dissect_spnego_krb5, proto_spnego_krb5); + spnego_krb5_wrap_handle = 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)); - expert_spnego = expert_register_protocol(proto_spnego); - expert_register_field_array(expert_spnego, ei, array_length(ei)); + /* Register fields and subtrees */ + proto_register_field_array(proto_spnego, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + expert_spnego = expert_register_protocol(proto_spnego); + expert_register_field_array(expert_spnego, ei, array_length(ei)); } /*--- proto_reg_handoff_spnego ---------------------------------------*/ void proto_reg_handoff_spnego(void) { - dissector_handle_t spnego_wrap_handle; - - /* Register protocol with GSS-API module */ - - spnego_wrap_handle = 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. - */ - 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"); + dissector_handle_t spnego_wrap_handle; + + /* Register protocol with GSS-API module */ + + spnego_wrap_handle = 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. + */ + 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"); } + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 2 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=2 tabstop=8 expandtab: + * :indentSize=2:tabSize=8:noTabs=true: + */ |