861fdadef0e5b456c92d22290a7b9c4906f40147
[metze/wireshark/wip.git] / epan / dissectors / asn1 / kerberos / packet-kerberos-template.c
1 /* packet-kerberos.c
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
7  *
8  * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API.
9  *                           decryption of kerberos blobs if keytab is provided
10  *
11  * See RFC 1510, and various I-Ds and other documents showing additions,
12  * e.g. ones listed under
13  *
14  *      http://www.isi.edu/people/bcn/krb-revisions/
15  *
16  * and
17  *
18  *      http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-07.txt
19  *
20  * and
21  *
22  *      http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-referrals-05.txt
23  *
24  * Some structures from RFC2630
25  *
26  * Wireshark - Network traffic analyzer
27  * By Gerald Combs <gerald@wireshark.org>
28  * Copyright 1998 Gerald Combs
29  *
30  * SPDX-License-Identifier: GPL-2.0-or-later
31  */
32
33 /*
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
40  * information.
41  */
42
43 #include <config.h>
44
45 //TODO
46 #define HAVE_KRB5_CRYPTO_FX_CF2 1
47 #define HAVE_KRB5_C_FX_CF2_SIMPLE 1
48
49 #include <stdio.h>
50
51 #include <epan/packet.h>
52 #include <epan/exceptions.h>
53 #include <epan/strutil.h>
54 #include <epan/conversation.h>
55 #include <epan/asn1.h>
56 #include <epan/expert.h>
57 #include <epan/prefs.h>
58 #include <epan/proto_data.h>
59 #include <wsutil/wsgcrypt.h>
60 #include <wsutil/file_util.h>
61 #include <wsutil/str_util.h>
62 #include <wsutil/pint.h>
63 #include "packet-kerberos.h"
64 #include "packet-netbios.h"
65 #include "packet-tcp.h"
66 #include "packet-ber.h"
67 #include "packet-pkinit.h"
68 #include "packet-cms.h"
69 #include "packet-windows-common.h"
70
71 #include "read_keytab_file.h"
72
73 #include "packet-dcerpc-netlogon.h"
74 #include "packet-dcerpc.h"
75
76 #include "packet-gssapi.h"
77 #include "packet-smb-common.h"
78 #include "packet-x509af.h"
79
80 #define KEY_USAGE_FAST_REQ_CHKSUM       50
81 #define KEY_USAGE_FAST_ENC              51
82 #define KEY_USAGE_FAST_REP              52
83 #define KEY_USAGE_FAST_FINISHED         53
84 #define KEY_USAGE_ENC_CHALLENGE_CLIENT  54
85 #define KEY_USAGE_ENC_CHALLENGE_KDC     55
86
87 void proto_register_kerberos(void);
88 void proto_reg_handoff_kerberos(void);
89
90 #define UDP_PORT_KERBEROS               88
91 #define TCP_PORT_KERBEROS               88
92
93 #define ADDRESS_STR_BUFSIZ 256
94
95 typedef struct kerberos_key {
96         guint32 keytype;
97         int keylength;
98         const guint8 *keyvalue;
99 } kerberos_key_t;
100
101 typedef struct {
102         guint32 msg_type;
103         gboolean kdc_response_initialized;
104         gboolean kdc_response;
105         guint32 errorcode;
106         gboolean try_nt_status;
107         guint32 etype;
108         guint32 padata_type;
109         guint32 is_enc_padata;
110         guint32 enctype;
111         kerberos_key_t key;
112         guint32 ad_type;
113         guint32 addr_type;
114         guint32 checksum_type;
115         const enc_key_t *last_decryption_key;
116         gboolean is_win2k_pkinit;
117         guint32 fast_type;
118         gboolean fast_armor_request;
119         gboolean fast_armor_within_enc_ticket_part;
120         const enc_key_t *fast_armor_ticket_sessionkey;
121         gboolean fast_armor_within_authenticator;
122         const enc_key_t *fast_armor_remote_subkey;
123         const enc_key_t *fast_armor_key;
124         gboolean fast_strengthen_key_needed;
125         const enc_key_t *fast_strengthen_key;
126 } kerberos_private_data_t;
127
128 static dissector_handle_t kerberos_handle_udp;
129
130 /* Forward declarations */
131 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_);
132 static int dissect_kerberos_AuthorizationData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
133 static int dissect_kerberos_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_);
134 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_);
135 static int dissect_kerberos_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_);
136 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_);
137 static int dissect_kerberos_PA_S4U_X509_USER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
138 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_);
139 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_);
140 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_);
141 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_);
142 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_);
143 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_);
144 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_);
145 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_);
146 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_);
147 static int dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
148 static int dissect_kerberos_PA_PAC_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
149 static int dissect_kerberos_KERB_AD_RESTRICTION_ENTRY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
150 static int dissect_kerberos_SEQUENCE_OF_ENCTYPE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
151 static int dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
152 static int dissect_kerberos_AD_TARGET_PRINCIPAL(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
153 static int dissect_kerberos_Checksum(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
154
155 /* Desegment Kerberos over TCP messages */
156 static gboolean krb_desegment = TRUE;
157
158 static gint proto_kerberos = -1;
159
160 static gint hf_krb_rm_reserved = -1;
161 static gint hf_krb_rm_reclen = -1;
162 static gint hf_krb_provsrv_location = -1;
163 static gint hf_krb_smb_nt_status = -1;
164 static gint hf_krb_smb_unknown = -1;
165 static gint hf_krb_address_ip = -1;
166 static gint hf_krb_address_netbios = -1;
167 static gint hf_krb_address_ipv6 = -1;
168 static gint hf_krb_gssapi_len = -1;
169 static gint hf_krb_gssapi_bnd = -1;
170 static gint hf_krb_gssapi_dlgopt = -1;
171 static gint hf_krb_gssapi_dlglen = -1;
172 static gint hf_krb_gssapi_c_flag_deleg = -1;
173 static gint hf_krb_gssapi_c_flag_mutual = -1;
174 static gint hf_krb_gssapi_c_flag_replay = -1;
175 static gint hf_krb_gssapi_c_flag_sequence = -1;
176 static gint hf_krb_gssapi_c_flag_conf = -1;
177 static gint hf_krb_gssapi_c_flag_integ = -1;
178 static gint hf_krb_gssapi_c_flag_dce_style = -1;
179 static gint hf_krb_midl_version = -1;
180 static gint hf_krb_midl_hdr_len = -1;
181 static gint hf_krb_midl_fill_bytes = -1;
182 static gint hf_krb_midl_blob_len = -1;
183 static gint hf_krb_pac_signature_type = -1;
184 static gint hf_krb_pac_signature_signature = -1;
185 static gint hf_krb_w2k_pac_entries = -1;
186 static gint hf_krb_w2k_pac_version = -1;
187 static gint hf_krb_w2k_pac_type = -1;
188 static gint hf_krb_w2k_pac_size = -1;
189 static gint hf_krb_w2k_pac_offset = -1;
190 static gint hf_krb_pac_clientid = -1;
191 static gint hf_krb_pac_namelen = -1;
192 static gint hf_krb_pac_clientname = -1;
193 static gint hf_krb_pac_logon_info = -1;
194 static gint hf_krb_pac_credential_data = -1;
195 static gint hf_krb_pac_credential_info = -1;
196 static gint hf_krb_pac_credential_info_version = -1;
197 static gint hf_krb_pac_credential_info_etype = -1;
198 static gint hf_krb_pac_s4u_delegation_info = -1;
199 static gint hf_krb_pac_upn_dns_info = -1;
200 static gint hf_krb_pac_upn_flags = -1;
201 static gint hf_krb_pac_upn_dns_offset = -1;
202 static gint hf_krb_pac_upn_dns_len = -1;
203 static gint hf_krb_pac_upn_upn_offset = -1;
204 static gint hf_krb_pac_upn_upn_len = -1;
205 static gint hf_krb_pac_upn_upn_name = -1;
206 static gint hf_krb_pac_upn_dns_name = -1;
207 static gint hf_krb_pac_server_checksum = -1;
208 static gint hf_krb_pac_privsvr_checksum = -1;
209 static gint hf_krb_pac_client_info_type = -1;
210 static gint hf_krb_pac_client_claims_info = -1;
211 static gint hf_krb_pac_device_info = -1;
212 static gint hf_krb_pac_device_claims_info = -1;
213 static gint hf_krb_pa_supported_enctypes = -1;
214 static gint hf_krb_pa_supported_enctypes_des_cbc_crc = -1;
215 static gint hf_krb_pa_supported_enctypes_des_cbc_md5 = -1;
216 static gint hf_krb_pa_supported_enctypes_rc4_hmac = -1;
217 static gint hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96 = -1;
218 static gint hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96 = -1;
219 static gint hf_krb_pa_supported_enctypes_fast_supported = -1;
220 static gint hf_krb_pa_supported_enctypes_compound_identity_supported = -1;
221 static gint hf_krb_pa_supported_enctypes_claims_supported = -1;
222 static gint hf_krb_pa_supported_enctypes_resource_sid_compression_disabled = -1;
223 static gint hf_krb_ad_ap_options = -1;
224 static gint hf_krb_ad_ap_options_cbt = -1;
225 static gint hf_krb_ad_target_principal = -1;
226 #include "packet-kerberos-hf.c"
227
228 /* Initialize the subtree pointers */
229 static gint ett_kerberos = -1;
230 static gint ett_krb_recordmark = -1;
231 static gint ett_krb_pac = -1;
232 static gint ett_krb_pac_drep = -1;
233 static gint ett_krb_pac_midl_blob = -1;
234 static gint ett_krb_pac_logon_info = -1;
235 static gint ett_krb_pac_credential_info = -1;
236 static gint ett_krb_pac_s4u_delegation_info = -1;
237 static gint ett_krb_pac_upn_dns_info = -1;
238 static gint ett_krb_pac_server_checksum = -1;
239 static gint ett_krb_pac_privsvr_checksum = -1;
240 static gint ett_krb_pac_client_info_type = -1;
241 static gint ett_krb_pa_supported_enctypes = -1;
242 static gint ett_krb_ad_ap_options = -1;
243 #include "packet-kerberos-ett.c"
244
245 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
246 static expert_field ei_kerberos_address = EI_INIT;
247 static expert_field ei_krb_gssapi_dlglen = EI_INIT;
248
249 static dissector_handle_t krb4_handle=NULL;
250
251 /* Global variables */
252 static guint32 gbl_keytype;
253 static gboolean gbl_do_col_info;
254
255 #include "packet-kerberos-val.h"
256
257 static void
258 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
259 {
260         if(!cb){
261                 return;
262         }
263
264         while(cb->tag){
265                 if(cb->tag==tag){
266                         cb->callback(pinfo, tvb, tree);
267                         return;
268                 }
269                 cb++;
270         }
271         return;
272 }
273
274 static kerberos_private_data_t*
275 kerberos_get_private_data_p(packet_info *pinfo)
276 {
277         void *p = p_get_proto_data(pinfo->pool, pinfo, proto_kerberos, 0);
278         if (p == NULL) {
279                 p = wmem_new0(pinfo->pool, kerberos_private_data_t);
280                 p_add_proto_data(pinfo->pool, pinfo, proto_kerberos, 0, p);
281         }
282         return (kerberos_private_data_t *)(p);
283 }
284
285 static kerberos_private_data_t*
286 kerberos_get_private_data(asn1_ctx_t *actx)
287 {
288         if (actx->private_data == NULL) {
289                 actx->private_data = kerberos_get_private_data_p(actx->pinfo);
290         }
291         return (kerberos_private_data_t *)(actx->private_data);
292 }
293
294 gboolean
295 kerberos_is_win2k_pkinit(asn1_ctx_t *actx)
296 {
297         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
298
299         return private_data->is_win2k_pkinit;
300 }
301
302 #ifdef HAVE_KERBEROS
303
304 /* Decrypt Kerberos blobs */
305 gboolean krb_decrypt = FALSE;
306
307 /* keytab filename */
308 static const char *keytab_filename = "";
309
310 void
311 read_keytab_file_from_preferences(void)
312 {
313         static char *last_keytab = NULL;
314
315         if (!krb_decrypt) {
316                 return;
317         }
318
319         if (keytab_filename == NULL) {
320                 return;
321         }
322
323         if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
324                 return;
325         }
326
327         g_free(last_keytab);
328         last_keytab = g_strdup(keytab_filename);
329
330         read_keytab_file(last_keytab);
331 }
332 #endif /* HAVE_KERBEROS */
333
334 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
335 #ifdef _WIN32
336 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
337 #undef HAVE_GETADDRINFO
338 #undef HAVE_SYS_TYPES_H
339 #endif /* _WIN32 */
340 #include <krb5.h>
341 enc_key_t *enc_key_list=NULL;
342
343 static void
344 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
345 {
346         enc_key_t *new_key;
347
348         if(pinfo->fd->visited){
349                 return;
350         }
351
352         new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
353         g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->num);
354         new_key->fd_num = pinfo->num;
355         new_key->next=enc_key_list;
356         enc_key_list=new_key;
357         new_key->keytype=keytype;
358         new_key->keylength=keylength;
359         /*XXX this needs to be freed later */
360         new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
361 }
362
363 static void used_encryption_key(proto_tree *tree, packet_info *pinfo,
364                                 enc_key_t *ek, int usage, tvbuff_t *cryptotvb)
365 {
366         kerberos_private_data_t *private_data = kerberos_get_private_data_p(pinfo);
367
368         proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype,
369                                      cryptotvb, 0, 0,
370                                      "Decrypted keytype %d usage %d in frame %u "
371                                      "using %s (%02x%02x%02x%02x...)",
372                                      ek->keytype, usage, pinfo->fd->num, ek->key_origin,
373                                      ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF,
374                                      ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF);
375
376         private_data->last_decryption_key = ek;
377 }
378
379 static void used_signing_key(proto_tree *tree, packet_info *pinfo,
380                              enc_key_t *ek, tvbuff_t *tvb,
381                              krb5_cksumtype checksum,
382                              const char *reason)
383 {
384         proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype,
385                                      tvb, 0, 0,
386                                      "%s checksum %d keytype %d in frame %u "
387                                      "using %s (%02x%02x%02x%02x...)",
388                                      reason, checksum, ek->keytype, pinfo->fd->num, ek->key_origin,
389                                      ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF,
390                                      ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF);
391 }
392
393 static void
394 krb5_fast_key(packet_info *pinfo,
395               const enc_key_t *ek1, const char *p1,
396               const enc_key_t *ek2, const char *p2,
397               const char *origin);
398
399 static void
400 krb5_fast_armor_key(packet_info *pinfo,
401                     const enc_key_t *remote_subkey,
402                     const enc_key_t *ticket_sessionkey)
403 {
404         kerberos_private_data_t *private_data = kerberos_get_private_data_p(pinfo);
405
406         krb5_fast_key(pinfo,
407                       remote_subkey,
408                       "subkeyarmor",
409                       ticket_sessionkey,
410                       "ticketarmor",
411                       "armorkey");
412
413         private_data->fast_armor_key = enc_key_list;
414 }
415
416 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
417
418 #if defined(HAVE_MIT_KERBEROS)
419
420 static krb5_context krb5_ctx;
421
422 static void
423 krb5_fast_key(packet_info *pinfo,
424               const enc_key_t *ek1, const char *p1,
425               const enc_key_t *ek2, const char *p2,
426               const char *origin)
427 {
428 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
429         krb5_error_code ret;
430         krb5_keyblock k1;
431         krb5_keyblock k2;
432         krb5_keyblock *k = NULL;
433
434         if (!krb_decrypt) {
435                 return;
436         }
437
438         if (ek1 == NULL) {
439                 return;
440         }
441
442         if (ek2 == NULL) {
443                 return;
444         }
445
446         k1.magic = KV5M_KEYBLOCK;
447         k1.enctype = ek1->keytype;
448         k1.length = ek1->keylength;
449         k1.contents = (guint8 *)ek1->keyvalue;
450
451         k2.magic = KV5M_KEYBLOCK;
452         k2.enctype = ek2->keytype;
453         k2.length = ek2->keylength;
454         k2.contents = (guint8 *)ek2->keyvalue;
455
456         ret = krb5_c_fx_cf2_simple(krb5_ctx, &k1, p1, &k2, p2, &k);
457         if (ret != 0) {
458                 return;
459         }
460
461         add_encryption_key(pinfo, k->enctype, k->length,
462                            (const char *)k->contents, origin);
463
464         krb5_free_keyblock(krb5_ctx, k);
465 #endif
466 }
467
468 USES_APPLE_DEPRECATED_API
469 void
470 read_keytab_file(const char *filename)
471 {
472         krb5_keytab keytab;
473         krb5_error_code ret;
474         krb5_keytab_entry key;
475         krb5_kt_cursor cursor;
476         static gboolean first_time=TRUE;
477
478         if (filename == NULL || filename[0] == 0) {
479                 return;
480         }
481
482         if(first_time){
483                 first_time=FALSE;
484                 ret = krb5_init_context(&krb5_ctx);
485                 if(ret && ret != KRB5_CONFIG_CANTOPEN){
486                         return;
487                 }
488         }
489
490         /* should use a file in the wireshark users dir */
491         ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
492         if(ret){
493                 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
494
495                 return;
496         }
497
498         ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
499         if(ret){
500                 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
501                 return;
502         }
503
504         do{
505                 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
506                 if(ret==0){
507                         enc_key_t *new_key;
508                         int i;
509                         char *pos;
510
511                         new_key = g_new(enc_key_t, 1);
512                         new_key->fd_num = -1;
513                         new_key->next = enc_key_list;
514
515                         /* generate origin string, describing where this key came from */
516                         pos=new_key->key_origin;
517                         pos+=MIN(KRB_MAX_ORIG_LEN,
518                                          g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
519                         for(i=0;i<key.principal->length;i++){
520                                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
521                                                  g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data));
522                         }
523                         pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
524                                          g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "@%s",key.principal->realm.data));
525                         *pos=0;
526                         new_key->keytype=key.key.enctype;
527                         new_key->keylength=key.key.length;
528                         new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
529                         enc_key_list=new_key;
530                         ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
531                         if (ret) {
532                                 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
533                                 ret = 0; /* try to continue with the next entry */
534                         }
535                 }
536         }while(ret==0);
537
538         ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
539         if(ret){
540                 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
541         }
542         ret = krb5_kt_close(krb5_ctx, keytab);
543         if(ret){
544                 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
545         }
546 }
547
548
549 guint8 *
550 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
551                                         int usage,
552                                         tvbuff_t *cryptotvb,
553                                         int keytype,
554                                         int *datalen)
555 {
556         kerberos_private_data_t *private_data = kerberos_get_private_data_p(pinfo);
557 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
558         const enc_key_t *ak = private_data->fast_armor_key;
559         const enc_key_t *sk = private_data->fast_strengthen_key;
560 #endif
561         krb5_error_code ret;
562         enc_key_t *ek;
563         krb5_data data = {0,0,NULL};
564         krb5_keytab_entry key;
565         int length = tvb_captured_length(cryptotvb);
566         const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
567
568         /* don't do anything if we are not attempting to decrypt data */
569         if(!krb_decrypt || length < 1){
570                 return NULL;
571         }
572
573         /* make sure we have all the data we need */
574         if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
575                 return NULL;
576         }
577
578         read_keytab_file_from_preferences();
579         data.data = (char *)wmem_alloc(pinfo->pool, length);
580         data.length = length;
581
582         for(ek=enc_key_list;ek;ek=ek->next){
583                 krb5_enc_data input;
584
585                 /* shortcircuit and bail out if enctypes are not matching */
586                 if((keytype != -1) && (ek->keytype != keytype)) {
587                         continue;
588                 }
589
590                 input.enctype = ek->keytype;
591                 input.ciphertext.length = length;
592                 input.ciphertext.data = (guint8 *)cryptotext;
593
594 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
595                 if (ak == ek) {
596                         continue;
597                 }
598
599                 if (ak != NULL && ak != ek && ak->keytype == ek->keytype) {
600                         krb5_keyblock k1;
601                         krb5_keyblock k2;
602                         krb5_keyblock *k = NULL;
603                         const char *p1 = NULL;
604
605                         k1.magic = KV5M_KEYBLOCK;
606                         k1.enctype = ak->keytype;
607                         k1.length = ak->keylength;
608                         k1.contents = (guint8 *)ak->keyvalue;
609
610                         k2.magic = KV5M_KEYBLOCK;
611                         k2.enctype = ek->keytype;
612                         k2.length = ek->keylength;
613                         k2.contents = (guint8 *)ek->keyvalue;
614
615                         if (private_data->kdc_response) {
616                                 p1 = "kdcchallengearmor";
617                         } else {
618                                 p1 = "clientchallengearmor";
619                         }
620
621                         ret = krb5_c_fx_cf2_simple(krb5_ctx,
622                                                    &k1, p1,
623                                                    &k2, "challengelongterm",
624                                                    &k);
625                         if (ret != 0) {
626                                 continue;
627                         }
628
629                         ret = krb5_c_decrypt(krb5_ctx, k, usage, 0, &input, &data);
630                         if(ret == 0) {
631                                 char *user_data;
632
633                                 add_encryption_key(pinfo, k->enctype, k->length,
634                                                    (const char *)k->contents,
635                                                    p1);
636                                 krb5_free_keyblock(krb5_ctx, k);
637                                 ek = enc_key_list;
638                                 used_encryption_key(tree, pinfo, ek, usage, cryptotvb);
639
640                                 /* return a private g_malloced blob to the caller */
641                                 user_data=data.data;
642                                 if (datalen) {
643                                         *datalen = data.length;
644                                 }
645                                 return user_data;
646                         }
647
648                         krb5_free_keyblock(krb5_ctx, k);
649                 }
650
651                 if (sk != NULL && sk != ek && sk->keytype == ek->keytype) {
652                         krb5_keyblock k1;
653                         krb5_keyblock k2;
654                         krb5_keyblock *k = NULL;
655
656                         k1.magic = KV5M_KEYBLOCK;
657                         k1.enctype = sk->keytype;
658                         k1.length = sk->keylength;
659                         k1.contents = (guint8 *)sk->keyvalue;
660
661                         k2.magic = KV5M_KEYBLOCK;
662                         k2.enctype = ek->keytype;
663                         k2.length = ek->keylength;
664                         k2.contents = (guint8 *)ek->keyvalue;
665
666                         ret = krb5_c_fx_cf2_simple(krb5_ctx,
667                                                    &k1, "strengthenkey",
668                                                    &k2, "replykey",
669                                                    &k);
670                         if (ret != 0) {
671                                 continue;
672                         }
673
674                         ret = krb5_c_decrypt(krb5_ctx, k, usage, 0, &input, &data);
675                         if(ret == 0) {
676                                 char *user_data;
677
678                                 add_encryption_key(pinfo, k->enctype, k->length,
679                                                    (const char *)k->contents,
680                                                    "strengthenkey");
681                                 krb5_free_keyblock(krb5_ctx, k);
682                                 ek = enc_key_list;
683                                 used_encryption_key(tree, pinfo, ek, usage, cryptotvb);
684
685                                 /* return a private g_malloced blob to the caller */
686                                 user_data=data.data;
687                                 if (datalen) {
688                                         *datalen = data.length;
689                                 }
690                                 return user_data;
691                         }
692
693                         krb5_free_keyblock(krb5_ctx, k);
694                 }
695 #endif
696
697                 key.key.enctype=ek->keytype;
698                 key.key.length=ek->keylength;
699                 key.key.contents=ek->keyvalue;
700                 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
701                 if(ret == 0){
702                         char *user_data;
703
704                         used_encryption_key(tree, pinfo, ek, usage, cryptotvb);
705
706                         user_data=data.data;
707                         if (datalen) {
708                                 *datalen = data.length;
709                         }
710                         return user_data;
711                 }
712         }
713
714         return NULL;
715 }
716 USES_APPLE_RST
717
718 extern krb5_error_code
719 krb5int_c_mandatory_cksumtype(krb5_context, krb5_enctype, krb5_cksumtype *);
720
721 static void
722 verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
723 {
724         krb5_error_code ret;
725         enc_key_t *ek = NULL;;
726         krb5_data checksum_data = {0,0,NULL};
727         krb5_cksumtype server_checksum = 0;
728         krb5_cksumtype kdc_checksum = 0;
729         int length = tvb_captured_length(pactvb);
730         const guint8 *pacbuffer = NULL;
731         krb5_pac pac;
732
733         /* don't do anything if we are not attempting to decrypt data */
734         if(!krb_decrypt || length < 1){
735                 return;
736         }
737
738         /* make sure we have all the data we need */
739         if (tvb_captured_length(pactvb) < tvb_reported_length(pactvb)) {
740                 return;
741         }
742
743         pacbuffer = tvb_get_ptr(pactvb, 0, length);
744
745         ret = krb5_pac_parse(krb5_ctx, pacbuffer, length, &pac);
746         if (ret != 0) {
747                 proto_tree_add_expert_format(tree, actx->pinfo, &ei_kerberos_decrypted_keytype,
748                                              pactvb, 0, 0,
749                                              "Failed to parse PAC buffer %d in frame %u",
750                                              ret, actx->pinfo->fd->num);
751                 return;
752         }
753
754         ret = krb5_pac_get_buffer(krb5_ctx, pac, KRB5_PAC_SERVER_CHECKSUM,
755                                   &checksum_data);
756         if (ret == 0) {
757                 server_checksum = pletoh32(checksum_data.data);
758                 krb5_free_data_contents(krb5_ctx, &checksum_data);
759         };
760         ret = krb5_pac_get_buffer(krb5_ctx, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
761                                   &checksum_data);
762         if (ret == 0) {
763                 kdc_checksum = pletoh32(checksum_data.data);
764                 krb5_free_data_contents(krb5_ctx, &checksum_data);
765         };
766
767         read_keytab_file_from_preferences();
768
769         for(ek=enc_key_list;ek;ek=ek->next){
770                 krb5_keyblock keyblock;
771                 krb5_cksumtype checksumtype = 0;
772
773                 if (server_checksum == 0 && kdc_checksum == 0) {
774                         break;
775                 }
776
777                 ret = krb5int_c_mandatory_cksumtype(krb5_ctx, ek->keytype,
778                                                     &checksumtype);
779                 if (ret != 0) {
780                         continue;
781                 }
782
783                 keyblock.magic = KV5M_KEYBLOCK;
784                 keyblock.enctype = ek->keytype;
785                 keyblock.length = ek->keylength;
786                 keyblock.contents = (guint8 *)ek->keyvalue;
787
788                 if (checksumtype == server_checksum) {
789                         ret = krb5_pac_verify(krb5_ctx, pac, 0, NULL,
790                                               &keyblock, NULL);
791                         if (ret == 0) {
792                                 used_signing_key(tree, actx->pinfo, ek, pactvb,
793                                                  server_checksum, "Verified Server");
794                                 server_checksum = 0;
795                         }
796                 }
797
798                 if (checksumtype == kdc_checksum) {
799                         ret = krb5_pac_verify(krb5_ctx, pac, 0, NULL,
800                                               NULL, &keyblock);
801                         if (ret == 0) {
802                                 used_signing_key(tree, actx->pinfo, ek, pactvb,
803                                                  kdc_checksum, "Verified KDC");
804                                 kdc_checksum = 0;
805                         }
806                 }
807
808         }
809
810         krb5_pac_free(krb5_ctx, pac);
811 }
812
813 #elif defined(HAVE_HEIMDAL_KERBEROS)
814 static krb5_context krb5_ctx;
815
816 USES_APPLE_DEPRECATED_API
817
818 static void
819 krb5_fast_key(packet_info *pinfo,
820               const enc_key_t *ek1, const char *p1,
821               const enc_key_t *ek2, const char *p2,
822               const char *origin)
823 {
824 #ifdef HAVE_KRB5_CRYPTO_FX_CF2
825 /* TODO */
826 #endif
827 }
828 void
829 read_keytab_file(const char *filename)
830 {
831         krb5_keytab keytab;
832         krb5_error_code ret;
833         krb5_keytab_entry key;
834         krb5_kt_cursor cursor;
835         enc_key_t *new_key;
836         static gboolean first_time=TRUE;
837
838         if (filename == NULL || filename[0] == 0) {
839                 return;
840         }
841
842         if(first_time){
843                 first_time=FALSE;
844                 ret = krb5_init_context(&krb5_ctx);
845                 if(ret){
846                         return;
847                 }
848         }
849
850         /* should use a file in the wireshark users dir */
851         ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
852         if(ret){
853                 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
854
855                 return;
856         }
857
858         ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
859         if(ret){
860                 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
861                 return;
862         }
863
864         do{
865                 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
866                 if(ret==0){
867                         unsigned int i;
868                         char *pos;
869
870                         new_key = g_new0(enc_key_t, 1);
871                         new_key->fd_num = -1;
872                         new_key->next = enc_key_list;
873
874                         /* generate origin string, describing where this key came from */
875                         pos=new_key->key_origin;
876                         pos+=MIN(KRB_MAX_ORIG_LEN,
877                                          g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
878                         for(i=0;i<key.principal->name.name_string.len;i++){
879                                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
880                                                  g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
881                         }
882                         pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
883                                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
884                         *pos=0;
885                         new_key->keytype=key.keyblock.keytype;
886                         new_key->keylength=(int)key.keyblock.keyvalue.length;
887                         new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
888                         enc_key_list=new_key;
889                         ret = krb5_kt_free_entry(krb5_ctx, &key);
890                         if (ret) {
891                                 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
892                                 ret = 0; /* try to continue with the next entry */
893                         }
894                 }
895         }while(ret==0);
896
897         ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
898         if(ret){
899                 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
900         }
901         ret = krb5_kt_close(krb5_ctx, keytab);
902         if(ret){
903                 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
904         }
905
906 }
907 USES_APPLE_RST
908
909
910 guint8 *
911 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
912                                         int usage,
913                                         tvbuff_t *cryptotvb,
914                                         int keytype,
915                                         int *datalen)
916 {
917         krb5_error_code ret;
918         krb5_data data;
919         enc_key_t *ek;
920         int length = tvb_captured_length(cryptotvb);
921         const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
922
923         /* don't do anything if we are not attempting to decrypt data */
924         if(!krb_decrypt){
925                 return NULL;
926         }
927
928         /* make sure we have all the data we need */
929         if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
930                 return NULL;
931         }
932
933         read_keytab_file_from_preferences();
934
935         for(ek=enc_key_list;ek;ek=ek->next){
936                 krb5_keytab_entry key;
937                 krb5_crypto crypto;
938                 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
939
940                 /* shortcircuit and bail out if enctypes are not matching */
941                 if((keytype != -1) && (ek->keytype != keytype)) {
942                         continue;
943                 }
944
945                 key.keyblock.keytype=ek->keytype;
946                 key.keyblock.keyvalue.length=ek->keylength;
947                 key.keyblock.keyvalue.data=ek->keyvalue;
948                 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto);
949                 if(ret){
950                         return NULL;
951                 }
952
953                 /* pre-0.6.1 versions of Heimdal would sometimes change
954                    the cryptotext data even when the decryption failed.
955                    This would obviously not work since we iterate over the
956                    keys. So just give it a copy of the crypto data instead.
957                    This has been seen for RC4-HMAC blobs.
958                 */
959                 cryptocopy = (guint8 *)wmem_memdup(wmem_packet_scope(), cryptotext, length);
960                 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
961                                                                 cryptocopy, length,
962                                                                 &data,
963                                                                 NULL);
964                 if((ret == 0) && (length>0)){
965                         char *user_data;
966
967                         proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype,
968                                                      NULL, 0, 0,
969                                                      "Decrypted keytype %d in frame %u using %s",
970                                                      ek->keytype, pinfo->num, ek->key_origin);
971
972                         krb5_crypto_destroy(krb5_ctx, crypto);
973                         /* return a private wmem_alloced blob to the caller */
974                         user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
975                         if (datalen) {
976                                 *datalen = (int)data.length;
977                         }
978                         return user_data;
979                 }
980                 krb5_crypto_destroy(krb5_ctx, crypto);
981         }
982         return NULL;
983 }
984
985 #elif defined (HAVE_LIBNETTLE)
986
987 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
988 #define KEYTYPE_DES3_CBC_MD5 5  /* Currently the only one supported */
989
990 typedef struct _service_key_t {
991         guint16 kvno;
992         int     keytype;
993         int     length;
994         guint8 *contents;
995         char    origin[KRB_MAX_ORIG_LEN+1];
996 } service_key_t;
997 GSList *service_key_list = NULL;
998
999
1000 static void
1001 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
1002 {
1003         service_key_t *new_key;
1004
1005         if(pinfo->fd->visited){
1006                 return;
1007         }
1008
1009         new_key = g_malloc(sizeof(service_key_t));
1010         new_key->kvno = 0;
1011         new_key->keytype = keytype;
1012         new_key->length = keylength;
1013         new_key->contents = g_memdup(keyvalue, keylength);
1014         g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
1015         service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
1016 }
1017
1018 static void
1019 clear_keytab(void) {
1020         GSList *ske;
1021         service_key_t *sk;
1022
1023         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
1024                 sk = (service_key_t *) ske->data;
1025                 if (sk) {
1026                         g_free(sk->contents);
1027                         g_free(sk);
1028                 }
1029         }
1030         g_slist_free(service_key_list);
1031         service_key_list = NULL;
1032 }
1033
1034 static void
1035 read_keytab_file(const char *service_key_file)
1036 {
1037         FILE *skf;
1038         ws_statb64 st;
1039         service_key_t *sk;
1040         unsigned char buf[SERVICE_KEY_SIZE];
1041         int newline_skip = 0, count = 0;
1042
1043         if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
1044
1045                 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
1046                  * There can be zero, one (\n), or two (\r\n) characters between
1047                  * keys.  Trailing characters are ignored.
1048                  */
1049
1050                 /* XXX We should support the standard keytab format instead */
1051                 if (st.st_size > SERVICE_KEY_SIZE) {
1052                         if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
1053                                  (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
1054                                 newline_skip = 1;
1055                         } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
1056                                  (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
1057                                 newline_skip = 2;
1058                         }
1059                 }
1060
1061                 skf = ws_fopen(service_key_file, "rb");
1062                 if (! skf) return;
1063
1064                 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
1065                         sk = g_malloc(sizeof(service_key_t));
1066                         sk->kvno = buf[0] << 8 | buf[1];
1067                         sk->keytype = KEYTYPE_DES3_CBC_MD5;
1068                         sk->length = DES3_KEY_SIZE;
1069                         sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
1070                         g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
1071                         service_key_list = g_slist_append(service_key_list, (gpointer) sk);
1072                         if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
1073                                 fprintf(stderr, "unable to seek...\n");
1074                                 return;
1075                         }
1076                         count++;
1077                 }
1078                 fclose(skf);
1079         }
1080 }
1081
1082 #define CONFOUNDER_PLUS_CHECKSUM 24
1083
1084 guint8 *
1085 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
1086                                         int _U_ usage,
1087                                         tvbuff_t *cryptotvb,
1088                                         int keytype,
1089                                         int *datalen)
1090 {
1091         tvbuff_t *encr_tvb;
1092         guint8 *decrypted_data = NULL, *plaintext = NULL;
1093         guint8 cls;
1094         gboolean pc;
1095         guint32 tag, item_len, data_len;
1096         int id_offset, offset;
1097         guint8 key[DES3_KEY_SIZE];
1098         guint8 initial_vector[DES_BLOCK_SIZE];
1099         gcry_md_hd_t md5_handle;
1100         guint8 *digest;
1101         guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1102         guint8 confounder[8];
1103         gboolean ind;
1104         GSList *ske;
1105         service_key_t *sk;
1106         struct des3_ctx ctx;
1107         int length = tvb_captured_length(cryptotvb);
1108         const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
1109
1110
1111         /* don't do anything if we are not attempting to decrypt data */
1112         if(!krb_decrypt){
1113                 return NULL;
1114         }
1115
1116         /* make sure we have all the data we need */
1117         if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
1118                 return NULL;
1119         }
1120
1121         if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
1122                 return NULL;
1123         }
1124
1125         decrypted_data = wmem_alloc(wmem_packet_scope(), length);
1126         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
1127                 gboolean do_continue = FALSE;
1128                 gboolean digest_ok;
1129                 sk = (service_key_t *) ske->data;
1130
1131                 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
1132
1133                 memset(initial_vector, 0, DES_BLOCK_SIZE);
1134                 des3_set_key(&ctx, key);
1135                 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
1136                                         length, decrypted_data, cryptotext);
1137                 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
1138
1139                 tvb_memcpy(encr_tvb, confounder, 0, 8);
1140
1141                 /* We have to pull the decrypted data length from the decrypted
1142                  * content.  If the key doesn't match or we otherwise get garbage,
1143                  * an exception may get thrown while decoding the ASN.1 header.
1144                  * Catch it, just in case.
1145                  */
1146                 TRY {
1147                         id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
1148                         offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
1149                 }
1150                 CATCH_BOUNDS_ERRORS {
1151                         tvb_free(encr_tvb);
1152                         do_continue = TRUE;
1153                 }
1154                 ENDTRY;
1155
1156                 if (do_continue) continue;
1157
1158                 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
1159                 if ((int) item_len + offset > length) {
1160                         tvb_free(encr_tvb);
1161                         continue;
1162                 }
1163
1164                 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
1165                         return NULL;
1166                 }
1167                 gcry_md_write(md5_handle, confounder, 8);
1168                 gcry_md_write(md5_handle, zero_fill, 16);
1169                 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
1170                 digest = gcry_md_read(md5_handle, 0);
1171
1172                 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
1173                 gcry_md_close(md5_handle);
1174                 if (digest_ok) {
1175                         plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
1176                         tvb_free(encr_tvb);
1177
1178                         if (datalen) {
1179                                 *datalen = data_len;
1180                         }
1181                         return(plaintext);
1182                 }
1183                 tvb_free(encr_tvb);
1184         }
1185
1186         return NULL;
1187 }
1188
1189 #endif  /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
1190
1191 #define INET6_ADDRLEN   16
1192
1193 /* TCP Record Mark */
1194 #define KRB_RM_RESERVED 0x80000000U
1195 #define KRB_RM_RECLEN   0x7fffffffU
1196
1197 #define KRB5_MSG_TICKET                 1       /* Ticket */
1198 #define KRB5_MSG_AUTHENTICATOR          2       /* Authenticator */
1199 #define KRB5_MSG_ENC_TICKET_PART        3       /* EncTicketPart */
1200 #define KRB5_MSG_AS_REQ                 10      /* AS-REQ type */
1201 #define KRB5_MSG_AS_REP                 11      /* AS-REP type */
1202 #define KRB5_MSG_TGS_REQ                12      /* TGS-REQ type */
1203 #define KRB5_MSG_TGS_REP                13      /* TGS-REP type */
1204 #define KRB5_MSG_AP_REQ                 14      /* AP-REQ type */
1205 #define KRB5_MSG_AP_REP                 15      /* AP-REP type */
1206
1207 #define KRB5_MSG_SAFE                   20      /* KRB-SAFE type */
1208 #define KRB5_MSG_PRIV                   21      /* KRB-PRIV type */
1209 #define KRB5_MSG_CRED                   22      /* KRB-CRED type */
1210 #define KRB5_MSG_ENC_AS_REP_PART        25      /* EncASRepPart */
1211 #define KRB5_MSG_ENC_TGS_REP_PART       26      /* EncTGSRepPart */
1212 #define KRB5_MSG_ENC_AP_REP_PART        27      /* EncAPRepPart */
1213 #define KRB5_MSG_ENC_KRB_PRIV_PART      28      /* EncKrbPrivPart */
1214 #define KRB5_MSG_ENC_KRB_CRED_PART      29      /* EncKrbCredPart */
1215 #define KRB5_MSG_ERROR                  30      /* KRB-ERROR type */
1216
1217 #define KRB5_CHKSUM_GSSAPI              0x8003
1218 /*
1219  * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
1220  *
1221  *      http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
1222  *
1223  * unless it's expired.
1224  */
1225
1226 /* Principal name-type */
1227 #define KRB5_NT_UNKNOWN         0
1228 #define KRB5_NT_PRINCIPAL       1
1229 #define KRB5_NT_SRV_INST        2
1230 #define KRB5_NT_SRV_HST         3
1231 #define KRB5_NT_SRV_XHST        4
1232 #define KRB5_NT_UID             5
1233 #define KRB5_NT_X500_PRINCIPAL  6
1234 #define KRB5_NT_SMTP_NAME       7
1235 #define KRB5_NT_ENTERPRISE      10
1236
1237 /*
1238  * MS specific name types, from
1239  *
1240  *      http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
1241  */
1242 #define KRB5_NT_MS_PRINCIPAL            -128
1243 #define KRB5_NT_MS_PRINCIPAL_AND_SID    -129
1244 #define KRB5_NT_ENT_PRINCIPAL_AND_SID   -130
1245 #define KRB5_NT_PRINCIPAL_AND_SID       -131
1246 #define KRB5_NT_SRV_INST_AND_SID        -132
1247
1248 /* error table constants */
1249 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
1250 #define KRB5_ET_KRB5KDC_ERR_NONE                        0
1251 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP                    1
1252 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP                 2
1253 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO                    3
1254 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO             4
1255 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO             5
1256 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN         6
1257 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN         7
1258 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE        8
1259 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY                    9
1260 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE             10
1261 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID                 11
1262 #define KRB5_ET_KRB5KDC_ERR_POLICY                      12
1263 #define KRB5_ET_KRB5KDC_ERR_BADOPTION                   13
1264 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP                14
1265 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP              15
1266 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP          16
1267 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP               17
1268 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED              18
1269 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED             19
1270 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED                 20
1271 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET               21
1272 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET              22
1273 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP                     23
1274 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED              24
1275 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED            25
1276 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH              26
1277 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER          27
1278 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED           28
1279 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE             29
1280 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY            31
1281 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED              32
1282 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV                  33
1283 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT                   34
1284 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US                   35
1285 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH                 36
1286 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW                     37
1287 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR                  38
1288 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION               39
1289 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE                 40
1290 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED                 41
1291 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER                 42
1292 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT               43
1293 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER                44
1294 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY                    45
1295 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL                 46
1296 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION             47
1297 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD                   48
1298 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ                   49
1299 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM              50
1300 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED            51
1301 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG            52
1302 #define KRB5_ET_KRB5KRB_ERR_GENERIC                     60
1303 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG               61
1304 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED            62
1305 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED               63
1306 #define KRB5_ET_KDC_ERROR_INVALID_SIG                   64
1307 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK                    65
1308 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH            66
1309 #define KRB5_ET_KRB_AP_ERR_NO_TGT                       67
1310 #define KRB5_ET_KDC_ERR_WRONG_REALM                     68
1311 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED        69
1312 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE         70
1313 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE             71
1314 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE             72
1315 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN       73
1316 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE   74
1317 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH            75
1318 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH               76
1319 #define KRB5_ET_KDC_ERR_PREAUTH_EXPIRED                 90
1320 #define KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED      91
1321 #define KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET  92
1322 #define KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS   93
1323
1324 static const value_string krb5_error_codes[] = {
1325         { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
1326         { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
1327         { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
1328         { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
1329         { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
1330         { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
1331         { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
1332         { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
1333         { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
1334         { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
1335         { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
1336         { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
1337         { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
1338         { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
1339         { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
1340         { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
1341         { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
1342         { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
1343         { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
1344         { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
1345         { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
1346         { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
1347         { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
1348         { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
1349         { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
1350         { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
1351         { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1352         { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1353         { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1354         { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1355         { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1356         { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1357         { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1358         { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1359         { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1360         { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1361         { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1362         { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1363         { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1364         { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1365         { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1366         { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1367         { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1368         { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1369         { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1370         { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1371         { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1372         { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1373         { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1374         { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1375         { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1376         { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1377         { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1378         { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1379         { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1380         { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1381         { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1382         { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1383         { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1384         { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1385         { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1386         { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1387         { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1388         { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1389         { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1390         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1391         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1392         { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1393         { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1394         { KRB5_ET_KDC_ERR_PREAUTH_EXPIRED, "KDC_ERR_PREAUTH_EXPIRED" },
1395         { KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, "KDC_ERR_MORE_PREAUTH_DATA_REQUIRED" },
1396         { KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET, "KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET" },
1397         { KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, "KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS" },
1398         { 0, NULL }
1399 };
1400
1401
1402 #define PAC_LOGON_INFO          1
1403 #define PAC_CREDENTIAL_TYPE     2
1404 #define PAC_SERVER_CHECKSUM     6
1405 #define PAC_PRIVSVR_CHECKSUM    7
1406 #define PAC_CLIENT_INFO_TYPE    10
1407 #define PAC_S4U_DELEGATION_INFO 11
1408 #define PAC_UPN_DNS_INFO        12
1409 #define PAC_CLIENT_CLAIMS_INFO  13
1410 #define PAC_DEVICE_INFO         14
1411 #define PAC_DEVICE_CLAIMS_INFO  15
1412 static const value_string w2k_pac_types[] = {
1413         { PAC_LOGON_INFO                , "Logon Info" },
1414         { PAC_CREDENTIAL_TYPE           , "Credential Type" },
1415         { PAC_SERVER_CHECKSUM           , "Server Checksum" },
1416         { PAC_PRIVSVR_CHECKSUM          , "Privsvr Checksum" },
1417         { PAC_CLIENT_INFO_TYPE          , "Client Info Type" },
1418         { PAC_S4U_DELEGATION_INFO       , "S4U Delegation Info" },
1419         { PAC_UPN_DNS_INFO              , "UPN DNS Info" },
1420         { PAC_CLIENT_CLAIMS_INFO        , "Client Claims Info" },
1421         { PAC_DEVICE_INFO               , "Device Info" },
1422         { PAC_DEVICE_CLAIMS_INFO        , "Device Claims Info" },
1423         { 0, NULL },
1424 };
1425
1426 static const value_string krb5_msg_types[] = {
1427         { KRB5_MSG_TICKET,              "Ticket" },
1428         { KRB5_MSG_AUTHENTICATOR,       "Authenticator" },
1429         { KRB5_MSG_ENC_TICKET_PART,     "EncTicketPart" },
1430         { KRB5_MSG_TGS_REQ,             "TGS-REQ" },
1431         { KRB5_MSG_TGS_REP,             "TGS-REP" },
1432         { KRB5_MSG_AS_REQ,              "AS-REQ" },
1433         { KRB5_MSG_AS_REP,              "AS-REP" },
1434         { KRB5_MSG_AP_REQ,              "AP-REQ" },
1435         { KRB5_MSG_AP_REP,              "AP-REP" },
1436         { KRB5_MSG_SAFE,                "KRB-SAFE" },
1437         { KRB5_MSG_PRIV,                "KRB-PRIV" },
1438         { KRB5_MSG_CRED,                "KRB-CRED" },
1439         { KRB5_MSG_ENC_AS_REP_PART,     "EncASRepPart" },
1440         { KRB5_MSG_ENC_TGS_REP_PART,    "EncTGSRepPart" },
1441         { KRB5_MSG_ENC_AP_REP_PART,     "EncAPRepPart" },
1442         { KRB5_MSG_ENC_KRB_PRIV_PART,   "EncKrbPrivPart" },
1443         { KRB5_MSG_ENC_KRB_CRED_PART,   "EncKrbCredPart" },
1444         { KRB5_MSG_ERROR,               "KRB-ERROR" },
1445         { 0, NULL },
1446 };
1447
1448 #define KRB5_GSS_C_DELEG_FLAG             0x01
1449 #define KRB5_GSS_C_MUTUAL_FLAG            0x02
1450 #define KRB5_GSS_C_REPLAY_FLAG            0x04
1451 #define KRB5_GSS_C_SEQUENCE_FLAG          0x08
1452 #define KRB5_GSS_C_CONF_FLAG              0x10
1453 #define KRB5_GSS_C_INTEG_FLAG             0x20
1454 #define KRB5_GSS_C_DCE_STYLE            0x1000
1455
1456 static const true_false_string tfs_gss_flags_deleg = {
1457         "Delegate credentials to remote peer",
1458         "Do NOT delegate"
1459 };
1460 static const true_false_string tfs_gss_flags_mutual = {
1461         "Request that remote peer authenticates itself",
1462         "Mutual authentication NOT required"
1463 };
1464 static const true_false_string tfs_gss_flags_replay = {
1465         "Enable replay protection for signed or sealed messages",
1466         "Do NOT enable replay protection"
1467 };
1468 static const true_false_string tfs_gss_flags_sequence = {
1469         "Enable Out-of-sequence detection for sign or sealed messages",
1470         "Do NOT enable out-of-sequence detection"
1471 };
1472 static const true_false_string tfs_gss_flags_conf = {
1473         "Confidentiality (sealing) may be invoked",
1474         "Do NOT use Confidentiality (sealing)"
1475 };
1476 static const true_false_string tfs_gss_flags_integ = {
1477         "Integrity protection (signing) may be invoked",
1478         "Do NOT use integrity protection"
1479 };
1480
1481 static const true_false_string tfs_gss_flags_dce_style = {
1482         "DCE-STYLE",
1483         "Not using DCE-STYLE"
1484 };
1485
1486 #ifdef HAVE_KERBEROS
1487 static int
1488 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1489                                                                         proto_tree *tree, int hf_index _U_)
1490 {
1491         guint8 *plaintext;
1492         int length;
1493         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1494         tvbuff_t *next_tvb;
1495
1496         next_tvb=tvb_new_subset_remaining(tvb, offset);
1497         length=tvb_captured_length_remaining(tvb, offset);
1498
1499         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1500          * 7.5.1
1501          * All Ticket encrypted parts use usage == 2
1502          */
1503         plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, private_data->etype, NULL);
1504
1505         if(plaintext){
1506                 tvbuff_t *child_tvb;
1507                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1508
1509                 /* Add the decrypted data to the data source list. */
1510                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1511
1512                 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1513         }
1514         return offset;
1515 }
1516
1517 static int
1518 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1519                                                                                         proto_tree *tree, int hf_index _U_)
1520 {
1521         guint8 *plaintext;
1522         int length;
1523         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1524         tvbuff_t *next_tvb;
1525
1526         next_tvb=tvb_new_subset_remaining(tvb, offset);
1527         length=tvb_captured_length_remaining(tvb, offset);
1528
1529         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1530          * 7.5.1
1531          * Authenticators are encrypted with usage
1532          * == 7 or
1533          * == 11
1534          */
1535         plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, private_data->etype, NULL);
1536
1537         if(!plaintext){
1538                 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, private_data->etype, NULL);
1539         }
1540
1541         if(plaintext){
1542                 tvbuff_t *child_tvb;
1543                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1544
1545                 /* Add the decrypted data to the data source list. */
1546                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1547
1548                 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1549         }
1550         return offset;
1551 }
1552
1553 static int
1554 dissect_krb5_decrypt_authorization_data(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1555                                         proto_tree *tree, int hf_index _U_)
1556 {
1557         guint8 *plaintext;
1558         int length;
1559         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1560         tvbuff_t *next_tvb;
1561
1562         next_tvb=tvb_new_subset_remaining(tvb, offset);
1563         length=tvb_captured_length_remaining(tvb, offset);
1564
1565         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1566          * 7.5.1
1567          * Authenticators are encrypted with usage
1568          * == 5 or
1569          * == 4
1570          */
1571         plaintext=decrypt_krb5_data(tree, actx->pinfo, 5, next_tvb, private_data->etype, NULL);
1572
1573         if(!plaintext){
1574                 plaintext=decrypt_krb5_data(tree, actx->pinfo, 4, next_tvb, private_data->etype, NULL);
1575         }
1576
1577         if(plaintext){
1578                 tvbuff_t *child_tvb;
1579                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1580
1581                 /* Add the decrypted data to the data source list. */
1582                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1583
1584                 offset=dissect_kerberos_AuthorizationData(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1585         }
1586         return offset;
1587 }
1588
1589 static int
1590 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1591                                                                         proto_tree *tree, int hf_index _U_)
1592 {
1593         guint8 *plaintext;
1594         int length;
1595         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1596         tvbuff_t *next_tvb;
1597
1598         next_tvb=tvb_new_subset_remaining(tvb, offset);
1599         length=tvb_captured_length_remaining(tvb, offset);
1600
1601         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1602          * 7.5.1
1603          * ASREP/TGSREP encryptedparts are encrypted with usage
1604          * == 3 or
1605          * == 8 or
1606          * == 9
1607          */
1608         plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, private_data->etype, NULL);
1609
1610         if(!plaintext){
1611                 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, private_data->etype, NULL);
1612         }
1613
1614         if(!plaintext){
1615                 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, private_data->etype, NULL);
1616         }
1617
1618         if(plaintext){
1619                 tvbuff_t *child_tvb;
1620                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1621
1622                 /* Add the decrypted data to the data source list. */
1623                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1624
1625                 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1626         }
1627         return offset;
1628 }
1629
1630 static int
1631 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1632                                                                                 proto_tree *tree, int hf_index _U_)
1633 {
1634         guint8 *plaintext;
1635         int length;
1636         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1637         tvbuff_t *next_tvb;
1638
1639         next_tvb=tvb_new_subset_remaining(tvb, offset);
1640         length=tvb_captured_length_remaining(tvb, offset);
1641
1642         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1643          * 7.5.1
1644          * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1645          * == 1
1646          */
1647         plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, private_data->etype, NULL);
1648
1649         if(plaintext){
1650                 tvbuff_t *child_tvb;
1651                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1652
1653                 /* Add the decrypted data to the data source list. */
1654                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1655
1656                 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1657         }
1658         return offset;
1659 }
1660
1661 static int
1662 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1663                                                                         proto_tree *tree, int hf_index _U_)
1664 {
1665         guint8 *plaintext;
1666         int length;
1667         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1668         tvbuff_t *next_tvb;
1669
1670         next_tvb=tvb_new_subset_remaining(tvb, offset);
1671         length=tvb_captured_length_remaining(tvb, offset);
1672
1673         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1674          * 7.5.1
1675          * AP-REP are encrypted with usage == 12
1676          */
1677         plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, private_data->etype, NULL);
1678
1679         if(plaintext){
1680                 tvbuff_t *child_tvb;
1681                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1682
1683                 /* Add the decrypted data to the data source list. */
1684                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1685
1686                 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1687         }
1688         return offset;
1689 }
1690
1691 static int
1692 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1693                                                                         proto_tree *tree, int hf_index _U_)
1694 {
1695         guint8 *plaintext;
1696         int length;
1697         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1698         tvbuff_t *next_tvb;
1699
1700         next_tvb=tvb_new_subset_remaining(tvb, offset);
1701         length=tvb_captured_length_remaining(tvb, offset);
1702
1703         /* RFC4120 :
1704          * EncKrbPrivPart encrypted with usage
1705          * == 13
1706          */
1707         plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, private_data->etype, NULL);
1708
1709         if(plaintext){
1710                 tvbuff_t *child_tvb;
1711                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1712
1713                 /* Add the decrypted data to the data source list. */
1714                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1715
1716                 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1717         }
1718         return offset;
1719 }
1720
1721 static int
1722 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1723                                                                         proto_tree *tree, int hf_index _U_)
1724 {
1725         guint8 *plaintext;
1726         int length;
1727         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1728         tvbuff_t *next_tvb;
1729
1730         next_tvb=tvb_new_subset_remaining(tvb, offset);
1731         length=tvb_captured_length_remaining(tvb, offset);
1732
1733         /* RFC4120 :
1734          * EncKrbCredPart encrypted with usage
1735          * == 14
1736          */
1737         plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, private_data->etype, NULL);
1738
1739         if(plaintext){
1740                 tvbuff_t *child_tvb;
1741                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1742
1743                 /* Add the decrypted data to the data source list. */
1744                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1745
1746                 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1747         }
1748         return offset;
1749 }
1750
1751 static int
1752 dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1753                                 proto_tree *tree, int hf_index _U_)
1754 {
1755         guint8 *plaintext;
1756         int length;
1757         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1758         tvbuff_t *next_tvb;
1759
1760         next_tvb=tvb_new_subset_remaining(tvb, offset);
1761         length=tvb_captured_length_remaining(tvb, offset);
1762
1763         /* RFC6113 :
1764          * KrbFastResponse encrypted with usage
1765          * KEY_USAGE_FAST_ENC 51
1766          */
1767         plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_ENC,
1768                                     next_tvb, private_data->etype, NULL);
1769
1770         if(plaintext){
1771                 tvbuff_t *child_tvb;
1772                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1773
1774                 /* Add the decrypted data to the data source list. */
1775                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1776
1777                 offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1778         }
1779         return offset;
1780 }
1781
1782 static int
1783 dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1784                                      proto_tree *tree, int hf_index _U_)
1785 {
1786         guint8 *plaintext;
1787         int length;
1788         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1789         tvbuff_t *next_tvb;
1790
1791         next_tvb=tvb_new_subset_remaining(tvb, offset);
1792         length=tvb_captured_length_remaining(tvb, offset);
1793
1794         /*
1795          * RFC6113 :
1796          * KrbFastResponse encrypted with usage
1797          * KEY_USAGE_FAST_REP 52
1798          */
1799         plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_REP,
1800                                     next_tvb, private_data->etype, NULL);
1801
1802         if(plaintext){
1803                 tvbuff_t *child_tvb;
1804                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1805
1806                 /* Add the decrypted data to the data source list. */
1807                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1808
1809                 private_data->fast_armor_key = private_data->last_decryption_key;
1810                 offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1811         }
1812         return offset;
1813 }
1814
1815 static int
1816 dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1817                                         proto_tree *tree, int hf_index _U_)
1818 {
1819         guint8 *plaintext;
1820         int length;
1821         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1822         tvbuff_t *next_tvb;
1823         int usage = 0;
1824
1825         next_tvb=tvb_new_subset_remaining(tvb, offset);
1826         length=tvb_captured_length_remaining(tvb, offset);
1827
1828         /* RFC6113 :
1829          * KEY_USAGE_ENC_CHALLENGE_CLIENT  54
1830          * KEY_USAGE_ENC_CHALLENGE_KDC     55
1831          */
1832         if (private_data->kdc_response) {
1833                 usage = KEY_USAGE_ENC_CHALLENGE_KDC;
1834         } else {
1835                 usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
1836         }
1837         plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, private_data->etype, NULL);
1838
1839         if(plaintext){
1840                 tvbuff_t *child_tvb;
1841                 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1842
1843                 /* Add the decrypted data to the data source list. */
1844                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1845
1846                 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1847         }
1848         return offset;
1849 }
1850 #endif
1851
1852 static const int *hf_krb_pa_supported_enctypes_fields[] = {
1853         &hf_krb_pa_supported_enctypes_des_cbc_crc,
1854         &hf_krb_pa_supported_enctypes_des_cbc_md5,
1855         &hf_krb_pa_supported_enctypes_rc4_hmac,
1856         &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
1857         &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
1858         &hf_krb_pa_supported_enctypes_fast_supported,
1859         &hf_krb_pa_supported_enctypes_compound_identity_supported,
1860         &hf_krb_pa_supported_enctypes_claims_supported,
1861         &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
1862         NULL,
1863 };
1864
1865 static const true_false_string supported_tfs = {
1866         "Supported", "Not supported"
1867 };
1868
1869 static int
1870 dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1871                                        int offset _U_, asn1_ctx_t *actx _U_,
1872                                        proto_tree *tree _U_, int hf_index _U_)
1873 {
1874         actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1875                                                     hf_krb_pa_supported_enctypes,
1876                                                     ett_krb_pa_supported_enctypes,
1877                                                     hf_krb_pa_supported_enctypes_fields,
1878                                                     ENC_LITTLE_ENDIAN);
1879         offset += 4;
1880
1881         return offset;
1882 }
1883
1884 static const int *hf_krb_ad_ap_options_fields[] = {
1885         &hf_krb_ad_ap_options_cbt,
1886         NULL,
1887 };
1888
1889 static const true_false_string set_tfs = {
1890         "Set", "Not set"
1891 };
1892
1893 static int
1894 dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1895                                int offset _U_, asn1_ctx_t *actx _U_,
1896                                proto_tree *tree _U_, int hf_index _U_)
1897 {
1898         actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1899                                                     hf_krb_ad_ap_options,
1900                                                     ett_krb_ad_ap_options,
1901                                                     hf_krb_ad_ap_options_fields,
1902                                                     ENC_LITTLE_ENDIAN);
1903         offset += 4;
1904
1905         return offset;
1906 }
1907
1908 static int
1909 dissect_kerberos_AD_TARGET_PRINCIPAL(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1910                                      int offset _U_, asn1_ctx_t *actx _U_,
1911                                      proto_tree *tree _U_, int hf_index _U_)
1912 {
1913         int tp_offset, tp_len;
1914         const char *tp;
1915         guint16 bc;
1916
1917         bc = tvb_reported_length_remaining(tvb, offset);
1918         tp_offset = offset;
1919         tp_len = bc;
1920         tp = get_unicode_or_ascii_string(tvb, &offset, TRUE, &tp_len, TRUE, TRUE, &bc);
1921         proto_tree_add_string(tree, hf_krb_ad_target_principal, tvb, tp_offset, tp_len, tp);
1922
1923         return offset;
1924 }
1925
1926 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1927  */
1928 static int
1929 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1930 {
1931         int offset=0;
1932         guint32 len;
1933         guint16 dlglen;
1934
1935         /* Length of Bnd field */
1936         len=tvb_get_letohl(tvb, offset);
1937         proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1938         offset += 4;
1939
1940         /* Bnd field */
1941         proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1942         offset += len;
1943
1944
1945         /* flags */
1946         proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1947         proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1948         proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1949         proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1950         proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1951         proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1952         proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1953         offset += 4;
1954
1955         /* the next fields are optional so we have to check that we have
1956          * more data in our buffers */
1957         if(tvb_reported_length_remaining(tvb, offset)<2){
1958                 return offset;
1959         }
1960         /* dlgopt identifier */
1961         proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1962         offset += 2;
1963
1964         if(tvb_reported_length_remaining(tvb, offset)<2){
1965                 return offset;
1966         }
1967         /* dlglen identifier */
1968         dlglen=tvb_get_letohs(tvb, offset);
1969         proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1970         offset += 2;
1971
1972         if(dlglen!=tvb_reported_length_remaining(tvb, offset)){
1973                 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0,
1974                                 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset));
1975                 return offset;
1976         }
1977
1978         /* this should now be a KRB_CRED message */
1979         offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1980
1981         return offset;
1982 }
1983
1984 static int
1985 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_)
1986 {
1987         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1988
1989         return offset;
1990 }
1991
1992 static int
1993 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_)
1994 {
1995         kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1996         gint remaining = tvb_reported_length_remaining(tvb, offset);
1997         guint32 nt_status = 0;
1998         guint32 val_0 = 0;
1999         guint32 val_1 = 0;
2000
2001         if (private_data->errorcode == 0) {
2002                 goto no_error;
2003         }
2004
2005         if (!private_data->try_nt_status) {
2006                 goto no_error;
2007         }
2008
2009         if (remaining != 12) {
2010                 goto no_error;
2011         }
2012
2013         nt_status=tvb_get_letohl(tvb, offset);
2014         val_0=tvb_get_letohl(tvb, offset + 4);
2015         val_1=tvb_get_letohl(tvb, offset + 8);
2016
2017         if (val_0 != 0 || val_1 != 1) {
2018                 goto no_error;
2019         }
2020
2021         /* Microsoft stores a special 12 byte blob here
2022          * guint32 NT_status
2023          * guint32 unknown (== 0)
2024          * guint32 unknown (== 1)
2025          */
2026         proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
2027                         ENC_LITTLE_ENDIAN);
2028         nt_status=tvb_get_letohl(tvb, offset);
2029         if(nt_status) {
2030                 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
2031                         " NT Status: %s",
2032                         val_to_str(nt_status, NT_errors,
2033                         "Unknown error code %#x"));
2034         }
2035         offset += 4;
2036
2037         proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
2038                         ENC_LITTLE_ENDIAN);
2039         offset += 4;
2040
2041         proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
2042                         ENC_LITTLE_ENDIAN);
2043         offset += 4;
2044
2045         return offset;
2046
2047  no_error:
2048         return offset + remaining;
2049 }
2050
2051 static int
2052 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
2053 {
2054         proto_tree *tree;
2055         guint8 val;
2056
2057         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
2058
2059         val = tvb_get_guint8(tvb, offset);
2060         proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
2061
2062         offset++;
2063
2064         if (drep) {
2065                 *drep = val;
2066         }
2067
2068         return offset;
2069 }
2070
2071 /* This might be some sort of header that MIDL generates when creating
2072  * marshalling/unmarshalling code for blobs that are not to be transported
2073  * ontop of DCERPC and where the DREP fields specifying things such as
2074  * endianess and similar are not available.
2075  */
2076 static int
2077 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
2078 {
2079         proto_tree *tree;
2080
2081         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header");
2082
2083         /* modified DREP field that is used for stuff that is transporetd ontop
2084            of non dcerpc
2085         */
2086         proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2087         offset++;
2088
2089         offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
2090
2091
2092         proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2093         offset+=2;
2094
2095         proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2096         offset += 4;
2097
2098         /* length of blob that follows */
2099         proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2100         offset += 8;
2101
2102         return offset;
2103 }
2104
2105 static int
2106 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2107 {
2108         proto_item *item;
2109         proto_tree *tree;
2110         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2111         static dcerpc_info di;      /* fake dcerpc_info struct */
2112         static dcerpc_call_value call_data;
2113
2114         item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
2115         tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
2116
2117         /* skip the first 16 bytes, they are some magic created by the idl
2118          * compiler   the first 4 bytes might be flags?
2119          */
2120         offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2121
2122         /* the PAC_LOGON_INFO blob */
2123         /* fake whatever state the dcerpc runtime support needs */
2124         di.conformant_run=0;
2125         /* we need di->call_data->flags.NDR64 == 0 */
2126         di.call_data=&call_data;
2127         init_ndr_pointer_list(&di);
2128         offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
2129                                                                         netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
2130                                                                         "PAC_LOGON_INFO:", -1);
2131
2132         return offset;
2133 }
2134
2135
2136 static int
2137 dissect_krb5_PAC_CREDENTIAL_DATA(proto_tree *parent_tree, tvbuff_t *tvb, int offset, packet_info *pinfo _U_)
2138 {
2139         proto_tree_add_item(parent_tree, hf_krb_pac_credential_data, tvb, offset, -1, ENC_NA);
2140
2141         return offset;
2142 }
2143
2144 static int
2145 dissect_krb5_PAC_CREDENTIAL_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2146 {
2147         proto_item *item;
2148         proto_tree *tree;
2149         guint32 etype;
2150         guint8 *plaintext = NULL;
2151         int plainlen = 0;
2152         int length;
2153         tvbuff_t *next_tvb;
2154 #define KRB5_KU_OTHER_ENCRYPTED 16
2155         int usage = KRB5_KU_OTHER_ENCRYPTED;
2156
2157         item = proto_tree_add_item(parent_tree, hf_krb_pac_credential_info, tvb, offset, -1, ENC_NA);
2158         tree = proto_item_add_subtree(item, ett_krb_pac_credential_info);
2159
2160         /* version */
2161         proto_tree_add_item(tree, hf_krb_pac_credential_info_version, tvb,
2162                             offset, 4, ENC_LITTLE_ENDIAN);
2163         offset+=4;
2164
2165         /* etype */
2166         etype = tvb_get_letohl(tvb, offset);
2167         proto_tree_add_item(tree, hf_krb_pac_credential_info_etype, tvb,
2168                             offset, 4, ENC_LITTLE_ENDIAN);
2169         offset+=4;
2170
2171         /* data */
2172         next_tvb=tvb_new_subset_remaining(tvb, offset);
2173         length=tvb_captured_length_remaining(tvb, offset);
2174
2175         plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, (int)etype, &plainlen);
2176
2177         if (plaintext != NULL) {
2178                 tvbuff_t *child_tvb;
2179                 child_tvb = tvb_new_child_real_data(tvb, plaintext, plainlen, plainlen);
2180
2181                 /* Add the decrypted data to the data source list. */
2182                 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
2183
2184                 dissect_krb5_PAC_CREDENTIAL_DATA(tree, child_tvb, 0, actx->pinfo);
2185         }
2186
2187         return offset + length;
2188 }
2189
2190 static int
2191 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2192 {
2193         proto_item *item;
2194         proto_tree *tree;
2195         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2196         static dcerpc_info di;      /* fake dcerpc_info struct */
2197         static dcerpc_call_value call_data;
2198
2199         item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
2200         tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
2201
2202         /* skip the first 16 bytes, they are some magic created by the idl
2203          * compiler   the first 4 bytes might be flags?
2204          */
2205         offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2206
2207
2208         /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
2209         /* fake whatever state the dcerpc runtime support needs */
2210         di.conformant_run=0;
2211         /* we need di->call_data->flags.NDR64 == 0 */
2212         di.call_data=&call_data;
2213         init_ndr_pointer_list(&di);
2214         offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
2215                                                                         netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
2216                                                                         "PAC_S4U_DELEGATION_INFO:", -1);
2217
2218         return offset;
2219 }
2220
2221 static int
2222 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2223 {
2224         proto_item *item;
2225         proto_tree *tree;
2226         guint16 dns_offset, dns_len;
2227         guint16 upn_offset, upn_len;
2228         const char *dn;
2229         int dn_len;
2230         guint16 bc;
2231
2232         item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
2233         tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
2234
2235         /* upn */
2236         upn_len = tvb_get_letohs(tvb, offset);
2237         proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2238         offset+=2;
2239         upn_offset = tvb_get_letohs(tvb, offset);
2240         proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2241         offset+=2;
2242
2243         /* dns */
2244         dns_len = tvb_get_letohs(tvb, offset);
2245         proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2246         offset+=2;
2247         dns_offset = tvb_get_letohs(tvb, offset);
2248         proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2249         offset+=2;
2250
2251         /* flags */
2252         proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2253
2254         /* upn */
2255         offset = upn_offset;
2256         dn_len = upn_len;
2257         bc = tvb_reported_length_remaining(tvb, offset);
2258         dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
2259         proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
2260
2261         /* dns */
2262         offset = dns_offset;
2263         dn_len = dns_len;
2264         bc = tvb_reported_length_remaining(tvb, offset);
2265         dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
2266         proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
2267
2268         return offset;
2269 }
2270
2271 static int
2272 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2273 {
2274         proto_tree_add_item(parent_tree, hf_krb_pac_client_claims_info, tvb, offset, -1, ENC_NA);
2275
2276         return offset;
2277 }
2278
2279 static int
2280 dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2281 {
2282         proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA);
2283
2284         return offset;
2285 }
2286
2287 static int
2288 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2289 {
2290         proto_tree_add_item(parent_tree, hf_krb_pac_device_claims_info, tvb, offset, -1, ENC_NA);
2291
2292         return offset;
2293 }
2294
2295 static int
2296 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2297 {
2298         proto_item *item;
2299         proto_tree *tree;
2300
2301         item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA);
2302         tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum);
2303
2304         /* signature type */
2305         proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2306         offset+=4;
2307
2308         /* signature data */
2309         proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
2310
2311         return offset;
2312 }
2313
2314 static int
2315 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2316 {
2317         proto_item *item;
2318         proto_tree *tree;
2319
2320         item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA);
2321         tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum);
2322
2323         /* signature type */
2324         proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2325         offset+=4;
2326
2327         /* signature data */
2328         proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
2329
2330         return offset;
2331 }
2332
2333 static int
2334 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2335 {
2336         proto_item *item;
2337         proto_tree *tree;
2338         guint16 namelen;
2339
2340         item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
2341         tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
2342
2343         /* clientid */
2344         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
2345
2346         /* name length */
2347         namelen=tvb_get_letohs(tvb, offset);
2348         proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
2349         offset+=2;
2350
2351         /* client name */
2352         proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
2353         offset+=namelen;
2354
2355         return offset;
2356 }
2357
2358 static int
2359 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2360 {
2361         guint32 pac_type;
2362         guint32 pac_size;
2363         guint32 pac_offset;
2364         proto_item *it=NULL;
2365         proto_tree *tr=NULL;
2366         tvbuff_t *next_tvb;
2367
2368         /* type of pac data */
2369         pac_type=tvb_get_letohl(tvb, offset);
2370         it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
2371         tr=proto_item_add_subtree(it, ett_krb_pac);
2372
2373         offset += 4;
2374
2375         /* size of pac data */
2376         pac_size=tvb_get_letohl(tvb, offset);
2377         proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
2378         offset += 4;
2379
2380         /* offset to pac data */
2381         pac_offset=tvb_get_letohl(tvb, offset);
2382         proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
2383         offset += 8;
2384
2385         next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size);
2386         switch(pac_type){
2387         case PAC_LOGON_INFO:
2388                 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
2389                 break;
2390         case PAC_CREDENTIAL_TYPE:
2391                 dissect_krb5_PAC_CREDENTIAL_INFO(tr, next_tvb, 0, actx);
2392                 break;
2393         case PAC_SERVER_CHECKSUM:
2394                 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
2395                 break;
2396         case PAC_PRIVSVR_CHECKSUM:
2397                 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
2398                 break;
2399         case PAC_CLIENT_INFO_TYPE:
2400                 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
2401                 break;
2402         case PAC_S4U_DELEGATION_INFO:
2403                 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
2404                 break;
2405         case PAC_UPN_DNS_INFO:
2406                 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
2407                 break;
2408         case PAC_CLIENT_CLAIMS_INFO:
2409                 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(tr, next_tvb, 0, actx);
2410                 break;
2411         case PAC_DEVICE_INFO:
2412                 dissect_krb5_PAC_DEVICE_INFO(tr, next_tvb, 0, actx);
2413                 break;
2414         case PAC_DEVICE_CLAIMS_INFO:
2415                 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(tr, next_tvb, 0, actx);
2416                 break;
2417
2418         default:
2419                 break;
2420         }
2421         return offset;
2422 }
2423
2424 static int
2425 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_)
2426 {
2427         guint32 entries;
2428         guint32 version;
2429         guint32 i;
2430
2431 #ifdef HAVE_KERBEROS
2432         verify_krb5_pac(tree, actx, tvb);
2433 #endif
2434
2435         /* first in the PAC structure comes the number of entries */
2436         entries=tvb_get_letohl(tvb, offset);
2437         proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
2438         offset += 4;
2439
2440         /* second comes the version */
2441         version=tvb_get_letohl(tvb, offset);
2442         proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
2443         offset += 4;
2444
2445         for(i=0;i<entries;i++){
2446                 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
2447         }
2448
2449         return offset;
2450 }
2451
2452 #include "packet-kerberos-fn.c"
2453
2454 /* Make wrappers around exported functions for now */
2455 int
2456 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2457 {
2458         return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
2459
2460 }
2461
2462 int
2463 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2464 {
2465         return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
2466 }
2467
2468
2469 int
2470 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2471 {
2472         return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
2473 }
2474 int
2475 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2476 {
2477         return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
2478 }
2479
2480
2481 static gint
2482 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2483     gboolean dci, gboolean do_col_protocol, gboolean have_rm,
2484     kerberos_callbacks *cb)
2485 {
2486         volatile int offset = 0;
2487         proto_tree *volatile kerberos_tree = NULL;
2488         proto_item *volatile item = NULL;
2489         asn1_ctx_t asn1_ctx;
2490
2491         /* TCP record mark and length */
2492         guint32 krb_rm = 0;
2493         gint krb_reclen = 0;
2494
2495         gbl_do_col_info=dci;
2496
2497         if (have_rm) {
2498                 krb_rm = tvb_get_ntohl(tvb, offset);
2499                 krb_reclen = kerberos_rm_to_reclen(krb_rm);
2500                 /*
2501                  * What is a reasonable size limit?
2502                  */
2503                 if (krb_reclen > 10 * 1024 * 1024) {
2504                         return (-1);
2505                 }
2506
2507                 if (do_col_protocol) {
2508                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2509                 }
2510
2511                 if (tree) {
2512                         item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
2513                         kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
2514                 }
2515
2516                 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
2517                 offset += 4;
2518         } else {
2519                 /* Do some sanity checking here,
2520                  * All krb5 packets start with a TAG class that is BER_CLASS_APP
2521                  * and a tag value that is either of the values below:
2522                  * If it doesn't look like kerberos, return 0 and let someone else have
2523                  * a go at it.
2524                  */
2525                 gint8 tmp_class;
2526                 gboolean tmp_pc;
2527                 gint32 tmp_tag;
2528
2529                 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
2530                 if(tmp_class!=BER_CLASS_APP){
2531                         return 0;
2532                 }
2533                 switch(tmp_tag){
2534                         case KRB5_MSG_TICKET:
2535                         case KRB5_MSG_AUTHENTICATOR:
2536                         case KRB5_MSG_ENC_TICKET_PART:
2537                         case KRB5_MSG_AS_REQ:
2538                         case KRB5_MSG_AS_REP:
2539                         case KRB5_MSG_TGS_REQ:
2540                         case KRB5_MSG_TGS_REP:
2541                         case KRB5_MSG_AP_REQ:
2542                         case KRB5_MSG_AP_REP:
2543                         case KRB5_MSG_ENC_AS_REP_PART:
2544                         case KRB5_MSG_ENC_TGS_REP_PART:
2545                         case KRB5_MSG_ENC_AP_REP_PART:
2546                         case KRB5_MSG_ENC_KRB_PRIV_PART:
2547                         case KRB5_MSG_ENC_KRB_CRED_PART:
2548                         case KRB5_MSG_SAFE:
2549                         case KRB5_MSG_PRIV:
2550                         case KRB5_MSG_ERROR:
2551                                 break;
2552                         default:
2553                                 return 0;
2554                 }
2555                 if (do_col_protocol) {
2556                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2557                 }
2558                 if (gbl_do_col_info) {
2559                         col_clear(pinfo->cinfo, COL_INFO);
2560                 }
2561                 if (tree) {
2562                         item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
2563                         kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
2564                 }
2565         }
2566         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2567         asn1_ctx.private_data = cb;
2568
2569         TRY {
2570                 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
2571         } CATCH_BOUNDS_ERRORS {
2572                 RETHROW;
2573         } ENDTRY;
2574
2575         proto_item_set_len(item, offset);
2576         return offset;
2577 }
2578
2579 /*
2580  * Display the TCP record mark.
2581  */
2582 void
2583 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
2584 {
2585         gint rec_len;
2586         proto_tree *rm_tree;
2587
2588         if (tree == NULL)
2589                 return;
2590
2591         rec_len = kerberos_rm_to_reclen(krb_rm);
2592         rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL,
2593                 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
2594         proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
2595         proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
2596 }
2597
2598 gint
2599 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
2600 {
2601         return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
2602 }
2603
2604 guint32
2605 kerberos_output_keytype(void)
2606 {
2607         return gbl_keytype;
2608 }
2609
2610 static gint
2611 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2612 {
2613         /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
2614            Since all (except weirdo transarc krb4 stuff) use
2615            an opcode <=16 in the first byte, use this to see if it might
2616            be krb4.
2617            All krb5 commands start with an APPL tag and thus is >=0x60
2618            so if first byte is <=16  just blindly assume it is krb4 then
2619         */
2620         if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
2621                 if(krb4_handle){
2622                         gboolean res;
2623
2624                         res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
2625                         return res;
2626                 }else{
2627                         return 0;
2628                 }
2629         }
2630
2631
2632         return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
2633 }
2634
2635 gint
2636 kerberos_rm_to_reclen(guint krb_rm)
2637 {
2638     return (krb_rm & KRB_RM_RECLEN);
2639 }
2640
2641 guint
2642 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2643 {
2644         guint krb_rm;
2645         gint pdulen;
2646
2647         krb_rm = tvb_get_ntohl(tvb, offset);
2648         pdulen = kerberos_rm_to_reclen(krb_rm);
2649         return (pdulen + 4);
2650 }
2651 static void
2652 kerberos_prefs_apply_cb(void) {
2653 #ifdef HAVE_LIBNETTLE
2654         clear_keytab();
2655         read_keytab_file(keytab_filename);
2656 #endif
2657 }
2658
2659 static int
2660 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2661 {
2662         pinfo->fragmented = TRUE;
2663         if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
2664                 /*
2665                  * The dissector failed to recognize this as a valid
2666                  * Kerberos message.  Mark it as a continuation packet.
2667                  */
2668                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
2669         }
2670
2671         return tvb_captured_length(tvb);
2672 }
2673
2674 static int
2675 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2676 {
2677         col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2678         col_clear(pinfo->cinfo, COL_INFO);
2679
2680         tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
2681                                          dissect_kerberos_tcp_pdu, data);
2682         return tvb_captured_length(tvb);
2683 }
2684
2685 /*--- proto_register_kerberos -------------------------------------------*/
2686 void proto_register_kerberos(void) {
2687
2688         /* List of fields */
2689
2690         static hf_register_info hf[] = {
2691         { &hf_krb_rm_reserved, {
2692                 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
2693                 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
2694         { &hf_krb_rm_reclen, {
2695                 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
2696                 NULL, KRB_RM_RECLEN, NULL, HFILL }},
2697         { &hf_krb_provsrv_location, {
2698                 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
2699                 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
2700         { &hf_krb_smb_nt_status,
2701                 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
2702                 VALS(NT_errors), 0, "NT Status code", HFILL }},
2703         { &hf_krb_smb_unknown,
2704                 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
2705                 NULL, 0, NULL, HFILL }},
2706         { &hf_krb_address_ip, {
2707                 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
2708                 NULL, 0, NULL, HFILL }},
2709         { &hf_krb_address_ipv6, {
2710                 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
2711                 NULL, 0, NULL, HFILL }},
2712         { &hf_krb_address_netbios, {
2713                 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
2714                 NULL, 0, "NetBIOS Address and type", HFILL }},
2715         { &hf_krb_gssapi_len, {
2716                 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
2717                 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
2718         { &hf_krb_gssapi_bnd, {
2719                 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
2720                 NULL, 0, "GSSAPI Bnd field", HFILL }},
2721         { &hf_krb_gssapi_c_flag_deleg, {
2722                 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
2723                 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
2724         { &hf_krb_gssapi_c_flag_mutual, {
2725                 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
2726                 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
2727         { &hf_krb_gssapi_c_flag_replay, {
2728                 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
2729                 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
2730         { &hf_krb_gssapi_c_flag_sequence, {
2731                 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
2732                 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
2733         { &hf_krb_gssapi_c_flag_conf, {
2734                 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
2735                 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
2736         { &hf_krb_gssapi_c_flag_integ, {
2737                 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
2738                 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
2739         { &hf_krb_gssapi_c_flag_dce_style, {
2740                 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
2741                 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
2742         { &hf_krb_gssapi_dlgopt, {
2743                 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
2744                 NULL, 0, "GSSAPI DlgOpt", HFILL }},
2745         { &hf_krb_gssapi_dlglen, {
2746                 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
2747                 NULL, 0, "GSSAPI DlgLen", HFILL }},
2748         { &hf_krb_midl_blob_len, {
2749                 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
2750                 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
2751         { &hf_krb_midl_fill_bytes, {
2752                 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
2753                 NULL, 0, "Just some fill bytes", HFILL }},
2754         { &hf_krb_midl_version, {
2755         "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
2756         NULL, 0, "Version of pickling", HFILL }},
2757         { &hf_krb_midl_hdr_len, {
2758                 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
2759                 NULL, 0, "Length of header", HFILL }},
2760         { &hf_krb_pac_signature_type, {
2761                 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
2762                 NULL, 0, "PAC Signature Type", HFILL }},
2763         { &hf_krb_pac_signature_signature, {
2764                 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
2765                 NULL, 0, "A PAC signature blob", HFILL }},
2766         { &hf_krb_w2k_pac_entries, {
2767                 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
2768                 NULL, 0, "Number of W2k PAC entries", HFILL }},
2769         { &hf_krb_w2k_pac_version, {
2770                 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
2771                 NULL, 0, "Version of PAC structures", HFILL }},
2772         { &hf_krb_w2k_pac_type, {
2773                 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
2774                 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
2775         { &hf_krb_w2k_pac_size, {
2776                 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
2777                 NULL, 0, "Size of W2k PAC entry", HFILL }},
2778         { &hf_krb_w2k_pac_offset, {
2779                 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
2780                 NULL, 0, "Offset to W2k PAC entry", HFILL }},
2781         { &hf_krb_pac_clientid, {
2782                 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2783                 NULL, 0, "ClientID Timestamp", HFILL }},
2784         { &hf_krb_pac_namelen, {
2785                 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
2786                 NULL, 0, "Length of client name", HFILL }},
2787         { &hf_krb_pac_clientname, {
2788                 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
2789                 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
2790         { &hf_krb_pac_logon_info, {
2791                 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE,
2792                 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
2793         { &hf_krb_pac_credential_data, {
2794                 "PAC_CREDENTIAL_DATA", "kerberos.pac_credential_data", FT_BYTES, BASE_NONE,
2795                 NULL, 0, "PAC_CREDENTIAL_DATA structure", HFILL }},
2796         { &hf_krb_pac_credential_info, {
2797                 "PAC_CREDENTIAL_INFO", "kerberos.pac_credential_info", FT_BYTES, BASE_NONE,
2798                 NULL, 0, "PAC_CREDENTIAL_INFO structure", HFILL }},
2799         { &hf_krb_pac_credential_info_version, {
2800                 "Version", "kerberos.pac_credential_info.version", FT_UINT32, BASE_DEC,
2801                 NULL, 0, NULL, HFILL }},
2802         { &hf_krb_pac_credential_info_etype, {
2803                 "Etype", "kerberos.pac_credential_info.etype", FT_UINT32, BASE_DEC,
2804                 NULL, 0, NULL, HFILL }},
2805         { &hf_krb_pac_server_checksum, {
2806                 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE,
2807                 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
2808         { &hf_krb_pac_privsvr_checksum, {
2809                 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE,
2810                 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
2811         { &hf_krb_pac_client_info_type, {
2812                 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE,
2813                 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
2814         { &hf_krb_pac_s4u_delegation_info, {
2815                 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE,
2816                 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
2817         { &hf_krb_pac_upn_dns_info, {
2818                 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE,
2819                 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
2820         { &hf_krb_pac_upn_flags, {
2821                 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
2822                 NULL, 0, "UPN flags", HFILL }},
2823         { &hf_krb_pac_upn_dns_offset, {
2824                 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
2825                 NULL, 0, NULL, HFILL }},
2826         { &hf_krb_pac_upn_dns_len, {
2827                 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
2828                 NULL, 0, NULL, HFILL }},
2829         { &hf_krb_pac_upn_upn_offset, {
2830                 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
2831                 NULL, 0, NULL, HFILL }},
2832         { &hf_krb_pac_upn_upn_len, {
2833                 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
2834                 NULL, 0, NULL, HFILL }},
2835         { &hf_krb_pac_upn_upn_name, {
2836                 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
2837                 NULL, 0, NULL, HFILL }},
2838         { &hf_krb_pac_upn_dns_name, {
2839                 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
2840                 NULL, 0, NULL, HFILL }},
2841         { &hf_krb_pac_client_claims_info, {
2842                 "PAC_CLIENT_CLAIMS_INFO", "kerberos.pac_client_claims_info", FT_BYTES, BASE_NONE,
2843                 NULL, 0, "PAC_CLIENT_CLAIMS_INFO structure", HFILL }},
2844         { &hf_krb_pac_device_info, {
2845                 "PAC_DEVICE_INFO", "kerberos.pac_device_info", FT_BYTES, BASE_NONE,
2846                 NULL, 0, "PAC_DEVICE_INFO structure", HFILL }},
2847         { &hf_krb_pac_device_claims_info, {
2848                 "PAC_DEVICE_CLAIMS_INFO", "kerberos.pac_device_claims_info", FT_BYTES, BASE_NONE,
2849                 NULL, 0, "PAC_DEVICE_CLAIMS_INFO structure", HFILL }},
2850         { &hf_krb_pa_supported_enctypes,
2851           { "SupportedEnctypes", "kerberos.supported_entypes",
2852             FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2853         { &hf_krb_pa_supported_enctypes_des_cbc_crc,
2854           { "des-cbc-crc", "kerberos.supported_entypes.des-cbc-crc",
2855             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000001, NULL, HFILL }},
2856         { &hf_krb_pa_supported_enctypes_des_cbc_md5,
2857           { "des-cbc-md5", "kerberos.supported_entypes.des-cbc-md5",
2858             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000002, NULL, HFILL }},
2859         { &hf_krb_pa_supported_enctypes_rc4_hmac,
2860           { "rc4-hmac", "kerberos.supported_entypes.rc4-hmac",
2861             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000004, NULL, HFILL }},
2862         { &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
2863           { "aes128-cts-hmac-sha1-96", "kerberos.supported_entypes.aes128-cts-hmac-sha1-96",
2864             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000008, NULL, HFILL }},
2865         { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
2866           { "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96",
2867             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000010, NULL, HFILL }},
2868         { &hf_krb_pa_supported_enctypes_fast_supported,
2869           { "fast-supported", "kerberos.supported_entypes.fast-supported",
2870             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00010000, NULL, HFILL }},
2871         { &hf_krb_pa_supported_enctypes_compound_identity_supported,
2872           { "compound-identity-supported", "kerberos.supported_entypes.compound-identity-supported",
2873             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00020000, NULL, HFILL }},
2874         { &hf_krb_pa_supported_enctypes_claims_supported,
2875           { "claims-supported", "kerberos.supported_entypes.claims-supported",
2876             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2877         { &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
2878           { "resource-sid-compression-disabled", "kerberos.supported_entypes.resource-sid-compression-disabled",
2879             FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00080000, NULL, HFILL }},
2880         { &hf_krb_ad_ap_options,
2881           { "AD-AP-Options", "kerberos.ad_ap_options",
2882             FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2883         { &hf_krb_ad_ap_options_cbt,
2884           { "ChannelBindings", "kerberos.ad_ap_options.cbt",
2885             FT_BOOLEAN, 32, TFS(&set_tfs), 0x00004000, NULL, HFILL }},
2886         { &hf_krb_ad_target_principal, {
2887                 "Target Principal", "kerberos.ad_target_principal", FT_STRING, BASE_NONE,
2888                 NULL, 0, NULL, HFILL }},
2889
2890 #include "packet-kerberos-hfarr.c"
2891         };
2892
2893         /* List of subtrees */
2894         static gint *ett[] = {
2895                 &ett_kerberos,
2896                 &ett_krb_recordmark,
2897                 &ett_krb_pac,
2898                 &ett_krb_pac_drep,
2899                 &ett_krb_pac_midl_blob,
2900                 &ett_krb_pac_logon_info,
2901                 &ett_krb_pac_credential_info,
2902                 &ett_krb_pac_s4u_delegation_info,
2903                 &ett_krb_pac_upn_dns_info,
2904                 &ett_krb_pac_server_checksum,
2905                 &ett_krb_pac_privsvr_checksum,
2906                 &ett_krb_pac_client_info_type,
2907                 &ett_krb_pa_supported_enctypes,
2908                 &ett_krb_ad_ap_options,
2909 #include "packet-kerberos-ettarr.c"
2910         };
2911
2912         static ei_register_info ei[] = {
2913                 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
2914                 { &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 }},
2915                 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }},
2916         };
2917
2918         expert_module_t* expert_krb;
2919         module_t *krb_module;
2920
2921         proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
2922         proto_register_field_array(proto_kerberos, hf, array_length(hf));
2923         proto_register_subtree_array(ett, array_length(ett));
2924         expert_krb = expert_register_protocol(proto_kerberos);
2925         expert_register_field_array(expert_krb, ei, array_length(ei));
2926
2927         /* Register preferences */
2928         krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2929         prefs_register_bool_preference(krb_module, "desegment",
2930         "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2931         "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2932         " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2933         &krb_desegment);
2934 #ifdef HAVE_KERBEROS
2935         prefs_register_bool_preference(krb_module, "decrypt",
2936         "Try to decrypt Kerberos blobs",
2937         "Whether the dissector should try to decrypt "
2938         "encrypted Kerberos blobs. This requires that the proper "
2939         "keytab file is installed as well.", &krb_decrypt);
2940
2941         prefs_register_filename_preference(krb_module, "file",
2942                                    "Kerberos keytab file",
2943                                    "The keytab file containing all the secrets",
2944                                    &keytab_filename, FALSE);
2945 #endif
2946
2947 }
2948 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2949                                  proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
2950 {
2951         tvbuff_t *auth_tvb;
2952
2953         auth_tvb = tvb_new_subset_remaining(tvb, offset);
2954
2955         dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2956
2957         return tvb_captured_length_remaining(tvb, offset);
2958 }
2959
2960
2961 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2962         wrap_dissect_gss_kerb,                      /* Bind */
2963         wrap_dissect_gss_kerb,                      /* Bind ACK */
2964         wrap_dissect_gss_kerb,                      /* AUTH3 */
2965         NULL,                                       /* Request verifier */
2966         NULL,                                       /* Response verifier */
2967         NULL,                                       /* Request data */
2968         NULL                                        /* Response data */
2969 };
2970
2971 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2972         wrap_dissect_gss_kerb,                      /* Bind */
2973         wrap_dissect_gss_kerb,                      /* Bind ACK */
2974         wrap_dissect_gss_kerb,                      /* AUTH3 */
2975         wrap_dissect_gssapi_verf,                   /* Request verifier */
2976         wrap_dissect_gssapi_verf,                   /* Response verifier */
2977         NULL,                                       /* Request data */
2978         NULL                                        /* Response data */
2979 };
2980
2981 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2982         wrap_dissect_gss_kerb,                      /* Bind */
2983         wrap_dissect_gss_kerb,                      /* Bind ACK */
2984         wrap_dissect_gss_kerb,                      /* AUTH3 */
2985         wrap_dissect_gssapi_verf,                   /* Request verifier */
2986         wrap_dissect_gssapi_verf,                   /* Response verifier */
2987         wrap_dissect_gssapi_payload,                /* Request data */
2988         wrap_dissect_gssapi_payload                 /* Response data */
2989 };
2990
2991
2992
2993 void
2994 proto_reg_handoff_kerberos(void)
2995 {
2996         dissector_handle_t kerberos_handle_tcp;
2997
2998         krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos);
2999
3000         kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
3001         proto_kerberos);
3002
3003         kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
3004         proto_kerberos);
3005
3006         dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
3007         dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
3008
3009         register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
3010                                                                           DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
3011                                                                           &gss_kerb_auth_connect_fns);
3012
3013         register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
3014                                                                           DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
3015                                                                           &gss_kerb_auth_sign_fns);
3016
3017         register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
3018                                                                           DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
3019                                                                           &gss_kerb_auth_seal_fns);
3020 }
3021
3022 /*
3023  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3024  *
3025  * Local variables:
3026  * c-basic-offset: 8
3027  * tab-width: 8
3028  * indent-tabs-mode: t
3029  * End:
3030  *
3031  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3032  * :indentSize=8:tabSize=8:noTabs=false:
3033  */