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;
104 } kerberos_private_data_t;
106 static dissector_handle_t kerberos_handle_udp;
108 /* Forward declarations */
109 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_);
110 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_);
111 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_);
112 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_);
113 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_);
114 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_);
115 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_);
116 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_);
117 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_);
118 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_);
119 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_);
120 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_);
121 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_);
122 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 /* Desegment Kerberos over TCP messages */
125 static gboolean krb_desegment = TRUE;
127 static gint proto_kerberos = -1;
129 static gint hf_krb_rm_reserved = -1;
130 static gint hf_krb_rm_reclen = -1;
131 static gint hf_krb_provsrv_location = -1;
132 static gint hf_krb_smb_nt_status = -1;
133 static gint hf_krb_smb_unknown = -1;
134 static gint hf_krb_address_ip = -1;
135 static gint hf_krb_address_netbios = -1;
136 static gint hf_krb_address_ipv6 = -1;
137 static gint hf_krb_gssapi_len = -1;
138 static gint hf_krb_gssapi_bnd = -1;
139 static gint hf_krb_gssapi_dlgopt = -1;
140 static gint hf_krb_gssapi_dlglen = -1;
141 static gint hf_krb_gssapi_c_flag_deleg = -1;
142 static gint hf_krb_gssapi_c_flag_mutual = -1;
143 static gint hf_krb_gssapi_c_flag_replay = -1;
144 static gint hf_krb_gssapi_c_flag_sequence = -1;
145 static gint hf_krb_gssapi_c_flag_conf = -1;
146 static gint hf_krb_gssapi_c_flag_integ = -1;
147 static gint hf_krb_gssapi_c_flag_dce_style = -1;
148 static gint hf_krb_midl_version = -1;
149 static gint hf_krb_midl_hdr_len = -1;
150 static gint hf_krb_midl_fill_bytes = -1;
151 static gint hf_krb_midl_blob_len = -1;
152 static gint hf_krb_pac_signature_type = -1;
153 static gint hf_krb_pac_signature_signature = -1;
154 static gint hf_krb_w2k_pac_entries = -1;
155 static gint hf_krb_w2k_pac_version = -1;
156 static gint hf_krb_w2k_pac_type = -1;
157 static gint hf_krb_w2k_pac_size = -1;
158 static gint hf_krb_w2k_pac_offset = -1;
159 static gint hf_krb_pac_clientid = -1;
160 static gint hf_krb_pac_namelen = -1;
161 static gint hf_krb_pac_clientname = -1;
162 static gint hf_krb_pac_logon_info = -1;
163 static gint hf_krb_pac_credential_type = -1;
164 static gint hf_krb_pac_s4u_delegation_info = -1;
165 static gint hf_krb_pac_upn_dns_info = -1;
166 static gint hf_krb_pac_upn_flags = -1;
167 static gint hf_krb_pac_upn_dns_offset = -1;
168 static gint hf_krb_pac_upn_dns_len = -1;
169 static gint hf_krb_pac_upn_upn_offset = -1;
170 static gint hf_krb_pac_upn_upn_len = -1;
171 static gint hf_krb_pac_upn_upn_name = -1;
172 static gint hf_krb_pac_upn_dns_name = -1;
173 static gint hf_krb_pac_server_checksum = -1;
174 static gint hf_krb_pac_privsvr_checksum = -1;
175 static gint hf_krb_pac_client_info_type = -1;
176 #include "packet-kerberos-hf.c"
178 /* Initialize the subtree pointers */
179 static gint ett_kerberos = -1;
180 static gint ett_krb_recordmark = -1;
181 static gint ett_krb_pac = -1;
182 static gint ett_krb_pac_drep = -1;
183 static gint ett_krb_pac_midl_blob = -1;
184 static gint ett_krb_pac_logon_info = -1;
185 static gint ett_krb_pac_s4u_delegation_info = -1;
186 static gint ett_krb_pac_upn_dns_info = -1;
187 static gint ett_krb_pac_server_checksum = -1;
188 static gint ett_krb_pac_privsvr_checksum = -1;
189 static gint ett_krb_pac_client_info_type = -1;
190 #include "packet-kerberos-ett.c"
192 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
193 static expert_field ei_kerberos_address = EI_INIT;
194 static expert_field ei_krb_gssapi_dlglen = EI_INIT;
196 static dissector_handle_t krb4_handle=NULL;
198 /* Global variables */
199 static guint32 krb5_errorcode;
200 static guint32 gbl_keytype;
201 static gboolean gbl_do_col_info;
203 #include "packet-kerberos-val.h"
206 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
214 cb->callback(pinfo, tvb, tree);
222 static kerberos_private_data_t*
223 kerberos_get_private_data(asn1_ctx_t *actx)
225 if (!actx->private_data) {
226 actx->private_data = wmem_new0(wmem_packet_scope(), kerberos_private_data_t);
228 return (kerberos_private_data_t *)(actx->private_data);
233 /* Decrypt Kerberos blobs */
234 gboolean krb_decrypt = FALSE;
236 /* keytab filename */
237 static const char *keytab_filename = "";
240 read_keytab_file_from_preferences(void)
242 static char *last_keytab = NULL;
248 if (keytab_filename == NULL) {
252 if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
257 last_keytab = g_strdup(keytab_filename);
259 read_keytab_file(last_keytab);
261 #endif /* HAVE_KERBEROS */
263 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
265 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
266 #undef HAVE_GETADDRINFO
267 #undef HAVE_SYS_TYPES_H
270 enc_key_t *enc_key_list=NULL;
273 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
277 if(pinfo->fd->flags.visited){
281 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
282 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->num);
283 new_key->fd_num = pinfo->num;
284 new_key->next=enc_key_list;
285 enc_key_list=new_key;
286 new_key->keytype=keytype;
287 new_key->keylength=keylength;
288 /*XXX this needs to be freed later */
289 new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
291 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
293 #if defined(HAVE_MIT_KERBEROS)
295 static krb5_context krb5_ctx;
297 USES_APPLE_DEPRECATED_API
299 read_keytab_file(const char *filename)
303 krb5_keytab_entry key;
304 krb5_kt_cursor cursor;
305 static gboolean first_time=TRUE;
307 if (filename == NULL || filename[0] == 0) {
313 ret = krb5_init_context(&krb5_ctx);
314 if(ret && ret != KRB5_CONFIG_CANTOPEN){
319 /* should use a file in the wireshark users dir */
320 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
322 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
327 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
329 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
334 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
340 new_key = g_new(enc_key_t, 1);
341 new_key->fd_num = -1;
342 new_key->next = enc_key_list;
344 /* generate origin string, describing where this key came from */
345 pos=new_key->key_origin;
346 pos+=MIN(KRB_MAX_ORIG_LEN,
347 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
348 for(i=0;i<key.principal->length;i++){
349 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
350 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data));
352 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
353 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "@%s",key.principal->realm.data));
355 new_key->keytype=key.key.enctype;
356 new_key->keylength=key.key.length;
357 new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
358 enc_key_list=new_key;
359 ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
361 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
362 ret = 0; /* try to continue with the next entry */
367 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
369 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
371 ret = krb5_kt_close(krb5_ctx, keytab);
373 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
379 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
387 krb5_data data = {0,0,NULL};
388 krb5_keytab_entry key;
389 int length = tvb_captured_length(cryptotvb);
390 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
392 /* don't do anything if we are not attempting to decrypt data */
393 if(!krb_decrypt || length < 1){
397 /* make sure we have all the data we need */
398 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
402 read_keytab_file_from_preferences();
403 data.data = (char *)wmem_alloc(pinfo->pool, length);
404 data.length = length;
406 for(ek=enc_key_list;ek;ek=ek->next){
409 /* shortcircuit and bail out if enctypes are not matching */
410 if((keytype != -1) && (ek->keytype != keytype)) {
414 input.enctype = ek->keytype;
415 input.ciphertext.length = length;
416 input.ciphertext.data = (guint8 *)cryptotext;
418 key.key.enctype=ek->keytype;
419 key.key.length=ek->keylength;
420 key.key.contents=ek->keyvalue;
421 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
425 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
426 "Decrypted keytype %d in frame %u using %s",
427 ek->keytype, pinfo->num, ek->key_origin);
429 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
433 *datalen = data.length;
443 #elif defined(HAVE_HEIMDAL_KERBEROS)
444 static krb5_context krb5_ctx;
446 USES_APPLE_DEPRECATED_API
448 read_keytab_file(const char *filename)
452 krb5_keytab_entry key;
453 krb5_kt_cursor cursor;
455 static gboolean first_time=TRUE;
457 if (filename == NULL || filename[0] == 0) {
463 ret = krb5_init_context(&krb5_ctx);
469 /* should use a file in the wireshark users dir */
470 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
472 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
477 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
479 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
484 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
489 new_key = g_new0(enc_key_t, 1);
490 new_key->fd_num = -1;
491 new_key->next = enc_key_list;
493 /* generate origin string, describing where this key came from */
494 pos=new_key->key_origin;
495 pos+=MIN(KRB_MAX_ORIG_LEN,
496 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
497 for(i=0;i<key.principal->name.name_string.len;i++){
498 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
499 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
501 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
502 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
504 new_key->keytype=key.keyblock.keytype;
505 new_key->keylength=(int)key.keyblock.keyvalue.length;
506 new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
507 enc_key_list=new_key;
508 ret = krb5_kt_free_entry(krb5_ctx, &key);
510 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
511 ret = 0; /* try to continue with the next entry */
516 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
518 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
520 ret = krb5_kt_close(krb5_ctx, keytab);
522 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
530 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
539 int length = tvb_captured_length(cryptotvb);
540 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
542 /* don't do anything if we are not attempting to decrypt data */
547 /* make sure we have all the data we need */
548 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
552 read_keytab_file_from_preferences();
554 for(ek=enc_key_list;ek;ek=ek->next){
555 krb5_keytab_entry key;
557 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
559 /* shortcircuit and bail out if enctypes are not matching */
560 if((keytype != -1) && (ek->keytype != keytype)) {
564 key.keyblock.keytype=ek->keytype;
565 key.keyblock.keyvalue.length=ek->keylength;
566 key.keyblock.keyvalue.data=ek->keyvalue;
567 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto);
572 /* pre-0.6.1 versions of Heimdal would sometimes change
573 the cryptotext data even when the decryption failed.
574 This would obviously not work since we iterate over the
575 keys. So just give it a copy of the crypto data instead.
576 This has been seen for RC4-HMAC blobs.
578 cryptocopy = (guint8 *)wmem_memdup(wmem_packet_scope(), cryptotext, length);
579 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
583 if((ret == 0) && (length>0)){
586 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
587 "Decrypted keytype %d in frame %u using %s",
588 ek->keytype, pinfo->num, ek->key_origin);
590 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
592 krb5_crypto_destroy(krb5_ctx, crypto);
593 /* return a private wmem_alloced blob to the caller */
594 user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
596 *datalen = (int)data.length;
600 krb5_crypto_destroy(krb5_ctx, crypto);
605 #elif defined (HAVE_LIBNETTLE)
607 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
608 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
610 typedef struct _service_key_t {
615 char origin[KRB_MAX_ORIG_LEN+1];
617 GSList *service_key_list = NULL;
621 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
623 service_key_t *new_key;
625 if(pinfo->fd->flags.visited){
629 new_key = g_malloc(sizeof(service_key_t));
631 new_key->keytype = keytype;
632 new_key->length = keylength;
633 new_key->contents = g_memdup(keyvalue, keylength);
634 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
635 service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
643 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
644 sk = (service_key_t *) ske->data;
646 g_free(sk->contents);
650 g_slist_free(service_key_list);
651 service_key_list = NULL;
655 read_keytab_file(const char *service_key_file)
660 unsigned char buf[SERVICE_KEY_SIZE];
661 int newline_skip = 0, count = 0;
663 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
665 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
666 * There can be zero, one (\n), or two (\r\n) characters between
667 * keys. Trailing characters are ignored.
670 /* XXX We should support the standard keytab format instead */
671 if (st.st_size > SERVICE_KEY_SIZE) {
672 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
673 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
675 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
676 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
681 skf = ws_fopen(service_key_file, "rb");
684 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
685 sk = g_malloc(sizeof(service_key_t));
686 sk->kvno = buf[0] << 8 | buf[1];
687 sk->keytype = KEYTYPE_DES3_CBC_MD5;
688 sk->length = DES3_KEY_SIZE;
689 sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
690 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
691 service_key_list = g_slist_append(service_key_list, (gpointer) sk);
692 if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
693 fprintf(stderr, "unable to seek...\n");
702 #define CONFOUNDER_PLUS_CHECKSUM 24
705 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
712 guint8 *decrypted_data = NULL, *plaintext = NULL;
715 guint32 tag, item_len, data_len;
716 int id_offset, offset;
717 guint8 key[DES3_KEY_SIZE];
718 guint8 initial_vector[DES_BLOCK_SIZE];
719 gcry_md_hd_t md5_handle;
721 guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
722 guint8 confounder[8];
727 int length = tvb_captured_length(cryptotvb);
728 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
731 /* don't do anything if we are not attempting to decrypt data */
736 /* make sure we have all the data we need */
737 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
741 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
745 decrypted_data = wmem_alloc(wmem_packet_scope(), length);
746 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
747 gboolean do_continue = FALSE;
749 sk = (service_key_t *) ske->data;
751 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
753 memset(initial_vector, 0, DES_BLOCK_SIZE);
754 des3_set_key(&ctx, key);
755 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
756 length, decrypted_data, cryptotext);
757 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
759 tvb_memcpy(encr_tvb, confounder, 0, 8);
761 /* We have to pull the decrypted data length from the decrypted
762 * content. If the key doesn't match or we otherwise get garbage,
763 * an exception may get thrown while decoding the ASN.1 header.
764 * Catch it, just in case.
767 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
768 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
770 CATCH_BOUNDS_ERRORS {
776 if (do_continue) continue;
778 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
779 if ((int) item_len + offset > length) {
784 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
787 gcry_md_write(md5_handle, confounder, 8);
788 gcry_md_write(md5_handle, zero_fill, 16);
789 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
790 digest = gcry_md_read(md5_handle, 0);
792 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
793 gcry_md_close(md5_handle);
795 plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
809 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
811 #define INET6_ADDRLEN 16
813 /* TCP Record Mark */
814 #define KRB_RM_RESERVED 0x80000000U
815 #define KRB_RM_RECLEN 0x7fffffffU
817 #define KRB5_MSG_TICKET 1 /* Ticket */
818 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
819 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
820 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
821 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
822 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
823 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
824 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
825 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
827 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
828 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
829 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
830 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
831 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
832 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
833 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
834 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
835 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
837 #define KRB5_CHKSUM_GSSAPI 0x8003
839 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
841 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
843 * unless it's expired.
846 /* Principal name-type */
847 #define KRB5_NT_UNKNOWN 0
848 #define KRB5_NT_PRINCIPAL 1
849 #define KRB5_NT_SRV_INST 2
850 #define KRB5_NT_SRV_HST 3
851 #define KRB5_NT_SRV_XHST 4
852 #define KRB5_NT_UID 5
853 #define KRB5_NT_X500_PRINCIPAL 6
854 #define KRB5_NT_SMTP_NAME 7
855 #define KRB5_NT_ENTERPRISE 10
858 * MS specific name types, from
860 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
862 #define KRB5_NT_MS_PRINCIPAL -128
863 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
864 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
865 #define KRB5_NT_PRINCIPAL_AND_SID -131
866 #define KRB5_NT_SRV_INST_AND_SID -132
868 /* error table constants */
869 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
870 #define KRB5_ET_KRB5KDC_ERR_NONE 0
871 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
872 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
873 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
874 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
875 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
876 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
877 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
878 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
879 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
880 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
881 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
882 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
883 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
884 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
885 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
886 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
887 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
888 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
889 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
890 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
891 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
892 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
893 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
894 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
895 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
896 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
897 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
898 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
899 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
900 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
901 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
902 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
903 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
904 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
905 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
906 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
907 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
908 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
909 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
910 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
911 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
912 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
913 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
914 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
915 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
916 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
917 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
918 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
919 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
920 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
921 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
922 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
923 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
924 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
925 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
926 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
927 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
928 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
929 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
930 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
931 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
932 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
933 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
934 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
935 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
936 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
937 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
938 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
940 static const value_string krb5_error_codes[] = {
941 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
942 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
943 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
944 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
945 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
946 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
947 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
948 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
949 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
950 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
951 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
952 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
953 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
954 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
955 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
956 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
957 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
958 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
959 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
960 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
961 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
962 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
963 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
964 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
965 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
966 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
967 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
968 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
969 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
970 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
971 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
972 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
973 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
974 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
975 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
976 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
977 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
978 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
979 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
980 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
981 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
982 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
983 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
984 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
985 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
986 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
987 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
988 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
989 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
990 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
991 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
992 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
993 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
994 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
995 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
996 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
997 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
998 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
999 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1000 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1001 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1002 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1003 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1004 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1005 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1006 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1007 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1008 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1009 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1014 #define PAC_LOGON_INFO 1
1015 #define PAC_CREDENTIAL_TYPE 2
1016 #define PAC_SERVER_CHECKSUM 6
1017 #define PAC_PRIVSVR_CHECKSUM 7
1018 #define PAC_CLIENT_INFO_TYPE 10
1019 #define PAC_S4U_DELEGATION_INFO 11
1020 #define PAC_UPN_DNS_INFO 12
1021 static const value_string w2k_pac_types[] = {
1022 { PAC_LOGON_INFO , "Logon Info" },
1023 { PAC_CREDENTIAL_TYPE , "Credential Type" },
1024 { PAC_SERVER_CHECKSUM , "Server Checksum" },
1025 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
1026 { PAC_CLIENT_INFO_TYPE , "Client Info Type" },
1027 { PAC_S4U_DELEGATION_INFO, "S4U Delegation Info" },
1028 { PAC_UPN_DNS_INFO , "UPN DNS Info" },
1032 static const value_string krb5_msg_types[] = {
1033 { KRB5_MSG_TICKET, "Ticket" },
1034 { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
1035 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
1036 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
1037 { KRB5_MSG_TGS_REP, "TGS-REP" },
1038 { KRB5_MSG_AS_REQ, "AS-REQ" },
1039 { KRB5_MSG_AS_REP, "AS-REP" },
1040 { KRB5_MSG_AP_REQ, "AP-REQ" },
1041 { KRB5_MSG_AP_REP, "AP-REP" },
1042 { KRB5_MSG_SAFE, "KRB-SAFE" },
1043 { KRB5_MSG_PRIV, "KRB-PRIV" },
1044 { KRB5_MSG_CRED, "KRB-CRED" },
1045 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
1046 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
1047 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
1048 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1049 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1050 { KRB5_MSG_ERROR, "KRB-ERROR" },
1054 #define KRB5_GSS_C_DELEG_FLAG 0x01
1055 #define KRB5_GSS_C_MUTUAL_FLAG 0x02
1056 #define KRB5_GSS_C_REPLAY_FLAG 0x04
1057 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08
1058 #define KRB5_GSS_C_CONF_FLAG 0x10
1059 #define KRB5_GSS_C_INTEG_FLAG 0x20
1060 #define KRB5_GSS_C_DCE_STYLE 0x1000
1062 static const true_false_string tfs_gss_flags_deleg = {
1063 "Delegate credentials to remote peer",
1066 static const true_false_string tfs_gss_flags_mutual = {
1067 "Request that remote peer authenticates itself",
1068 "Mutual authentication NOT required"
1070 static const true_false_string tfs_gss_flags_replay = {
1071 "Enable replay protection for signed or sealed messages",
1072 "Do NOT enable replay protection"
1074 static const true_false_string tfs_gss_flags_sequence = {
1075 "Enable Out-of-sequence detection for sign or sealed messages",
1076 "Do NOT enable out-of-sequence detection"
1078 static const true_false_string tfs_gss_flags_conf = {
1079 "Confidentiality (sealing) may be invoked",
1080 "Do NOT use Confidentiality (sealing)"
1082 static const true_false_string tfs_gss_flags_integ = {
1083 "Integrity protection (signing) may be invoked",
1084 "Do NOT use integrity protection"
1087 static const true_false_string tfs_gss_flags_dce_style = {
1089 "Not using DCE-STYLE"
1092 #ifdef HAVE_KERBEROS
1094 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1095 proto_tree *tree, int hf_index _U_)
1099 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1102 next_tvb=tvb_new_subset_remaining(tvb, offset);
1103 length=tvb_captured_length_remaining(tvb, offset);
1105 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1107 * All Ticket encrypted parts use usage == 2
1109 plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, private_data->etype, NULL);
1112 tvbuff_t *child_tvb;
1113 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1115 /* Add the decrypted data to the data source list. */
1116 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1118 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1124 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1125 proto_tree *tree, int hf_index _U_)
1129 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1132 next_tvb=tvb_new_subset_remaining(tvb, offset);
1133 length=tvb_captured_length_remaining(tvb, offset);
1135 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1137 * Authenticators are encrypted with usage
1141 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, private_data->etype, NULL);
1144 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, private_data->etype, NULL);
1148 tvbuff_t *child_tvb;
1149 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1151 /* Add the decrypted data to the data source list. */
1152 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1154 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1160 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1161 proto_tree *tree, int hf_index _U_)
1165 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1168 next_tvb=tvb_new_subset_remaining(tvb, offset);
1169 length=tvb_captured_length_remaining(tvb, offset);
1171 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1173 * ASREP/TGSREP encryptedparts are encrypted with usage
1178 plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, private_data->etype, NULL);
1181 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, private_data->etype, NULL);
1185 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, private_data->etype, NULL);
1189 tvbuff_t *child_tvb;
1190 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1192 /* Add the decrypted data to the data source list. */
1193 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1195 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1201 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1202 proto_tree *tree, int hf_index _U_)
1206 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1209 next_tvb=tvb_new_subset_remaining(tvb, offset);
1210 length=tvb_captured_length_remaining(tvb, offset);
1212 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1214 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1217 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, private_data->etype, NULL);
1220 tvbuff_t *child_tvb;
1221 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1223 /* Add the decrypted data to the data source list. */
1224 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1226 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1232 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1233 proto_tree *tree, int hf_index _U_)
1237 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1240 next_tvb=tvb_new_subset_remaining(tvb, offset);
1241 length=tvb_captured_length_remaining(tvb, offset);
1243 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1245 * AP-REP are encrypted with usage == 12
1247 plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, private_data->etype, NULL);
1250 tvbuff_t *child_tvb;
1251 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1253 /* Add the decrypted data to the data source list. */
1254 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1256 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1262 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1263 proto_tree *tree, int hf_index _U_)
1267 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1270 next_tvb=tvb_new_subset_remaining(tvb, offset);
1271 length=tvb_captured_length_remaining(tvb, offset);
1274 * EncKrbPrivPart encrypted with usage
1277 plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, private_data->etype, NULL);
1280 tvbuff_t *child_tvb;
1281 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1283 /* Add the decrypted data to the data source list. */
1284 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1286 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1292 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1293 proto_tree *tree, int hf_index _U_)
1297 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1300 next_tvb=tvb_new_subset_remaining(tvb, offset);
1301 length=tvb_captured_length_remaining(tvb, offset);
1304 * EncKrbCredPart encrypted with usage
1307 plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, private_data->etype, NULL);
1310 tvbuff_t *child_tvb;
1311 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1313 /* Add the decrypted data to the data source list. */
1314 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1316 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1322 dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1323 proto_tree *tree, int hf_index _U_)
1327 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1330 next_tvb=tvb_new_subset_remaining(tvb, offset);
1331 length=tvb_captured_length_remaining(tvb, offset);
1334 * KrbFastResponse encrypted with usage
1335 * KEY_USAGE_FAST_ENC 51
1337 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_ENC,
1338 next_tvb, private_data->etype, NULL);
1341 tvbuff_t *child_tvb;
1342 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1343 tvb_set_free_cb(child_tvb, g_free);
1345 /* Add the decrypted data to the data source list. */
1346 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1348 offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1354 dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1355 proto_tree *tree, int hf_index _U_)
1359 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1362 next_tvb=tvb_new_subset_remaining(tvb, offset);
1363 length=tvb_captured_length_remaining(tvb, offset);
1367 * KrbFastResponse encrypted with usage
1368 * KEY_USAGE_FAST_REP 52
1370 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_REP,
1371 next_tvb, private_data->etype, NULL);
1374 tvbuff_t *child_tvb;
1375 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1376 tvb_set_free_cb(child_tvb, g_free);
1378 /* Add the decrypted data to the data source list. */
1379 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1381 offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1387 dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1388 proto_tree *tree, int hf_index _U_)
1392 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1396 next_tvb=tvb_new_subset_remaining(tvb, offset);
1397 length=tvb_captured_length_remaining(tvb, offset);
1400 * KEY_USAGE_ENC_CHALLENGE_CLIENT 54
1401 * KEY_USAGE_ENC_CHALLENGE_KDC 55
1403 if (private_data->kdc_response) {
1404 usage = KEY_USAGE_ENC_CHALLENGE_KDC;
1406 usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
1408 plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, private_data->etype, NULL);
1411 tvbuff_t *child_tvb;
1412 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1413 tvb_set_free_cb(child_tvb, g_free);
1415 /* Add the decrypted data to the data source list. */
1416 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1418 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1424 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1427 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1433 /* Length of Bnd field */
1434 len=tvb_get_letohl(tvb, offset);
1435 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1439 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1444 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1445 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1446 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1447 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1448 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1449 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1450 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1453 /* the next fields are optional so we have to check that we have
1454 * more data in our buffers */
1455 if(tvb_reported_length_remaining(tvb, offset)<2){
1458 /* dlgopt identifier */
1459 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1462 if(tvb_reported_length_remaining(tvb, offset)<2){
1465 /* dlglen identifier */
1466 dlglen=tvb_get_letohs(tvb, offset);
1467 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1470 if(dlglen!=tvb_reported_length_remaining(tvb, offset)){
1471 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0,
1472 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset));
1476 /* this should now be a KRB_CRED message */
1477 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1483 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_)
1485 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1491 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_)
1495 /* Microsoft stores a special 12 byte blob here
1499 * decode everything as this blob for now until we see if anyone
1500 * else ever uses it or we learn how to tell whether this
1501 * is such an MS blob or not.
1503 proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
1505 nt_status=tvb_get_letohl(tvb, offset);
1507 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
1509 val_to_str(nt_status, NT_errors,
1510 "Unknown error code %#x"));
1514 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1518 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1526 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
1531 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
1533 val = tvb_get_guint8(tvb, offset);
1534 proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
1545 /* This might be some sort of header that MIDL generates when creating
1546 * marshalling/unmarshalling code for blobs that are not to be transported
1547 * ontop of DCERPC and where the DREP fields specifying things such as
1548 * endianess and similar are not available.
1551 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
1555 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header");
1557 /* modified DREP field that is used for stuff that is transporetd ontop
1560 proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1563 offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
1566 proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1569 proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1572 /* length of blob that follows */
1573 proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1580 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1584 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1585 static dcerpc_info di; /* fake dcerpc_info struct */
1586 static dcerpc_call_value call_data;
1588 item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
1589 tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
1591 /* skip the first 16 bytes, they are some magic created by the idl
1592 * compiler the first 4 bytes might be flags?
1594 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1596 /* the PAC_LOGON_INFO blob */
1597 /* fake whatever state the dcerpc runtime support needs */
1598 di.conformant_run=0;
1599 /* we need di->call_data->flags.NDR64 == 0 */
1600 di.call_data=&call_data;
1601 init_ndr_pointer_list(&di);
1602 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1603 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
1604 "PAC_LOGON_INFO:", -1);
1610 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1614 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1615 static dcerpc_info di; /* fake dcerpc_info struct */
1616 static dcerpc_call_value call_data;
1618 item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
1619 tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
1621 /* skip the first 16 bytes, they are some magic created by the idl
1622 * compiler the first 4 bytes might be flags?
1624 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
1627 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
1628 /* fake whatever state the dcerpc runtime support needs */
1629 di.conformant_run=0;
1630 /* we need di->call_data->flags.NDR64 == 0 */
1631 di.call_data=&call_data;
1632 init_ndr_pointer_list(&di);
1633 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
1634 netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
1635 "PAC_S4U_DELEGATION_INFO:", -1);
1641 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1645 guint16 dns_offset, dns_len;
1646 guint16 upn_offset, upn_len;
1651 item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
1652 tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
1655 upn_len = tvb_get_letohs(tvb, offset);
1656 proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1658 upn_offset = tvb_get_letohs(tvb, offset);
1659 proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1663 dns_len = tvb_get_letohs(tvb, offset);
1664 proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1666 dns_offset = tvb_get_letohs(tvb, offset);
1667 proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1671 proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1674 offset = upn_offset;
1676 bc = tvb_reported_length_remaining(tvb, offset);
1677 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1678 proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
1681 offset = dns_offset;
1683 bc = tvb_reported_length_remaining(tvb, offset);
1684 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
1685 proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
1691 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1693 proto_tree_add_item(parent_tree, hf_krb_pac_credential_type, tvb, offset, -1, ENC_NA);
1699 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1704 item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA);
1705 tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum);
1707 /* signature type */
1708 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1711 /* signature data */
1712 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1718 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1723 item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA);
1724 tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum);
1726 /* signature type */
1727 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1730 /* signature data */
1731 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
1737 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1743 item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
1744 tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
1747 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
1750 namelen=tvb_get_letohs(tvb, offset);
1751 proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
1755 proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
1762 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
1767 proto_item *it=NULL;
1768 proto_tree *tr=NULL;
1771 /* type of pac data */
1772 pac_type=tvb_get_letohl(tvb, offset);
1773 it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
1774 tr=proto_item_add_subtree(it, ett_krb_pac);
1778 /* size of pac data */
1779 pac_size=tvb_get_letohl(tvb, offset);
1780 proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
1783 /* offset to pac data */
1784 pac_offset=tvb_get_letohl(tvb, offset);
1785 proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
1788 next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size);
1790 case PAC_LOGON_INFO:
1791 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
1793 case PAC_CREDENTIAL_TYPE:
1794 dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
1796 case PAC_SERVER_CHECKSUM:
1797 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
1799 case PAC_PRIVSVR_CHECKSUM:
1800 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
1802 case PAC_CLIENT_INFO_TYPE:
1803 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
1805 case PAC_S4U_DELEGATION_INFO:
1806 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
1808 case PAC_UPN_DNS_INFO:
1809 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
1819 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_)
1825 /* first in the PAC structure comes the number of entries */
1826 entries=tvb_get_letohl(tvb, offset);
1827 proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
1830 /* second comes the version */
1831 version=tvb_get_letohl(tvb, offset);
1832 proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
1835 for(i=0;i<entries;i++){
1836 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
1842 #include "packet-kerberos-fn.c"
1844 /* Make wrappers around exported functions for now */
1846 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1848 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
1853 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1855 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
1860 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1862 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
1865 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1867 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
1872 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1873 gboolean dci, gboolean do_col_protocol, gboolean have_rm,
1874 kerberos_callbacks *cb)
1876 volatile int offset = 0;
1877 proto_tree *volatile kerberos_tree = NULL;
1878 proto_item *volatile item = NULL;
1879 asn1_ctx_t asn1_ctx;
1881 /* TCP record mark and length */
1883 gint krb_reclen = 0;
1885 gbl_do_col_info=dci;
1888 krb_rm = tvb_get_ntohl(tvb, offset);
1889 krb_reclen = kerberos_rm_to_reclen(krb_rm);
1891 * What is a reasonable size limit?
1893 if (krb_reclen > 10 * 1024 * 1024) {
1897 if (do_col_protocol) {
1898 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1902 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1903 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1906 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1909 /* Do some sanity checking here,
1910 * All krb5 packets start with a TAG class that is BER_CLASS_APP
1911 * and a tag value that is either of the values below:
1912 * If it doesn't look like kerberos, return 0 and let someone else have
1919 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
1920 if(tmp_class!=BER_CLASS_APP){
1924 case KRB5_MSG_TICKET:
1925 case KRB5_MSG_AUTHENTICATOR:
1926 case KRB5_MSG_ENC_TICKET_PART:
1927 case KRB5_MSG_AS_REQ:
1928 case KRB5_MSG_AS_REP:
1929 case KRB5_MSG_TGS_REQ:
1930 case KRB5_MSG_TGS_REP:
1931 case KRB5_MSG_AP_REQ:
1932 case KRB5_MSG_AP_REP:
1933 case KRB5_MSG_ENC_AS_REP_PART:
1934 case KRB5_MSG_ENC_TGS_REP_PART:
1935 case KRB5_MSG_ENC_AP_REP_PART:
1936 case KRB5_MSG_ENC_KRB_PRIV_PART:
1937 case KRB5_MSG_ENC_KRB_CRED_PART:
1940 case KRB5_MSG_ERROR:
1945 if (do_col_protocol) {
1946 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1948 if (gbl_do_col_info) {
1949 col_clear(pinfo->cinfo, COL_INFO);
1952 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1953 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1956 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1957 asn1_ctx.private_data = cb;
1960 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
1961 } CATCH_BOUNDS_ERRORS {
1965 proto_item_set_len(item, offset);
1970 * Display the TCP record mark.
1973 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
1976 proto_tree *rm_tree;
1981 rec_len = kerberos_rm_to_reclen(krb_rm);
1982 rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL,
1983 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
1984 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
1985 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
1989 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
1991 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
1995 kerberos_output_keytype(void)
2001 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2003 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
2004 Since all (except weirdo transarc krb4 stuff) use
2005 an opcode <=16 in the first byte, use this to see if it might
2007 All krb5 commands start with an APPL tag and thus is >=0x60
2008 so if first byte is <=16 just blindly assume it is krb4 then
2010 if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
2014 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
2022 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
2026 kerberos_rm_to_reclen(guint krb_rm)
2028 return (krb_rm & KRB_RM_RECLEN);
2032 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2037 krb_rm = tvb_get_ntohl(tvb, offset);
2038 pdulen = kerberos_rm_to_reclen(krb_rm);
2039 return (pdulen + 4);
2042 kerberos_prefs_apply_cb(void) {
2043 #ifdef HAVE_LIBNETTLE
2045 read_keytab_file(keytab_filename);
2050 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2052 pinfo->fragmented = TRUE;
2053 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
2055 * The dissector failed to recognize this as a valid
2056 * Kerberos message. Mark it as a continuation packet.
2058 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
2061 return tvb_captured_length(tvb);
2065 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2067 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2068 col_clear(pinfo->cinfo, COL_INFO);
2070 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
2071 dissect_kerberos_tcp_pdu, data);
2072 return tvb_captured_length(tvb);
2075 /*--- proto_register_kerberos -------------------------------------------*/
2076 void proto_register_kerberos(void) {
2078 /* List of fields */
2080 static hf_register_info hf[] = {
2081 { &hf_krb_rm_reserved, {
2082 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
2083 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
2084 { &hf_krb_rm_reclen, {
2085 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
2086 NULL, KRB_RM_RECLEN, NULL, HFILL }},
2087 { &hf_krb_provsrv_location, {
2088 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
2089 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
2090 { &hf_krb_smb_nt_status,
2091 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
2092 VALS(NT_errors), 0, "NT Status code", HFILL }},
2093 { &hf_krb_smb_unknown,
2094 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
2095 NULL, 0, NULL, HFILL }},
2096 { &hf_krb_address_ip, {
2097 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
2098 NULL, 0, NULL, HFILL }},
2099 { &hf_krb_address_ipv6, {
2100 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
2101 NULL, 0, NULL, HFILL }},
2102 { &hf_krb_address_netbios, {
2103 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
2104 NULL, 0, "NetBIOS Address and type", HFILL }},
2105 { &hf_krb_gssapi_len, {
2106 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
2107 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
2108 { &hf_krb_gssapi_bnd, {
2109 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
2110 NULL, 0, "GSSAPI Bnd field", HFILL }},
2111 { &hf_krb_gssapi_c_flag_deleg, {
2112 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
2113 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
2114 { &hf_krb_gssapi_c_flag_mutual, {
2115 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
2116 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
2117 { &hf_krb_gssapi_c_flag_replay, {
2118 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
2119 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
2120 { &hf_krb_gssapi_c_flag_sequence, {
2121 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
2122 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
2123 { &hf_krb_gssapi_c_flag_conf, {
2124 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
2125 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
2126 { &hf_krb_gssapi_c_flag_integ, {
2127 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
2128 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
2129 { &hf_krb_gssapi_c_flag_dce_style, {
2130 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
2131 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
2132 { &hf_krb_gssapi_dlgopt, {
2133 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
2134 NULL, 0, "GSSAPI DlgOpt", HFILL }},
2135 { &hf_krb_gssapi_dlglen, {
2136 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
2137 NULL, 0, "GSSAPI DlgLen", HFILL }},
2138 { &hf_krb_midl_blob_len, {
2139 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
2140 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
2141 { &hf_krb_midl_fill_bytes, {
2142 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
2143 NULL, 0, "Just some fill bytes", HFILL }},
2144 { &hf_krb_midl_version, {
2145 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
2146 NULL, 0, "Version of pickling", HFILL }},
2147 { &hf_krb_midl_hdr_len, {
2148 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
2149 NULL, 0, "Length of header", HFILL }},
2150 { &hf_krb_pac_signature_type, {
2151 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
2152 NULL, 0, "PAC Signature Type", HFILL }},
2153 { &hf_krb_pac_signature_signature, {
2154 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
2155 NULL, 0, "A PAC signature blob", HFILL }},
2156 { &hf_krb_w2k_pac_entries, {
2157 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
2158 NULL, 0, "Number of W2k PAC entries", HFILL }},
2159 { &hf_krb_w2k_pac_version, {
2160 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
2161 NULL, 0, "Version of PAC structures", HFILL }},
2162 { &hf_krb_w2k_pac_type, {
2163 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
2164 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
2165 { &hf_krb_w2k_pac_size, {
2166 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
2167 NULL, 0, "Size of W2k PAC entry", HFILL }},
2168 { &hf_krb_w2k_pac_offset, {
2169 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
2170 NULL, 0, "Offset to W2k PAC entry", HFILL }},
2171 { &hf_krb_pac_clientid, {
2172 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2173 NULL, 0, "ClientID Timestamp", HFILL }},
2174 { &hf_krb_pac_namelen, {
2175 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
2176 NULL, 0, "Length of client name", HFILL }},
2177 { &hf_krb_pac_clientname, {
2178 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
2179 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
2180 { &hf_krb_pac_logon_info, {
2181 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE,
2182 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
2183 { &hf_krb_pac_credential_type, {
2184 "PAC_CREDENTIAL_TYPE", "kerberos.pac_credential_type", FT_BYTES, BASE_NONE,
2185 NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
2186 { &hf_krb_pac_server_checksum, {
2187 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE,
2188 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
2189 { &hf_krb_pac_privsvr_checksum, {
2190 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE,
2191 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
2192 { &hf_krb_pac_client_info_type, {
2193 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE,
2194 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
2195 { &hf_krb_pac_s4u_delegation_info, {
2196 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE,
2197 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
2198 { &hf_krb_pac_upn_dns_info, {
2199 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE,
2200 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
2201 { &hf_krb_pac_upn_flags, {
2202 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
2203 NULL, 0, "UPN flags", HFILL }},
2204 { &hf_krb_pac_upn_dns_offset, {
2205 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
2206 NULL, 0, NULL, HFILL }},
2207 { &hf_krb_pac_upn_dns_len, {
2208 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
2209 NULL, 0, NULL, HFILL }},
2210 { &hf_krb_pac_upn_upn_offset, {
2211 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
2212 NULL, 0, NULL, HFILL }},
2213 { &hf_krb_pac_upn_upn_len, {
2214 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
2215 NULL, 0, NULL, HFILL }},
2216 { &hf_krb_pac_upn_upn_name, {
2217 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
2218 NULL, 0, NULL, HFILL }},
2219 { &hf_krb_pac_upn_dns_name, {
2220 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
2221 NULL, 0, NULL, HFILL }},
2223 #include "packet-kerberos-hfarr.c"
2226 /* List of subtrees */
2227 static gint *ett[] = {
2229 &ett_krb_recordmark,
2232 &ett_krb_pac_midl_blob,
2233 &ett_krb_pac_logon_info,
2234 &ett_krb_pac_s4u_delegation_info,
2235 &ett_krb_pac_upn_dns_info,
2236 &ett_krb_pac_server_checksum,
2237 &ett_krb_pac_privsvr_checksum,
2238 &ett_krb_pac_client_info_type,
2239 #include "packet-kerberos-ettarr.c"
2242 static ei_register_info ei[] = {
2243 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
2244 { &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 }},
2245 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }},
2248 expert_module_t* expert_krb;
2249 module_t *krb_module;
2251 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
2252 proto_register_field_array(proto_kerberos, hf, array_length(hf));
2253 proto_register_subtree_array(ett, array_length(ett));
2254 expert_krb = expert_register_protocol(proto_kerberos);
2255 expert_register_field_array(expert_krb, ei, array_length(ei));
2257 /* Register preferences */
2258 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2259 prefs_register_bool_preference(krb_module, "desegment",
2260 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2261 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2262 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2264 #ifdef HAVE_KERBEROS
2265 prefs_register_bool_preference(krb_module, "decrypt",
2266 "Try to decrypt Kerberos blobs",
2267 "Whether the dissector should try to decrypt "
2268 "encrypted Kerberos blobs. This requires that the proper "
2269 "keytab file is installed as well.", &krb_decrypt);
2271 prefs_register_filename_preference(krb_module, "file",
2272 "Kerberos keytab file",
2273 "The keytab file containing all the secrets",
2274 &keytab_filename, FALSE);
2278 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2279 proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
2283 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2285 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2287 return tvb_captured_length_remaining(tvb, offset);
2291 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2292 wrap_dissect_gss_kerb, /* Bind */
2293 wrap_dissect_gss_kerb, /* Bind ACK */
2294 wrap_dissect_gss_kerb, /* AUTH3 */
2295 NULL, /* Request verifier */
2296 NULL, /* Response verifier */
2297 NULL, /* Request data */
2298 NULL /* Response data */
2301 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2302 wrap_dissect_gss_kerb, /* Bind */
2303 wrap_dissect_gss_kerb, /* Bind ACK */
2304 wrap_dissect_gss_kerb, /* AUTH3 */
2305 wrap_dissect_gssapi_verf, /* Request verifier */
2306 wrap_dissect_gssapi_verf, /* Response verifier */
2307 NULL, /* Request data */
2308 NULL /* Response data */
2311 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2312 wrap_dissect_gss_kerb, /* Bind */
2313 wrap_dissect_gss_kerb, /* Bind ACK */
2314 wrap_dissect_gss_kerb, /* AUTH3 */
2315 wrap_dissect_gssapi_verf, /* Request verifier */
2316 wrap_dissect_gssapi_verf, /* Response verifier */
2317 wrap_dissect_gssapi_payload, /* Request data */
2318 wrap_dissect_gssapi_payload /* Response data */
2324 proto_reg_handoff_kerberos(void)
2326 dissector_handle_t kerberos_handle_tcp;
2328 krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos);
2330 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
2333 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
2336 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
2337 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
2339 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2340 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2341 &gss_kerb_auth_connect_fns);
2343 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2344 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2345 &gss_kerb_auth_sign_fns);
2347 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2348 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2349 &gss_kerb_auth_seal_fns);
2353 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2358 * indent-tabs-mode: t
2361 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2362 * :indentSize=8:tabSize=8:noTabs=false: