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"
74 void proto_register_kerberos(void);
75 void proto_reg_handoff_kerberos(void);
77 #define UDP_PORT_KERBEROS 88
78 #define TCP_PORT_KERBEROS 88
80 #define ADDRESS_STR_BUFSIZ 256
82 typedef struct kerberos_key {
85 const guint8 *keyvalue;
96 guint32 checksum_type;
97 } kerberos_private_data_t;
99 static dissector_handle_t kerberos_handle_udp;
101 /* Forward declarations */
102 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_);
103 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_);
104 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_);
105 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_);
106 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_);
107 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_);
108 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_);
109 static int dissect_kerberos_PA_AUTHENTICATION_SET(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
110 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_);
111 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_);
112 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_);
114 /* Desegment Kerberos over TCP messages */
115 static gboolean krb_desegment = TRUE;
117 static gint proto_kerberos = -1;
119 static gint hf_krb_rm_reserved = -1;
120 static gint hf_krb_rm_reclen = -1;
121 static gint hf_krb_provsrv_location = -1;
122 static gint hf_krb_smb_nt_status = -1;
123 static gint hf_krb_smb_unknown = -1;
124 static gint hf_krb_address_ip = -1;
125 static gint hf_krb_address_netbios = -1;
126 static gint hf_krb_address_ipv6 = -1;
127 static gint hf_krb_gssapi_len = -1;
128 static gint hf_krb_gssapi_bnd = -1;
129 static gint hf_krb_gssapi_dlgopt = -1;
130 static gint hf_krb_gssapi_dlglen = -1;
131 static gint hf_krb_gssapi_c_flag_deleg = -1;
132 static gint hf_krb_gssapi_c_flag_mutual = -1;
133 static gint hf_krb_gssapi_c_flag_replay = -1;
134 static gint hf_krb_gssapi_c_flag_sequence = -1;
135 static gint hf_krb_gssapi_c_flag_conf = -1;
136 static gint hf_krb_gssapi_c_flag_integ = -1;
137 static gint hf_krb_gssapi_c_flag_dce_style = -1;
138 static gint hf_krb_midl_version = -1;
139 static gint hf_krb_midl_hdr_len = -1;
140 static gint hf_krb_midl_fill_bytes = -1;
141 static gint hf_krb_midl_blob_len = -1;
142 static gint hf_krb_pac_signature_type = -1;
143 static gint hf_krb_pac_signature_signature = -1;
144 static gint hf_krb_w2k_pac_entries = -1;
145 static gint hf_krb_w2k_pac_version = -1;
146 static gint hf_krb_w2k_pac_type = -1;
147 static gint hf_krb_w2k_pac_size = -1;
148 static gint hf_krb_w2k_pac_offset = -1;
149 static gint hf_krb_pac_clientid = -1;
150 static gint hf_krb_pac_namelen = -1;
151 static gint hf_krb_pac_clientname = -1;
152 static gint hf_krb_pac_logon_info = -1;
153 static gint hf_krb_pac_credential_type = -1;
154 static gint hf_krb_pac_s4u_delegation_info = -1;
155 static gint hf_krb_pac_upn_dns_info = -1;
156 static gint hf_krb_pac_upn_flags = -1;
157 static gint hf_krb_pac_upn_dns_offset = -1;
158 static gint hf_krb_pac_upn_dns_len = -1;
159 static gint hf_krb_pac_upn_upn_offset = -1;
160 static gint hf_krb_pac_upn_upn_len = -1;
161 static gint hf_krb_pac_upn_upn_name = -1;
162 static gint hf_krb_pac_upn_dns_name = -1;
163 static gint hf_krb_pac_server_checksum = -1;
164 static gint hf_krb_pac_privsvr_checksum = -1;
165 static gint hf_krb_pac_client_info_type = -1;
166 #include "packet-kerberos-hf.c"
168 /* Initialize the subtree pointers */
169 static gint ett_kerberos = -1;
170 static gint ett_krb_recordmark = -1;
171 static gint ett_krb_pac = -1;
172 static gint ett_krb_pac_drep = -1;
173 static gint ett_krb_pac_midl_blob = -1;
174 static gint ett_krb_pac_logon_info = -1;
175 static gint ett_krb_pac_s4u_delegation_info = -1;
176 static gint ett_krb_pac_upn_dns_info = -1;
177 static gint ett_krb_pac_server_checksum = -1;
178 static gint ett_krb_pac_privsvr_checksum = -1;
179 static gint ett_krb_pac_client_info_type = -1;
180 #include "packet-kerberos-ett.c"
182 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
183 static expert_field ei_kerberos_address = EI_INIT;
184 static expert_field ei_krb_gssapi_dlglen = EI_INIT;
186 static dissector_handle_t krb4_handle=NULL;
188 /* Global variables */
189 static guint32 krb5_errorcode;
190 static guint32 gbl_keytype;
191 static gboolean gbl_do_col_info;
193 #include "packet-kerberos-val.h"
196 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
204 cb->callback(pinfo, tvb, tree);
212 static kerberos_private_data_t*
213 kerberos_get_private_data(asn1_ctx_t *actx)
215 if (!actx->private_data) {
216 actx->private_data = wmem_new0(wmem_packet_scope(), kerberos_private_data_t);
218 return (kerberos_private_data_t *)(actx->private_data);
223 /* Decrypt Kerberos blobs */
224 gboolean krb_decrypt = FALSE;
226 /* keytab filename */
227 static const char *keytab_filename = "";
230 read_keytab_file_from_preferences(void)
232 static char *last_keytab = NULL;
238 if (keytab_filename == NULL) {
242 if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
247 last_keytab = g_strdup(keytab_filename);
249 read_keytab_file(last_keytab);
251 #endif /* HAVE_KERBEROS */
253 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
255 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
256 #undef HAVE_GETADDRINFO
257 #undef HAVE_SYS_TYPES_H
260 enc_key_t *enc_key_list=NULL;
263 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
267 if(pinfo->fd->flags.visited){
271 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
272 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->num);
273 new_key->fd_num = pinfo->num;
274 new_key->next=enc_key_list;
275 enc_key_list=new_key;
276 new_key->keytype=keytype;
277 new_key->keylength=keylength;
278 /*XXX this needs to be freed later */
279 new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
281 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
283 #if defined(HAVE_MIT_KERBEROS)
285 static krb5_context krb5_ctx;
287 USES_APPLE_DEPRECATED_API
289 read_keytab_file(const char *filename)
293 krb5_keytab_entry key;
294 krb5_kt_cursor cursor;
295 static gboolean first_time=TRUE;
297 if (filename == NULL || filename[0] == 0) {
303 ret = krb5_init_context(&krb5_ctx);
304 if(ret && ret != KRB5_CONFIG_CANTOPEN){
309 /* should use a file in the wireshark users dir */
310 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
312 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
317 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
319 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
324 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
330 new_key = g_new(enc_key_t, 1);
331 new_key->fd_num = -1;
332 new_key->next = enc_key_list;
334 /* generate origin string, describing where this key came from */
335 pos=new_key->key_origin;
336 pos+=MIN(KRB_MAX_ORIG_LEN,
337 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
338 for(i=0;i<key.principal->length;i++){
339 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
340 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data));
342 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
343 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "@%s",key.principal->realm.data));
345 new_key->keytype=key.key.enctype;
346 new_key->keylength=key.key.length;
347 new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
348 enc_key_list=new_key;
349 ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
351 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
352 ret = 0; /* try to continue with the next entry */
357 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
359 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
361 ret = krb5_kt_close(krb5_ctx, keytab);
363 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
369 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
377 krb5_data data = {0,0,NULL};
378 krb5_keytab_entry key;
379 int length = tvb_captured_length(cryptotvb);
380 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
382 /* don't do anything if we are not attempting to decrypt data */
383 if(!krb_decrypt || length < 1){
387 /* make sure we have all the data we need */
388 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
392 read_keytab_file_from_preferences();
393 data.data = (char *)wmem_alloc(pinfo->pool, length);
394 data.length = length;
396 for(ek=enc_key_list;ek;ek=ek->next){
399 /* shortcircuit and bail out if enctypes are not matching */
400 if((keytype != -1) && (ek->keytype != keytype)) {
404 input.enctype = ek->keytype;
405 input.ciphertext.length = length;
406 input.ciphertext.data = (guint8 *)cryptotext;
408 key.key.enctype=ek->keytype;
409 key.key.length=ek->keylength;
410 key.key.contents=ek->keyvalue;
411 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
415 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
416 "Decrypted keytype %d in frame %u using %s",
417 ek->keytype, pinfo->num, ek->key_origin);
419 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
423 *datalen = data.length;
433 #elif defined(HAVE_HEIMDAL_KERBEROS)
434 static krb5_context krb5_ctx;
436 USES_APPLE_DEPRECATED_API
438 read_keytab_file(const char *filename)
442 krb5_keytab_entry key;
443 krb5_kt_cursor cursor;
445 static gboolean first_time=TRUE;
447 if (filename == NULL || filename[0] == 0) {
453 ret = krb5_init_context(&krb5_ctx);
459 /* should use a file in the wireshark users dir */
460 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
462 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
467 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
469 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
474 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
479 new_key = g_new0(enc_key_t, 1);
480 new_key->fd_num = -1;
481 new_key->next = enc_key_list;
483 /* generate origin string, describing where this key came from */
484 pos=new_key->key_origin;
485 pos+=MIN(KRB_MAX_ORIG_LEN,
486 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
487 for(i=0;i<key.principal->name.name_string.len;i++){
488 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
489 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
491 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
492 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
494 new_key->keytype=key.keyblock.keytype;
495 new_key->keylength=(int)key.keyblock.keyvalue.length;
496 new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
497 enc_key_list=new_key;
498 ret = krb5_kt_free_entry(krb5_ctx, &key);
500 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
501 ret = 0; /* try to continue with the next entry */
506 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
508 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
510 ret = krb5_kt_close(krb5_ctx, keytab);
512 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
520 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
529 int length = tvb_captured_length(cryptotvb);
530 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
532 /* don't do anything if we are not attempting to decrypt data */
537 /* make sure we have all the data we need */
538 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
542 read_keytab_file_from_preferences();
544 for(ek=enc_key_list;ek;ek=ek->next){
545 krb5_keytab_entry key;
547 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
549 /* shortcircuit and bail out if enctypes are not matching */
550 if((keytype != -1) && (ek->keytype != keytype)) {
554 key.keyblock.keytype=ek->keytype;
555 key.keyblock.keyvalue.length=ek->keylength;
556 key.keyblock.keyvalue.data=ek->keyvalue;
557 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto);
562 /* pre-0.6.1 versions of Heimdal would sometimes change
563 the cryptotext data even when the decryption failed.
564 This would obviously not work since we iterate over the
565 keys. So just give it a copy of the crypto data instead.
566 This has been seen for RC4-HMAC blobs.
568 cryptocopy = (guint8 *)wmem_memdup(wmem_packet_scope(), cryptotext, length);
569 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
573 if((ret == 0) && (length>0)){
576 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
577 "Decrypted keytype %d in frame %u using %s",
578 ek->keytype, pinfo->num, ek->key_origin);
580 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
582 krb5_crypto_destroy(krb5_ctx, crypto);
583 /* return a private wmem_alloced blob to the caller */
584 user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
586 *datalen = (int)data.length;
590 krb5_crypto_destroy(krb5_ctx, crypto);
595 #elif defined (HAVE_LIBNETTLE)
597 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
598 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
600 typedef struct _service_key_t {
605 char origin[KRB_MAX_ORIG_LEN+1];
607 GSList *service_key_list = NULL;
611 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
613 service_key_t *new_key;
615 if(pinfo->fd->flags.visited){
619 new_key = g_malloc(sizeof(service_key_t));
621 new_key->keytype = keytype;
622 new_key->length = keylength;
623 new_key->contents = g_memdup(keyvalue, keylength);
624 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
625 service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
633 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
634 sk = (service_key_t *) ske->data;
636 g_free(sk->contents);
640 g_slist_free(service_key_list);
641 service_key_list = NULL;
645 read_keytab_file(const char *service_key_file)
650 unsigned char buf[SERVICE_KEY_SIZE];
651 int newline_skip = 0, count = 0;
653 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
655 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
656 * There can be zero, one (\n), or two (\r\n) characters between
657 * keys. Trailing characters are ignored.
660 /* XXX We should support the standard keytab format instead */
661 if (st.st_size > SERVICE_KEY_SIZE) {
662 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
663 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
665 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
666 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
671 skf = ws_fopen(service_key_file, "rb");
674 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
675 sk = g_malloc(sizeof(service_key_t));
676 sk->kvno = buf[0] << 8 | buf[1];
677 sk->keytype = KEYTYPE_DES3_CBC_MD5;
678 sk->length = DES3_KEY_SIZE;
679 sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
680 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
681 service_key_list = g_slist_append(service_key_list, (gpointer) sk);
682 if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
683 fprintf(stderr, "unable to seek...\n");
692 #define CONFOUNDER_PLUS_CHECKSUM 24
695 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
702 guint8 *decrypted_data = NULL, *plaintext = NULL;
705 guint32 tag, item_len, data_len;
706 int id_offset, offset;
707 guint8 key[DES3_KEY_SIZE];
708 guint8 initial_vector[DES_BLOCK_SIZE];
709 gcry_md_hd_t md5_handle;
711 guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
712 guint8 confounder[8];
717 int length = tvb_captured_length(cryptotvb);
718 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
721 /* don't do anything if we are not attempting to decrypt data */
726 /* make sure we have all the data we need */
727 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
731 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
735 decrypted_data = wmem_alloc(wmem_packet_scope(), length);
736 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
737 gboolean do_continue = FALSE;
739 sk = (service_key_t *) ske->data;
741 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
743 memset(initial_vector, 0, DES_BLOCK_SIZE);
744 des3_set_key(&ctx, key);
745 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
746 length, decrypted_data, cryptotext);
747 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
749 tvb_memcpy(encr_tvb, confounder, 0, 8);
751 /* We have to pull the decrypted data length from the decrypted
752 * content. If the key doesn't match or we otherwise get garbage,
753 * an exception may get thrown while decoding the ASN.1 header.
754 * Catch it, just in case.
757 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
758 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
760 CATCH_BOUNDS_ERRORS {
766 if (do_continue) continue;
768 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
769 if ((int) item_len + offset > length) {
774 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
777 gcry_md_write(md5_handle, confounder, 8);
778 gcry_md_write(md5_handle, zero_fill, 16);
779 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
780 digest = gcry_md_read(md5_handle, 0);
782 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
783 gcry_md_close(md5_handle);
785 plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
799 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
801 #define INET6_ADDRLEN 16
803 /* TCP Record Mark */
804 #define KRB_RM_RESERVED 0x80000000U
805 #define KRB_RM_RECLEN 0x7fffffffU
807 #define KRB5_MSG_TICKET 1 /* Ticket */
808 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
809 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
810 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
811 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
812 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
813 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
814 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
815 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
817 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
818 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
819 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
820 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
821 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
822 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
823 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
824 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
825 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
827 #define KRB5_CHKSUM_GSSAPI 0x8003
829 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
831 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
833 * unless it's expired.
836 /* Principal name-type */
837 #define KRB5_NT_UNKNOWN 0
838 #define KRB5_NT_PRINCIPAL 1
839 #define KRB5_NT_SRV_INST 2
840 #define KRB5_NT_SRV_HST 3
841 #define KRB5_NT_SRV_XHST 4
842 #define KRB5_NT_UID 5
843 #define KRB5_NT_X500_PRINCIPAL 6
844 #define KRB5_NT_SMTP_NAME 7
845 #define KRB5_NT_ENTERPRISE 10
848 * MS specific name types, from
850 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
852 #define KRB5_NT_MS_PRINCIPAL -128
853 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
854 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
855 #define KRB5_NT_PRINCIPAL_AND_SID -131
856 #define KRB5_NT_SRV_INST_AND_SID -132
858 /* error table constants */
859 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
860 #define KRB5_ET_KRB5KDC_ERR_NONE 0
861 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
862 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
863 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
864 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
865 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
866 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
867 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
868 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
869 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
870 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
871 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
872 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
873 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
874 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
875 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
876 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
877 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
878 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
879 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
880 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
881 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
882 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
883 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
884 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
885 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
886 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
887 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
888 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
889 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
890 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
891 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
892 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
893 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
894 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
895 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
896 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
897 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
898 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
899 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
900 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
901 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
902 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
903 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
904 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
905 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
906 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
907 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
908 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
909 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
910 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
911 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
912 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
913 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
914 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
915 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
916 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
917 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
918 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
919 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
920 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
921 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
922 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
923 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
924 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
925 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
926 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
927 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
928 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
930 static const value_string krb5_error_codes[] = {
931 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
932 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
933 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
934 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
935 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
936 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
937 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
938 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
939 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
940 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
941 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
942 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
943 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
944 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
945 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
946 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
947 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
948 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
949 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
950 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
951 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
952 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
953 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
954 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
955 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
956 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
957 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
958 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
959 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
960 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
961 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
962 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
963 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
964 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
965 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
966 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
967 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
968 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
969 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
970 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
971 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
972 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
973 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
974 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
975 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
976 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
977 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
978 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
979 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
980 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
981 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
982 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
983 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
984 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
985 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
986 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
987 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
988 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
989 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
990 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
991 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
992 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
993 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
994 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
995 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
996 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
997 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
998 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
999 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1004 #define PAC_LOGON_INFO 1
1005 #define PAC_CREDENTIAL_TYPE 2
1006 #define PAC_SERVER_CHECKSUM 6
1007 #define PAC_PRIVSVR_CHECKSUM 7
1008 #define PAC_CLIENT_INFO_TYPE 10
1009 #define PAC_S4U_DELEGATION_INFO 11
1010 #define PAC_UPN_DNS_INFO 12
1011 static const value_string w2k_pac_types[] = {
1012 { PAC_LOGON_INFO , "Logon Info" },
1013 { PAC_CREDENTIAL_TYPE , "Credential Type" },
1014 { PAC_SERVER_CHECKSUM , "Server Checksum" },
1015 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
1016 { PAC_CLIENT_INFO_TYPE , "Client Info Type" },
1017 { PAC_S4U_DELEGATION_INFO, "S4U Delegation Info" },
1018 { PAC_UPN_DNS_INFO , "UPN DNS Info" },
1023 static const value_string krb5_princ_types[] = {
1024 { KRB5_NT_UNKNOWN , "Unknown" },
1025 { KRB5_NT_PRINCIPAL , "Principal" },
1026 { KRB5_NT_SRV_INST , "Service and Instance" },
1027 { KRB5_NT_SRV_HST , "Service and Host" },
1028 { KRB5_NT_SRV_XHST , "Service and Host Components" },
1029 { KRB5_NT_UID , "Unique ID" },
1030 { KRB5_NT_X500_PRINCIPAL , "Encoded X.509 Distinguished Name" },
1031 { KRB5_NT_SMTP_NAME , "SMTP Name" },
1032 { KRB5_NT_ENTERPRISE , "Enterprise Name" },
1033 { KRB5_NT_MS_PRINCIPAL , "NT 4.0 style name (MS specific)" },
1034 { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
1035 { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
1036 { KRB5_NT_PRINCIPAL_AND_SID , "Principal name and SID (MS specific)"},
1037 { KRB5_NT_SRV_INST_AND_SID , "SPN and SID (MS specific)"},
1043 static const value_string krb5_preauthentication_types[] = {
1044 { KRB5_PA_TGS_REQ , "PA-TGS-REQ" },
1045 { KRB5_PA_ENC_TIMESTAMP , "PA-ENC-TIMESTAMP" },
1046 { KRB5_PA_PW_SALT , "PA-PW-SALT" },
1047 { KRB5_PA_ENC_ENCKEY , "PA-ENC-ENCKEY" },
1048 { KRB5_PA_ENC_UNIX_TIME , "PA-ENC-UNIX-TIME" },
1049 { KRB5_PA_ENC_SANDIA_SECURID , "PA-PW-SALT" },
1050 { KRB5_PA_SESAME , "PA-SESAME" },
1051 { KRB5_PA_OSF_DCE , "PA-OSF-DCE" },
1052 { KRB5_PA_CYBERSAFE_SECUREID , "PA-CYBERSAFE-SECURID" },
1053 { KRB5_PA_AFS3_SALT , "PA-AFS3-SALT" },
1054 { KRB5_PA_ENCTYPE_INFO , "PA-ENCTYPE-INFO" },
1055 { KRB5_PA_ENCTYPE_INFO2 , "PA-ENCTYPE-INFO2" },
1056 { KRB5_PA_SAM_CHALLENGE , "PA-SAM-CHALLENGE" },
1057 { KRB5_PA_SAM_RESPONSE , "PA-SAM-RESPONSE" },
1058 { KRB5_PA_PK_AS_REQ , "PA-PK-AS-REQ" },
1059 { KRB5_PA_PK_AS_REP , "PA-PK-AS-REP" },
1060 { KRB5_PA_DASS , "PA-DASS" },
1061 { KRB5_PA_PK_AS_REP_17 , "PA-PK-AS-REP-17" },
1062 { KRB5_PA_USE_SPECIFIED_KVNO , "PA-USE-SPECIFIED-KVNO" },
1063 { KRB5_PA_SAM_REDIRECT , "PA-SAM-REDIRECT" },
1064 { KRB5_PA_GET_FROM_TYPED_DATA , "PA-GET-FROM-TYPED-DATA" },
1065 { KRB5_PA_SAM_ETYPE_INFO , "PA-SAM-ETYPE-INFO" },
1066 { KRB5_PA_ALT_PRINC , "PA-ALT-PRINC" },
1067 { KRB5_PA_SAM_CHALLENGE2 , "PA-SAM-CHALLENGE2" },
1068 { KRB5_PA_SAM_RESPONSE2 , "PA-SAM-RESPONSE2" },
1069 { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
1070 { KRB5_TD_KRB_PRINCIPAL , "TD-KRB-PRINCIPAL" },
1071 { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
1072 { KRB5_TD_TRUSTED_CERTIFIERS , "TD-TRUSTED-CERTIFIERS" },
1073 { KRB5_TD_CERTIFICATE_INDEX , "TD-CERTIFICATE-INDEX" },
1074 { KRB5_TD_APP_DEFINED_ERROR , "TD-APP-DEFINED-ERROR" },
1075 { KRB5_TD_REQ_NONCE , "TD-REQ-NONCE" },
1076 { KRB5_TD_REQ_SEQ , "TD-REQ-SEQ" },
1077 { KRB5_PA_PAC_REQUEST , "PA-PAC-REQUEST" },
1078 { KRB5_PA_FOR_USER , "PA-FOR-USER" },
1079 { KRB5_PADATA_S4U_X509_USER , "PA-S4U-X509-USER" },
1080 { KRB5_PADATA_FX_COOKIE , "PA-FX-COOKIE" },
1081 { KRB5_PA_AUTHENTICATION_SET , "KRB5-PA-AUTHENTICATION-SET" },
1083 { KRB5_PADATA_FX_FAST , "PA-FX-FAST" },
1084 { KRB5_PADATA_FX_ERROR , "PA-FX-ERROR" },
1085 { KRB5_PADATA_ENCRYPTED_CHALLENGE , "PA-ENCRYPTED-CHALLENGE" },
1086 { KRB5_PADATA_PKINIT_KX , "PA-PKINIT-KX" },
1087 { KRB5_ENCPADATA_REQ_ENC_PA_REP , "PA-REQ-ENC-PA-REP" },
1088 { KRB5_PA_PROV_SRV_LOCATION , "PA-PROV-SRV-LOCATION" },
1093 #define KRB5_AD_IF_RELEVANT 1
1094 #define KRB5_AD_INTENDED_FOR_SERVER 2
1095 #define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS 3
1096 #define KRB5_AD_KDC_ISSUED 4
1097 #define KRB5_AD_OR 5
1098 #define KRB5_AD_MANDATORY_TICKET_EXTENSIONS 6
1099 #define KRB5_AD_IN_TICKET_EXTENSIONS 7
1100 #define KRB5_AD_MANDATORY_FOR_KDC 8
1101 #define KRB5_AD_OSF_DCE 64
1102 #define KRB5_AD_SESAME 65
1103 #define KRB5_AD_OSF_DCE_PKI_CERTID 66
1104 #define KRB5_AD_WIN2K_PAC 128
1105 #define KRB5_AD_SIGNTICKET 0xffffffef
1107 static const value_string krb5_ad_types[] = {
1108 { KRB5_AD_IF_RELEVANT , "AD-IF-RELEVANT" },
1109 { KRB5_AD_INTENDED_FOR_SERVER , "AD-Intended-For-Server" },
1110 { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS , "AD-Intended-For-Application-Class" },
1111 { KRB5_AD_KDC_ISSUED , "AD-KDCIssued" },
1112 { KRB5_AD_OR , "AD-AND-OR" },
1113 { KRB5_AD_MANDATORY_TICKET_EXTENSIONS , "AD-Mandatory-Ticket-Extensions" },
1114 { KRB5_AD_IN_TICKET_EXTENSIONS , "AD-IN-Ticket-Extensions" },
1115 { KRB5_AD_MANDATORY_FOR_KDC , "AD-MANDATORY-FOR-KDC" },
1116 { KRB5_AD_OSF_DCE , "AD-OSF-DCE" },
1117 { KRB5_AD_SESAME , "AD-SESAME" },
1118 { KRB5_AD_OSF_DCE_PKI_CERTID , "AD-OSF-DCE-PKI-CertID" },
1119 { KRB5_AD_WIN2K_PAC , "AD-Win2k-PAC" },
1120 { KRB5_AD_SIGNTICKET , "AD-SignTicket" },
1124 static const value_string krb5_transited_types[] = {
1125 { 1 , "DOMAIN-X500-COMPRESS" },
1130 static const value_string krb5_msg_types[] = {
1131 { KRB5_MSG_TICKET, "Ticket" },
1132 { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
1133 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
1134 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
1135 { KRB5_MSG_TGS_REP, "TGS-REP" },
1136 { KRB5_MSG_AS_REQ, "AS-REQ" },
1137 { KRB5_MSG_AS_REP, "AS-REP" },
1138 { KRB5_MSG_AP_REQ, "AP-REQ" },
1139 { KRB5_MSG_AP_REP, "AP-REP" },
1140 { KRB5_MSG_SAFE, "KRB-SAFE" },
1141 { KRB5_MSG_PRIV, "KRB-PRIV" },
1142 { KRB5_MSG_CRED, "KRB-CRED" },
1143 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
1144 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
1145 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
1146 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1147 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1148 { KRB5_MSG_ERROR, "KRB-ERROR" },
1152 #define KRB5_GSS_C_DELEG_FLAG 0x01
1153 #define KRB5_GSS_C_MUTUAL_FLAG 0x02
1154 #define KRB5_GSS_C_REPLAY_FLAG 0x04
1155 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08
1156 #define KRB5_GSS_C_CONF_FLAG 0x10
1157 #define KRB5_GSS_C_INTEG_FLAG 0x20
1158 #define KRB5_GSS_C_DCE_STYLE 0x1000
1160 static const true_false_string tfs_gss_flags_deleg = {
1161 "Delegate credentials to remote peer",
1164 static const true_false_string tfs_gss_flags_mutual = {
1165 "Request that remote peer authenticates itself",
1166 "Mutual authentication NOT required"
1168 static const true_false_string tfs_gss_flags_replay = {
1169 "Enable replay protection for signed or sealed messages",
1170 "Do NOT enable replay protection"
1172 static const true_false_string tfs_gss_flags_sequence = {
1173 "Enable Out-of-sequence detection for sign or sealed messages",
1174 "Do NOT enable out-of-sequence detection"
1176 static const true_false_string tfs_gss_flags_conf = {
1177 "Confidentiality (sealing) may be invoked",
1178 "Do NOT use Confidentiality (sealing)"
1180 static const true_false_string tfs_gss_flags_integ = {
1181 "Integrity protection (signing) may be invoked",
1182 "Do NOT use integrity protection"
1185 static const true_false_string tfs_gss_flags_dce_style = {
1187 "Not using DCE-STYLE"
1190 #ifdef HAVE_KERBEROS
1192 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1193 proto_tree *tree, int hf_index _U_)
1197 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1200 next_tvb=tvb_new_subset_remaining(tvb, offset);
1201 length=tvb_captured_length_remaining(tvb, offset);
1203 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1205 * All Ticket encrypted parts use usage == 2
1207 plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, private_data->etype, NULL);
1210 tvbuff_t *child_tvb;
1211 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1213 /* Add the decrypted data to the data source list. */
1214 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1216 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1222 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1223 proto_tree *tree, int hf_index _U_)
1227 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1230 next_tvb=tvb_new_subset_remaining(tvb, offset);
1231 length=tvb_captured_length_remaining(tvb, offset);
1233 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1235 * Authenticators are encrypted with usage
1239 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, private_data->etype, NULL);
1242 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, private_data->etype, NULL);
1246 tvbuff_t *child_tvb;
1247 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1249 /* Add the decrypted data to the data source list. */
1250 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1252 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1258 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1259 proto_tree *tree, int hf_index _U_)
1263 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1266 next_tvb=tvb_new_subset_remaining(tvb, offset);
1267 length=tvb_captured_length_remaining(tvb, offset);
1269 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1271 * ASREP/TGSREP encryptedparts are encrypted with usage
1276 plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, private_data->etype, NULL);
1279 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, private_data->etype, NULL);
1283 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, private_data->etype, NULL);
1287 tvbuff_t *child_tvb;
1288 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1290 /* Add the decrypted data to the data source list. */
1291 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1293 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1299 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1300 proto_tree *tree, int hf_index _U_)
1304 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1307 next_tvb=tvb_new_subset_remaining(tvb, offset);
1308 length=tvb_captured_length_remaining(tvb, offset);
1310 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1312 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1315 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, private_data->etype, NULL);
1318 tvbuff_t *child_tvb;
1319 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1321 /* Add the decrypted data to the data source list. */
1322 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1324 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1330 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1331 proto_tree *tree, int hf_index _U_)
1335 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1338 next_tvb=tvb_new_subset_remaining(tvb, offset);
1339 length=tvb_captured_length_remaining(tvb, offset);
1341 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1343 * AP-REP are encrypted with usage == 12
1345 plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, private_data->etype, NULL);
1348 tvbuff_t *child_tvb;
1349 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1351 /* Add the decrypted data to the data source list. */
1352 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1354 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1360 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1361 proto_tree *tree, int hf_index _U_)
1365 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1368 next_tvb=tvb_new_subset_remaining(tvb, offset);
1369 length=tvb_captured_length_remaining(tvb, offset);
1372 * EncKrbPrivPart encrypted with usage
1375 plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, private_data->etype, NULL);
1378 tvbuff_t *child_tvb;
1379 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1381 /* Add the decrypted data to the data source list. */
1382 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1384 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1390 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1391 proto_tree *tree, int hf_index _U_)
1395 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1398 next_tvb=tvb_new_subset_remaining(tvb, offset);
1399 length=tvb_captured_length_remaining(tvb, offset);
1402 * EncKrbCredPart encrypted with usage
1405 plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, private_data->etype, NULL);
1408 tvbuff_t *child_tvb;
1409 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1411 /* Add the decrypted data to the data source list. */
1412 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1414 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1420 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1423 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1429 /* Length of Bnd field */
1430 len=tvb_get_letohl(tvb, offset);
1431 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1435 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1440 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1441 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1442 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1443 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1444 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1445 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1446 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1449 /* the next fields are optional so we have to check that we have
1450 * more data in our buffers */
1451 if(tvb_reported_length_remaining(tvb, offset)<2){
1454 /* dlgopt identifier */
1455 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1458 if(tvb_reported_length_remaining(tvb, offset)<2){
1461 /* dlglen identifier */
1462 dlglen=tvb_get_letohs(tvb, offset);
1463 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1466 if(dlglen!=tvb_reported_length_remaining(tvb, offset)){
1467 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0,
1468 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset));
1472 /* this should now be a KRB_CRED message */
1473 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1479 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_)
1481 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1487 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_)
1491 /* Microsoft stores a special 12 byte blob here
1495 * decode everything as this blob for now until we see if anyone
1496 * else ever uses it or we learn how to tell whether this
1497 * is such an MS blob or not.
1499 proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
1501 nt_status=tvb_get_letohl(tvb, offset);
1503 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
1505 val_to_str(nt_status, NT_errors,
1506 "Unknown error code %#x"));
1510 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1514 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1522 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
1527 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
1529 val = tvb_get_guint8(tvb, offset);
1530 proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
1541 /* This might be some sort of header that MIDL generates when creating
1542 * marshalling/unmarshalling code for blobs that are not to be transported
1543 * ontop of DCERPC and where the DREP fields specifying things such as
1544 * endianess and similar are not available.
1547 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
1551 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header");
1553 /* modified DREP field that is used for stuff that is transporetd ontop
1556 proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1559 offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
1562 proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1565 proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1568 /* length of blob that follows */
1569 proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1576 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1580 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1581 static dcerpc_info di; /* fake dcerpc_info struct */
1582 static dcerpc_call_value call_data;
1584 item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
1585 tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
1587 /* skip the first 16 bytes, they are some magic created by the idl
1588 * compiler the first 4 bytes might be flags?
1590 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1592 /* the PAC_LOGON_INFO blob */
1593 /* fake whatever state the dcerpc runtime support needs */
1594 di.conformant_run=0;
1595 /* we need di->call_data->flags.NDR64 == 0 */
1596 di.call_data=&call_data;
1597 init_ndr_pointer_list(&di);
1598 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1599 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
1600 "PAC_LOGON_INFO:", -1);
1606 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1610 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1611 static dcerpc_info di; /* fake dcerpc_info struct */
1612 static dcerpc_call_value call_data;
1614 item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
1615 tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
1617 /* skip the first 16 bytes, they are some magic created by the idl
1618 * compiler the first 4 bytes might be flags?
1620 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1623 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
1624 /* fake whatever state the dcerpc runtime support needs */
1625 di.conformant_run=0;
1626 /* we need di->call_data->flags.NDR64 == 0 */
1627 di.call_data=&call_data;
1628 init_ndr_pointer_list(&di);
1629 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1630 netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
1631 "PAC_S4U_DELEGATION_INFO:", -1);
1637 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1641 guint16 dns_offset, dns_len;
1642 guint16 upn_offset, upn_len;
1647 item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
1648 tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
1651 upn_len = tvb_get_letohs(tvb, offset);
1652 proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1654 upn_offset = tvb_get_letohs(tvb, offset);
1655 proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1659 dns_len = tvb_get_letohs(tvb, offset);
1660 proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1662 dns_offset = tvb_get_letohs(tvb, offset);
1663 proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1667 proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1670 offset = upn_offset;
1672 bc = tvb_reported_length_remaining(tvb, offset);
1673 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1674 proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
1677 offset = dns_offset;
1679 bc = tvb_reported_length_remaining(tvb, offset);
1680 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1681 proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
1687 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1689 proto_tree_add_item(parent_tree, hf_krb_pac_credential_type, tvb, offset, -1, ENC_NA);
1695 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1700 item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA);
1701 tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum);
1703 /* signature type */
1704 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1707 /* signature data */
1708 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1714 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1719 item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA);
1720 tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum);
1722 /* signature type */
1723 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1726 /* signature data */
1727 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1733 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1739 item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
1740 tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
1743 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
1746 namelen=tvb_get_letohs(tvb, offset);
1747 proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
1751 proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
1758 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1763 proto_item *it=NULL;
1764 proto_tree *tr=NULL;
1767 /* type of pac data */
1768 pac_type=tvb_get_letohl(tvb, offset);
1769 it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
1770 tr=proto_item_add_subtree(it, ett_krb_pac);
1774 /* size of pac data */
1775 pac_size=tvb_get_letohl(tvb, offset);
1776 proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
1779 /* offset to pac data */
1780 pac_offset=tvb_get_letohl(tvb, offset);
1781 proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
1784 next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size);
1786 case PAC_LOGON_INFO:
1787 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
1789 case PAC_CREDENTIAL_TYPE:
1790 dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
1792 case PAC_SERVER_CHECKSUM:
1793 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
1795 case PAC_PRIVSVR_CHECKSUM:
1796 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
1798 case PAC_CLIENT_INFO_TYPE:
1799 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
1801 case PAC_S4U_DELEGATION_INFO:
1802 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
1804 case PAC_UPN_DNS_INFO:
1805 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
1815 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_)
1821 /* first in the PAC structure comes the number of entries */
1822 entries=tvb_get_letohl(tvb, offset);
1823 proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
1826 /* second comes the version */
1827 version=tvb_get_letohl(tvb, offset);
1828 proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
1831 for(i=0;i<entries;i++){
1832 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
1838 #include "packet-kerberos-fn.c"
1840 /* Make wrappers around exported functions for now */
1842 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1844 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
1849 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1851 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
1856 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1858 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
1861 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1863 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
1868 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1869 gboolean dci, gboolean do_col_protocol, gboolean have_rm,
1870 kerberos_callbacks *cb)
1872 volatile int offset = 0;
1873 proto_tree *volatile kerberos_tree = NULL;
1874 proto_item *volatile item = NULL;
1875 asn1_ctx_t asn1_ctx;
1877 /* TCP record mark and length */
1879 gint krb_reclen = 0;
1881 gbl_do_col_info=dci;
1884 krb_rm = tvb_get_ntohl(tvb, offset);
1885 krb_reclen = kerberos_rm_to_reclen(krb_rm);
1887 * What is a reasonable size limit?
1889 if (krb_reclen > 10 * 1024 * 1024) {
1893 if (do_col_protocol) {
1894 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1898 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1899 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1902 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1905 /* Do some sanity checking here,
1906 * All krb5 packets start with a TAG class that is BER_CLASS_APP
1907 * and a tag value that is either of the values below:
1908 * If it doesn't look like kerberos, return 0 and let someone else have
1915 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
1916 if(tmp_class!=BER_CLASS_APP){
1920 case KRB5_MSG_TICKET:
1921 case KRB5_MSG_AUTHENTICATOR:
1922 case KRB5_MSG_ENC_TICKET_PART:
1923 case KRB5_MSG_AS_REQ:
1924 case KRB5_MSG_AS_REP:
1925 case KRB5_MSG_TGS_REQ:
1926 case KRB5_MSG_TGS_REP:
1927 case KRB5_MSG_AP_REQ:
1928 case KRB5_MSG_AP_REP:
1929 case KRB5_MSG_ENC_AS_REP_PART:
1930 case KRB5_MSG_ENC_TGS_REP_PART:
1931 case KRB5_MSG_ENC_AP_REP_PART:
1932 case KRB5_MSG_ENC_KRB_PRIV_PART:
1933 case KRB5_MSG_ENC_KRB_CRED_PART:
1936 case KRB5_MSG_ERROR:
1941 if (do_col_protocol) {
1942 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1944 if (gbl_do_col_info) {
1945 col_clear(pinfo->cinfo, COL_INFO);
1948 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1949 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1952 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1953 asn1_ctx.private_data = cb;
1956 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
1957 } CATCH_BOUNDS_ERRORS {
1961 proto_item_set_len(item, offset);
1966 * Display the TCP record mark.
1969 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
1972 proto_tree *rm_tree;
1977 rec_len = kerberos_rm_to_reclen(krb_rm);
1978 rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL,
1979 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
1980 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
1981 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
1985 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
1987 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
1991 kerberos_output_keytype(void)
1997 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1999 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
2000 Since all (except weirdo transarc krb4 stuff) use
2001 an opcode <=16 in the first byte, use this to see if it might
2003 All krb5 commands start with an APPL tag and thus is >=0x60
2004 so if first byte is <=16 just blindly assume it is krb4 then
2006 if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
2010 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
2018 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
2022 kerberos_rm_to_reclen(guint krb_rm)
2024 return (krb_rm & KRB_RM_RECLEN);
2028 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2033 krb_rm = tvb_get_ntohl(tvb, offset);
2034 pdulen = kerberos_rm_to_reclen(krb_rm);
2035 return (pdulen + 4);
2038 kerberos_prefs_apply_cb(void) {
2039 #ifdef HAVE_LIBNETTLE
2041 read_keytab_file(keytab_filename);
2046 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2048 pinfo->fragmented = TRUE;
2049 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
2051 * The dissector failed to recognize this as a valid
2052 * Kerberos message. Mark it as a continuation packet.
2054 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
2057 return tvb_captured_length(tvb);
2061 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2063 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2064 col_clear(pinfo->cinfo, COL_INFO);
2066 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
2067 dissect_kerberos_tcp_pdu, data);
2068 return tvb_captured_length(tvb);
2071 /*--- proto_register_kerberos -------------------------------------------*/
2072 void proto_register_kerberos(void) {
2074 /* List of fields */
2076 static hf_register_info hf[] = {
2077 { &hf_krb_rm_reserved, {
2078 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
2079 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
2080 { &hf_krb_rm_reclen, {
2081 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
2082 NULL, KRB_RM_RECLEN, NULL, HFILL }},
2083 { &hf_krb_provsrv_location, {
2084 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
2085 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
2086 { &hf_krb_smb_nt_status,
2087 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
2088 VALS(NT_errors), 0, "NT Status code", HFILL }},
2089 { &hf_krb_smb_unknown,
2090 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
2091 NULL, 0, NULL, HFILL }},
2092 { &hf_krb_address_ip, {
2093 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
2094 NULL, 0, NULL, HFILL }},
2095 { &hf_krb_address_ipv6, {
2096 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
2097 NULL, 0, NULL, HFILL }},
2098 { &hf_krb_address_netbios, {
2099 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
2100 NULL, 0, "NetBIOS Address and type", HFILL }},
2101 { &hf_krb_gssapi_len, {
2102 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
2103 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
2104 { &hf_krb_gssapi_bnd, {
2105 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
2106 NULL, 0, "GSSAPI Bnd field", HFILL }},
2107 { &hf_krb_gssapi_c_flag_deleg, {
2108 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
2109 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
2110 { &hf_krb_gssapi_c_flag_mutual, {
2111 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
2112 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
2113 { &hf_krb_gssapi_c_flag_replay, {
2114 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
2115 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
2116 { &hf_krb_gssapi_c_flag_sequence, {
2117 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
2118 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
2119 { &hf_krb_gssapi_c_flag_conf, {
2120 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
2121 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
2122 { &hf_krb_gssapi_c_flag_integ, {
2123 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
2124 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
2125 { &hf_krb_gssapi_c_flag_dce_style, {
2126 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
2127 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
2128 { &hf_krb_gssapi_dlgopt, {
2129 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
2130 NULL, 0, "GSSAPI DlgOpt", HFILL }},
2131 { &hf_krb_gssapi_dlglen, {
2132 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
2133 NULL, 0, "GSSAPI DlgLen", HFILL }},
2134 { &hf_krb_midl_blob_len, {
2135 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
2136 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
2137 { &hf_krb_midl_fill_bytes, {
2138 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
2139 NULL, 0, "Just some fill bytes", HFILL }},
2140 { &hf_krb_midl_version, {
2141 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
2142 NULL, 0, "Version of pickling", HFILL }},
2143 { &hf_krb_midl_hdr_len, {
2144 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
2145 NULL, 0, "Length of header", HFILL }},
2146 { &hf_krb_pac_signature_type, {
2147 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
2148 NULL, 0, "PAC Signature Type", HFILL }},
2149 { &hf_krb_pac_signature_signature, {
2150 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
2151 NULL, 0, "A PAC signature blob", HFILL }},
2152 { &hf_krb_w2k_pac_entries, {
2153 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
2154 NULL, 0, "Number of W2k PAC entries", HFILL }},
2155 { &hf_krb_w2k_pac_version, {
2156 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
2157 NULL, 0, "Version of PAC structures", HFILL }},
2158 { &hf_krb_w2k_pac_type, {
2159 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
2160 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
2161 { &hf_krb_w2k_pac_size, {
2162 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
2163 NULL, 0, "Size of W2k PAC entry", HFILL }},
2164 { &hf_krb_w2k_pac_offset, {
2165 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
2166 NULL, 0, "Offset to W2k PAC entry", HFILL }},
2167 { &hf_krb_pac_clientid, {
2168 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2169 NULL, 0, "ClientID Timestamp", HFILL }},
2170 { &hf_krb_pac_namelen, {
2171 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
2172 NULL, 0, "Length of client name", HFILL }},
2173 { &hf_krb_pac_clientname, {
2174 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
2175 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
2176 { &hf_krb_pac_logon_info, {
2177 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE,
2178 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
2179 { &hf_krb_pac_credential_type, {
2180 "PAC_CREDENTIAL_TYPE", "kerberos.pac_credential_type", FT_BYTES, BASE_NONE,
2181 NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
2182 { &hf_krb_pac_server_checksum, {
2183 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE,
2184 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
2185 { &hf_krb_pac_privsvr_checksum, {
2186 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE,
2187 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
2188 { &hf_krb_pac_client_info_type, {
2189 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE,
2190 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
2191 { &hf_krb_pac_s4u_delegation_info, {
2192 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE,
2193 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
2194 { &hf_krb_pac_upn_dns_info, {
2195 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE,
2196 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
2197 { &hf_krb_pac_upn_flags, {
2198 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
2199 NULL, 0, "UPN flags", HFILL }},
2200 { &hf_krb_pac_upn_dns_offset, {
2201 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
2202 NULL, 0, NULL, HFILL }},
2203 { &hf_krb_pac_upn_dns_len, {
2204 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
2205 NULL, 0, NULL, HFILL }},
2206 { &hf_krb_pac_upn_upn_offset, {
2207 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
2208 NULL, 0, NULL, HFILL }},
2209 { &hf_krb_pac_upn_upn_len, {
2210 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
2211 NULL, 0, NULL, HFILL }},
2212 { &hf_krb_pac_upn_upn_name, {
2213 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
2214 NULL, 0, NULL, HFILL }},
2215 { &hf_krb_pac_upn_dns_name, {
2216 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
2217 NULL, 0, NULL, HFILL }},
2219 #include "packet-kerberos-hfarr.c"
2222 /* List of subtrees */
2223 static gint *ett[] = {
2225 &ett_krb_recordmark,
2228 &ett_krb_pac_midl_blob,
2229 &ett_krb_pac_logon_info,
2230 &ett_krb_pac_s4u_delegation_info,
2231 &ett_krb_pac_upn_dns_info,
2232 &ett_krb_pac_server_checksum,
2233 &ett_krb_pac_privsvr_checksum,
2234 &ett_krb_pac_client_info_type,
2235 #include "packet-kerberos-ettarr.c"
2238 static ei_register_info ei[] = {
2239 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
2240 { &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 }},
2241 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }},
2244 expert_module_t* expert_krb;
2245 module_t *krb_module;
2247 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
2248 proto_register_field_array(proto_kerberos, hf, array_length(hf));
2249 proto_register_subtree_array(ett, array_length(ett));
2250 expert_krb = expert_register_protocol(proto_kerberos);
2251 expert_register_field_array(expert_krb, ei, array_length(ei));
2253 /* Register preferences */
2254 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2255 prefs_register_bool_preference(krb_module, "desegment",
2256 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2257 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2258 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2260 #ifdef HAVE_KERBEROS
2261 prefs_register_bool_preference(krb_module, "decrypt",
2262 "Try to decrypt Kerberos blobs",
2263 "Whether the dissector should try to decrypt "
2264 "encrypted Kerberos blobs. This requires that the proper "
2265 "keytab file is installed as well.", &krb_decrypt);
2267 prefs_register_filename_preference(krb_module, "file",
2268 "Kerberos keytab file",
2269 "The keytab file containing all the secrets",
2270 &keytab_filename, FALSE);
2274 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2275 proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
2279 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2281 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2283 return tvb_captured_length_remaining(tvb, offset);
2287 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2288 wrap_dissect_gss_kerb, /* Bind */
2289 wrap_dissect_gss_kerb, /* Bind ACK */
2290 wrap_dissect_gss_kerb, /* AUTH3 */
2291 NULL, /* Request verifier */
2292 NULL, /* Response verifier */
2293 NULL, /* Request data */
2294 NULL /* Response data */
2297 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2298 wrap_dissect_gss_kerb, /* Bind */
2299 wrap_dissect_gss_kerb, /* Bind ACK */
2300 wrap_dissect_gss_kerb, /* AUTH3 */
2301 wrap_dissect_gssapi_verf, /* Request verifier */
2302 wrap_dissect_gssapi_verf, /* Response verifier */
2303 NULL, /* Request data */
2304 NULL /* Response data */
2307 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2308 wrap_dissect_gss_kerb, /* Bind */
2309 wrap_dissect_gss_kerb, /* Bind ACK */
2310 wrap_dissect_gss_kerb, /* AUTH3 */
2311 wrap_dissect_gssapi_verf, /* Request verifier */
2312 wrap_dissect_gssapi_verf, /* Response verifier */
2313 wrap_dissect_gssapi_payload, /* Request data */
2314 wrap_dissect_gssapi_payload /* Response data */
2320 proto_reg_handoff_kerberos(void)
2322 dissector_handle_t kerberos_handle_tcp;
2324 krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos);
2326 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
2329 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
2332 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
2333 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
2335 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2336 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2337 &gss_kerb_auth_connect_fns);
2339 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2340 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2341 &gss_kerb_auth_sign_fns);
2343 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2344 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2345 &gss_kerb_auth_seal_fns);
2349 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2354 * indent-tabs-mode: t
2357 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2358 * :indentSize=8:tabSize=8:noTabs=false: