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"
72 #include "packet-x509af.h"
74 #define KEY_USAGE_FAST_REQ_CHKSUM 50
75 #define KEY_USAGE_FAST_ENC 51
76 #define KEY_USAGE_FAST_REP 52
77 #define KEY_USAGE_FAST_FINISHED 53
78 #define KEY_USAGE_ENC_CHALLENGE_CLIENT 54
79 #define KEY_USAGE_ENC_CHALLENGE_KDC 55
81 void proto_register_kerberos(void);
82 void proto_reg_handoff_kerberos(void);
84 #define UDP_PORT_KERBEROS 88
85 #define TCP_PORT_KERBEROS 88
87 #define ADDRESS_STR_BUFSIZ 256
89 typedef struct kerberos_key {
92 const guint8 *keyvalue;
97 gboolean kdc_response_initialized;
98 gboolean kdc_response;
101 guint32 is_enc_padata;
106 guint32 checksum_type;
107 } kerberos_private_data_t;
109 static dissector_handle_t kerberos_handle_udp;
111 /* Forward declarations */
112 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_);
113 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_);
114 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_);
115 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_);
116 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_);
117 static int dissect_kerberos_PA_S4U_X509_USER(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_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_);
119 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_);
120 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_);
121 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_);
122 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_);
123 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_);
124 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_);
125 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_);
126 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_);
127 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_);
128 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_);
129 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_);
130 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_);
131 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_);
133 /* Desegment Kerberos over TCP messages */
134 static gboolean krb_desegment = TRUE;
136 static gint proto_kerberos = -1;
138 static gint hf_krb_rm_reserved = -1;
139 static gint hf_krb_rm_reclen = -1;
140 static gint hf_krb_provsrv_location = -1;
141 static gint hf_krb_smb_nt_status = -1;
142 static gint hf_krb_smb_unknown = -1;
143 static gint hf_krb_address_ip = -1;
144 static gint hf_krb_address_netbios = -1;
145 static gint hf_krb_address_ipv6 = -1;
146 static gint hf_krb_gssapi_len = -1;
147 static gint hf_krb_gssapi_bnd = -1;
148 static gint hf_krb_gssapi_dlgopt = -1;
149 static gint hf_krb_gssapi_dlglen = -1;
150 static gint hf_krb_gssapi_c_flag_deleg = -1;
151 static gint hf_krb_gssapi_c_flag_mutual = -1;
152 static gint hf_krb_gssapi_c_flag_replay = -1;
153 static gint hf_krb_gssapi_c_flag_sequence = -1;
154 static gint hf_krb_gssapi_c_flag_conf = -1;
155 static gint hf_krb_gssapi_c_flag_integ = -1;
156 static gint hf_krb_gssapi_c_flag_dce_style = -1;
157 static gint hf_krb_midl_version = -1;
158 static gint hf_krb_midl_hdr_len = -1;
159 static gint hf_krb_midl_fill_bytes = -1;
160 static gint hf_krb_midl_blob_len = -1;
161 static gint hf_krb_pac_signature_type = -1;
162 static gint hf_krb_pac_signature_signature = -1;
163 static gint hf_krb_w2k_pac_entries = -1;
164 static gint hf_krb_w2k_pac_version = -1;
165 static gint hf_krb_w2k_pac_type = -1;
166 static gint hf_krb_w2k_pac_size = -1;
167 static gint hf_krb_w2k_pac_offset = -1;
168 static gint hf_krb_pac_clientid = -1;
169 static gint hf_krb_pac_namelen = -1;
170 static gint hf_krb_pac_clientname = -1;
171 static gint hf_krb_pac_logon_info = -1;
172 static gint hf_krb_pac_credential_type = -1;
173 static gint hf_krb_pac_s4u_delegation_info = -1;
174 static gint hf_krb_pac_upn_dns_info = -1;
175 static gint hf_krb_pac_upn_flags = -1;
176 static gint hf_krb_pac_upn_dns_offset = -1;
177 static gint hf_krb_pac_upn_dns_len = -1;
178 static gint hf_krb_pac_upn_upn_offset = -1;
179 static gint hf_krb_pac_upn_upn_len = -1;
180 static gint hf_krb_pac_upn_upn_name = -1;
181 static gint hf_krb_pac_upn_dns_name = -1;
182 static gint hf_krb_pac_server_checksum = -1;
183 static gint hf_krb_pac_privsvr_checksum = -1;
184 static gint hf_krb_pac_client_info_type = -1;
185 static gint hf_krb_pa_supported_enctypes = -1;
186 static gint hf_krb_pa_supported_enctypes_des_cbc_crc = -1;
187 static gint hf_krb_pa_supported_enctypes_des_cbc_md5 = -1;
188 static gint hf_krb_pa_supported_enctypes_rc4_hmac = -1;
189 static gint hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96 = -1;
190 static gint hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96 = -1;
191 static gint hf_krb_pa_supported_enctypes_fast_supported = -1;
192 static gint hf_krb_pa_supported_enctypes_compound_identity_supported = -1;
193 static gint hf_krb_pa_supported_enctypes_claims_supported = -1;
194 static gint hf_krb_pa_supported_enctypes_resource_sid_compression_disabled = -1;
195 static gint hf_krb_ad_ap_options = -1;
196 static gint hf_krb_ad_ap_options_cbt = -1;
197 #include "packet-kerberos-hf.c"
199 /* Initialize the subtree pointers */
200 static gint ett_kerberos = -1;
201 static gint ett_krb_recordmark = -1;
202 static gint ett_krb_pac = -1;
203 static gint ett_krb_pac_drep = -1;
204 static gint ett_krb_pac_midl_blob = -1;
205 static gint ett_krb_pac_logon_info = -1;
206 static gint ett_krb_pac_s4u_delegation_info = -1;
207 static gint ett_krb_pac_upn_dns_info = -1;
208 static gint ett_krb_pac_server_checksum = -1;
209 static gint ett_krb_pac_privsvr_checksum = -1;
210 static gint ett_krb_pac_client_info_type = -1;
211 static gint ett_krb_pa_supported_enctypes = -1;
212 static gint ett_krb_ad_ap_options = -1;
213 #include "packet-kerberos-ett.c"
215 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
216 static expert_field ei_kerberos_address = EI_INIT;
217 static expert_field ei_krb_gssapi_dlglen = EI_INIT;
219 static dissector_handle_t krb4_handle=NULL;
221 /* Global variables */
222 static guint32 krb5_errorcode;
223 static guint32 gbl_keytype;
224 static gboolean gbl_do_col_info;
226 #include "packet-kerberos-val.h"
229 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
237 cb->callback(pinfo, tvb, tree);
245 static kerberos_private_data_t*
246 kerberos_get_private_data(asn1_ctx_t *actx)
248 if (!actx->private_data) {
249 actx->private_data = wmem_new0(wmem_packet_scope(), kerberos_private_data_t);
251 return (kerberos_private_data_t *)(actx->private_data);
256 /* Decrypt Kerberos blobs */
257 gboolean krb_decrypt = FALSE;
259 /* keytab filename */
260 static const char *keytab_filename = "";
263 read_keytab_file_from_preferences(void)
265 static char *last_keytab = NULL;
271 if (keytab_filename == NULL) {
275 if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
280 last_keytab = g_strdup(keytab_filename);
282 read_keytab_file(last_keytab);
284 #endif /* HAVE_KERBEROS */
286 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
288 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
289 #undef HAVE_GETADDRINFO
290 #undef HAVE_SYS_TYPES_H
293 enc_key_t *enc_key_list=NULL;
296 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
300 if(pinfo->fd->visited){
304 printf("%d:%s:%s: added key in %u keytype:%d len:%d\n", __LINE__, G_STRFUNC, origin, pinfo->fd->num, keytype, keylength);
305 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
306 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->num);
307 new_key->fd_num = pinfo->num;
308 new_key->next=enc_key_list;
309 enc_key_list=new_key;
310 new_key->keytype=keytype;
311 new_key->keylength=keylength;
312 /*XXX this needs to be freed later */
313 new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
315 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
317 #if defined(HAVE_MIT_KERBEROS)
319 static krb5_context krb5_ctx;
321 USES_APPLE_DEPRECATED_API
323 read_keytab_file(const char *filename)
327 krb5_keytab_entry key;
328 krb5_kt_cursor cursor;
329 static gboolean first_time=TRUE;
331 if (filename == NULL || filename[0] == 0) {
337 ret = krb5_init_context(&krb5_ctx);
338 if(ret && ret != KRB5_CONFIG_CANTOPEN){
343 /* should use a file in the wireshark users dir */
344 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
346 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
351 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
353 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
358 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
364 new_key = g_new(enc_key_t, 1);
365 new_key->fd_num = -1;
366 new_key->next = enc_key_list;
368 /* generate origin string, describing where this key came from */
369 pos=new_key->key_origin;
370 pos+=MIN(KRB_MAX_ORIG_LEN,
371 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
372 for(i=0;i<key.principal->length;i++){
373 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
374 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data));
376 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
377 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "@%s",key.principal->realm.data));
379 new_key->keytype=key.key.enctype;
380 new_key->keylength=key.key.length;
381 new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
382 enc_key_list=new_key;
383 ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
385 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
386 ret = 0; /* try to continue with the next entry */
391 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
393 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
395 ret = krb5_kt_close(krb5_ctx, keytab);
397 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
403 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
411 krb5_data data = {0,0,NULL};
412 krb5_keytab_entry key;
413 int length = tvb_captured_length(cryptotvb);
414 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
416 /* don't do anything if we are not attempting to decrypt data */
417 if(!krb_decrypt || length < 1){
421 /* make sure we have all the data we need */
422 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
426 read_keytab_file_from_preferences();
427 data.data = (char *)wmem_alloc(pinfo->pool, length);
428 data.length = length;
430 for(ek=enc_key_list;ek;ek=ek->next){
433 /* shortcircuit and bail out if enctypes are not matching */
434 if((keytype != -1) && (ek->keytype != keytype)) {
438 input.enctype = ek->keytype;
439 input.ciphertext.length = length;
440 input.ciphertext.data = (guint8 *)cryptotext;
442 key.key.enctype=ek->keytype;
443 key.key.length=ek->keylength;
444 key.key.contents=ek->keyvalue;
445 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
449 printf("%d:%s:%s: woohoo decrypted keytype:%d in frame:%u\n", __LINE__, G_STRFUNC, ek->key_origin, ek->keytype, pinfo->fd->num);
450 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
451 "Decrypted keytype %d in frame %u using %s",
452 ek->keytype, pinfo->num, ek->key_origin);
454 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
458 *datalen = data.length;
468 #elif defined(HAVE_HEIMDAL_KERBEROS)
469 static krb5_context krb5_ctx;
471 USES_APPLE_DEPRECATED_API
473 read_keytab_file(const char *filename)
477 krb5_keytab_entry key;
478 krb5_kt_cursor cursor;
480 static gboolean first_time=TRUE;
482 if (filename == NULL || filename[0] == 0) {
488 ret = krb5_init_context(&krb5_ctx);
494 /* should use a file in the wireshark users dir */
495 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
497 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
502 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
504 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
509 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
514 new_key = g_new0(enc_key_t, 1);
515 new_key->fd_num = -1;
516 new_key->next = enc_key_list;
518 /* generate origin string, describing where this key came from */
519 pos=new_key->key_origin;
520 pos+=MIN(KRB_MAX_ORIG_LEN,
521 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
522 for(i=0;i<key.principal->name.name_string.len;i++){
523 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
524 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
526 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
527 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
529 new_key->keytype=key.keyblock.keytype;
530 new_key->keylength=(int)key.keyblock.keyvalue.length;
531 new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
532 enc_key_list=new_key;
533 ret = krb5_kt_free_entry(krb5_ctx, &key);
535 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
536 ret = 0; /* try to continue with the next entry */
541 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
543 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
545 ret = krb5_kt_close(krb5_ctx, keytab);
547 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
555 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
564 int length = tvb_captured_length(cryptotvb);
565 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
567 /* don't do anything if we are not attempting to decrypt data */
572 /* make sure we have all the data we need */
573 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
577 read_keytab_file_from_preferences();
579 for(ek=enc_key_list;ek;ek=ek->next){
580 krb5_keytab_entry key;
582 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
584 /* shortcircuit and bail out if enctypes are not matching */
585 if((keytype != -1) && (ek->keytype != keytype)) {
589 key.keyblock.keytype=ek->keytype;
590 key.keyblock.keyvalue.length=ek->keylength;
591 key.keyblock.keyvalue.data=ek->keyvalue;
592 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto);
597 /* pre-0.6.1 versions of Heimdal would sometimes change
598 the cryptotext data even when the decryption failed.
599 This would obviously not work since we iterate over the
600 keys. So just give it a copy of the crypto data instead.
601 This has been seen for RC4-HMAC blobs.
603 cryptocopy = (guint8 *)wmem_memdup(wmem_packet_scope(), cryptotext, length);
604 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
608 if((ret == 0) && (length>0)){
611 printf("%d:%s:%s: woohoo decrypted keytype:%d in frame:%u\n", __LINE__, G_STRFUNC, ek->key_origin, ek->keytype, pinfo->fd->num);
612 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
613 "Decrypted keytype %d in frame %u using %s",
614 ek->keytype, pinfo->num, ek->key_origin);
616 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
618 krb5_crypto_destroy(krb5_ctx, crypto);
619 /* return a private wmem_alloced blob to the caller */
620 user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
622 *datalen = (int)data.length;
626 krb5_crypto_destroy(krb5_ctx, crypto);
631 #elif defined (HAVE_LIBNETTLE)
633 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
634 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
636 typedef struct _service_key_t {
641 char origin[KRB_MAX_ORIG_LEN+1];
643 GSList *service_key_list = NULL;
647 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
649 service_key_t *new_key;
651 if(pinfo->fd->visited){
655 printf("%d:%s:%s: added key in %u keytype:%d len:%d\n", __LINE__, G_STRFUNC, origin, pinfo->fd->num, keytype, keylength);
657 new_key = g_malloc(sizeof(service_key_t));
659 new_key->keytype = keytype;
660 new_key->length = keylength;
661 new_key->contents = g_memdup(keyvalue, keylength);
662 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
663 service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
671 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
672 sk = (service_key_t *) ske->data;
674 g_free(sk->contents);
678 g_slist_free(service_key_list);
679 service_key_list = NULL;
683 read_keytab_file(const char *service_key_file)
688 unsigned char buf[SERVICE_KEY_SIZE];
689 int newline_skip = 0, count = 0;
691 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
693 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
694 * There can be zero, one (\n), or two (\r\n) characters between
695 * keys. Trailing characters are ignored.
698 /* XXX We should support the standard keytab format instead */
699 if (st.st_size > SERVICE_KEY_SIZE) {
700 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
701 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
703 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
704 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
709 skf = ws_fopen(service_key_file, "rb");
712 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
713 sk = g_malloc(sizeof(service_key_t));
714 sk->kvno = buf[0] << 8 | buf[1];
715 sk->keytype = KEYTYPE_DES3_CBC_MD5;
716 sk->length = DES3_KEY_SIZE;
717 sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
718 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
719 service_key_list = g_slist_append(service_key_list, (gpointer) sk);
720 if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
721 fprintf(stderr, "unable to seek...\n");
730 #define CONFOUNDER_PLUS_CHECKSUM 24
733 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
740 guint8 *decrypted_data = NULL, *plaintext = NULL;
743 guint32 tag, item_len, data_len;
744 int id_offset, offset;
745 guint8 key[DES3_KEY_SIZE];
746 guint8 initial_vector[DES_BLOCK_SIZE];
747 gcry_md_hd_t md5_handle;
749 guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
750 guint8 confounder[8];
755 int length = tvb_captured_length(cryptotvb);
756 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
759 /* don't do anything if we are not attempting to decrypt data */
764 /* make sure we have all the data we need */
765 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
769 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
773 decrypted_data = wmem_alloc(wmem_packet_scope(), length);
774 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
775 gboolean do_continue = FALSE;
777 sk = (service_key_t *) ske->data;
779 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
781 memset(initial_vector, 0, DES_BLOCK_SIZE);
782 des3_set_key(&ctx, key);
783 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
784 length, decrypted_data, cryptotext);
785 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
787 tvb_memcpy(encr_tvb, confounder, 0, 8);
789 /* We have to pull the decrypted data length from the decrypted
790 * content. If the key doesn't match or we otherwise get garbage,
791 * an exception may get thrown while decoding the ASN.1 header.
792 * Catch it, just in case.
795 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
796 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
798 CATCH_BOUNDS_ERRORS {
804 if (do_continue) continue;
806 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
807 if ((int) item_len + offset > length) {
812 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
815 gcry_md_write(md5_handle, confounder, 8);
816 gcry_md_write(md5_handle, zero_fill, 16);
817 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
818 digest = gcry_md_read(md5_handle, 0);
820 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
821 gcry_md_close(md5_handle);
823 plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
837 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
839 #define INET6_ADDRLEN 16
841 /* TCP Record Mark */
842 #define KRB_RM_RESERVED 0x80000000U
843 #define KRB_RM_RECLEN 0x7fffffffU
845 #define KRB5_MSG_TICKET 1 /* Ticket */
846 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
847 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
848 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
849 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
850 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
851 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
852 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
853 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
855 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
856 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
857 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
858 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
859 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
860 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
861 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
862 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
863 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
865 #define KRB5_CHKSUM_GSSAPI 0x8003
867 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
869 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
871 * unless it's expired.
874 /* Principal name-type */
875 #define KRB5_NT_UNKNOWN 0
876 #define KRB5_NT_PRINCIPAL 1
877 #define KRB5_NT_SRV_INST 2
878 #define KRB5_NT_SRV_HST 3
879 #define KRB5_NT_SRV_XHST 4
880 #define KRB5_NT_UID 5
881 #define KRB5_NT_X500_PRINCIPAL 6
882 #define KRB5_NT_SMTP_NAME 7
883 #define KRB5_NT_ENTERPRISE 10
886 * MS specific name types, from
888 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
890 #define KRB5_NT_MS_PRINCIPAL -128
891 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
892 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
893 #define KRB5_NT_PRINCIPAL_AND_SID -131
894 #define KRB5_NT_SRV_INST_AND_SID -132
896 /* error table constants */
897 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
898 #define KRB5_ET_KRB5KDC_ERR_NONE 0
899 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
900 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
901 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
902 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
903 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
904 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
905 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
906 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
907 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
908 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
909 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
910 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
911 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
912 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
913 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
914 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
915 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
916 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
917 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
918 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
919 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
920 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
921 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
922 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
923 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
924 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
925 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
926 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
927 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
928 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
929 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
930 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
931 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
932 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
933 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
934 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
935 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
936 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
937 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
938 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
939 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
940 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
941 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
942 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
943 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
944 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
945 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
946 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
947 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
948 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
949 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
950 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
951 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
952 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
953 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
954 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
955 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
956 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
957 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
958 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
959 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
960 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
961 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
962 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
963 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
964 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
965 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
966 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
968 static const value_string krb5_error_codes[] = {
969 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
970 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
971 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
972 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
973 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
974 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
975 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
976 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
977 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
978 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
979 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
980 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
981 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
982 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
983 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
984 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
985 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
986 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
987 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
988 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
989 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
990 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
991 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
992 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
993 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
994 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
995 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
996 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
997 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
998 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
999 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1000 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1001 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1002 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1003 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1004 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1005 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1006 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1007 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1008 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1009 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1010 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1011 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1012 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1013 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1014 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1015 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1016 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1017 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1018 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1019 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1020 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1021 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1022 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1023 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1024 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1025 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1026 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1027 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1028 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1029 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1030 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1031 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1032 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1033 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1034 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1035 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1036 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1037 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1042 #define PAC_LOGON_INFO 1
1043 #define PAC_CREDENTIAL_TYPE 2
1044 #define PAC_SERVER_CHECKSUM 6
1045 #define PAC_PRIVSVR_CHECKSUM 7
1046 #define PAC_CLIENT_INFO_TYPE 10
1047 #define PAC_S4U_DELEGATION_INFO 11
1048 #define PAC_UPN_DNS_INFO 12
1049 static const value_string w2k_pac_types[] = {
1050 { PAC_LOGON_INFO , "Logon Info" },
1051 { PAC_CREDENTIAL_TYPE , "Credential Type" },
1052 { PAC_SERVER_CHECKSUM , "Server Checksum" },
1053 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
1054 { PAC_CLIENT_INFO_TYPE , "Client Info Type" },
1055 { PAC_S4U_DELEGATION_INFO, "S4U Delegation Info" },
1056 { PAC_UPN_DNS_INFO , "UPN DNS Info" },
1060 static const value_string krb5_msg_types[] = {
1061 { KRB5_MSG_TICKET, "Ticket" },
1062 { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
1063 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
1064 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
1065 { KRB5_MSG_TGS_REP, "TGS-REP" },
1066 { KRB5_MSG_AS_REQ, "AS-REQ" },
1067 { KRB5_MSG_AS_REP, "AS-REP" },
1068 { KRB5_MSG_AP_REQ, "AP-REQ" },
1069 { KRB5_MSG_AP_REP, "AP-REP" },
1070 { KRB5_MSG_SAFE, "KRB-SAFE" },
1071 { KRB5_MSG_PRIV, "KRB-PRIV" },
1072 { KRB5_MSG_CRED, "KRB-CRED" },
1073 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
1074 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
1075 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
1076 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1077 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1078 { KRB5_MSG_ERROR, "KRB-ERROR" },
1082 #define KRB5_GSS_C_DELEG_FLAG 0x01
1083 #define KRB5_GSS_C_MUTUAL_FLAG 0x02
1084 #define KRB5_GSS_C_REPLAY_FLAG 0x04
1085 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08
1086 #define KRB5_GSS_C_CONF_FLAG 0x10
1087 #define KRB5_GSS_C_INTEG_FLAG 0x20
1088 #define KRB5_GSS_C_DCE_STYLE 0x1000
1090 static const true_false_string tfs_gss_flags_deleg = {
1091 "Delegate credentials to remote peer",
1094 static const true_false_string tfs_gss_flags_mutual = {
1095 "Request that remote peer authenticates itself",
1096 "Mutual authentication NOT required"
1098 static const true_false_string tfs_gss_flags_replay = {
1099 "Enable replay protection for signed or sealed messages",
1100 "Do NOT enable replay protection"
1102 static const true_false_string tfs_gss_flags_sequence = {
1103 "Enable Out-of-sequence detection for sign or sealed messages",
1104 "Do NOT enable out-of-sequence detection"
1106 static const true_false_string tfs_gss_flags_conf = {
1107 "Confidentiality (sealing) may be invoked",
1108 "Do NOT use Confidentiality (sealing)"
1110 static const true_false_string tfs_gss_flags_integ = {
1111 "Integrity protection (signing) may be invoked",
1112 "Do NOT use integrity protection"
1115 static const true_false_string tfs_gss_flags_dce_style = {
1117 "Not using DCE-STYLE"
1120 #ifdef HAVE_KERBEROS
1122 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1123 proto_tree *tree, int hf_index _U_)
1127 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1130 next_tvb=tvb_new_subset_remaining(tvb, offset);
1131 length=tvb_captured_length_remaining(tvb, offset);
1133 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1135 * All Ticket encrypted parts use usage == 2
1137 plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, private_data->etype, NULL);
1140 tvbuff_t *child_tvb;
1141 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1143 /* Add the decrypted data to the data source list. */
1144 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1146 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1152 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1153 proto_tree *tree, int hf_index _U_)
1157 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1160 next_tvb=tvb_new_subset_remaining(tvb, offset);
1161 length=tvb_captured_length_remaining(tvb, offset);
1163 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1165 * Authenticators are encrypted with usage
1169 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, private_data->etype, NULL);
1172 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, private_data->etype, NULL);
1176 tvbuff_t *child_tvb;
1177 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1179 /* Add the decrypted data to the data source list. */
1180 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1182 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1188 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1189 proto_tree *tree, int hf_index _U_)
1193 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1196 next_tvb=tvb_new_subset_remaining(tvb, offset);
1197 length=tvb_captured_length_remaining(tvb, offset);
1199 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1201 * ASREP/TGSREP encryptedparts are encrypted with usage
1206 plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, private_data->etype, NULL);
1209 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, private_data->etype, NULL);
1213 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, private_data->etype, NULL);
1217 tvbuff_t *child_tvb;
1218 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1220 /* Add the decrypted data to the data source list. */
1221 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1223 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1229 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1230 proto_tree *tree, int hf_index _U_)
1234 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1237 next_tvb=tvb_new_subset_remaining(tvb, offset);
1238 length=tvb_captured_length_remaining(tvb, offset);
1240 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1242 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1245 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, private_data->etype, NULL);
1248 tvbuff_t *child_tvb;
1249 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1251 /* Add the decrypted data to the data source list. */
1252 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1254 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1260 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1261 proto_tree *tree, int hf_index _U_)
1265 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1268 next_tvb=tvb_new_subset_remaining(tvb, offset);
1269 length=tvb_captured_length_remaining(tvb, offset);
1271 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1273 * AP-REP are encrypted with usage == 12
1275 plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, private_data->etype, NULL);
1278 tvbuff_t *child_tvb;
1279 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1281 /* Add the decrypted data to the data source list. */
1282 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1284 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1290 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1291 proto_tree *tree, int hf_index _U_)
1295 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1298 next_tvb=tvb_new_subset_remaining(tvb, offset);
1299 length=tvb_captured_length_remaining(tvb, offset);
1302 * EncKrbPrivPart encrypted with usage
1305 plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, private_data->etype, NULL);
1308 tvbuff_t *child_tvb;
1309 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1311 /* Add the decrypted data to the data source list. */
1312 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1314 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1320 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1321 proto_tree *tree, int hf_index _U_)
1325 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1328 next_tvb=tvb_new_subset_remaining(tvb, offset);
1329 length=tvb_captured_length_remaining(tvb, offset);
1332 * EncKrbCredPart encrypted with usage
1335 plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, private_data->etype, NULL);
1338 tvbuff_t *child_tvb;
1339 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1341 /* Add the decrypted data to the data source list. */
1342 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1344 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1350 dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1351 proto_tree *tree, int hf_index _U_)
1355 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1358 next_tvb=tvb_new_subset_remaining(tvb, offset);
1359 length=tvb_captured_length_remaining(tvb, offset);
1362 * KrbFastResponse encrypted with usage
1363 * KEY_USAGE_FAST_ENC 51
1365 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_ENC,
1366 next_tvb, private_data->etype, NULL);
1369 tvbuff_t *child_tvb;
1370 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1371 tvb_set_free_cb(child_tvb, g_free);
1373 /* Add the decrypted data to the data source list. */
1374 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1376 offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1382 dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1383 proto_tree *tree, int hf_index _U_)
1387 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1390 next_tvb=tvb_new_subset_remaining(tvb, offset);
1391 length=tvb_captured_length_remaining(tvb, offset);
1395 * KrbFastResponse encrypted with usage
1396 * KEY_USAGE_FAST_REP 52
1398 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_REP,
1399 next_tvb, private_data->etype, NULL);
1402 tvbuff_t *child_tvb;
1403 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1404 tvb_set_free_cb(child_tvb, g_free);
1406 /* Add the decrypted data to the data source list. */
1407 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1409 offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1415 dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1416 proto_tree *tree, int hf_index _U_)
1420 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1424 next_tvb=tvb_new_subset_remaining(tvb, offset);
1425 length=tvb_captured_length_remaining(tvb, offset);
1428 * KEY_USAGE_ENC_CHALLENGE_CLIENT 54
1429 * KEY_USAGE_ENC_CHALLENGE_KDC 55
1431 if (private_data->kdc_response) {
1432 usage = KEY_USAGE_ENC_CHALLENGE_KDC;
1434 usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
1436 plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, private_data->etype, NULL);
1439 tvbuff_t *child_tvb;
1440 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1441 tvb_set_free_cb(child_tvb, g_free);
1443 /* Add the decrypted data to the data source list. */
1444 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1446 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1452 static const int *hf_krb_pa_supported_enctypes_fields[] = {
1453 &hf_krb_pa_supported_enctypes_des_cbc_crc,
1454 &hf_krb_pa_supported_enctypes_des_cbc_md5,
1455 &hf_krb_pa_supported_enctypes_rc4_hmac,
1456 &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
1457 &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
1458 &hf_krb_pa_supported_enctypes_fast_supported,
1459 &hf_krb_pa_supported_enctypes_compound_identity_supported,
1460 &hf_krb_pa_supported_enctypes_claims_supported,
1461 &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
1465 static const true_false_string supported_tfs = {
1466 "Supported", "Not supported"
1470 dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1471 int offset _U_, asn1_ctx_t *actx _U_,
1472 proto_tree *tree _U_, int hf_index _U_)
1474 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1475 hf_krb_pa_supported_enctypes,
1476 ett_krb_pa_supported_enctypes,
1477 hf_krb_pa_supported_enctypes_fields,
1484 static const int *hf_krb_ad_ap_options_fields[] = {
1485 &hf_krb_ad_ap_options_cbt,
1489 static const true_false_string set_tfs = {
1494 dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1495 int offset _U_, asn1_ctx_t *actx _U_,
1496 proto_tree *tree _U_, int hf_index _U_)
1498 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1499 hf_krb_ad_ap_options,
1500 ett_krb_ad_ap_options,
1501 hf_krb_ad_ap_options_fields,
1507 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1510 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1516 /* Length of Bnd field */
1517 len=tvb_get_letohl(tvb, offset);
1518 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1522 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1527 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1528 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1529 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1530 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1531 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1532 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1533 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1536 /* the next fields are optional so we have to check that we have
1537 * more data in our buffers */
1538 if(tvb_reported_length_remaining(tvb, offset)<2){
1541 /* dlgopt identifier */
1542 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1545 if(tvb_reported_length_remaining(tvb, offset)<2){
1548 /* dlglen identifier */
1549 dlglen=tvb_get_letohs(tvb, offset);
1550 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1553 if(dlglen!=tvb_reported_length_remaining(tvb, offset)){
1554 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0,
1555 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset));
1559 /* this should now be a KRB_CRED message */
1560 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1566 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_)
1568 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1574 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_)
1578 /* Microsoft stores a special 12 byte blob here
1582 * decode everything as this blob for now until we see if anyone
1583 * else ever uses it or we learn how to tell whether this
1584 * is such an MS blob or not.
1586 proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
1588 nt_status=tvb_get_letohl(tvb, offset);
1590 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
1592 val_to_str(nt_status, NT_errors,
1593 "Unknown error code %#x"));
1597 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1601 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1609 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
1614 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
1616 val = tvb_get_guint8(tvb, offset);
1617 proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
1628 /* This might be some sort of header that MIDL generates when creating
1629 * marshalling/unmarshalling code for blobs that are not to be transported
1630 * ontop of DCERPC and where the DREP fields specifying things such as
1631 * endianess and similar are not available.
1634 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
1638 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header");
1640 /* modified DREP field that is used for stuff that is transporetd ontop
1643 proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1646 offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
1649 proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1652 proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1655 /* length of blob that follows */
1656 proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1663 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1667 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1668 static dcerpc_info di; /* fake dcerpc_info struct */
1669 static dcerpc_call_value call_data;
1671 item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
1672 tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
1674 /* skip the first 16 bytes, they are some magic created by the idl
1675 * compiler the first 4 bytes might be flags?
1677 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1679 /* the PAC_LOGON_INFO blob */
1680 /* fake whatever state the dcerpc runtime support needs */
1681 di.conformant_run=0;
1682 /* we need di->call_data->flags.NDR64 == 0 */
1683 di.call_data=&call_data;
1684 init_ndr_pointer_list(&di);
1685 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1686 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
1687 "PAC_LOGON_INFO:", -1);
1693 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1697 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1698 static dcerpc_info di; /* fake dcerpc_info struct */
1699 static dcerpc_call_value call_data;
1701 item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
1702 tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
1704 /* skip the first 16 bytes, they are some magic created by the idl
1705 * compiler the first 4 bytes might be flags?
1707 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1710 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
1711 /* fake whatever state the dcerpc runtime support needs */
1712 di.conformant_run=0;
1713 /* we need di->call_data->flags.NDR64 == 0 */
1714 di.call_data=&call_data;
1715 init_ndr_pointer_list(&di);
1716 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1717 netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
1718 "PAC_S4U_DELEGATION_INFO:", -1);
1724 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1728 guint16 dns_offset, dns_len;
1729 guint16 upn_offset, upn_len;
1734 item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
1735 tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
1738 upn_len = tvb_get_letohs(tvb, offset);
1739 proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1741 upn_offset = tvb_get_letohs(tvb, offset);
1742 proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1746 dns_len = tvb_get_letohs(tvb, offset);
1747 proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1749 dns_offset = tvb_get_letohs(tvb, offset);
1750 proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1754 proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1757 offset = upn_offset;
1759 bc = tvb_reported_length_remaining(tvb, offset);
1760 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1761 proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
1764 offset = dns_offset;
1766 bc = tvb_reported_length_remaining(tvb, offset);
1767 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1768 proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
1774 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1776 proto_tree_add_item(parent_tree, hf_krb_pac_credential_type, tvb, offset, -1, ENC_NA);
1782 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1787 item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA);
1788 tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum);
1790 /* signature type */
1791 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1794 /* signature data */
1795 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1801 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1806 item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA);
1807 tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum);
1809 /* signature type */
1810 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1813 /* signature data */
1814 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1820 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1826 item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
1827 tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
1830 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
1833 namelen=tvb_get_letohs(tvb, offset);
1834 proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
1838 proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
1845 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1850 proto_item *it=NULL;
1851 proto_tree *tr=NULL;
1854 /* type of pac data */
1855 pac_type=tvb_get_letohl(tvb, offset);
1856 it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
1857 tr=proto_item_add_subtree(it, ett_krb_pac);
1861 /* size of pac data */
1862 pac_size=tvb_get_letohl(tvb, offset);
1863 proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
1866 /* offset to pac data */
1867 pac_offset=tvb_get_letohl(tvb, offset);
1868 proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
1871 next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size);
1873 case PAC_LOGON_INFO:
1874 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
1876 case PAC_CREDENTIAL_TYPE:
1877 dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
1879 case PAC_SERVER_CHECKSUM:
1880 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
1882 case PAC_PRIVSVR_CHECKSUM:
1883 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
1885 case PAC_CLIENT_INFO_TYPE:
1886 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
1888 case PAC_S4U_DELEGATION_INFO:
1889 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
1891 case PAC_UPN_DNS_INFO:
1892 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
1902 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_)
1908 /* first in the PAC structure comes the number of entries */
1909 entries=tvb_get_letohl(tvb, offset);
1910 proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
1913 /* second comes the version */
1914 version=tvb_get_letohl(tvb, offset);
1915 proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
1918 for(i=0;i<entries;i++){
1919 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
1925 #include "packet-kerberos-fn.c"
1927 /* Make wrappers around exported functions for now */
1929 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1931 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
1936 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1938 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
1943 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1945 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
1948 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1950 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
1955 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1956 gboolean dci, gboolean do_col_protocol, gboolean have_rm,
1957 kerberos_callbacks *cb)
1959 volatile int offset = 0;
1960 proto_tree *volatile kerberos_tree = NULL;
1961 proto_item *volatile item = NULL;
1962 asn1_ctx_t asn1_ctx;
1964 /* TCP record mark and length */
1966 gint krb_reclen = 0;
1968 gbl_do_col_info=dci;
1971 krb_rm = tvb_get_ntohl(tvb, offset);
1972 krb_reclen = kerberos_rm_to_reclen(krb_rm);
1974 * What is a reasonable size limit?
1976 if (krb_reclen > 10 * 1024 * 1024) {
1980 if (do_col_protocol) {
1981 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1985 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1986 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1989 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1992 /* Do some sanity checking here,
1993 * All krb5 packets start with a TAG class that is BER_CLASS_APP
1994 * and a tag value that is either of the values below:
1995 * If it doesn't look like kerberos, return 0 and let someone else have
2002 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
2003 if(tmp_class!=BER_CLASS_APP){
2007 case KRB5_MSG_TICKET:
2008 case KRB5_MSG_AUTHENTICATOR:
2009 case KRB5_MSG_ENC_TICKET_PART:
2010 case KRB5_MSG_AS_REQ:
2011 case KRB5_MSG_AS_REP:
2012 case KRB5_MSG_TGS_REQ:
2013 case KRB5_MSG_TGS_REP:
2014 case KRB5_MSG_AP_REQ:
2015 case KRB5_MSG_AP_REP:
2016 case KRB5_MSG_ENC_AS_REP_PART:
2017 case KRB5_MSG_ENC_TGS_REP_PART:
2018 case KRB5_MSG_ENC_AP_REP_PART:
2019 case KRB5_MSG_ENC_KRB_PRIV_PART:
2020 case KRB5_MSG_ENC_KRB_CRED_PART:
2023 case KRB5_MSG_ERROR:
2028 if (do_col_protocol) {
2029 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2031 if (gbl_do_col_info) {
2032 col_clear(pinfo->cinfo, COL_INFO);
2035 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
2036 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
2039 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2040 asn1_ctx.private_data = cb;
2043 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
2044 } CATCH_BOUNDS_ERRORS {
2048 proto_item_set_len(item, offset);
2053 * Display the TCP record mark.
2056 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
2059 proto_tree *rm_tree;
2064 rec_len = kerberos_rm_to_reclen(krb_rm);
2065 rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL,
2066 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
2067 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
2068 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
2072 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
2074 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
2078 kerberos_output_keytype(void)
2084 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2086 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
2087 Since all (except weirdo transarc krb4 stuff) use
2088 an opcode <=16 in the first byte, use this to see if it might
2090 All krb5 commands start with an APPL tag and thus is >=0x60
2091 so if first byte is <=16 just blindly assume it is krb4 then
2093 if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
2097 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
2105 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
2109 kerberos_rm_to_reclen(guint krb_rm)
2111 return (krb_rm & KRB_RM_RECLEN);
2115 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2120 krb_rm = tvb_get_ntohl(tvb, offset);
2121 pdulen = kerberos_rm_to_reclen(krb_rm);
2122 return (pdulen + 4);
2125 kerberos_prefs_apply_cb(void) {
2126 #ifdef HAVE_LIBNETTLE
2128 read_keytab_file(keytab_filename);
2133 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2135 pinfo->fragmented = TRUE;
2136 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
2138 * The dissector failed to recognize this as a valid
2139 * Kerberos message. Mark it as a continuation packet.
2141 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
2144 return tvb_captured_length(tvb);
2148 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2150 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2151 col_clear(pinfo->cinfo, COL_INFO);
2153 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
2154 dissect_kerberos_tcp_pdu, data);
2155 return tvb_captured_length(tvb);
2158 /*--- proto_register_kerberos -------------------------------------------*/
2159 void proto_register_kerberos(void) {
2161 /* List of fields */
2163 static hf_register_info hf[] = {
2164 { &hf_krb_rm_reserved, {
2165 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
2166 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
2167 { &hf_krb_rm_reclen, {
2168 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
2169 NULL, KRB_RM_RECLEN, NULL, HFILL }},
2170 { &hf_krb_provsrv_location, {
2171 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
2172 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
2173 { &hf_krb_smb_nt_status,
2174 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
2175 VALS(NT_errors), 0, "NT Status code", HFILL }},
2176 { &hf_krb_smb_unknown,
2177 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
2178 NULL, 0, NULL, HFILL }},
2179 { &hf_krb_address_ip, {
2180 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
2181 NULL, 0, NULL, HFILL }},
2182 { &hf_krb_address_ipv6, {
2183 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
2184 NULL, 0, NULL, HFILL }},
2185 { &hf_krb_address_netbios, {
2186 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
2187 NULL, 0, "NetBIOS Address and type", HFILL }},
2188 { &hf_krb_gssapi_len, {
2189 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
2190 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
2191 { &hf_krb_gssapi_bnd, {
2192 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
2193 NULL, 0, "GSSAPI Bnd field", HFILL }},
2194 { &hf_krb_gssapi_c_flag_deleg, {
2195 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
2196 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
2197 { &hf_krb_gssapi_c_flag_mutual, {
2198 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
2199 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
2200 { &hf_krb_gssapi_c_flag_replay, {
2201 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
2202 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
2203 { &hf_krb_gssapi_c_flag_sequence, {
2204 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
2205 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
2206 { &hf_krb_gssapi_c_flag_conf, {
2207 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
2208 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
2209 { &hf_krb_gssapi_c_flag_integ, {
2210 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
2211 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
2212 { &hf_krb_gssapi_c_flag_dce_style, {
2213 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
2214 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
2215 { &hf_krb_gssapi_dlgopt, {
2216 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
2217 NULL, 0, "GSSAPI DlgOpt", HFILL }},
2218 { &hf_krb_gssapi_dlglen, {
2219 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
2220 NULL, 0, "GSSAPI DlgLen", HFILL }},
2221 { &hf_krb_midl_blob_len, {
2222 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
2223 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
2224 { &hf_krb_midl_fill_bytes, {
2225 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
2226 NULL, 0, "Just some fill bytes", HFILL }},
2227 { &hf_krb_midl_version, {
2228 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
2229 NULL, 0, "Version of pickling", HFILL }},
2230 { &hf_krb_midl_hdr_len, {
2231 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
2232 NULL, 0, "Length of header", HFILL }},
2233 { &hf_krb_pac_signature_type, {
2234 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
2235 NULL, 0, "PAC Signature Type", HFILL }},
2236 { &hf_krb_pac_signature_signature, {
2237 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
2238 NULL, 0, "A PAC signature blob", HFILL }},
2239 { &hf_krb_w2k_pac_entries, {
2240 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
2241 NULL, 0, "Number of W2k PAC entries", HFILL }},
2242 { &hf_krb_w2k_pac_version, {
2243 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
2244 NULL, 0, "Version of PAC structures", HFILL }},
2245 { &hf_krb_w2k_pac_type, {
2246 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
2247 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
2248 { &hf_krb_w2k_pac_size, {
2249 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
2250 NULL, 0, "Size of W2k PAC entry", HFILL }},
2251 { &hf_krb_w2k_pac_offset, {
2252 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
2253 NULL, 0, "Offset to W2k PAC entry", HFILL }},
2254 { &hf_krb_pac_clientid, {
2255 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2256 NULL, 0, "ClientID Timestamp", HFILL }},
2257 { &hf_krb_pac_namelen, {
2258 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
2259 NULL, 0, "Length of client name", HFILL }},
2260 { &hf_krb_pac_clientname, {
2261 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
2262 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
2263 { &hf_krb_pac_logon_info, {
2264 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE,
2265 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
2266 { &hf_krb_pac_credential_type, {
2267 "PAC_CREDENTIAL_TYPE", "kerberos.pac_credential_type", FT_BYTES, BASE_NONE,
2268 NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
2269 { &hf_krb_pac_server_checksum, {
2270 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE,
2271 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
2272 { &hf_krb_pac_privsvr_checksum, {
2273 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE,
2274 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
2275 { &hf_krb_pac_client_info_type, {
2276 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE,
2277 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
2278 { &hf_krb_pac_s4u_delegation_info, {
2279 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE,
2280 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
2281 { &hf_krb_pac_upn_dns_info, {
2282 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE,
2283 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
2284 { &hf_krb_pac_upn_flags, {
2285 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
2286 NULL, 0, "UPN flags", HFILL }},
2287 { &hf_krb_pac_upn_dns_offset, {
2288 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
2289 NULL, 0, NULL, HFILL }},
2290 { &hf_krb_pac_upn_dns_len, {
2291 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
2292 NULL, 0, NULL, HFILL }},
2293 { &hf_krb_pac_upn_upn_offset, {
2294 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
2295 NULL, 0, NULL, HFILL }},
2296 { &hf_krb_pac_upn_upn_len, {
2297 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
2298 NULL, 0, NULL, HFILL }},
2299 { &hf_krb_pac_upn_upn_name, {
2300 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
2301 NULL, 0, NULL, HFILL }},
2302 { &hf_krb_pac_upn_dns_name, {
2303 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
2304 NULL, 0, NULL, HFILL }},
2305 { &hf_krb_pa_supported_enctypes,
2306 { "SupportedEnctypes", "kerberos.supported_entypes",
2307 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2308 { &hf_krb_pa_supported_enctypes_des_cbc_crc,
2309 { "des-cbc-crc", "kerberos.supported_entypes.des-cbc-crc",
2310 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000001, NULL, HFILL }},
2311 { &hf_krb_pa_supported_enctypes_des_cbc_md5,
2312 { "des-cbc-md5", "kerberos.supported_entypes.des-cbc-md5",
2313 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000002, NULL, HFILL }},
2314 { &hf_krb_pa_supported_enctypes_rc4_hmac,
2315 { "rc4-hmac", "kerberos.supported_entypes.rc4-hmac",
2316 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000004, NULL, HFILL }},
2317 { &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
2318 { "aes128-cts-hmac-sha1-96", "kerberos.supported_entypes.aes128-cts-hmac-sha1-96",
2319 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000008, NULL, HFILL }},
2320 { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
2321 { "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96",
2322 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000010, NULL, HFILL }},
2323 { &hf_krb_pa_supported_enctypes_fast_supported,
2324 { "fast-supported", "kerberos.supported_entypes.fast-supported",
2325 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00010000, NULL, HFILL }},
2326 { &hf_krb_pa_supported_enctypes_compound_identity_supported,
2327 { "compound-identity-supported", "kerberos.supported_entypes.compound-identity-supported",
2328 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00020000, NULL, HFILL }},
2329 { &hf_krb_pa_supported_enctypes_claims_supported,
2330 { "claims-supported", "kerberos.supported_entypes.claims-supported",
2331 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2332 { &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
2333 { "resource-sid-compression-disabled", "kerberos.supported_entypes.resource-sid-compression-disabled",
2334 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2335 { &hf_krb_ad_ap_options,
2336 { "AD-AP-Options", "kerberos.ad_ap_options",
2337 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2338 { &hf_krb_ad_ap_options_cbt,
2339 { "ChannelBindings", "kerberos.ad_ap_options.cbt",
2340 FT_BOOLEAN, 32, TFS(&set_tfs), 0x00004000, NULL, HFILL }},
2342 #include "packet-kerberos-hfarr.c"
2345 /* List of subtrees */
2346 static gint *ett[] = {
2348 &ett_krb_recordmark,
2351 &ett_krb_pac_midl_blob,
2352 &ett_krb_pac_logon_info,
2353 &ett_krb_pac_s4u_delegation_info,
2354 &ett_krb_pac_upn_dns_info,
2355 &ett_krb_pac_server_checksum,
2356 &ett_krb_pac_privsvr_checksum,
2357 &ett_krb_pac_client_info_type,
2358 &ett_krb_pa_supported_enctypes,
2359 &ett_krb_ad_ap_options,
2360 #include "packet-kerberos-ettarr.c"
2363 static ei_register_info ei[] = {
2364 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
2365 { &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 }},
2366 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }},
2369 expert_module_t* expert_krb;
2370 module_t *krb_module;
2372 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
2373 proto_register_field_array(proto_kerberos, hf, array_length(hf));
2374 proto_register_subtree_array(ett, array_length(ett));
2375 expert_krb = expert_register_protocol(proto_kerberos);
2376 expert_register_field_array(expert_krb, ei, array_length(ei));
2378 /* Register preferences */
2379 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2380 prefs_register_bool_preference(krb_module, "desegment",
2381 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2382 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2383 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2385 #ifdef HAVE_KERBEROS
2386 prefs_register_bool_preference(krb_module, "decrypt",
2387 "Try to decrypt Kerberos blobs",
2388 "Whether the dissector should try to decrypt "
2389 "encrypted Kerberos blobs. This requires that the proper "
2390 "keytab file is installed as well.", &krb_decrypt);
2392 prefs_register_filename_preference(krb_module, "file",
2393 "Kerberos keytab file",
2394 "The keytab file containing all the secrets",
2395 &keytab_filename, FALSE);
2399 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2400 proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
2404 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2406 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2408 return tvb_captured_length_remaining(tvb, offset);
2412 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2413 wrap_dissect_gss_kerb, /* Bind */
2414 wrap_dissect_gss_kerb, /* Bind ACK */
2415 wrap_dissect_gss_kerb, /* AUTH3 */
2416 NULL, /* Request verifier */
2417 NULL, /* Response verifier */
2418 NULL, /* Request data */
2419 NULL /* Response data */
2422 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2423 wrap_dissect_gss_kerb, /* Bind */
2424 wrap_dissect_gss_kerb, /* Bind ACK */
2425 wrap_dissect_gss_kerb, /* AUTH3 */
2426 wrap_dissect_gssapi_verf, /* Request verifier */
2427 wrap_dissect_gssapi_verf, /* Response verifier */
2428 NULL, /* Request data */
2429 NULL /* Response data */
2432 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2433 wrap_dissect_gss_kerb, /* Bind */
2434 wrap_dissect_gss_kerb, /* Bind ACK */
2435 wrap_dissect_gss_kerb, /* AUTH3 */
2436 wrap_dissect_gssapi_verf, /* Request verifier */
2437 wrap_dissect_gssapi_verf, /* Response verifier */
2438 wrap_dissect_gssapi_payload, /* Request data */
2439 wrap_dissect_gssapi_payload /* Response data */
2445 proto_reg_handoff_kerberos(void)
2447 dissector_handle_t kerberos_handle_tcp;
2449 krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos);
2451 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
2454 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
2457 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
2458 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
2460 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2461 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2462 &gss_kerb_auth_connect_fns);
2464 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2465 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2466 &gss_kerb_auth_sign_fns);
2468 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2469 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2470 &gss_kerb_auth_seal_fns);
2474 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2479 * indent-tabs-mode: t
2482 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2483 * :indentSize=8:tabSize=8:noTabs=false: