2 * Routines for Kerberos
3 * Wes Hardaker (c) 2000
4 * wjhardaker@ucdavis.edu
5 * Richard Sharpe (C) 2002, rsharpe@samba.org, modularized a bit more and
6 * added AP-REQ and AP-REP dissection
8 * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API.
9 * decryption of kerberos blobs if keytab is provided
11 * See RFC 1510, and various I-Ds and other documents showing additions,
12 * e.g. ones listed under
14 * http://www.isi.edu/people/bcn/krb-revisions/
18 * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-07.txt
22 * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-referrals-05.txt
24 * Some structures from RFC2630
26 * Wireshark - Network traffic analyzer
27 * By Gerald Combs <gerald@wireshark.org>
28 * Copyright 1998 Gerald Combs
30 * SPDX-License-Identifier: GPL-2.0-or-later
34 * Some of the development of the Kerberos protocol decoder was sponsored by
35 * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
36 * CableLabs' specifications. Your license and use of this protocol decoder
37 * does not mean that you are licensed to use the CableLabs'
38 * specifications. If you have questions about this protocol, contact
39 * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
47 #include <epan/packet.h>
48 #include <epan/exceptions.h>
49 #include <epan/strutil.h>
50 #include <epan/conversation.h>
51 #include <epan/asn1.h>
52 #include <epan/expert.h>
53 #include <epan/prefs.h>
54 #include <wsutil/wsgcrypt.h>
55 #include <wsutil/file_util.h>
56 #include <wsutil/str_util.h>
57 #include "packet-kerberos.h"
58 #include "packet-netbios.h"
59 #include "packet-tcp.h"
60 #include "packet-ber.h"
61 #include "packet-pkinit.h"
62 #include "packet-cms.h"
63 #include "packet-windows-common.h"
65 #include "read_keytab_file.h"
67 #include "packet-dcerpc-netlogon.h"
68 #include "packet-dcerpc.h"
70 #include "packet-gssapi.h"
71 #include "packet-smb-common.h"
73 #define KEY_USAGE_FAST_REQ_CHKSUM 50
74 #define KEY_USAGE_FAST_ENC 51
75 #define KEY_USAGE_FAST_REP 52
76 #define KEY_USAGE_FAST_FINISHED 53
77 #define KEY_USAGE_ENC_CHALLENGE_CLIENT 54
78 #define KEY_USAGE_ENC_CHALLENGE_KDC 55
80 void proto_register_kerberos(void);
81 void proto_reg_handoff_kerberos(void);
83 #define UDP_PORT_KERBEROS 88
84 #define TCP_PORT_KERBEROS 88
86 #define ADDRESS_STR_BUFSIZ 256
88 typedef struct kerberos_key {
91 const guint8 *keyvalue;
95 gboolean kdc_response_initialized;
96 gboolean kdc_response;
103 guint32 checksum_type;
105 gboolean fast_armor_request;
106 gboolean fast_armor_within_enc_ticket_part;
107 gboolean fast_armor_ticket_sessionkey_needed;
108 const enc_key_t *fast_armor_ticket_sessionkey;
109 gboolean fast_armor_within_authenticator;
110 gboolean fast_armor_remote_subkey_needed;
111 const enc_key_t *fast_armor_remote_subkey;
112 } kerberos_private_data_t;
114 static dissector_handle_t kerberos_handle_udp;
116 /* Forward declarations */
117 static int dissect_kerberos_Applications(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
118 static int dissect_kerberos_PA_ENC_TIMESTAMP(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
119 static int dissect_kerberos_PA_ENC_TS_ENC(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
120 static int dissect_kerberos_KERB_PA_PAC_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
121 static int dissect_kerberos_PA_S4U2Self(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
122 static int dissect_kerberos_ETYPE_INFO(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
123 static int dissect_kerberos_ETYPE_INFO2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
124 static int dissect_kerberos_AD_IF_RELEVANT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
125 static int dissect_kerberos_PA_AUTHENTICATION_SET_ELEM(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
126 static int dissect_kerberos_PA_FX_FAST_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
127 static int dissect_kerberos_PA_FX_FAST_REPLY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
128 static int dissect_kerberos_KrbFastReq(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
129 static int dissect_kerberos_KrbFastResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
130 static int dissect_kerberos_EncryptedChallenge(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
131 static int dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
132 static int dissect_kerberos_PA_PAC_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
133 static int dissect_kerberos_KERB_AD_RESTRICTION_ENTRY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
134 static int dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
135 static int dissect_kerberos_Checksum(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
137 /* Desegment Kerberos over TCP messages */
138 static gboolean krb_desegment = TRUE;
140 static gint proto_kerberos = -1;
142 static gint hf_krb_rm_reserved = -1;
143 static gint hf_krb_rm_reclen = -1;
144 static gint hf_krb_provsrv_location = -1;
145 static gint hf_krb_smb_nt_status = -1;
146 static gint hf_krb_smb_unknown = -1;
147 static gint hf_krb_address_ip = -1;
148 static gint hf_krb_address_netbios = -1;
149 static gint hf_krb_address_ipv6 = -1;
150 static gint hf_krb_gssapi_len = -1;
151 static gint hf_krb_gssapi_bnd = -1;
152 static gint hf_krb_gssapi_dlgopt = -1;
153 static gint hf_krb_gssapi_dlglen = -1;
154 static gint hf_krb_gssapi_c_flag_deleg = -1;
155 static gint hf_krb_gssapi_c_flag_mutual = -1;
156 static gint hf_krb_gssapi_c_flag_replay = -1;
157 static gint hf_krb_gssapi_c_flag_sequence = -1;
158 static gint hf_krb_gssapi_c_flag_conf = -1;
159 static gint hf_krb_gssapi_c_flag_integ = -1;
160 static gint hf_krb_gssapi_c_flag_dce_style = -1;
161 static gint hf_krb_midl_version = -1;
162 static gint hf_krb_midl_hdr_len = -1;
163 static gint hf_krb_midl_fill_bytes = -1;
164 static gint hf_krb_midl_blob_len = -1;
165 static gint hf_krb_pac_signature_type = -1;
166 static gint hf_krb_pac_signature_signature = -1;
167 static gint hf_krb_w2k_pac_entries = -1;
168 static gint hf_krb_w2k_pac_version = -1;
169 static gint hf_krb_w2k_pac_type = -1;
170 static gint hf_krb_w2k_pac_size = -1;
171 static gint hf_krb_w2k_pac_offset = -1;
172 static gint hf_krb_pac_clientid = -1;
173 static gint hf_krb_pac_namelen = -1;
174 static gint hf_krb_pac_clientname = -1;
175 static gint hf_krb_pac_logon_info = -1;
176 static gint hf_krb_pac_credential_type = -1;
177 static gint hf_krb_pac_s4u_delegation_info = -1;
178 static gint hf_krb_pac_upn_dns_info = -1;
179 static gint hf_krb_pac_upn_flags = -1;
180 static gint hf_krb_pac_upn_dns_offset = -1;
181 static gint hf_krb_pac_upn_dns_len = -1;
182 static gint hf_krb_pac_upn_upn_offset = -1;
183 static gint hf_krb_pac_upn_upn_len = -1;
184 static gint hf_krb_pac_upn_upn_name = -1;
185 static gint hf_krb_pac_upn_dns_name = -1;
186 static gint hf_krb_pac_server_checksum = -1;
187 static gint hf_krb_pac_privsvr_checksum = -1;
188 static gint hf_krb_pac_client_info_type = -1;
189 static gint hf_krb_pa_supported_enctypes = -1;
190 static gint hf_krb_pa_supported_enctypes_des_cbc_crc = -1;
191 static gint hf_krb_pa_supported_enctypes_des_cbc_md5 = -1;
192 static gint hf_krb_pa_supported_enctypes_rc4_hmac = -1;
193 static gint hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96 = -1;
194 static gint hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96 = -1;
195 static gint hf_krb_pa_supported_enctypes_fast_supported = -1;
196 static gint hf_krb_pa_supported_enctypes_compound_identity_supported = -1;
197 static gint hf_krb_pa_supported_enctypes_claims_supported = -1;
198 static gint hf_krb_pa_supported_enctypes_resource_sid_compression_disabled = -1;
199 static gint hf_krb_ad_ap_options = -1;
200 static gint hf_krb_ad_ap_options_cbt = -1;
201 #include "packet-kerberos-hf.c"
203 /* Initialize the subtree pointers */
204 static gint ett_kerberos = -1;
205 static gint ett_krb_recordmark = -1;
206 static gint ett_krb_pac = -1;
207 static gint ett_krb_pac_drep = -1;
208 static gint ett_krb_pac_midl_blob = -1;
209 static gint ett_krb_pac_logon_info = -1;
210 static gint ett_krb_pac_s4u_delegation_info = -1;
211 static gint ett_krb_pac_upn_dns_info = -1;
212 static gint ett_krb_pac_server_checksum = -1;
213 static gint ett_krb_pac_privsvr_checksum = -1;
214 static gint ett_krb_pac_client_info_type = -1;
215 static gint ett_krb_pa_supported_enctypes = -1;
216 static gint ett_krb_ad_ap_options = -1;
217 #include "packet-kerberos-ett.c"
219 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
220 static expert_field ei_kerberos_address = EI_INIT;
221 static expert_field ei_krb_gssapi_dlglen = EI_INIT;
223 static dissector_handle_t krb4_handle=NULL;
225 /* Global variables */
226 static guint32 krb5_errorcode;
227 static guint32 gbl_keytype;
228 static gboolean gbl_do_col_info;
230 #include "packet-kerberos-val.h"
233 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
241 cb->callback(pinfo, tvb, tree);
249 static kerberos_private_data_t*
250 kerberos_get_private_data(asn1_ctx_t *actx)
252 if (!actx->private_data) {
253 actx->private_data = wmem_new0(wmem_packet_scope(), kerberos_private_data_t);
255 return (kerberos_private_data_t *)(actx->private_data);
260 /* Decrypt Kerberos blobs */
261 gboolean krb_decrypt = FALSE;
263 /* keytab filename */
264 static const char *keytab_filename = "";
267 read_keytab_file_from_preferences(void)
269 static char *last_keytab = NULL;
275 if (keytab_filename == NULL) {
279 if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
284 last_keytab = g_strdup(keytab_filename);
286 read_keytab_file(last_keytab);
288 #endif /* HAVE_KERBEROS */
290 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
292 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
293 #undef HAVE_GETADDRINFO
294 #undef HAVE_SYS_TYPES_H
297 enc_key_t *enc_key_list=NULL;
300 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
304 if(pinfo->fd->flags.visited){
308 printf("%d:%s:%s: added key in %u keytype:%d len:%d\n", __LINE__, G_STRFUNC, origin, pinfo->fd->num, keytype, keylength);
309 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
310 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->num);
311 new_key->fd_num = pinfo->num;
312 new_key->next=enc_key_list;
313 enc_key_list=new_key;
314 new_key->keytype=keytype;
315 new_key->keylength=keylength;
316 /*XXX this needs to be freed later */
317 new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
319 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
321 #if defined(HAVE_MIT_KERBEROS)
323 static krb5_context krb5_ctx;
325 USES_APPLE_DEPRECATED_API
327 read_keytab_file(const char *filename)
331 krb5_keytab_entry key;
332 krb5_kt_cursor cursor;
333 static gboolean first_time=TRUE;
335 if (filename == NULL || filename[0] == 0) {
341 ret = krb5_init_context(&krb5_ctx);
342 if(ret && ret != KRB5_CONFIG_CANTOPEN){
347 /* should use a file in the wireshark users dir */
348 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
350 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
355 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
357 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
362 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
368 new_key = g_new(enc_key_t, 1);
369 new_key->fd_num = -1;
370 new_key->next = enc_key_list;
372 /* generate origin string, describing where this key came from */
373 pos=new_key->key_origin;
374 pos+=MIN(KRB_MAX_ORIG_LEN,
375 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
376 for(i=0;i<key.principal->length;i++){
377 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
378 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data));
380 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
381 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "@%s",key.principal->realm.data));
383 new_key->keytype=key.key.enctype;
384 new_key->keylength=key.key.length;
385 new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
386 enc_key_list=new_key;
387 ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
389 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
390 ret = 0; /* try to continue with the next entry */
395 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
397 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
399 ret = krb5_kt_close(krb5_ctx, keytab);
401 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
407 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
415 krb5_data data = {0,0,NULL};
416 krb5_keytab_entry key;
417 int length = tvb_captured_length(cryptotvb);
418 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
420 /* don't do anything if we are not attempting to decrypt data */
421 if(!krb_decrypt || length < 1){
425 /* make sure we have all the data we need */
426 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
430 read_keytab_file_from_preferences();
431 data.data = (char *)wmem_alloc(pinfo->pool, length);
432 data.length = length;
434 for(ek=enc_key_list;ek;ek=ek->next){
437 /* shortcircuit and bail out if enctypes are not matching */
438 if((keytype != -1) && (ek->keytype != keytype)) {
442 input.enctype = ek->keytype;
443 input.ciphertext.length = length;
444 input.ciphertext.data = (guint8 *)cryptotext;
446 key.key.enctype=ek->keytype;
447 key.key.length=ek->keylength;
448 key.key.contents=ek->keyvalue;
449 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
453 printf("%d:%s:%s: woohoo decrypted keytype:%d in frame:%u\n", __LINE__, G_STRFUNC, ek->key_origin, ek->keytype, pinfo->fd->num);
454 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
455 "Decrypted keytype %d in frame %u using %s",
456 ek->keytype, pinfo->num, ek->key_origin);
458 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
462 *datalen = data.length;
472 #elif defined(HAVE_HEIMDAL_KERBEROS)
473 static krb5_context krb5_ctx;
475 USES_APPLE_DEPRECATED_API
477 read_keytab_file(const char *filename)
481 krb5_keytab_entry key;
482 krb5_kt_cursor cursor;
484 static gboolean first_time=TRUE;
486 if (filename == NULL || filename[0] == 0) {
492 ret = krb5_init_context(&krb5_ctx);
498 /* should use a file in the wireshark users dir */
499 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
501 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
506 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
508 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
513 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
518 new_key = g_new0(enc_key_t, 1);
519 new_key->fd_num = -1;
520 new_key->next = enc_key_list;
522 /* generate origin string, describing where this key came from */
523 pos=new_key->key_origin;
524 pos+=MIN(KRB_MAX_ORIG_LEN,
525 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
526 for(i=0;i<key.principal->name.name_string.len;i++){
527 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
528 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
530 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
531 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
533 new_key->keytype=key.keyblock.keytype;
534 new_key->keylength=(int)key.keyblock.keyvalue.length;
535 new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
536 enc_key_list=new_key;
537 ret = krb5_kt_free_entry(krb5_ctx, &key);
539 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
540 ret = 0; /* try to continue with the next entry */
545 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
547 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
549 ret = krb5_kt_close(krb5_ctx, keytab);
551 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
559 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
568 int length = tvb_captured_length(cryptotvb);
569 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
571 /* don't do anything if we are not attempting to decrypt data */
576 /* make sure we have all the data we need */
577 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
581 read_keytab_file_from_preferences();
583 for(ek=enc_key_list;ek;ek=ek->next){
584 krb5_keytab_entry key;
586 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
588 /* shortcircuit and bail out if enctypes are not matching */
589 if((keytype != -1) && (ek->keytype != keytype)) {
593 key.keyblock.keytype=ek->keytype;
594 key.keyblock.keyvalue.length=ek->keylength;
595 key.keyblock.keyvalue.data=ek->keyvalue;
596 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto);
601 /* pre-0.6.1 versions of Heimdal would sometimes change
602 the cryptotext data even when the decryption failed.
603 This would obviously not work since we iterate over the
604 keys. So just give it a copy of the crypto data instead.
605 This has been seen for RC4-HMAC blobs.
607 cryptocopy = (guint8 *)wmem_memdup(wmem_packet_scope(), cryptotext, length);
608 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
612 if((ret == 0) && (length>0)){
615 printf("%d:%s:%s: woohoo decrypted keytype:%d in frame:%u\n", __LINE__, G_STRFUNC, ek->key_origin, ek->keytype, pinfo->fd->num);
616 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
617 "Decrypted keytype %d in frame %u using %s",
618 ek->keytype, pinfo->num, ek->key_origin);
620 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
622 krb5_crypto_destroy(krb5_ctx, crypto);
623 /* return a private wmem_alloced blob to the caller */
624 user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
626 *datalen = (int)data.length;
630 krb5_crypto_destroy(krb5_ctx, crypto);
635 #elif defined (HAVE_LIBNETTLE)
637 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
638 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
640 typedef struct _service_key_t {
645 char origin[KRB_MAX_ORIG_LEN+1];
647 GSList *service_key_list = NULL;
651 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
653 service_key_t *new_key;
655 if(pinfo->fd->flags.visited){
659 printf("%d:%s:%s: added key in %u keytype:%d len:%d\n", __LINE__, G_STRFUNC, origin, pinfo->fd->num, keytype, keylength);
661 new_key = g_malloc(sizeof(service_key_t));
663 new_key->keytype = keytype;
664 new_key->length = keylength;
665 new_key->contents = g_memdup(keyvalue, keylength);
666 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
667 service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
675 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
676 sk = (service_key_t *) ske->data;
678 g_free(sk->contents);
682 g_slist_free(service_key_list);
683 service_key_list = NULL;
687 read_keytab_file(const char *service_key_file)
692 unsigned char buf[SERVICE_KEY_SIZE];
693 int newline_skip = 0, count = 0;
695 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
697 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
698 * There can be zero, one (\n), or two (\r\n) characters between
699 * keys. Trailing characters are ignored.
702 /* XXX We should support the standard keytab format instead */
703 if (st.st_size > SERVICE_KEY_SIZE) {
704 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
705 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
707 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
708 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
713 skf = ws_fopen(service_key_file, "rb");
716 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
717 sk = g_malloc(sizeof(service_key_t));
718 sk->kvno = buf[0] << 8 | buf[1];
719 sk->keytype = KEYTYPE_DES3_CBC_MD5;
720 sk->length = DES3_KEY_SIZE;
721 sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
722 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
723 service_key_list = g_slist_append(service_key_list, (gpointer) sk);
724 if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
725 fprintf(stderr, "unable to seek...\n");
734 #define CONFOUNDER_PLUS_CHECKSUM 24
737 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
744 guint8 *decrypted_data = NULL, *plaintext = NULL;
747 guint32 tag, item_len, data_len;
748 int id_offset, offset;
749 guint8 key[DES3_KEY_SIZE];
750 guint8 initial_vector[DES_BLOCK_SIZE];
751 gcry_md_hd_t md5_handle;
753 guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
754 guint8 confounder[8];
759 int length = tvb_captured_length(cryptotvb);
760 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
763 /* don't do anything if we are not attempting to decrypt data */
768 /* make sure we have all the data we need */
769 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
773 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
777 decrypted_data = wmem_alloc(wmem_packet_scope(), length);
778 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
779 gboolean do_continue = FALSE;
781 sk = (service_key_t *) ske->data;
783 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
785 memset(initial_vector, 0, DES_BLOCK_SIZE);
786 des3_set_key(&ctx, key);
787 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
788 length, decrypted_data, cryptotext);
789 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
791 tvb_memcpy(encr_tvb, confounder, 0, 8);
793 /* We have to pull the decrypted data length from the decrypted
794 * content. If the key doesn't match or we otherwise get garbage,
795 * an exception may get thrown while decoding the ASN.1 header.
796 * Catch it, just in case.
799 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
800 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
802 CATCH_BOUNDS_ERRORS {
808 if (do_continue) continue;
810 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
811 if ((int) item_len + offset > length) {
816 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
819 gcry_md_write(md5_handle, confounder, 8);
820 gcry_md_write(md5_handle, zero_fill, 16);
821 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
822 digest = gcry_md_read(md5_handle, 0);
824 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
825 gcry_md_close(md5_handle);
827 plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
841 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
843 #define INET6_ADDRLEN 16
845 /* TCP Record Mark */
846 #define KRB_RM_RESERVED 0x80000000U
847 #define KRB_RM_RECLEN 0x7fffffffU
849 #define KRB5_MSG_TICKET 1 /* Ticket */
850 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
851 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
852 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
853 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
854 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
855 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
856 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
857 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
859 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
860 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
861 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
862 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
863 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
864 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
865 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
866 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
867 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
869 #define KRB5_CHKSUM_GSSAPI 0x8003
871 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
873 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
875 * unless it's expired.
878 /* Principal name-type */
879 #define KRB5_NT_UNKNOWN 0
880 #define KRB5_NT_PRINCIPAL 1
881 #define KRB5_NT_SRV_INST 2
882 #define KRB5_NT_SRV_HST 3
883 #define KRB5_NT_SRV_XHST 4
884 #define KRB5_NT_UID 5
885 #define KRB5_NT_X500_PRINCIPAL 6
886 #define KRB5_NT_SMTP_NAME 7
887 #define KRB5_NT_ENTERPRISE 10
890 * MS specific name types, from
892 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
894 #define KRB5_NT_MS_PRINCIPAL -128
895 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
896 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
897 #define KRB5_NT_PRINCIPAL_AND_SID -131
898 #define KRB5_NT_SRV_INST_AND_SID -132
900 /* error table constants */
901 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
902 #define KRB5_ET_KRB5KDC_ERR_NONE 0
903 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
904 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
905 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
906 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
907 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
908 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
909 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
910 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
911 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
912 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
913 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
914 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
915 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
916 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
917 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
918 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
919 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
920 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
921 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
922 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
923 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
924 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
925 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
926 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
927 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
928 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
929 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
930 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
931 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
932 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
933 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
934 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
935 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
936 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
937 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
938 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
939 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
940 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
941 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
942 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
943 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
944 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
945 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
946 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
947 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
948 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
949 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
950 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
951 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
952 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
953 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
954 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
955 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
956 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
957 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
958 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
959 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
960 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
961 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
962 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
963 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
964 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
965 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
966 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
967 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
968 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
969 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
970 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
972 static const value_string krb5_error_codes[] = {
973 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
974 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
975 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
976 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
977 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
978 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
979 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
980 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
981 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
982 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
983 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
984 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
985 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
986 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
987 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
988 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
989 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
990 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
991 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
992 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
993 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
994 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
995 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
996 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
997 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
998 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
999 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1000 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1001 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1002 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1003 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1004 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1005 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1006 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1007 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1008 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1009 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1010 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1011 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1012 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1013 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1014 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1015 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1016 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1017 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1018 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1019 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1020 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1021 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1022 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1023 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1024 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1025 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1026 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1027 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1028 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1029 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1030 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1031 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1032 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1033 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1034 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1035 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1036 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1037 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1038 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1039 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1040 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1041 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1046 #define PAC_LOGON_INFO 1
1047 #define PAC_CREDENTIAL_TYPE 2
1048 #define PAC_SERVER_CHECKSUM 6
1049 #define PAC_PRIVSVR_CHECKSUM 7
1050 #define PAC_CLIENT_INFO_TYPE 10
1051 #define PAC_S4U_DELEGATION_INFO 11
1052 #define PAC_UPN_DNS_INFO 12
1053 static const value_string w2k_pac_types[] = {
1054 { PAC_LOGON_INFO , "Logon Info" },
1055 { PAC_CREDENTIAL_TYPE , "Credential Type" },
1056 { PAC_SERVER_CHECKSUM , "Server Checksum" },
1057 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
1058 { PAC_CLIENT_INFO_TYPE , "Client Info Type" },
1059 { PAC_S4U_DELEGATION_INFO, "S4U Delegation Info" },
1060 { PAC_UPN_DNS_INFO , "UPN DNS Info" },
1064 static const value_string krb5_msg_types[] = {
1065 { KRB5_MSG_TICKET, "Ticket" },
1066 { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
1067 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
1068 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
1069 { KRB5_MSG_TGS_REP, "TGS-REP" },
1070 { KRB5_MSG_AS_REQ, "AS-REQ" },
1071 { KRB5_MSG_AS_REP, "AS-REP" },
1072 { KRB5_MSG_AP_REQ, "AP-REQ" },
1073 { KRB5_MSG_AP_REP, "AP-REP" },
1074 { KRB5_MSG_SAFE, "KRB-SAFE" },
1075 { KRB5_MSG_PRIV, "KRB-PRIV" },
1076 { KRB5_MSG_CRED, "KRB-CRED" },
1077 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
1078 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
1079 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
1080 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1081 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1082 { KRB5_MSG_ERROR, "KRB-ERROR" },
1086 #define KRB5_GSS_C_DELEG_FLAG 0x01
1087 #define KRB5_GSS_C_MUTUAL_FLAG 0x02
1088 #define KRB5_GSS_C_REPLAY_FLAG 0x04
1089 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08
1090 #define KRB5_GSS_C_CONF_FLAG 0x10
1091 #define KRB5_GSS_C_INTEG_FLAG 0x20
1092 #define KRB5_GSS_C_DCE_STYLE 0x1000
1094 static const true_false_string tfs_gss_flags_deleg = {
1095 "Delegate credentials to remote peer",
1098 static const true_false_string tfs_gss_flags_mutual = {
1099 "Request that remote peer authenticates itself",
1100 "Mutual authentication NOT required"
1102 static const true_false_string tfs_gss_flags_replay = {
1103 "Enable replay protection for signed or sealed messages",
1104 "Do NOT enable replay protection"
1106 static const true_false_string tfs_gss_flags_sequence = {
1107 "Enable Out-of-sequence detection for sign or sealed messages",
1108 "Do NOT enable out-of-sequence detection"
1110 static const true_false_string tfs_gss_flags_conf = {
1111 "Confidentiality (sealing) may be invoked",
1112 "Do NOT use Confidentiality (sealing)"
1114 static const true_false_string tfs_gss_flags_integ = {
1115 "Integrity protection (signing) may be invoked",
1116 "Do NOT use integrity protection"
1119 static const true_false_string tfs_gss_flags_dce_style = {
1121 "Not using DCE-STYLE"
1124 #ifdef HAVE_KERBEROS
1126 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1127 proto_tree *tree, int hf_index _U_)
1131 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1134 next_tvb=tvb_new_subset_remaining(tvb, offset);
1135 length=tvb_captured_length_remaining(tvb, offset);
1137 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1139 * All Ticket encrypted parts use usage == 2
1141 plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, private_data->etype, NULL);
1144 tvbuff_t *child_tvb;
1145 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1147 /* Add the decrypted data to the data source list. */
1148 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1150 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1156 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1157 proto_tree *tree, int hf_index _U_)
1161 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1164 next_tvb=tvb_new_subset_remaining(tvb, offset);
1165 length=tvb_captured_length_remaining(tvb, offset);
1167 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1169 * Authenticators are encrypted with usage
1173 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, private_data->etype, NULL);
1176 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, private_data->etype, NULL);
1180 tvbuff_t *child_tvb;
1181 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1183 /* Add the decrypted data to the data source list. */
1184 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1186 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1192 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1193 proto_tree *tree, int hf_index _U_)
1197 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1200 next_tvb=tvb_new_subset_remaining(tvb, offset);
1201 length=tvb_captured_length_remaining(tvb, offset);
1203 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1205 * ASREP/TGSREP encryptedparts are encrypted with usage
1210 plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, private_data->etype, NULL);
1213 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, private_data->etype, NULL);
1217 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, private_data->etype, NULL);
1221 tvbuff_t *child_tvb;
1222 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1224 /* Add the decrypted data to the data source list. */
1225 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1227 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1233 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1234 proto_tree *tree, int hf_index _U_)
1238 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1241 next_tvb=tvb_new_subset_remaining(tvb, offset);
1242 length=tvb_captured_length_remaining(tvb, offset);
1244 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1246 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1249 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, private_data->etype, NULL);
1252 tvbuff_t *child_tvb;
1253 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1255 /* Add the decrypted data to the data source list. */
1256 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1258 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1264 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1265 proto_tree *tree, int hf_index _U_)
1269 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1272 next_tvb=tvb_new_subset_remaining(tvb, offset);
1273 length=tvb_captured_length_remaining(tvb, offset);
1275 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1277 * AP-REP are encrypted with usage == 12
1279 plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, private_data->etype, NULL);
1282 tvbuff_t *child_tvb;
1283 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1285 /* Add the decrypted data to the data source list. */
1286 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1288 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1294 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1295 proto_tree *tree, int hf_index _U_)
1299 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1302 next_tvb=tvb_new_subset_remaining(tvb, offset);
1303 length=tvb_captured_length_remaining(tvb, offset);
1306 * EncKrbPrivPart encrypted with usage
1309 plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, private_data->etype, NULL);
1312 tvbuff_t *child_tvb;
1313 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1315 /* Add the decrypted data to the data source list. */
1316 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1318 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1324 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1325 proto_tree *tree, int hf_index _U_)
1329 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1332 next_tvb=tvb_new_subset_remaining(tvb, offset);
1333 length=tvb_captured_length_remaining(tvb, offset);
1336 * EncKrbCredPart encrypted with usage
1339 plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, private_data->etype, NULL);
1342 tvbuff_t *child_tvb;
1343 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1345 /* Add the decrypted data to the data source list. */
1346 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1348 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1354 dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1355 proto_tree *tree, int hf_index _U_)
1359 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1362 next_tvb=tvb_new_subset_remaining(tvb, offset);
1363 length=tvb_captured_length_remaining(tvb, offset);
1366 * KrbFastResponse encrypted with usage
1367 * KEY_USAGE_FAST_ENC 51
1369 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_ENC,
1370 next_tvb, private_data->etype, NULL);
1373 tvbuff_t *child_tvb;
1374 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1375 tvb_set_free_cb(child_tvb, g_free);
1377 /* Add the decrypted data to the data source list. */
1378 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1380 offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1386 dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1387 proto_tree *tree, int hf_index _U_)
1391 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1394 next_tvb=tvb_new_subset_remaining(tvb, offset);
1395 length=tvb_captured_length_remaining(tvb, offset);
1399 * KrbFastResponse encrypted with usage
1400 * KEY_USAGE_FAST_REP 52
1402 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_REP,
1403 next_tvb, private_data->etype, NULL);
1406 tvbuff_t *child_tvb;
1407 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1408 tvb_set_free_cb(child_tvb, g_free);
1410 /* Add the decrypted data to the data source list. */
1411 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1413 offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1419 dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1420 proto_tree *tree, int hf_index _U_)
1424 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1428 next_tvb=tvb_new_subset_remaining(tvb, offset);
1429 length=tvb_captured_length_remaining(tvb, offset);
1432 * KEY_USAGE_ENC_CHALLENGE_CLIENT 54
1433 * KEY_USAGE_ENC_CHALLENGE_KDC 55
1435 if (private_data->kdc_response) {
1436 usage = KEY_USAGE_ENC_CHALLENGE_KDC;
1438 usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
1440 plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, private_data->etype, NULL);
1443 tvbuff_t *child_tvb;
1444 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1445 tvb_set_free_cb(child_tvb, g_free);
1447 /* Add the decrypted data to the data source list. */
1448 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1450 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1456 static const int *hf_krb_pa_supported_enctypes_fields[] = {
1457 &hf_krb_pa_supported_enctypes_des_cbc_crc,
1458 &hf_krb_pa_supported_enctypes_des_cbc_md5,
1459 &hf_krb_pa_supported_enctypes_rc4_hmac,
1460 &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
1461 &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
1462 &hf_krb_pa_supported_enctypes_fast_supported,
1463 &hf_krb_pa_supported_enctypes_compound_identity_supported,
1464 &hf_krb_pa_supported_enctypes_claims_supported,
1465 &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
1469 static const true_false_string supported_tfs = {
1470 "Supported", "Not supported"
1474 dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1475 int offset _U_, asn1_ctx_t *actx _U_,
1476 proto_tree *tree _U_, int hf_index _U_)
1478 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1479 hf_krb_pa_supported_enctypes,
1480 ett_krb_pa_supported_enctypes,
1481 hf_krb_pa_supported_enctypes_fields,
1488 static const int *hf_krb_ad_ap_options_fields[] = {
1489 &hf_krb_ad_ap_options_cbt,
1493 static const true_false_string set_tfs = {
1498 dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1499 int offset _U_, asn1_ctx_t *actx _U_,
1500 proto_tree *tree _U_, int hf_index _U_)
1502 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1503 hf_krb_ad_ap_options,
1504 ett_krb_ad_ap_options,
1505 hf_krb_ad_ap_options_fields,
1511 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1514 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1520 /* Length of Bnd field */
1521 len=tvb_get_letohl(tvb, offset);
1522 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1526 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1531 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1532 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1533 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1534 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1535 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1536 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1537 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1540 /* the next fields are optional so we have to check that we have
1541 * more data in our buffers */
1542 if(tvb_reported_length_remaining(tvb, offset)<2){
1545 /* dlgopt identifier */
1546 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1549 if(tvb_reported_length_remaining(tvb, offset)<2){
1552 /* dlglen identifier */
1553 dlglen=tvb_get_letohs(tvb, offset);
1554 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1557 if(dlglen!=tvb_reported_length_remaining(tvb, offset)){
1558 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0,
1559 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset));
1563 /* this should now be a KRB_CRED message */
1564 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1570 dissect_krb5_PA_PROV_SRV_LOCATION(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
1572 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1578 dissect_krb5_PW_SALT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
1582 /* Microsoft stores a special 12 byte blob here
1586 * decode everything as this blob for now until we see if anyone
1587 * else ever uses it or we learn how to tell whether this
1588 * is such an MS blob or not.
1590 proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
1592 nt_status=tvb_get_letohl(tvb, offset);
1594 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
1596 val_to_str(nt_status, NT_errors,
1597 "Unknown error code %#x"));
1601 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1605 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1613 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
1618 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
1620 val = tvb_get_guint8(tvb, offset);
1621 proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
1632 /* This might be some sort of header that MIDL generates when creating
1633 * marshalling/unmarshalling code for blobs that are not to be transported
1634 * ontop of DCERPC and where the DREP fields specifying things such as
1635 * endianess and similar are not available.
1638 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
1642 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header");
1644 /* modified DREP field that is used for stuff that is transporetd ontop
1647 proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1650 offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
1653 proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1656 proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1659 /* length of blob that follows */
1660 proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1667 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1671 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1672 static dcerpc_info di; /* fake dcerpc_info struct */
1673 static dcerpc_call_value call_data;
1675 item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
1676 tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
1678 /* skip the first 16 bytes, they are some magic created by the idl
1679 * compiler the first 4 bytes might be flags?
1681 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1683 /* the PAC_LOGON_INFO blob */
1684 /* fake whatever state the dcerpc runtime support needs */
1685 di.conformant_run=0;
1686 /* we need di->call_data->flags.NDR64 == 0 */
1687 di.call_data=&call_data;
1688 init_ndr_pointer_list(&di);
1689 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1690 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
1691 "PAC_LOGON_INFO:", -1);
1697 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1701 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1702 static dcerpc_info di; /* fake dcerpc_info struct */
1703 static dcerpc_call_value call_data;
1705 item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
1706 tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
1708 /* skip the first 16 bytes, they are some magic created by the idl
1709 * compiler the first 4 bytes might be flags?
1711 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1714 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
1715 /* fake whatever state the dcerpc runtime support needs */
1716 di.conformant_run=0;
1717 /* we need di->call_data->flags.NDR64 == 0 */
1718 di.call_data=&call_data;
1719 init_ndr_pointer_list(&di);
1720 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1721 netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
1722 "PAC_S4U_DELEGATION_INFO:", -1);
1728 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1732 guint16 dns_offset, dns_len;
1733 guint16 upn_offset, upn_len;
1738 item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
1739 tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
1742 upn_len = tvb_get_letohs(tvb, offset);
1743 proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1745 upn_offset = tvb_get_letohs(tvb, offset);
1746 proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1750 dns_len = tvb_get_letohs(tvb, offset);
1751 proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1753 dns_offset = tvb_get_letohs(tvb, offset);
1754 proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1758 proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1761 offset = upn_offset;
1763 bc = tvb_reported_length_remaining(tvb, offset);
1764 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1765 proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
1768 offset = dns_offset;
1770 bc = tvb_reported_length_remaining(tvb, offset);
1771 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1772 proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
1778 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1780 proto_tree_add_item(parent_tree, hf_krb_pac_credential_type, tvb, offset, -1, ENC_NA);
1786 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1791 item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA);
1792 tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum);
1794 /* signature type */
1795 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1798 /* signature data */
1799 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1805 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1810 item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA);
1811 tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum);
1813 /* signature type */
1814 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1817 /* signature data */
1818 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1824 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1830 item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
1831 tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
1834 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
1837 namelen=tvb_get_letohs(tvb, offset);
1838 proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
1842 proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
1849 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1854 proto_item *it=NULL;
1855 proto_tree *tr=NULL;
1858 /* type of pac data */
1859 pac_type=tvb_get_letohl(tvb, offset);
1860 it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
1861 tr=proto_item_add_subtree(it, ett_krb_pac);
1865 /* size of pac data */
1866 pac_size=tvb_get_letohl(tvb, offset);
1867 proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
1870 /* offset to pac data */
1871 pac_offset=tvb_get_letohl(tvb, offset);
1872 proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
1875 next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size);
1877 case PAC_LOGON_INFO:
1878 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
1880 case PAC_CREDENTIAL_TYPE:
1881 dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
1883 case PAC_SERVER_CHECKSUM:
1884 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
1886 case PAC_PRIVSVR_CHECKSUM:
1887 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
1889 case PAC_CLIENT_INFO_TYPE:
1890 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
1892 case PAC_S4U_DELEGATION_INFO:
1893 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
1895 case PAC_UPN_DNS_INFO:
1896 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
1906 dissect_krb5_AD_WIN2K_PAC(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
1912 /* first in the PAC structure comes the number of entries */
1913 entries=tvb_get_letohl(tvb, offset);
1914 proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
1917 /* second comes the version */
1918 version=tvb_get_letohl(tvb, offset);
1919 proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
1922 for(i=0;i<entries;i++){
1923 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
1929 #include "packet-kerberos-fn.c"
1931 /* Make wrappers around exported functions for now */
1933 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1935 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
1940 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1942 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
1947 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1949 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
1952 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1954 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
1959 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1960 gboolean dci, gboolean do_col_protocol, gboolean have_rm,
1961 kerberos_callbacks *cb)
1963 volatile int offset = 0;
1964 proto_tree *volatile kerberos_tree = NULL;
1965 proto_item *volatile item = NULL;
1966 asn1_ctx_t asn1_ctx;
1968 /* TCP record mark and length */
1970 gint krb_reclen = 0;
1972 gbl_do_col_info=dci;
1975 krb_rm = tvb_get_ntohl(tvb, offset);
1976 krb_reclen = kerberos_rm_to_reclen(krb_rm);
1978 * What is a reasonable size limit?
1980 if (krb_reclen > 10 * 1024 * 1024) {
1984 if (do_col_protocol) {
1985 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1989 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1990 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1993 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1996 /* Do some sanity checking here,
1997 * All krb5 packets start with a TAG class that is BER_CLASS_APP
1998 * and a tag value that is either of the values below:
1999 * If it doesn't look like kerberos, return 0 and let someone else have
2006 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
2007 if(tmp_class!=BER_CLASS_APP){
2011 case KRB5_MSG_TICKET:
2012 case KRB5_MSG_AUTHENTICATOR:
2013 case KRB5_MSG_ENC_TICKET_PART:
2014 case KRB5_MSG_AS_REQ:
2015 case KRB5_MSG_AS_REP:
2016 case KRB5_MSG_TGS_REQ:
2017 case KRB5_MSG_TGS_REP:
2018 case KRB5_MSG_AP_REQ:
2019 case KRB5_MSG_AP_REP:
2020 case KRB5_MSG_ENC_AS_REP_PART:
2021 case KRB5_MSG_ENC_TGS_REP_PART:
2022 case KRB5_MSG_ENC_AP_REP_PART:
2023 case KRB5_MSG_ENC_KRB_PRIV_PART:
2024 case KRB5_MSG_ENC_KRB_CRED_PART:
2027 case KRB5_MSG_ERROR:
2032 if (do_col_protocol) {
2033 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2035 if (gbl_do_col_info) {
2036 col_clear(pinfo->cinfo, COL_INFO);
2039 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
2040 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
2043 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2044 asn1_ctx.private_data = cb;
2047 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
2048 } CATCH_BOUNDS_ERRORS {
2052 proto_item_set_len(item, offset);
2057 * Display the TCP record mark.
2060 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
2063 proto_tree *rm_tree;
2068 rec_len = kerberos_rm_to_reclen(krb_rm);
2069 rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL,
2070 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
2071 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
2072 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
2076 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
2078 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
2082 kerberos_output_keytype(void)
2088 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2090 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
2091 Since all (except weirdo transarc krb4 stuff) use
2092 an opcode <=16 in the first byte, use this to see if it might
2094 All krb5 commands start with an APPL tag and thus is >=0x60
2095 so if first byte is <=16 just blindly assume it is krb4 then
2097 if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
2101 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
2109 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
2113 kerberos_rm_to_reclen(guint krb_rm)
2115 return (krb_rm & KRB_RM_RECLEN);
2119 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2124 krb_rm = tvb_get_ntohl(tvb, offset);
2125 pdulen = kerberos_rm_to_reclen(krb_rm);
2126 return (pdulen + 4);
2129 kerberos_prefs_apply_cb(void) {
2130 #ifdef HAVE_LIBNETTLE
2132 read_keytab_file(keytab_filename);
2137 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2139 pinfo->fragmented = TRUE;
2140 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
2142 * The dissector failed to recognize this as a valid
2143 * Kerberos message. Mark it as a continuation packet.
2145 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
2148 return tvb_captured_length(tvb);
2152 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2154 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2155 col_clear(pinfo->cinfo, COL_INFO);
2157 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
2158 dissect_kerberos_tcp_pdu, data);
2159 return tvb_captured_length(tvb);
2162 /*--- proto_register_kerberos -------------------------------------------*/
2163 void proto_register_kerberos(void) {
2165 /* List of fields */
2167 static hf_register_info hf[] = {
2168 { &hf_krb_rm_reserved, {
2169 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
2170 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
2171 { &hf_krb_rm_reclen, {
2172 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
2173 NULL, KRB_RM_RECLEN, NULL, HFILL }},
2174 { &hf_krb_provsrv_location, {
2175 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
2176 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
2177 { &hf_krb_smb_nt_status,
2178 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
2179 VALS(NT_errors), 0, "NT Status code", HFILL }},
2180 { &hf_krb_smb_unknown,
2181 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
2182 NULL, 0, NULL, HFILL }},
2183 { &hf_krb_address_ip, {
2184 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
2185 NULL, 0, NULL, HFILL }},
2186 { &hf_krb_address_ipv6, {
2187 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
2188 NULL, 0, NULL, HFILL }},
2189 { &hf_krb_address_netbios, {
2190 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
2191 NULL, 0, "NetBIOS Address and type", HFILL }},
2192 { &hf_krb_gssapi_len, {
2193 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
2194 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
2195 { &hf_krb_gssapi_bnd, {
2196 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
2197 NULL, 0, "GSSAPI Bnd field", HFILL }},
2198 { &hf_krb_gssapi_c_flag_deleg, {
2199 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
2200 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
2201 { &hf_krb_gssapi_c_flag_mutual, {
2202 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
2203 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
2204 { &hf_krb_gssapi_c_flag_replay, {
2205 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
2206 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
2207 { &hf_krb_gssapi_c_flag_sequence, {
2208 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
2209 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
2210 { &hf_krb_gssapi_c_flag_conf, {
2211 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
2212 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
2213 { &hf_krb_gssapi_c_flag_integ, {
2214 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
2215 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
2216 { &hf_krb_gssapi_c_flag_dce_style, {
2217 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
2218 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
2219 { &hf_krb_gssapi_dlgopt, {
2220 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
2221 NULL, 0, "GSSAPI DlgOpt", HFILL }},
2222 { &hf_krb_gssapi_dlglen, {
2223 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
2224 NULL, 0, "GSSAPI DlgLen", HFILL }},
2225 { &hf_krb_midl_blob_len, {
2226 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
2227 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
2228 { &hf_krb_midl_fill_bytes, {
2229 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
2230 NULL, 0, "Just some fill bytes", HFILL }},
2231 { &hf_krb_midl_version, {
2232 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
2233 NULL, 0, "Version of pickling", HFILL }},
2234 { &hf_krb_midl_hdr_len, {
2235 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
2236 NULL, 0, "Length of header", HFILL }},
2237 { &hf_krb_pac_signature_type, {
2238 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
2239 NULL, 0, "PAC Signature Type", HFILL }},
2240 { &hf_krb_pac_signature_signature, {
2241 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
2242 NULL, 0, "A PAC signature blob", HFILL }},
2243 { &hf_krb_w2k_pac_entries, {
2244 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
2245 NULL, 0, "Number of W2k PAC entries", HFILL }},
2246 { &hf_krb_w2k_pac_version, {
2247 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
2248 NULL, 0, "Version of PAC structures", HFILL }},
2249 { &hf_krb_w2k_pac_type, {
2250 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
2251 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
2252 { &hf_krb_w2k_pac_size, {
2253 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
2254 NULL, 0, "Size of W2k PAC entry", HFILL }},
2255 { &hf_krb_w2k_pac_offset, {
2256 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
2257 NULL, 0, "Offset to W2k PAC entry", HFILL }},
2258 { &hf_krb_pac_clientid, {
2259 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2260 NULL, 0, "ClientID Timestamp", HFILL }},
2261 { &hf_krb_pac_namelen, {
2262 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
2263 NULL, 0, "Length of client name", HFILL }},
2264 { &hf_krb_pac_clientname, {
2265 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
2266 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
2267 { &hf_krb_pac_logon_info, {
2268 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE,
2269 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
2270 { &hf_krb_pac_credential_type, {
2271 "PAC_CREDENTIAL_TYPE", "kerberos.pac_credential_type", FT_BYTES, BASE_NONE,
2272 NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
2273 { &hf_krb_pac_server_checksum, {
2274 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE,
2275 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
2276 { &hf_krb_pac_privsvr_checksum, {
2277 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE,
2278 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
2279 { &hf_krb_pac_client_info_type, {
2280 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE,
2281 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
2282 { &hf_krb_pac_s4u_delegation_info, {
2283 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE,
2284 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
2285 { &hf_krb_pac_upn_dns_info, {
2286 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE,
2287 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
2288 { &hf_krb_pac_upn_flags, {
2289 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
2290 NULL, 0, "UPN flags", HFILL }},
2291 { &hf_krb_pac_upn_dns_offset, {
2292 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
2293 NULL, 0, NULL, HFILL }},
2294 { &hf_krb_pac_upn_dns_len, {
2295 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
2296 NULL, 0, NULL, HFILL }},
2297 { &hf_krb_pac_upn_upn_offset, {
2298 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
2299 NULL, 0, NULL, HFILL }},
2300 { &hf_krb_pac_upn_upn_len, {
2301 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
2302 NULL, 0, NULL, HFILL }},
2303 { &hf_krb_pac_upn_upn_name, {
2304 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
2305 NULL, 0, NULL, HFILL }},
2306 { &hf_krb_pac_upn_dns_name, {
2307 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
2308 NULL, 0, NULL, HFILL }},
2309 { &hf_krb_pa_supported_enctypes,
2310 { "SupportedEnctypes", "kerberos.supported_entypes",
2311 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2312 { &hf_krb_pa_supported_enctypes_des_cbc_crc,
2313 { "des-cbc-crc", "kerberos.supported_entypes.des-cbc-crc",
2314 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000001, NULL, HFILL }},
2315 { &hf_krb_pa_supported_enctypes_des_cbc_md5,
2316 { "des-cbc-md5", "kerberos.supported_entypes.des-cbc-md5",
2317 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000002, NULL, HFILL }},
2318 { &hf_krb_pa_supported_enctypes_rc4_hmac,
2319 { "rc4-hmac", "kerberos.supported_entypes.rc4-hmac",
2320 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000004, NULL, HFILL }},
2321 { &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
2322 { "aes128-cts-hmac-sha1-96", "kerberos.supported_entypes.aes128-cts-hmac-sha1-96",
2323 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000008, NULL, HFILL }},
2324 { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
2325 { "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96",
2326 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000010, NULL, HFILL }},
2327 { &hf_krb_pa_supported_enctypes_fast_supported,
2328 { "fast-supported", "kerberos.supported_entypes.fast-supported",
2329 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00010000, NULL, HFILL }},
2330 { &hf_krb_pa_supported_enctypes_compound_identity_supported,
2331 { "compound-identity-supported", "kerberos.supported_entypes.compound-identity-supported",
2332 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00020000, NULL, HFILL }},
2333 { &hf_krb_pa_supported_enctypes_claims_supported,
2334 { "claims-supported", "kerberos.supported_entypes.claims-supported",
2335 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2336 { &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
2337 { "resource-sid-compression-disabled", "kerberos.supported_entypes.resource-sid-compression-disabled",
2338 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2339 { &hf_krb_ad_ap_options,
2340 { "AD-AP-Options", "kerberos.ad_ap_options",
2341 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2342 { &hf_krb_ad_ap_options_cbt,
2343 { "ChannelBindings", "kerberos.ad_ap_options.cbt",
2344 FT_BOOLEAN, 32, TFS(&set_tfs), 0x00004000, NULL, HFILL }},
2346 #include "packet-kerberos-hfarr.c"
2349 /* List of subtrees */
2350 static gint *ett[] = {
2352 &ett_krb_recordmark,
2355 &ett_krb_pac_midl_blob,
2356 &ett_krb_pac_logon_info,
2357 &ett_krb_pac_s4u_delegation_info,
2358 &ett_krb_pac_upn_dns_info,
2359 &ett_krb_pac_server_checksum,
2360 &ett_krb_pac_privsvr_checksum,
2361 &ett_krb_pac_client_info_type,
2362 &ett_krb_pa_supported_enctypes,
2363 &ett_krb_ad_ap_options,
2364 #include "packet-kerberos-ettarr.c"
2367 static ei_register_info ei[] = {
2368 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
2369 { &ei_kerberos_address, { "kerberos.address.unknown", PI_UNDECODED, PI_WARN, "KRB Address: I don't know how to parse this type of address yet", EXPFILL }},
2370 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }},
2373 expert_module_t* expert_krb;
2374 module_t *krb_module;
2376 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
2377 proto_register_field_array(proto_kerberos, hf, array_length(hf));
2378 proto_register_subtree_array(ett, array_length(ett));
2379 expert_krb = expert_register_protocol(proto_kerberos);
2380 expert_register_field_array(expert_krb, ei, array_length(ei));
2382 /* Register preferences */
2383 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2384 prefs_register_bool_preference(krb_module, "desegment",
2385 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2386 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2387 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2389 #ifdef HAVE_KERBEROS
2390 prefs_register_bool_preference(krb_module, "decrypt",
2391 "Try to decrypt Kerberos blobs",
2392 "Whether the dissector should try to decrypt "
2393 "encrypted Kerberos blobs. This requires that the proper "
2394 "keytab file is installed as well.", &krb_decrypt);
2396 prefs_register_filename_preference(krb_module, "file",
2397 "Kerberos keytab file",
2398 "The keytab file containing all the secrets",
2399 &keytab_filename, FALSE);
2403 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2404 proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
2408 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2410 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2412 return tvb_captured_length_remaining(tvb, offset);
2416 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2417 wrap_dissect_gss_kerb, /* Bind */
2418 wrap_dissect_gss_kerb, /* Bind ACK */
2419 wrap_dissect_gss_kerb, /* AUTH3 */
2420 NULL, /* Request verifier */
2421 NULL, /* Response verifier */
2422 NULL, /* Request data */
2423 NULL /* Response data */
2426 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2427 wrap_dissect_gss_kerb, /* Bind */
2428 wrap_dissect_gss_kerb, /* Bind ACK */
2429 wrap_dissect_gss_kerb, /* AUTH3 */
2430 wrap_dissect_gssapi_verf, /* Request verifier */
2431 wrap_dissect_gssapi_verf, /* Response verifier */
2432 NULL, /* Request data */
2433 NULL /* Response data */
2436 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2437 wrap_dissect_gss_kerb, /* Bind */
2438 wrap_dissect_gss_kerb, /* Bind ACK */
2439 wrap_dissect_gss_kerb, /* AUTH3 */
2440 wrap_dissect_gssapi_verf, /* Request verifier */
2441 wrap_dissect_gssapi_verf, /* Response verifier */
2442 wrap_dissect_gssapi_payload, /* Request data */
2443 wrap_dissect_gssapi_payload /* Response data */
2449 proto_reg_handoff_kerberos(void)
2451 dissector_handle_t kerberos_handle_tcp;
2453 krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos);
2455 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
2458 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
2461 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
2462 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
2464 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2465 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2466 &gss_kerb_auth_connect_fns);
2468 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2469 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2470 &gss_kerb_auth_sign_fns);
2472 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2473 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2474 &gss_kerb_auth_seal_fns);
2478 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2483 * indent-tabs-mode: t
2486 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2487 * :indentSize=8:tabSize=8:noTabs=false: