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 } kerberos_private_data_t;
107 static dissector_handle_t kerberos_handle_udp;
109 /* Forward declarations */
110 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_);
111 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_);
112 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_);
113 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_);
114 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_);
115 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_);
116 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_);
117 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_);
118 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_);
119 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_);
120 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_);
121 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_);
122 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_);
123 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_);
124 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_);
125 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_);
126 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_);
127 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_);
128 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_);
130 /* Desegment Kerberos over TCP messages */
131 static gboolean krb_desegment = TRUE;
133 static gint proto_kerberos = -1;
135 static gint hf_krb_rm_reserved = -1;
136 static gint hf_krb_rm_reclen = -1;
137 static gint hf_krb_provsrv_location = -1;
138 static gint hf_krb_smb_nt_status = -1;
139 static gint hf_krb_smb_unknown = -1;
140 static gint hf_krb_address_ip = -1;
141 static gint hf_krb_address_netbios = -1;
142 static gint hf_krb_address_ipv6 = -1;
143 static gint hf_krb_gssapi_len = -1;
144 static gint hf_krb_gssapi_bnd = -1;
145 static gint hf_krb_gssapi_dlgopt = -1;
146 static gint hf_krb_gssapi_dlglen = -1;
147 static gint hf_krb_gssapi_c_flag_deleg = -1;
148 static gint hf_krb_gssapi_c_flag_mutual = -1;
149 static gint hf_krb_gssapi_c_flag_replay = -1;
150 static gint hf_krb_gssapi_c_flag_sequence = -1;
151 static gint hf_krb_gssapi_c_flag_conf = -1;
152 static gint hf_krb_gssapi_c_flag_integ = -1;
153 static gint hf_krb_gssapi_c_flag_dce_style = -1;
154 static gint hf_krb_midl_version = -1;
155 static gint hf_krb_midl_hdr_len = -1;
156 static gint hf_krb_midl_fill_bytes = -1;
157 static gint hf_krb_midl_blob_len = -1;
158 static gint hf_krb_pac_signature_type = -1;
159 static gint hf_krb_pac_signature_signature = -1;
160 static gint hf_krb_w2k_pac_entries = -1;
161 static gint hf_krb_w2k_pac_version = -1;
162 static gint hf_krb_w2k_pac_type = -1;
163 static gint hf_krb_w2k_pac_size = -1;
164 static gint hf_krb_w2k_pac_offset = -1;
165 static gint hf_krb_pac_clientid = -1;
166 static gint hf_krb_pac_namelen = -1;
167 static gint hf_krb_pac_clientname = -1;
168 static gint hf_krb_pac_logon_info = -1;
169 static gint hf_krb_pac_credential_type = -1;
170 static gint hf_krb_pac_s4u_delegation_info = -1;
171 static gint hf_krb_pac_upn_dns_info = -1;
172 static gint hf_krb_pac_upn_flags = -1;
173 static gint hf_krb_pac_upn_dns_offset = -1;
174 static gint hf_krb_pac_upn_dns_len = -1;
175 static gint hf_krb_pac_upn_upn_offset = -1;
176 static gint hf_krb_pac_upn_upn_len = -1;
177 static gint hf_krb_pac_upn_upn_name = -1;
178 static gint hf_krb_pac_upn_dns_name = -1;
179 static gint hf_krb_pac_server_checksum = -1;
180 static gint hf_krb_pac_privsvr_checksum = -1;
181 static gint hf_krb_pac_client_info_type = -1;
182 static gint hf_krb_pa_supported_enctypes = -1;
183 static gint hf_krb_pa_supported_enctypes_des_cbc_crc = -1;
184 static gint hf_krb_pa_supported_enctypes_des_cbc_md5 = -1;
185 static gint hf_krb_pa_supported_enctypes_rc4_hmac = -1;
186 static gint hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96 = -1;
187 static gint hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96 = -1;
188 static gint hf_krb_pa_supported_enctypes_fast_supported = -1;
189 static gint hf_krb_pa_supported_enctypes_compound_identity_supported = -1;
190 static gint hf_krb_pa_supported_enctypes_claims_supported = -1;
191 static gint hf_krb_pa_supported_enctypes_resource_sid_compression_disabled = -1;
192 static gint hf_krb_ad_ap_options = -1;
193 static gint hf_krb_ad_ap_options_cbt = -1;
194 #include "packet-kerberos-hf.c"
196 /* Initialize the subtree pointers */
197 static gint ett_kerberos = -1;
198 static gint ett_krb_recordmark = -1;
199 static gint ett_krb_pac = -1;
200 static gint ett_krb_pac_drep = -1;
201 static gint ett_krb_pac_midl_blob = -1;
202 static gint ett_krb_pac_logon_info = -1;
203 static gint ett_krb_pac_s4u_delegation_info = -1;
204 static gint ett_krb_pac_upn_dns_info = -1;
205 static gint ett_krb_pac_server_checksum = -1;
206 static gint ett_krb_pac_privsvr_checksum = -1;
207 static gint ett_krb_pac_client_info_type = -1;
208 static gint ett_krb_pa_supported_enctypes = -1;
209 static gint ett_krb_ad_ap_options = -1;
210 #include "packet-kerberos-ett.c"
212 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
213 static expert_field ei_kerberos_address = EI_INIT;
214 static expert_field ei_krb_gssapi_dlglen = EI_INIT;
216 static dissector_handle_t krb4_handle=NULL;
218 /* Global variables */
219 static guint32 krb5_errorcode;
220 static guint32 gbl_keytype;
221 static gboolean gbl_do_col_info;
223 #include "packet-kerberos-val.h"
226 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
234 cb->callback(pinfo, tvb, tree);
242 static kerberos_private_data_t*
243 kerberos_get_private_data(asn1_ctx_t *actx)
245 if (!actx->private_data) {
246 actx->private_data = wmem_new0(wmem_packet_scope(), kerberos_private_data_t);
248 return (kerberos_private_data_t *)(actx->private_data);
253 /* Decrypt Kerberos blobs */
254 gboolean krb_decrypt = FALSE;
256 /* keytab filename */
257 static const char *keytab_filename = "";
260 read_keytab_file_from_preferences(void)
262 static char *last_keytab = NULL;
268 if (keytab_filename == NULL) {
272 if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
277 last_keytab = g_strdup(keytab_filename);
279 read_keytab_file(last_keytab);
281 #endif /* HAVE_KERBEROS */
283 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
285 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
286 #undef HAVE_GETADDRINFO
287 #undef HAVE_SYS_TYPES_H
290 enc_key_t *enc_key_list=NULL;
293 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
297 if(pinfo->fd->flags.visited){
301 printf("%d:%s:%s: added key in %u keytype:%d len:%d\n", __LINE__, G_STRFUNC, origin, pinfo->fd->num, keytype, keylength);
302 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
303 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->num);
304 new_key->fd_num = pinfo->num;
305 new_key->next=enc_key_list;
306 enc_key_list=new_key;
307 new_key->keytype=keytype;
308 new_key->keylength=keylength;
309 /*XXX this needs to be freed later */
310 new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
312 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
314 #if defined(HAVE_MIT_KERBEROS)
316 static krb5_context krb5_ctx;
318 USES_APPLE_DEPRECATED_API
320 read_keytab_file(const char *filename)
324 krb5_keytab_entry key;
325 krb5_kt_cursor cursor;
326 static gboolean first_time=TRUE;
328 if (filename == NULL || filename[0] == 0) {
334 ret = krb5_init_context(&krb5_ctx);
335 if(ret && ret != KRB5_CONFIG_CANTOPEN){
340 /* should use a file in the wireshark users dir */
341 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
343 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
348 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
350 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
355 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
361 new_key = g_new(enc_key_t, 1);
362 new_key->fd_num = -1;
363 new_key->next = enc_key_list;
365 /* generate origin string, describing where this key came from */
366 pos=new_key->key_origin;
367 pos+=MIN(KRB_MAX_ORIG_LEN,
368 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
369 for(i=0;i<key.principal->length;i++){
370 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
371 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data));
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",key.principal->realm.data));
376 new_key->keytype=key.key.enctype;
377 new_key->keylength=key.key.length;
378 new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
379 enc_key_list=new_key;
380 ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
382 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
383 ret = 0; /* try to continue with the next entry */
388 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
390 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
392 ret = krb5_kt_close(krb5_ctx, keytab);
394 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
400 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
408 krb5_data data = {0,0,NULL};
409 krb5_keytab_entry key;
410 int length = tvb_captured_length(cryptotvb);
411 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
413 /* don't do anything if we are not attempting to decrypt data */
414 if(!krb_decrypt || length < 1){
418 /* make sure we have all the data we need */
419 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
423 read_keytab_file_from_preferences();
424 data.data = (char *)wmem_alloc(pinfo->pool, length);
425 data.length = length;
427 for(ek=enc_key_list;ek;ek=ek->next){
430 /* shortcircuit and bail out if enctypes are not matching */
431 if((keytype != -1) && (ek->keytype != keytype)) {
435 input.enctype = ek->keytype;
436 input.ciphertext.length = length;
437 input.ciphertext.data = (guint8 *)cryptotext;
439 key.key.enctype=ek->keytype;
440 key.key.length=ek->keylength;
441 key.key.contents=ek->keyvalue;
442 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
446 printf("%d:%s:%s: woohoo decrypted keytype:%d in frame:%u\n", __LINE__, G_STRFUNC, ek->key_origin, ek->keytype, pinfo->fd->num);
447 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
448 "Decrypted keytype %d in frame %u using %s",
449 ek->keytype, pinfo->num, ek->key_origin);
451 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
455 *datalen = data.length;
465 #elif defined(HAVE_HEIMDAL_KERBEROS)
466 static krb5_context krb5_ctx;
468 USES_APPLE_DEPRECATED_API
470 read_keytab_file(const char *filename)
474 krb5_keytab_entry key;
475 krb5_kt_cursor cursor;
477 static gboolean first_time=TRUE;
479 if (filename == NULL || filename[0] == 0) {
485 ret = krb5_init_context(&krb5_ctx);
491 /* should use a file in the wireshark users dir */
492 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
494 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
499 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
501 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
506 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
511 new_key = g_new0(enc_key_t, 1);
512 new_key->fd_num = -1;
513 new_key->next = enc_key_list;
515 /* generate origin string, describing where this key came from */
516 pos=new_key->key_origin;
517 pos+=MIN(KRB_MAX_ORIG_LEN,
518 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
519 for(i=0;i<key.principal->name.name_string.len;i++){
520 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
521 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[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",key.principal->realm));
526 new_key->keytype=key.keyblock.keytype;
527 new_key->keylength=(int)key.keyblock.keyvalue.length;
528 new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
529 enc_key_list=new_key;
530 ret = krb5_kt_free_entry(krb5_ctx, &key);
532 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
533 ret = 0; /* try to continue with the next entry */
538 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
540 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
542 ret = krb5_kt_close(krb5_ctx, keytab);
544 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
552 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
561 int length = tvb_captured_length(cryptotvb);
562 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
564 /* don't do anything if we are not attempting to decrypt data */
569 /* make sure we have all the data we need */
570 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
574 read_keytab_file_from_preferences();
576 for(ek=enc_key_list;ek;ek=ek->next){
577 krb5_keytab_entry key;
579 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
581 /* shortcircuit and bail out if enctypes are not matching */
582 if((keytype != -1) && (ek->keytype != keytype)) {
586 key.keyblock.keytype=ek->keytype;
587 key.keyblock.keyvalue.length=ek->keylength;
588 key.keyblock.keyvalue.data=ek->keyvalue;
589 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto);
594 /* pre-0.6.1 versions of Heimdal would sometimes change
595 the cryptotext data even when the decryption failed.
596 This would obviously not work since we iterate over the
597 keys. So just give it a copy of the crypto data instead.
598 This has been seen for RC4-HMAC blobs.
600 cryptocopy = (guint8 *)wmem_memdup(wmem_packet_scope(), cryptotext, length);
601 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
605 if((ret == 0) && (length>0)){
608 printf("%d:%s:%s: woohoo decrypted keytype:%d in frame:%u\n", __LINE__, G_STRFUNC, ek->key_origin, ek->keytype, pinfo->fd->num);
609 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
610 "Decrypted keytype %d in frame %u using %s",
611 ek->keytype, pinfo->num, ek->key_origin);
613 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
615 krb5_crypto_destroy(krb5_ctx, crypto);
616 /* return a private wmem_alloced blob to the caller */
617 user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
619 *datalen = (int)data.length;
623 krb5_crypto_destroy(krb5_ctx, crypto);
628 #elif defined (HAVE_LIBNETTLE)
630 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
631 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
633 typedef struct _service_key_t {
638 char origin[KRB_MAX_ORIG_LEN+1];
640 GSList *service_key_list = NULL;
644 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
646 service_key_t *new_key;
648 if(pinfo->fd->flags.visited){
652 printf("%d:%s:%s: added key in %u keytype:%d len:%d\n", __LINE__, G_STRFUNC, origin, pinfo->fd->num, keytype, keylength);
654 new_key = g_malloc(sizeof(service_key_t));
656 new_key->keytype = keytype;
657 new_key->length = keylength;
658 new_key->contents = g_memdup(keyvalue, keylength);
659 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
660 service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
668 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
669 sk = (service_key_t *) ske->data;
671 g_free(sk->contents);
675 g_slist_free(service_key_list);
676 service_key_list = NULL;
680 read_keytab_file(const char *service_key_file)
685 unsigned char buf[SERVICE_KEY_SIZE];
686 int newline_skip = 0, count = 0;
688 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
690 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
691 * There can be zero, one (\n), or two (\r\n) characters between
692 * keys. Trailing characters are ignored.
695 /* XXX We should support the standard keytab format instead */
696 if (st.st_size > SERVICE_KEY_SIZE) {
697 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
698 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
700 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
701 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
706 skf = ws_fopen(service_key_file, "rb");
709 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
710 sk = g_malloc(sizeof(service_key_t));
711 sk->kvno = buf[0] << 8 | buf[1];
712 sk->keytype = KEYTYPE_DES3_CBC_MD5;
713 sk->length = DES3_KEY_SIZE;
714 sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
715 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
716 service_key_list = g_slist_append(service_key_list, (gpointer) sk);
717 if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
718 fprintf(stderr, "unable to seek...\n");
727 #define CONFOUNDER_PLUS_CHECKSUM 24
730 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
737 guint8 *decrypted_data = NULL, *plaintext = NULL;
740 guint32 tag, item_len, data_len;
741 int id_offset, offset;
742 guint8 key[DES3_KEY_SIZE];
743 guint8 initial_vector[DES_BLOCK_SIZE];
744 gcry_md_hd_t md5_handle;
746 guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
747 guint8 confounder[8];
752 int length = tvb_captured_length(cryptotvb);
753 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
756 /* don't do anything if we are not attempting to decrypt data */
761 /* make sure we have all the data we need */
762 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
766 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
770 decrypted_data = wmem_alloc(wmem_packet_scope(), length);
771 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
772 gboolean do_continue = FALSE;
774 sk = (service_key_t *) ske->data;
776 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
778 memset(initial_vector, 0, DES_BLOCK_SIZE);
779 des3_set_key(&ctx, key);
780 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
781 length, decrypted_data, cryptotext);
782 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
784 tvb_memcpy(encr_tvb, confounder, 0, 8);
786 /* We have to pull the decrypted data length from the decrypted
787 * content. If the key doesn't match or we otherwise get garbage,
788 * an exception may get thrown while decoding the ASN.1 header.
789 * Catch it, just in case.
792 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
793 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
795 CATCH_BOUNDS_ERRORS {
801 if (do_continue) continue;
803 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
804 if ((int) item_len + offset > length) {
809 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
812 gcry_md_write(md5_handle, confounder, 8);
813 gcry_md_write(md5_handle, zero_fill, 16);
814 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
815 digest = gcry_md_read(md5_handle, 0);
817 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
818 gcry_md_close(md5_handle);
820 plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
834 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
836 #define INET6_ADDRLEN 16
838 /* TCP Record Mark */
839 #define KRB_RM_RESERVED 0x80000000U
840 #define KRB_RM_RECLEN 0x7fffffffU
842 #define KRB5_MSG_TICKET 1 /* Ticket */
843 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
844 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
845 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
846 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
847 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
848 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
849 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
850 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
852 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
853 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
854 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
855 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
856 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
857 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
858 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
859 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
860 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
862 #define KRB5_CHKSUM_GSSAPI 0x8003
864 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
866 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
868 * unless it's expired.
871 /* Principal name-type */
872 #define KRB5_NT_UNKNOWN 0
873 #define KRB5_NT_PRINCIPAL 1
874 #define KRB5_NT_SRV_INST 2
875 #define KRB5_NT_SRV_HST 3
876 #define KRB5_NT_SRV_XHST 4
877 #define KRB5_NT_UID 5
878 #define KRB5_NT_X500_PRINCIPAL 6
879 #define KRB5_NT_SMTP_NAME 7
880 #define KRB5_NT_ENTERPRISE 10
883 * MS specific name types, from
885 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
887 #define KRB5_NT_MS_PRINCIPAL -128
888 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
889 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
890 #define KRB5_NT_PRINCIPAL_AND_SID -131
891 #define KRB5_NT_SRV_INST_AND_SID -132
893 /* error table constants */
894 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
895 #define KRB5_ET_KRB5KDC_ERR_NONE 0
896 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
897 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
898 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
899 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
900 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
901 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
902 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
903 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
904 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
905 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
906 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
907 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
908 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
909 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
910 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
911 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
912 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
913 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
914 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
915 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
916 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
917 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
918 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
919 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
920 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
921 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
922 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
923 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
924 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
925 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
926 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
927 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
928 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
929 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
930 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
931 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
932 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
933 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
934 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
935 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
936 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
937 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
938 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
939 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
940 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
941 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
942 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
943 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
944 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
945 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
946 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
947 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
948 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
949 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
950 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
951 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
952 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
953 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
954 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
955 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
956 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
957 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
958 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
959 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
960 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
961 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
962 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
963 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
965 static const value_string krb5_error_codes[] = {
966 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
967 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
968 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
969 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
970 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
971 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
972 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
973 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
974 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
975 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
976 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
977 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
978 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
979 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
980 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
981 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
982 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
983 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
984 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
985 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
986 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
987 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
988 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
989 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
990 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
991 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
992 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
993 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
994 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
995 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
996 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
997 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
998 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
999 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1000 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1001 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1002 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1003 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1004 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1005 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1006 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1007 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1008 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1009 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1010 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1011 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1012 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1013 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1014 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1015 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1016 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1017 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1018 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1019 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1020 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1021 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1022 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1023 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1024 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1025 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1026 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1027 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1028 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1029 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1030 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1031 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1032 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1033 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1034 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1039 #define PAC_LOGON_INFO 1
1040 #define PAC_CREDENTIAL_TYPE 2
1041 #define PAC_SERVER_CHECKSUM 6
1042 #define PAC_PRIVSVR_CHECKSUM 7
1043 #define PAC_CLIENT_INFO_TYPE 10
1044 #define PAC_S4U_DELEGATION_INFO 11
1045 #define PAC_UPN_DNS_INFO 12
1046 static const value_string w2k_pac_types[] = {
1047 { PAC_LOGON_INFO , "Logon Info" },
1048 { PAC_CREDENTIAL_TYPE , "Credential Type" },
1049 { PAC_SERVER_CHECKSUM , "Server Checksum" },
1050 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
1051 { PAC_CLIENT_INFO_TYPE , "Client Info Type" },
1052 { PAC_S4U_DELEGATION_INFO, "S4U Delegation Info" },
1053 { PAC_UPN_DNS_INFO , "UPN DNS Info" },
1057 static const value_string krb5_msg_types[] = {
1058 { KRB5_MSG_TICKET, "Ticket" },
1059 { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
1060 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
1061 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
1062 { KRB5_MSG_TGS_REP, "TGS-REP" },
1063 { KRB5_MSG_AS_REQ, "AS-REQ" },
1064 { KRB5_MSG_AS_REP, "AS-REP" },
1065 { KRB5_MSG_AP_REQ, "AP-REQ" },
1066 { KRB5_MSG_AP_REP, "AP-REP" },
1067 { KRB5_MSG_SAFE, "KRB-SAFE" },
1068 { KRB5_MSG_PRIV, "KRB-PRIV" },
1069 { KRB5_MSG_CRED, "KRB-CRED" },
1070 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
1071 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
1072 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
1073 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1074 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1075 { KRB5_MSG_ERROR, "KRB-ERROR" },
1079 #define KRB5_GSS_C_DELEG_FLAG 0x01
1080 #define KRB5_GSS_C_MUTUAL_FLAG 0x02
1081 #define KRB5_GSS_C_REPLAY_FLAG 0x04
1082 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08
1083 #define KRB5_GSS_C_CONF_FLAG 0x10
1084 #define KRB5_GSS_C_INTEG_FLAG 0x20
1085 #define KRB5_GSS_C_DCE_STYLE 0x1000
1087 static const true_false_string tfs_gss_flags_deleg = {
1088 "Delegate credentials to remote peer",
1091 static const true_false_string tfs_gss_flags_mutual = {
1092 "Request that remote peer authenticates itself",
1093 "Mutual authentication NOT required"
1095 static const true_false_string tfs_gss_flags_replay = {
1096 "Enable replay protection for signed or sealed messages",
1097 "Do NOT enable replay protection"
1099 static const true_false_string tfs_gss_flags_sequence = {
1100 "Enable Out-of-sequence detection for sign or sealed messages",
1101 "Do NOT enable out-of-sequence detection"
1103 static const true_false_string tfs_gss_flags_conf = {
1104 "Confidentiality (sealing) may be invoked",
1105 "Do NOT use Confidentiality (sealing)"
1107 static const true_false_string tfs_gss_flags_integ = {
1108 "Integrity protection (signing) may be invoked",
1109 "Do NOT use integrity protection"
1112 static const true_false_string tfs_gss_flags_dce_style = {
1114 "Not using DCE-STYLE"
1117 #ifdef HAVE_KERBEROS
1119 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1120 proto_tree *tree, int hf_index _U_)
1124 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1127 next_tvb=tvb_new_subset_remaining(tvb, offset);
1128 length=tvb_captured_length_remaining(tvb, offset);
1130 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1132 * All Ticket encrypted parts use usage == 2
1134 plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, private_data->etype, NULL);
1137 tvbuff_t *child_tvb;
1138 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1140 /* Add the decrypted data to the data source list. */
1141 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1143 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1149 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1150 proto_tree *tree, int hf_index _U_)
1154 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1157 next_tvb=tvb_new_subset_remaining(tvb, offset);
1158 length=tvb_captured_length_remaining(tvb, offset);
1160 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1162 * Authenticators are encrypted with usage
1166 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, private_data->etype, NULL);
1169 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, private_data->etype, NULL);
1173 tvbuff_t *child_tvb;
1174 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1176 /* Add the decrypted data to the data source list. */
1177 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1179 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1185 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1186 proto_tree *tree, int hf_index _U_)
1190 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1193 next_tvb=tvb_new_subset_remaining(tvb, offset);
1194 length=tvb_captured_length_remaining(tvb, offset);
1196 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1198 * ASREP/TGSREP encryptedparts are encrypted with usage
1203 plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, private_data->etype, NULL);
1206 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, private_data->etype, NULL);
1210 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, private_data->etype, NULL);
1214 tvbuff_t *child_tvb;
1215 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1217 /* Add the decrypted data to the data source list. */
1218 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1220 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1226 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1227 proto_tree *tree, int hf_index _U_)
1231 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1234 next_tvb=tvb_new_subset_remaining(tvb, offset);
1235 length=tvb_captured_length_remaining(tvb, offset);
1237 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1239 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1242 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, private_data->etype, NULL);
1245 tvbuff_t *child_tvb;
1246 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1248 /* Add the decrypted data to the data source list. */
1249 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1251 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1257 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1258 proto_tree *tree, int hf_index _U_)
1262 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1265 next_tvb=tvb_new_subset_remaining(tvb, offset);
1266 length=tvb_captured_length_remaining(tvb, offset);
1268 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1270 * AP-REP are encrypted with usage == 12
1272 plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, private_data->etype, NULL);
1275 tvbuff_t *child_tvb;
1276 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1278 /* Add the decrypted data to the data source list. */
1279 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1281 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1287 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1288 proto_tree *tree, int hf_index _U_)
1292 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1295 next_tvb=tvb_new_subset_remaining(tvb, offset);
1296 length=tvb_captured_length_remaining(tvb, offset);
1299 * EncKrbPrivPart encrypted with usage
1302 plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, private_data->etype, NULL);
1305 tvbuff_t *child_tvb;
1306 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1308 /* Add the decrypted data to the data source list. */
1309 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1311 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1317 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1318 proto_tree *tree, int hf_index _U_)
1322 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1325 next_tvb=tvb_new_subset_remaining(tvb, offset);
1326 length=tvb_captured_length_remaining(tvb, offset);
1329 * EncKrbCredPart encrypted with usage
1332 plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, private_data->etype, NULL);
1335 tvbuff_t *child_tvb;
1336 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1338 /* Add the decrypted data to the data source list. */
1339 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1341 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1347 dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1348 proto_tree *tree, int hf_index _U_)
1352 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1355 next_tvb=tvb_new_subset_remaining(tvb, offset);
1356 length=tvb_captured_length_remaining(tvb, offset);
1359 * KrbFastResponse encrypted with usage
1360 * KEY_USAGE_FAST_ENC 51
1362 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_ENC,
1363 next_tvb, private_data->etype, NULL);
1366 tvbuff_t *child_tvb;
1367 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1368 tvb_set_free_cb(child_tvb, g_free);
1370 /* Add the decrypted data to the data source list. */
1371 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1373 offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1379 dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1380 proto_tree *tree, int hf_index _U_)
1384 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1387 next_tvb=tvb_new_subset_remaining(tvb, offset);
1388 length=tvb_captured_length_remaining(tvb, offset);
1392 * KrbFastResponse encrypted with usage
1393 * KEY_USAGE_FAST_REP 52
1395 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_REP,
1396 next_tvb, private_data->etype, NULL);
1399 tvbuff_t *child_tvb;
1400 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1401 tvb_set_free_cb(child_tvb, g_free);
1403 /* Add the decrypted data to the data source list. */
1404 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1406 offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1412 dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1413 proto_tree *tree, int hf_index _U_)
1417 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1421 next_tvb=tvb_new_subset_remaining(tvb, offset);
1422 length=tvb_captured_length_remaining(tvb, offset);
1425 * KEY_USAGE_ENC_CHALLENGE_CLIENT 54
1426 * KEY_USAGE_ENC_CHALLENGE_KDC 55
1428 if (private_data->kdc_response) {
1429 usage = KEY_USAGE_ENC_CHALLENGE_KDC;
1431 usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
1433 plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, private_data->etype, NULL);
1436 tvbuff_t *child_tvb;
1437 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1438 tvb_set_free_cb(child_tvb, g_free);
1440 /* Add the decrypted data to the data source list. */
1441 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1443 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1449 static const int *hf_krb_pa_supported_enctypes_fields[] = {
1450 &hf_krb_pa_supported_enctypes_des_cbc_crc,
1451 &hf_krb_pa_supported_enctypes_des_cbc_md5,
1452 &hf_krb_pa_supported_enctypes_rc4_hmac,
1453 &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
1454 &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
1455 &hf_krb_pa_supported_enctypes_fast_supported,
1456 &hf_krb_pa_supported_enctypes_compound_identity_supported,
1457 &hf_krb_pa_supported_enctypes_claims_supported,
1458 &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
1462 static const true_false_string supported_tfs = {
1463 "Supported", "Not supported"
1467 dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1468 int offset _U_, asn1_ctx_t *actx _U_,
1469 proto_tree *tree _U_, int hf_index _U_)
1471 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1472 hf_krb_pa_supported_enctypes,
1473 ett_krb_pa_supported_enctypes,
1474 hf_krb_pa_supported_enctypes_fields,
1481 static const int *hf_krb_ad_ap_options_fields[] = {
1482 &hf_krb_ad_ap_options_cbt,
1486 static const true_false_string set_tfs = {
1491 dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1492 int offset _U_, asn1_ctx_t *actx _U_,
1493 proto_tree *tree _U_, int hf_index _U_)
1495 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1496 hf_krb_ad_ap_options,
1497 ett_krb_ad_ap_options,
1498 hf_krb_ad_ap_options_fields,
1504 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1507 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1513 /* Length of Bnd field */
1514 len=tvb_get_letohl(tvb, offset);
1515 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1519 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1524 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1525 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1526 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1527 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1528 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1529 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1530 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1533 /* the next fields are optional so we have to check that we have
1534 * more data in our buffers */
1535 if(tvb_reported_length_remaining(tvb, offset)<2){
1538 /* dlgopt identifier */
1539 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1542 if(tvb_reported_length_remaining(tvb, offset)<2){
1545 /* dlglen identifier */
1546 dlglen=tvb_get_letohs(tvb, offset);
1547 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1550 if(dlglen!=tvb_reported_length_remaining(tvb, offset)){
1551 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0,
1552 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset));
1556 /* this should now be a KRB_CRED message */
1557 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1563 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_)
1565 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1571 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_)
1575 /* Microsoft stores a special 12 byte blob here
1579 * decode everything as this blob for now until we see if anyone
1580 * else ever uses it or we learn how to tell whether this
1581 * is such an MS blob or not.
1583 proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
1585 nt_status=tvb_get_letohl(tvb, offset);
1587 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
1589 val_to_str(nt_status, NT_errors,
1590 "Unknown error code %#x"));
1594 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1598 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1606 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
1611 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
1613 val = tvb_get_guint8(tvb, offset);
1614 proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
1625 /* This might be some sort of header that MIDL generates when creating
1626 * marshalling/unmarshalling code for blobs that are not to be transported
1627 * ontop of DCERPC and where the DREP fields specifying things such as
1628 * endianess and similar are not available.
1631 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
1635 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header");
1637 /* modified DREP field that is used for stuff that is transporetd ontop
1640 proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1643 offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
1646 proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1649 proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1652 /* length of blob that follows */
1653 proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1660 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1664 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1665 static dcerpc_info di; /* fake dcerpc_info struct */
1666 static dcerpc_call_value call_data;
1668 item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
1669 tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
1671 /* skip the first 16 bytes, they are some magic created by the idl
1672 * compiler the first 4 bytes might be flags?
1674 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1676 /* the PAC_LOGON_INFO blob */
1677 /* fake whatever state the dcerpc runtime support needs */
1678 di.conformant_run=0;
1679 /* we need di->call_data->flags.NDR64 == 0 */
1680 di.call_data=&call_data;
1681 init_ndr_pointer_list(&di);
1682 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1683 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
1684 "PAC_LOGON_INFO:", -1);
1690 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1694 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1695 static dcerpc_info di; /* fake dcerpc_info struct */
1696 static dcerpc_call_value call_data;
1698 item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
1699 tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
1701 /* skip the first 16 bytes, they are some magic created by the idl
1702 * compiler the first 4 bytes might be flags?
1704 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1707 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
1708 /* fake whatever state the dcerpc runtime support needs */
1709 di.conformant_run=0;
1710 /* we need di->call_data->flags.NDR64 == 0 */
1711 di.call_data=&call_data;
1712 init_ndr_pointer_list(&di);
1713 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1714 netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
1715 "PAC_S4U_DELEGATION_INFO:", -1);
1721 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1725 guint16 dns_offset, dns_len;
1726 guint16 upn_offset, upn_len;
1731 item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
1732 tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
1735 upn_len = tvb_get_letohs(tvb, offset);
1736 proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1738 upn_offset = tvb_get_letohs(tvb, offset);
1739 proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1743 dns_len = tvb_get_letohs(tvb, offset);
1744 proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1746 dns_offset = tvb_get_letohs(tvb, offset);
1747 proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1751 proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1754 offset = upn_offset;
1756 bc = tvb_reported_length_remaining(tvb, offset);
1757 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1758 proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
1761 offset = dns_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_dns_name, tvb, dns_offset, dns_len, dn);
1771 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1773 proto_tree_add_item(parent_tree, hf_krb_pac_credential_type, tvb, offset, -1, ENC_NA);
1779 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1784 item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA);
1785 tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum);
1787 /* signature type */
1788 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1791 /* signature data */
1792 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1798 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1803 item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA);
1804 tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum);
1806 /* signature type */
1807 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1810 /* signature data */
1811 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1817 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1823 item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
1824 tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
1827 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
1830 namelen=tvb_get_letohs(tvb, offset);
1831 proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
1835 proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
1842 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1847 proto_item *it=NULL;
1848 proto_tree *tr=NULL;
1851 /* type of pac data */
1852 pac_type=tvb_get_letohl(tvb, offset);
1853 it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
1854 tr=proto_item_add_subtree(it, ett_krb_pac);
1858 /* size of pac data */
1859 pac_size=tvb_get_letohl(tvb, offset);
1860 proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
1863 /* offset to pac data */
1864 pac_offset=tvb_get_letohl(tvb, offset);
1865 proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
1868 next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size);
1870 case PAC_LOGON_INFO:
1871 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
1873 case PAC_CREDENTIAL_TYPE:
1874 dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
1876 case PAC_SERVER_CHECKSUM:
1877 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
1879 case PAC_PRIVSVR_CHECKSUM:
1880 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
1882 case PAC_CLIENT_INFO_TYPE:
1883 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
1885 case PAC_S4U_DELEGATION_INFO:
1886 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
1888 case PAC_UPN_DNS_INFO:
1889 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
1899 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_)
1905 /* first in the PAC structure comes the number of entries */
1906 entries=tvb_get_letohl(tvb, offset);
1907 proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
1910 /* second comes the version */
1911 version=tvb_get_letohl(tvb, offset);
1912 proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
1915 for(i=0;i<entries;i++){
1916 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
1922 #include "packet-kerberos-fn.c"
1924 /* Make wrappers around exported functions for now */
1926 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1928 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
1933 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1935 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
1940 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1942 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
1945 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1947 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
1952 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1953 gboolean dci, gboolean do_col_protocol, gboolean have_rm,
1954 kerberos_callbacks *cb)
1956 volatile int offset = 0;
1957 proto_tree *volatile kerberos_tree = NULL;
1958 proto_item *volatile item = NULL;
1959 asn1_ctx_t asn1_ctx;
1961 /* TCP record mark and length */
1963 gint krb_reclen = 0;
1965 gbl_do_col_info=dci;
1968 krb_rm = tvb_get_ntohl(tvb, offset);
1969 krb_reclen = kerberos_rm_to_reclen(krb_rm);
1971 * What is a reasonable size limit?
1973 if (krb_reclen > 10 * 1024 * 1024) {
1977 if (do_col_protocol) {
1978 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1982 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1983 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1986 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1989 /* Do some sanity checking here,
1990 * All krb5 packets start with a TAG class that is BER_CLASS_APP
1991 * and a tag value that is either of the values below:
1992 * If it doesn't look like kerberos, return 0 and let someone else have
1999 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
2000 if(tmp_class!=BER_CLASS_APP){
2004 case KRB5_MSG_TICKET:
2005 case KRB5_MSG_AUTHENTICATOR:
2006 case KRB5_MSG_ENC_TICKET_PART:
2007 case KRB5_MSG_AS_REQ:
2008 case KRB5_MSG_AS_REP:
2009 case KRB5_MSG_TGS_REQ:
2010 case KRB5_MSG_TGS_REP:
2011 case KRB5_MSG_AP_REQ:
2012 case KRB5_MSG_AP_REP:
2013 case KRB5_MSG_ENC_AS_REP_PART:
2014 case KRB5_MSG_ENC_TGS_REP_PART:
2015 case KRB5_MSG_ENC_AP_REP_PART:
2016 case KRB5_MSG_ENC_KRB_PRIV_PART:
2017 case KRB5_MSG_ENC_KRB_CRED_PART:
2020 case KRB5_MSG_ERROR:
2025 if (do_col_protocol) {
2026 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2028 if (gbl_do_col_info) {
2029 col_clear(pinfo->cinfo, COL_INFO);
2032 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
2033 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
2036 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2037 asn1_ctx.private_data = cb;
2040 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
2041 } CATCH_BOUNDS_ERRORS {
2045 proto_item_set_len(item, offset);
2050 * Display the TCP record mark.
2053 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
2056 proto_tree *rm_tree;
2061 rec_len = kerberos_rm_to_reclen(krb_rm);
2062 rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL,
2063 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
2064 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
2065 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
2069 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
2071 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
2075 kerberos_output_keytype(void)
2081 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2083 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
2084 Since all (except weirdo transarc krb4 stuff) use
2085 an opcode <=16 in the first byte, use this to see if it might
2087 All krb5 commands start with an APPL tag and thus is >=0x60
2088 so if first byte is <=16 just blindly assume it is krb4 then
2090 if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
2094 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
2102 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
2106 kerberos_rm_to_reclen(guint krb_rm)
2108 return (krb_rm & KRB_RM_RECLEN);
2112 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2117 krb_rm = tvb_get_ntohl(tvb, offset);
2118 pdulen = kerberos_rm_to_reclen(krb_rm);
2119 return (pdulen + 4);
2122 kerberos_prefs_apply_cb(void) {
2123 #ifdef HAVE_LIBNETTLE
2125 read_keytab_file(keytab_filename);
2130 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2132 pinfo->fragmented = TRUE;
2133 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
2135 * The dissector failed to recognize this as a valid
2136 * Kerberos message. Mark it as a continuation packet.
2138 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
2141 return tvb_captured_length(tvb);
2145 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2147 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2148 col_clear(pinfo->cinfo, COL_INFO);
2150 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
2151 dissect_kerberos_tcp_pdu, data);
2152 return tvb_captured_length(tvb);
2155 /*--- proto_register_kerberos -------------------------------------------*/
2156 void proto_register_kerberos(void) {
2158 /* List of fields */
2160 static hf_register_info hf[] = {
2161 { &hf_krb_rm_reserved, {
2162 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
2163 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
2164 { &hf_krb_rm_reclen, {
2165 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
2166 NULL, KRB_RM_RECLEN, NULL, HFILL }},
2167 { &hf_krb_provsrv_location, {
2168 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
2169 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
2170 { &hf_krb_smb_nt_status,
2171 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
2172 VALS(NT_errors), 0, "NT Status code", HFILL }},
2173 { &hf_krb_smb_unknown,
2174 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
2175 NULL, 0, NULL, HFILL }},
2176 { &hf_krb_address_ip, {
2177 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
2178 NULL, 0, NULL, HFILL }},
2179 { &hf_krb_address_ipv6, {
2180 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
2181 NULL, 0, NULL, HFILL }},
2182 { &hf_krb_address_netbios, {
2183 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
2184 NULL, 0, "NetBIOS Address and type", HFILL }},
2185 { &hf_krb_gssapi_len, {
2186 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
2187 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
2188 { &hf_krb_gssapi_bnd, {
2189 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
2190 NULL, 0, "GSSAPI Bnd field", HFILL }},
2191 { &hf_krb_gssapi_c_flag_deleg, {
2192 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
2193 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
2194 { &hf_krb_gssapi_c_flag_mutual, {
2195 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
2196 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
2197 { &hf_krb_gssapi_c_flag_replay, {
2198 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
2199 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
2200 { &hf_krb_gssapi_c_flag_sequence, {
2201 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
2202 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
2203 { &hf_krb_gssapi_c_flag_conf, {
2204 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
2205 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
2206 { &hf_krb_gssapi_c_flag_integ, {
2207 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
2208 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
2209 { &hf_krb_gssapi_c_flag_dce_style, {
2210 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
2211 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
2212 { &hf_krb_gssapi_dlgopt, {
2213 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
2214 NULL, 0, "GSSAPI DlgOpt", HFILL }},
2215 { &hf_krb_gssapi_dlglen, {
2216 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
2217 NULL, 0, "GSSAPI DlgLen", HFILL }},
2218 { &hf_krb_midl_blob_len, {
2219 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
2220 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
2221 { &hf_krb_midl_fill_bytes, {
2222 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
2223 NULL, 0, "Just some fill bytes", HFILL }},
2224 { &hf_krb_midl_version, {
2225 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
2226 NULL, 0, "Version of pickling", HFILL }},
2227 { &hf_krb_midl_hdr_len, {
2228 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
2229 NULL, 0, "Length of header", HFILL }},
2230 { &hf_krb_pac_signature_type, {
2231 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
2232 NULL, 0, "PAC Signature Type", HFILL }},
2233 { &hf_krb_pac_signature_signature, {
2234 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
2235 NULL, 0, "A PAC signature blob", HFILL }},
2236 { &hf_krb_w2k_pac_entries, {
2237 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
2238 NULL, 0, "Number of W2k PAC entries", HFILL }},
2239 { &hf_krb_w2k_pac_version, {
2240 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
2241 NULL, 0, "Version of PAC structures", HFILL }},
2242 { &hf_krb_w2k_pac_type, {
2243 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
2244 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
2245 { &hf_krb_w2k_pac_size, {
2246 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
2247 NULL, 0, "Size of W2k PAC entry", HFILL }},
2248 { &hf_krb_w2k_pac_offset, {
2249 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
2250 NULL, 0, "Offset to W2k PAC entry", HFILL }},
2251 { &hf_krb_pac_clientid, {
2252 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2253 NULL, 0, "ClientID Timestamp", HFILL }},
2254 { &hf_krb_pac_namelen, {
2255 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
2256 NULL, 0, "Length of client name", HFILL }},
2257 { &hf_krb_pac_clientname, {
2258 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
2259 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
2260 { &hf_krb_pac_logon_info, {
2261 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE,
2262 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
2263 { &hf_krb_pac_credential_type, {
2264 "PAC_CREDENTIAL_TYPE", "kerberos.pac_credential_type", FT_BYTES, BASE_NONE,
2265 NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
2266 { &hf_krb_pac_server_checksum, {
2267 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE,
2268 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
2269 { &hf_krb_pac_privsvr_checksum, {
2270 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE,
2271 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
2272 { &hf_krb_pac_client_info_type, {
2273 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE,
2274 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
2275 { &hf_krb_pac_s4u_delegation_info, {
2276 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE,
2277 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
2278 { &hf_krb_pac_upn_dns_info, {
2279 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE,
2280 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
2281 { &hf_krb_pac_upn_flags, {
2282 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
2283 NULL, 0, "UPN flags", HFILL }},
2284 { &hf_krb_pac_upn_dns_offset, {
2285 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
2286 NULL, 0, NULL, HFILL }},
2287 { &hf_krb_pac_upn_dns_len, {
2288 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
2289 NULL, 0, NULL, HFILL }},
2290 { &hf_krb_pac_upn_upn_offset, {
2291 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
2292 NULL, 0, NULL, HFILL }},
2293 { &hf_krb_pac_upn_upn_len, {
2294 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
2295 NULL, 0, NULL, HFILL }},
2296 { &hf_krb_pac_upn_upn_name, {
2297 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
2298 NULL, 0, NULL, HFILL }},
2299 { &hf_krb_pac_upn_dns_name, {
2300 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
2301 NULL, 0, NULL, HFILL }},
2302 { &hf_krb_pa_supported_enctypes,
2303 { "SupportedEnctypes", "kerberos.supported_entypes",
2304 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2305 { &hf_krb_pa_supported_enctypes_des_cbc_crc,
2306 { "des-cbc-crc", "kerberos.supported_entypes.des-cbc-crc",
2307 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000001, NULL, HFILL }},
2308 { &hf_krb_pa_supported_enctypes_des_cbc_md5,
2309 { "des-cbc-md5", "kerberos.supported_entypes.des-cbc-md5",
2310 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000002, NULL, HFILL }},
2311 { &hf_krb_pa_supported_enctypes_rc4_hmac,
2312 { "rc4-hmac", "kerberos.supported_entypes.rc4-hmac",
2313 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000004, NULL, HFILL }},
2314 { &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
2315 { "aes128-cts-hmac-sha1-96", "kerberos.supported_entypes.aes128-cts-hmac-sha1-96",
2316 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000008, NULL, HFILL }},
2317 { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
2318 { "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96",
2319 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000010, NULL, HFILL }},
2320 { &hf_krb_pa_supported_enctypes_fast_supported,
2321 { "fast-supported", "kerberos.supported_entypes.fast-supported",
2322 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00010000, NULL, HFILL }},
2323 { &hf_krb_pa_supported_enctypes_compound_identity_supported,
2324 { "compound-identity-supported", "kerberos.supported_entypes.compound-identity-supported",
2325 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00020000, NULL, HFILL }},
2326 { &hf_krb_pa_supported_enctypes_claims_supported,
2327 { "claims-supported", "kerberos.supported_entypes.claims-supported",
2328 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2329 { &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
2330 { "resource-sid-compression-disabled", "kerberos.supported_entypes.resource-sid-compression-disabled",
2331 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2332 { &hf_krb_ad_ap_options,
2333 { "AD-AP-Options", "kerberos.ad_ap_options",
2334 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2335 { &hf_krb_ad_ap_options_cbt,
2336 { "ChannelBindings", "kerberos.ad_ap_options.cbt",
2337 FT_BOOLEAN, 32, TFS(&set_tfs), 0x00004000, NULL, HFILL }},
2339 #include "packet-kerberos-hfarr.c"
2342 /* List of subtrees */
2343 static gint *ett[] = {
2345 &ett_krb_recordmark,
2348 &ett_krb_pac_midl_blob,
2349 &ett_krb_pac_logon_info,
2350 &ett_krb_pac_s4u_delegation_info,
2351 &ett_krb_pac_upn_dns_info,
2352 &ett_krb_pac_server_checksum,
2353 &ett_krb_pac_privsvr_checksum,
2354 &ett_krb_pac_client_info_type,
2355 &ett_krb_pa_supported_enctypes,
2356 &ett_krb_ad_ap_options,
2357 #include "packet-kerberos-ettarr.c"
2360 static ei_register_info ei[] = {
2361 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
2362 { &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 }},
2363 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }},
2366 expert_module_t* expert_krb;
2367 module_t *krb_module;
2369 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
2370 proto_register_field_array(proto_kerberos, hf, array_length(hf));
2371 proto_register_subtree_array(ett, array_length(ett));
2372 expert_krb = expert_register_protocol(proto_kerberos);
2373 expert_register_field_array(expert_krb, ei, array_length(ei));
2375 /* Register preferences */
2376 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2377 prefs_register_bool_preference(krb_module, "desegment",
2378 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2379 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2380 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2382 #ifdef HAVE_KERBEROS
2383 prefs_register_bool_preference(krb_module, "decrypt",
2384 "Try to decrypt Kerberos blobs",
2385 "Whether the dissector should try to decrypt "
2386 "encrypted Kerberos blobs. This requires that the proper "
2387 "keytab file is installed as well.", &krb_decrypt);
2389 prefs_register_filename_preference(krb_module, "file",
2390 "Kerberos keytab file",
2391 "The keytab file containing all the secrets",
2392 &keytab_filename, FALSE);
2396 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2397 proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
2401 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2403 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2405 return tvb_captured_length_remaining(tvb, offset);
2409 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2410 wrap_dissect_gss_kerb, /* Bind */
2411 wrap_dissect_gss_kerb, /* Bind ACK */
2412 wrap_dissect_gss_kerb, /* AUTH3 */
2413 NULL, /* Request verifier */
2414 NULL, /* Response verifier */
2415 NULL, /* Request data */
2416 NULL /* Response data */
2419 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2420 wrap_dissect_gss_kerb, /* Bind */
2421 wrap_dissect_gss_kerb, /* Bind ACK */
2422 wrap_dissect_gss_kerb, /* AUTH3 */
2423 wrap_dissect_gssapi_verf, /* Request verifier */
2424 wrap_dissect_gssapi_verf, /* Response verifier */
2425 NULL, /* Request data */
2426 NULL /* Response data */
2429 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2430 wrap_dissect_gss_kerb, /* Bind */
2431 wrap_dissect_gss_kerb, /* Bind ACK */
2432 wrap_dissect_gss_kerb, /* AUTH3 */
2433 wrap_dissect_gssapi_verf, /* Request verifier */
2434 wrap_dissect_gssapi_verf, /* Response verifier */
2435 wrap_dissect_gssapi_payload, /* Request data */
2436 wrap_dissect_gssapi_payload /* Response data */
2442 proto_reg_handoff_kerberos(void)
2444 dissector_handle_t kerberos_handle_tcp;
2446 krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos);
2448 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
2451 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
2454 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
2455 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
2457 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2458 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2459 &gss_kerb_auth_connect_fns);
2461 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2462 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2463 &gss_kerb_auth_sign_fns);
2465 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2466 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2467 &gss_kerb_auth_seal_fns);
2471 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2476 * indent-tabs-mode: t
2479 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2480 * :indentSize=8:tabSize=8:noTabs=false: