packet-kerberos: remember in what frame a key was learned
[metze/wireshark/wip.git] / epan / dissectors / packet-kerberos.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  * Ted Percival ted[AT]midg3t.net
27  *      Support for PA-S4U2Self Kerberos packet type based on ASN.1 description
28  *      in Heimdal:
29  *      http://loka.it.su.se/source/xref/heimdal/heimdal/lib/asn1/k5.asn1
30  *
31  * $Id$
32  *
33  * Wireshark - Network traffic analyzer
34  * By Gerald Combs <gerald@wireshark.org>
35  * Copyright 1998 Gerald Combs
36  *
37  * This program is free software; you can redistribute it and/or
38  * modify it under the terms of the GNU General Public License
39  * as published by the Free Software Foundation; either version 2
40  * of the License, or (at your option) any later version.
41  *
42  * This program is distributed in the hope that it will be useful,
43  * but WITHOUT ANY WARRANTY; without even the implied warranty of
44  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45  * GNU General Public License for more details.
46  *
47  * You should have received a copy of the GNU General Public License
48  * along with this program; if not, write to the Free Software
49  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
50  */
51
52 /*
53  * Some of the development of the Kerberos protocol decoder was sponsored by
54  * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
55  * CableLabs' specifications. Your license and use of this protocol decoder
56  * does not mean that you are licensed to use the CableLabs'
57  * specifications.  If you have questions about this protocol, contact
58  * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
59  * information.
60  */
61
62 #include "config.h"
63
64 #include <stdio.h>
65 #include <string.h>
66
67 #include <glib.h>
68
69 #ifdef HAVE_LIBNETTLE
70 #define HAVE_KERBEROS
71 #ifdef _WIN32
72 #include <des.h>
73 #include <cbc.h>
74 #else
75 #include <nettle/des.h>
76 #include <nettle/cbc.h>
77 #endif
78 #include <wsutil/md5.h>
79 #include <sys/stat.h>   /* For keyfile manipulation */
80 #endif
81
82 #include <epan/packet.h>
83
84 #include <epan/strutil.h>
85
86 #include <epan/conversation.h>
87 #include <epan/exceptions.h>
88 #include <epan/wmem/wmem.h>
89 #include <epan/asn1.h>
90 #include <epan/expert.h>
91 #include <epan/dissectors/packet-kerberos.h>
92 #include <epan/dissectors/packet-netbios.h>
93 #include <epan/dissectors/packet-tcp.h>
94 #include <epan/prefs.h>
95 #include <epan/dissectors/packet-ber.h>
96 #include <epan/dissectors/packet-pkinit.h>
97 #include <epan/dissectors/packet-cms.h>
98 #include <epan/dissectors/packet-windows-common.h>
99
100 #include <epan/dissectors/packet-dcerpc-netlogon.h>
101 #include <epan/dissectors/packet-dcerpc.h>
102
103 #include <epan/dissectors/packet-gssapi.h>
104 #include <epan/dissectors/packet-smb-common.h>
105
106 #include <wsutil/file_util.h>
107
108 void proto_register_kerberos(void);
109 void proto_reg_handoff_kerberos(void);
110
111 #define UDP_PORT_KERBEROS               88
112 #define TCP_PORT_KERBEROS               88
113
114 static dissector_handle_t kerberos_handle_udp;
115
116 /* Desegment Kerberos over TCP messages */
117 static gboolean krb_desegment = TRUE;
118
119 static gint proto_kerberos = -1;
120 static gint hf_krb_rm_reserved = -1;
121 static gint hf_krb_rm_reclen = -1;
122
123 static gint hf_krb_pac_signature_type = -1;
124 static gint hf_krb_pac_signature_signature = -1;
125 static gint hf_krb_pac_clientid = -1;
126 static gint hf_krb_pac_namelen = -1;
127 static gint hf_krb_pac_clientname = -1;
128 static gint hf_krb_pac_upn_flags = -1;
129 static gint hf_krb_pac_upn_upn_name = -1;
130 static gint hf_krb_pac_upn_dns_name = -1;
131 static gint hf_krb_pac_upn_dns_offset = -1;
132 static gint hf_krb_pac_upn_dns_len = -1;
133 static gint hf_krb_pac_upn_upn_offset = -1;
134 static gint hf_krb_pac_upn_upn_len = -1;
135 static gint hf_krb_w2k_pac_entries = -1;
136 static gint hf_krb_w2k_pac_version = -1;
137 static gint hf_krb_w2k_pac_type = -1;
138 static gint hf_krb_w2k_pac_size = -1;
139 static gint hf_krb_w2k_pac_offset = -1;
140 static gint hf_krb_padata = -1;
141 static gint hf_krb_error_code = -1;
142 static gint hf_krb_ticket = -1;
143 static gint hf_krb_AP_REP_enc = -1;
144 static gint hf_krb_KDC_REP_enc = -1;
145 static gint hf_krb_tkt_vno = -1;
146 static gint hf_krb_e_data = -1;
147 static gint hf_krb_TransitedEncoding = -1;
148 static gint hf_krb_PA_PAC_REQUEST_flag = -1;
149 static gint hf_krb_encrypted_authenticator_data = -1;
150 static gint hf_krb_PAC_LOGON_INFO = -1;
151 static gint hf_krb_PAC_CREDENTIAL_TYPE = -1;
152 static gint hf_krb_PAC_SERVER_CHECKSUM = -1;
153 static gint hf_krb_PAC_PRIVSVR_CHECKSUM = -1;
154 static gint hf_krb_PAC_CLIENT_INFO_TYPE = -1;
155 static gint hf_krb_PAC_S4U_DELEGATION_INFO = -1;
156 static gint hf_krb_PAC_UPN_DNS_INFO = -1;
157 static gint hf_krb_encrypted_PA_ENC_TIMESTAMP = -1;
158 static gint hf_krb_encrypted_enc_authorization_data = -1;
159 static gint hf_krb_encrypted_EncKrbCredPart = -1;
160 static gint hf_krb_checksum_checksum = -1;
161 static gint hf_krb_encrypted_PRIV = -1;
162 static gint hf_krb_encrypted_Ticket_data = -1;
163 static gint hf_krb_encrypted_AP_REP_data = -1;
164 static gint hf_krb_encrypted_KDC_REP_data = -1;
165 static gint hf_krb_PA_DATA_type = -1;
166 static gint hf_krb_PA_DATA_value = -1;
167 static gint hf_krb_etype_info_salt = -1;
168 static gint hf_krb_etype_info2_salt = -1;
169 static gint hf_krb_etype_info2_s2kparams = -1;
170 static gint hf_krb_SAFE_BODY_user_data = -1;
171 static gint hf_krb_PRIV_BODY_user_data = -1;
172 static gint hf_krb_realm = -1;
173 static gint hf_krb_srealm = -1;
174 static gint hf_krb_prealm = -1;
175 static gint hf_krb_crealm = -1;
176 static gint hf_krb_sname = -1;
177 static gint hf_krb_pname = -1;
178 static gint hf_krb_cname = -1;
179 static gint hf_krb_name_string = -1;
180 static gint hf_krb_provsrv_location = -1;
181 static gint hf_krb_e_text = -1;
182 static gint hf_krb_s4u2self_auth = -1;
183 static gint hf_krb_name_type = -1;
184 static gint hf_krb_lr_type = -1;
185 static gint hf_krb_from = -1;
186 static gint hf_krb_till = -1;
187 static gint hf_krb_authtime = -1;
188 static gint hf_krb_patimestamp = -1;
189 static gint hf_krb_SAFE_BODY_timestamp = -1;
190 static gint hf_krb_pausec = -1;
191 static gint hf_krb_lr_time = -1;
192 static gint hf_krb_starttime = -1;
193 static gint hf_krb_endtime = -1;
194 static gint hf_krb_key_expire = -1;
195 static gint hf_krb_renew_till = -1;
196 static gint hf_krb_rtime = -1;
197 static gint hf_krb_ctime = -1;
198 static gint hf_krb_cusec = -1;
199 static gint hf_krb_stime = -1;
200 static gint hf_krb_susec = -1;
201 static gint hf_krb_SAFE_BODY_usec = -1;
202 static gint hf_krb_nonce = -1;
203 static gint hf_krb_transitedtype = -1;
204 static gint hf_krb_transitedcontents = -1;
205 static gint hf_krb_keytype = -1;
206 static gint hf_krb_keyvalue = -1;
207 static gint hf_krb_IF_RELEVANT_type = -1;
208 static gint hf_krb_IF_RELEVANT_value = -1;
209 static gint hf_krb_adtype = -1;
210 static gint hf_krb_advalue = -1;
211 static gint hf_krb_etype = -1;
212 static gint hf_krb_etypes = -1;
213 static gint hf_krb_KrbCredInfos = -1;
214 static gint hf_krb_sq_tickets = -1;
215 static gint hf_krb_LastReqs = -1;
216 static gint hf_krb_IF_RELEVANT = -1;
217 static gint hf_krb_addr_type = -1;
218 static gint hf_krb_address_ip = -1;
219 static gint hf_krb_address_ipv6 = -1;
220 static gint hf_krb_address_netbios = -1;
221 static gint hf_krb_msg_type = -1;
222 static gint hf_krb_pvno = -1;
223 static gint hf_krb_kvno = -1;
224 static gint hf_krb_checksum_type = -1;
225 static gint hf_krb_authenticator_vno = -1;
226 static gint hf_krb_AuthorizationData = -1;
227 static gint hf_krb_key = -1;
228 static gint hf_krb_subkey = -1;
229 static gint hf_krb_seq_number = -1;
230 static gint hf_krb_EncTicketPart = -1;
231 static gint hf_krb_EncAPRepPart = -1;
232 static gint hf_krb_EncKrbPrivPart = -1;
233 static gint hf_krb_EncKrbCredPart = -1;
234 static gint hf_krb_EncKDCRepPart = -1;
235 static gint hf_krb_LastReq = -1;
236 static gint hf_krb_Authenticator = -1;
237 static gint hf_krb_Checksum = -1;
238 static gint hf_krb_s_address = -1;
239 static gint hf_krb_r_address = -1;
240 static gint hf_krb_KrbCredInfo = -1;
241 static gint hf_krb_HostAddress = -1;
242 static gint hf_krb_HostAddresses = -1;
243 static gint hf_krb_APOptions = -1;
244 static gint hf_krb_APOptions_reserved = -1;
245 static gint hf_krb_APOptions_use_session_key = -1;
246 static gint hf_krb_APOptions_mutual_required = -1;
247 static gint hf_krb_TicketFlags = -1;
248 static gint hf_krb_TicketFlags_forwardable = -1;
249 static gint hf_krb_TicketFlags_forwarded = -1;
250 static gint hf_krb_TicketFlags_proxiable = -1;
251 static gint hf_krb_TicketFlags_proxy = -1;
252 static gint hf_krb_TicketFlags_allow_postdate = -1;
253 static gint hf_krb_TicketFlags_postdated = -1;
254 static gint hf_krb_TicketFlags_invalid = -1;
255 static gint hf_krb_TicketFlags_renewable = -1;
256 static gint hf_krb_TicketFlags_initial = -1;
257 static gint hf_krb_TicketFlags_pre_auth = -1;
258 static gint hf_krb_TicketFlags_hw_auth = -1;
259 static gint hf_krb_TicketFlags_transited_policy_checked = -1;
260 static gint hf_krb_TicketFlags_ok_as_delegate = -1;
261 static gint hf_krb_KDCOptions = -1;
262 static gint hf_krb_KDCOptions_forwardable = -1;
263 static gint hf_krb_KDCOptions_forwarded = -1;
264 static gint hf_krb_KDCOptions_proxiable = -1;
265 static gint hf_krb_KDCOptions_proxy = -1;
266 static gint hf_krb_KDCOptions_allow_postdate = -1;
267 static gint hf_krb_KDCOptions_postdated = -1;
268 static gint hf_krb_KDCOptions_renewable = -1;
269 static gint hf_krb_KDCOptions_constrained_delegation = -1;
270 static gint hf_krb_KDCOptions_canonicalize = -1;
271 static gint hf_krb_KDCOptions_opt_hardware_auth = -1;
272 static gint hf_krb_KDCOptions_disable_transited_check = -1;
273 static gint hf_krb_KDCOptions_renewable_ok = -1;
274 static gint hf_krb_KDCOptions_enc_tkt_in_skey = -1;
275 static gint hf_krb_KDCOptions_renew = -1;
276 static gint hf_krb_KDCOptions_validate = -1;
277 static gint hf_krb_KDC_REQ_BODY = -1;
278 static gint hf_krb_PRIV_BODY = -1;
279 static gint hf_krb_CRED_BODY = -1;
280 static gint hf_krb_ENC_PRIV = -1;
281 static gint hf_krb_authenticator_enc = -1;
282 static gint hf_krb_CRED_enc = -1;
283 static gint hf_krb_ticket_enc = -1;
284 static gint hf_krb_e_checksum = -1;
285 static gint hf_krb_gssapi_len = -1;
286 static gint hf_krb_gssapi_bnd = -1;
287 static gint hf_krb_gssapi_dlgopt = -1;
288 static gint hf_krb_gssapi_dlglen = -1;
289 static gint hf_krb_gssapi_c_flag_deleg = -1;
290 static gint hf_krb_gssapi_c_flag_mutual = -1;
291 static gint hf_krb_gssapi_c_flag_replay = -1;
292 static gint hf_krb_gssapi_c_flag_sequence = -1;
293 static gint hf_krb_gssapi_c_flag_conf = -1;
294 static gint hf_krb_gssapi_c_flag_integ = -1;
295 static gint hf_krb_gssapi_c_flag_dce_style = -1;
296 static gint hf_krb_smb_nt_status = -1;
297 static gint hf_krb_smb_unknown = -1;
298 static gint hf_krb_midl_blob_len = -1;
299 static gint hf_krb_midl_fill_bytes = -1;
300 static gint hf_krb_midl_version = -1;
301 static gint hf_krb_midl_hdr_len = -1;
302
303 static gint ett_krb_kerberos = -1;
304 static gint ett_krb_TransitedEncoding = -1;
305 static gint ett_krb_PAC_LOGON_INFO = -1;
306 static gint ett_krb_PAC_SERVER_CHECKSUM = -1;
307 static gint ett_krb_PAC_PRIVSVR_CHECKSUM = -1;
308 static gint ett_krb_PAC_CLIENT_INFO_TYPE = -1;
309 static gint ett_krb_PAC_S4U_DELEGATION_INFO = -1;
310 static gint ett_krb_KDC_REP_enc = -1;
311 static gint ett_krb_EncTicketPart = -1;
312 static gint ett_krb_EncAPRepPart = -1;
313 static gint ett_krb_EncKrbPrivPart = -1;
314 static gint ett_krb_EncKrbCredPart = -1;
315 static gint ett_krb_EncKDCRepPart = -1;
316 static gint ett_krb_LastReq = -1;
317 static gint ett_krb_Authenticator = -1;
318 static gint ett_krb_Checksum = -1;
319 static gint ett_krb_key = -1;
320 static gint ett_krb_subkey = -1;
321 static gint ett_krb_AuthorizationData = -1;
322 static gint ett_krb_sname = -1;
323 static gint ett_krb_pname = -1;
324 static gint ett_krb_cname = -1;
325 static gint ett_krb_AP_REP_enc = -1;
326 static gint ett_krb_padata = -1;
327 static gint ett_krb_etypes = -1;
328 static gint ett_krb_KrbCredInfos = -1;
329 static gint ett_krb_sq_tickets = -1;
330 static gint ett_krb_LastReqs = -1;
331 static gint ett_krb_IF_RELEVANT = -1;
332 static gint ett_krb_PA_DATA_tree = -1;
333 static gint ett_krb_PAC = -1;
334 static gint ett_krb_s_address = -1;
335 static gint ett_krb_r_address = -1;
336 static gint ett_krb_KrbCredInfo = -1;
337 static gint ett_krb_HostAddress = -1;
338 static gint ett_krb_HostAddresses = -1;
339 static gint ett_krb_authenticator_enc = -1;
340 static gint ett_krb_CRED_enc = -1;
341 static gint ett_krb_AP_Options = -1;
342 static gint ett_krb_KDC_Options = -1;
343 static gint ett_krb_Ticket_Flags = -1;
344 static gint ett_krb_request = -1;
345 static gint ett_krb_recordmark = -1;
346 static gint ett_krb_ticket = -1;
347 static gint ett_krb_ticket_enc = -1;
348 static gint ett_krb_CRED = -1;
349 static gint ett_krb_PRIV = -1;
350 static gint ett_krb_PRIV_enc = -1;
351 static gint ett_krb_e_checksum = -1;
352 static gint ett_krb_PAC_MIDL_BLOB = -1;
353 static gint ett_krb_PAC_DREP = -1;
354 static gint ett_krb_PAC_UPN_DNS_INFO = -1;
355
356 static expert_field ei_krb_decrypted_keytype = EI_INIT;
357
358 static guint32 krb5_errorcode;
359
360
361 static dissector_handle_t krb4_handle=NULL;
362
363 static gboolean gbl_do_col_info;
364
365
366 static void
367 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
368 {
369     if(!cb){
370         return;
371     }
372
373     while(cb->tag){
374         if(cb->tag==tag){
375             cb->callback(pinfo, tvb, tree);
376             return;
377         }
378         cb++;
379     }
380     return;
381 }
382
383
384
385 #ifdef HAVE_KERBEROS
386
387 /* Decrypt Kerberos blobs */
388 gboolean krb_decrypt = FALSE;
389
390 /* keytab filename */
391 static const char *keytab_filename = "";
392
393 WS_DLL_PUBLIC
394 void read_keytab_file(const char *);
395
396 void
397 read_keytab_file_from_preferences(void)
398 {
399     static char *last_keytab = NULL;
400
401     if (!krb_decrypt) {
402         return;
403     }
404
405     if (keytab_filename == NULL) {
406         return;
407     }
408
409     if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
410         return;
411     }
412
413     if (last_keytab != NULL) {
414         g_free(last_keytab);
415         last_keytab = NULL;
416     }
417     last_keytab = g_strdup(keytab_filename);
418
419     read_keytab_file(last_keytab);
420 }
421
422 #elif defined(_WIN32)
423
424 /*
425  * Dummy version to allow us to export this function -- even
426  * on systems without KERBEROS.
427  */
428 void
429 read_keytab_file_from_preferences(void)
430 {
431 }
432
433 #endif
434
435 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
436 #ifdef _WIN32
437 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
438 #undef HAVE_STDARG_H
439 #undef HAVE_STDLIB_H
440 #undef HAVE_STRING_H
441 #undef HAVE_SYS_TYPES_H
442 #endif
443 #include <krb5.h>
444 enc_key_t *enc_key_list=NULL;
445
446 static void
447 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
448 {
449     enc_key_t *new_key;
450
451     if(pinfo->fd->flags.visited){
452         return;
453     }
454 printf("added key in %u    keytype:%d len:%d\n",pinfo->fd->num, keytype, keylength);
455
456     new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
457     g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->fd->num);
458     new_key->fd_num = pinfo->fd->num;
459     new_key->next=enc_key_list;
460     enc_key_list=new_key;
461     new_key->keytype=keytype;
462     new_key->keylength=keylength;
463     /*XXX this needs to be freed later */
464     new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
465 }
466 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
467
468 #if defined(_WIN32) && !defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_MIT_KERBEROS) && !defined(HAVE_LIBNETTLE)
469 void
470 read_keytab_file(const char *filename _U_)
471 {
472 }
473 #endif
474
475 #ifdef HAVE_MIT_KERBEROS
476
477 static krb5_context krb5_ctx;
478
479 void
480 read_keytab_file(const char *filename)
481 {
482     krb5_keytab keytab;
483     krb5_error_code ret;
484     krb5_keytab_entry key;
485     krb5_kt_cursor cursor;
486     enc_key_t *new_key;
487     static gboolean first_time=TRUE;
488
489 printf("read keytab file %s\n", filename);
490     if(first_time){
491         first_time=FALSE;
492         ret = krb5_init_context(&krb5_ctx);
493         if(ret && ret != KRB5_CONFIG_CANTOPEN){
494             return;
495         }
496     }
497
498     /* should use a file in the wireshark users dir */
499     ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
500     if(ret){
501         fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
502
503         return;
504     }
505
506     ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
507     if(ret){
508         fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
509         return;
510     }
511
512     do{
513         new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
514         new_key->fd_num = -1;
515         new_key->next=enc_key_list;
516         ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
517         if(ret==0){
518             int i;
519             char *pos;
520
521             /* generate origin string, describing where this key came from */
522             pos=new_key->key_origin;
523             pos+=MIN(KRB_MAX_ORIG_LEN,
524                      g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
525             for(i=0;i<key.principal->length;i++){
526                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
527                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),(key.principal->data[i]).data));
528             }
529             pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
530                      g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm.data));
531             *pos=0;
532 /*printf("added key for principal :%s\n", new_key->key_origin);*/
533             new_key->keytype=key.key.enctype;
534             new_key->keylength=key.key.length;
535             new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
536             enc_key_list=new_key;
537         }
538     }while(ret==0);
539
540     ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
541     if(ret){
542         krb5_kt_close(krb5_ctx, keytab);
543     }
544
545 }
546
547
548 guint8 *
549 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
550                   int usage,
551                   tvbuff_t *cryptotvb,
552                   int keytype,
553                   int *datalen)
554 {
555     krb5_error_code ret;
556     enc_key_t *ek;
557     krb5_data data = {0,0,NULL};
558     krb5_keytab_entry key;
559     int length = tvb_length(cryptotvb);
560     const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
561
562     /* don't do anything if we are not attempting to decrypt data */
563     if(!krb_decrypt || length < 1){
564         return NULL;
565     }
566
567     /* make sure we have all the data we need */
568     if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
569         return NULL;
570     }
571
572     read_keytab_file_from_preferences();
573     data.data = (char *)g_malloc(length);
574     data.length = length;
575
576     for(ek=enc_key_list;ek;ek=ek->next){
577         krb5_enc_data input;
578
579         /* shortcircuit and bail out if enctypes are not matching */
580         if((keytype != -1) && (ek->keytype != keytype)) {
581             continue;
582         }
583
584         input.enctype = ek->keytype;
585         input.ciphertext.length = length;
586         input.ciphertext.data = (guint8 *)cryptotext;
587
588         key.key.enctype=ek->keytype;
589         key.key.length=ek->keylength;
590         key.key.contents=ek->keyvalue;
591         ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
592         if(ret == 0){
593             char *user_data;
594
595             expert_add_info_format(pinfo, NULL, &ei_krb_decrypted_keytype,
596                                    "Decrypted keytype %d in frame %u using %s",
597                                    ek->keytype, pinfo->fd->num, ek->key_origin);
598
599             proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
600             /* return a private g_malloced blob to the caller */
601             user_data=data.data;
602             if (datalen) {
603                 *datalen = data.length;
604             }
605             return user_data;
606         }
607     }
608     g_free(data.data);
609
610     return NULL;
611 }
612
613 #elif defined(HAVE_HEIMDAL_KERBEROS)
614 static krb5_context krb5_ctx;
615
616 void
617 read_keytab_file(const char *filename)
618 {
619     krb5_keytab keytab;
620     krb5_error_code ret;
621     krb5_keytab_entry key;
622     krb5_kt_cursor cursor;
623     enc_key_t *new_key;
624     static gboolean first_time=TRUE;
625
626     if(first_time){
627         first_time=FALSE;
628         ret = krb5_init_context(&krb5_ctx);
629         if(ret){
630             return;
631         }
632     }
633
634     /* should use a file in the wireshark users dir */
635     ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
636     if(ret){
637         fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
638
639         return;
640     }
641
642     ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
643     if(ret){
644         fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
645         return;
646     }
647
648     do{
649         new_key=(enc_key_t*)g_malloc(sizeof(enc_key_t));
650         new_key->fd_num = -1;
651         new_key->next=enc_key_list;
652         ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
653         if(ret==0){
654             unsigned int i;
655             char *pos;
656
657             /* generate origin string, describing where this key came from */
658             pos=new_key->key_origin;
659             pos+=MIN(KRB_MAX_ORIG_LEN,
660                      g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
661             for(i=0;i<key.principal->name.name_string.len;i++){
662                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
663                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
664             }
665             pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
666                      g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
667             *pos=0;
668             new_key->keytype=key.keyblock.keytype;
669             new_key->keylength=key.keyblock.keyvalue.length;
670             new_key->keyvalue=(char*)g_memdup(key.keyblock.keyvalue.data, key.keyblock.keyvalue.length);
671             enc_key_list=new_key;
672         }
673     }while(ret==0);
674
675     ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
676     if(ret){
677         krb5_kt_close(krb5_ctx, keytab);
678     }
679
680 }
681
682
683 guint8 *
684 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
685                   int usage,
686                   tvbuff_t *cryptotvb,
687                   int keytype,
688                   int *datalen)
689 {
690     krb5_error_code ret;
691     krb5_data data;
692     enc_key_t *ek;
693     int length = tvb_length(cryptotvb);
694     const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
695
696     /* don't do anything if we are not attempting to decrypt data */
697     if(!krb_decrypt){
698         return NULL;
699     }
700
701     /* make sure we have all the data we need */
702     if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
703         return NULL;
704     }
705
706     read_keytab_file_from_preferences();
707
708     for(ek=enc_key_list;ek;ek=ek->next){
709         krb5_keytab_entry key;
710         krb5_crypto crypto;
711         guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
712
713         /* shortcircuit and bail out if enctypes are not matching */
714         if((keytype != -1) && (ek->keytype != keytype)) {
715             continue;
716         }
717
718         key.keyblock.keytype=ek->keytype;
719         key.keyblock.keyvalue.length=ek->keylength;
720         key.keyblock.keyvalue.data=ek->keyvalue;
721         ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)0, &crypto);
722         if(ret){
723             return NULL;
724         }
725
726         /* pre-0.6.1 versions of Heimdal would sometimes change
727            the cryptotext data even when the decryption failed.
728            This would obviously not work since we iterate over the
729            keys. So just give it a copy of the crypto data instead.
730            This has been seen for RC4-HMAC blobs.
731         */
732         cryptocopy=(guint8*)g_memdup(cryptotext, length);
733         ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
734                                 cryptocopy, length,
735                                 &data,
736                                 NULL);
737         g_free(cryptocopy);
738         if((ret == 0) && (length>0)){
739             char *user_data;
740
741 printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
742             proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
743             krb5_crypto_destroy(krb5_ctx, crypto);
744             /* return a private g_malloced blob to the caller */
745             user_data=(char*)g_memdup(data.data, data.length);
746             if (datalen) {
747                 *datalen = data.length;
748             }
749             return user_data;
750         }
751         krb5_crypto_destroy(krb5_ctx, crypto);
752     }
753     return NULL;
754 }
755
756 #elif defined (HAVE_LIBNETTLE)
757
758 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
759 #define KEYTYPE_DES3_CBC_MD5 5  /* Currently the only one supported */
760
761 typedef struct _service_key_t {
762     guint16 kvno;
763     int     keytype;
764     int     length;
765     guint8 *contents;
766     char    origin[KRB_MAX_ORIG_LEN+1];
767 } service_key_t;
768 GSList *service_key_list = NULL;
769
770
771 static void
772 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
773 {
774     service_key_t *new_key;
775
776     if(pinfo->fd->flags.visited){
777         return;
778     }
779 printf("added key in %u\n",pinfo->fd->num);
780
781     new_key = g_malloc(sizeof(service_key_t));
782     new_key->kvno = 0;
783     new_key->keytype = keytype;
784     new_key->length = keylength;
785     new_key->contents = g_memdup(keyvalue, keylength);
786     g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->fd->num);
787     service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
788 }
789
790 static void
791 clear_keytab(void) {
792     GSList *ske;
793     service_key_t *sk;
794
795     for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
796         sk = (service_key_t *) ske->data;
797         if (sk) {
798             g_free(sk->contents);
799             g_free(sk);
800         }
801     }
802     g_slist_free(service_key_list);
803     service_key_list = NULL;
804 }
805
806 static void
807 read_keytab_file(const char *service_key_file)
808 {
809     FILE *skf;
810     ws_statb64 st;
811     service_key_t *sk;
812     unsigned char buf[SERVICE_KEY_SIZE];
813     int newline_skip = 0, count = 0;
814
815     if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
816
817         /* The service key file contains raw 192-bit (24 byte) 3DES keys.
818          * There can be zero, one (\n), or two (\r\n) characters between
819          * keys.  Trailing characters are ignored.
820          */
821
822         /* XXX We should support the standard keytab format instead */
823         if (st.st_size > SERVICE_KEY_SIZE) {
824             if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
825                  (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
826                 newline_skip = 1;
827             } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
828                         (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
829                 newline_skip = 2;
830             }
831         }
832
833         skf = ws_fopen(service_key_file, "rb");
834         if (! skf) return;
835
836         while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
837             sk = g_malloc(sizeof(service_key_t));
838             sk->kvno = buf[0] << 8 | buf[1];
839             sk->keytype = KEYTYPE_DES3_CBC_MD5;
840             sk->length = DES3_KEY_SIZE;
841             sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
842             g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
843             service_key_list = g_slist_append(service_key_list, (gpointer) sk);
844             fseek(skf, newline_skip, SEEK_CUR);
845             count++;
846 g_warning("added key: %s", sk->origin);
847         }
848         fclose(skf);
849     }
850 }
851
852 #define CONFOUNDER_PLUS_CHECKSUM 24
853
854 guint8 *
855 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
856                   int _U_ usage,
857                   tvbuff_t *cryptotvb,
858                   int keytype,
859                   int *datalen)
860 {
861     tvbuff_t *encr_tvb;
862     guint8 *decrypted_data = NULL, *plaintext = NULL;
863     guint8 cls;
864     gboolean pc;
865     guint32 tag, item_len, data_len;
866     int id_offset, offset;
867     guint8 key[DES3_KEY_SIZE];
868     guint8 initial_vector[DES_BLOCK_SIZE];
869     md5_state_t md5s;
870     md5_byte_t digest[16];
871     md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
872     md5_byte_t confounder[8];
873     gboolean ind;
874     GSList *ske;
875     service_key_t *sk;
876     struct des3_ctx ctx;
877     int length = tvb_length(cryptotvb);
878     const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
879
880
881     /* don't do anything if we are not attempting to decrypt data */
882     if(!krb_decrypt){
883         return NULL;
884     }
885
886     /* make sure we have all the data we need */
887     if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
888         return NULL;
889     }
890
891     if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
892         return NULL;
893     }
894
895     decrypted_data = g_malloc(length);
896     for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
897         gboolean do_continue = FALSE;
898         sk = (service_key_t *) ske->data;
899
900         des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
901
902         md5_init(&md5s);
903         memset(initial_vector, 0, DES_BLOCK_SIZE);
904         des3_set_key(&ctx, key);
905         cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
906                     length, decrypted_data, cryptotext);
907         encr_tvb = tvb_new_real_data(decrypted_data, length, length);
908
909         tvb_memcpy(encr_tvb, confounder, 0, 8);
910
911         /* We have to pull the decrypted data length from the decrypted
912          * content.  If the key doesn't match or we otherwise get garbage,
913          * an exception may get thrown while decoding the ASN.1 header.
914          * Catch it, just in case.
915          */
916         TRY {
917             id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
918             offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
919         }
920         CATCH_BOUNDS_ERRORS {
921             tvb_free(encr_tvb);
922             do_continue = TRUE;
923         }
924         ENDTRY;
925
926         if (do_continue) continue;
927
928         data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
929         if ((int) item_len + offset > length) {
930             tvb_free(encr_tvb);
931             continue;
932         }
933
934         md5_append(&md5s, confounder, 8);
935         md5_append(&md5s, zero_fill, 16);
936         md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
937         md5_finish(&md5s, digest);
938
939         if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) {
940 g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
941             plaintext = g_malloc(data_len);
942             tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
943             tvb_free(encr_tvb);
944
945             if (datalen) {
946                 *datalen = data_len;
947             }
948             g_free(decrypted_data);
949             return(plaintext);
950         }
951         tvb_free(encr_tvb);
952     }
953
954     g_free(decrypted_data);
955     return NULL;
956 }
957
958
959 #endif  /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
960
961 #define INET6_ADDRLEN   16
962
963 /* TCP Record Mark */
964 #define KRB_RM_RESERVED 0x80000000U
965 #define KRB_RM_RECLEN   0x7fffffffU
966
967 #define KRB5_MSG_TICKET                  1      /* Ticket */
968 #define KRB5_MSG_AUTHENTICATOR           2      /* Authenticator */
969 #define KRB5_MSG_ENC_TICKET_PART         3      /* EncTicketPart */
970 #define KRB5_MSG_AS_REQ                 10      /* AS-REQ type */
971 #define KRB5_MSG_AS_REP                 11      /* AS-REP type */
972 #define KRB5_MSG_TGS_REQ                12      /* TGS-REQ type */
973 #define KRB5_MSG_TGS_REP                13      /* TGS-REP type */
974 #define KRB5_MSG_AP_REQ                 14      /* AP-REQ type */
975 #define KRB5_MSG_AP_REP                 15      /* AP-REP type */
976
977 #define KRB5_MSG_SAFE                   20      /* KRB-SAFE type */
978 #define KRB5_MSG_PRIV                   21      /* KRB-PRIV type */
979 #define KRB5_MSG_CRED                   22      /* KRB-CRED type */
980 #define KRB5_MSG_ENC_AS_REP_PART        25      /* EncASRepPart */
981 #define KRB5_MSG_ENC_TGS_REP_PART       26      /* EncTGSRepPart */
982 #define KRB5_MSG_ENC_AP_REP_PART        27      /* EncAPRepPart */
983 #define KRB5_MSG_ENC_KRB_PRIV_PART      28      /* EncKrbPrivPart */
984 #define KRB5_MSG_ENC_KRB_CRED_PART      29      /* EncKrbCredPart */
985 #define KRB5_MSG_ERROR                  30      /* KRB-ERROR type */
986
987 /* address type constants */
988 #define KRB5_ADDR_IPv4       0x02
989 #define KRB5_ADDR_CHAOS      0x05
990 #define KRB5_ADDR_XEROX      0x06
991 #define KRB5_ADDR_ISO        0x07
992 #define KRB5_ADDR_DECNET     0x0c
993 #define KRB5_ADDR_APPLETALK  0x10
994 #define KRB5_ADDR_NETBIOS    0x14
995 #define KRB5_ADDR_IPv6       0x18
996
997 /* encryption type constants */
998 #define KRB5_ENCTYPE_NULL                          0
999 #define KRB5_ENCTYPE_DES_CBC_CRC                   1
1000 #define KRB5_ENCTYPE_DES_CBC_MD4                   2
1001 #define KRB5_ENCTYPE_DES_CBC_MD5                   3
1002 #define KRB5_ENCTYPE_DES_CBC_RAW                   4
1003 #define KRB5_ENCTYPE_DES3_CBC_SHA                  5
1004 #define KRB5_ENCTYPE_DES3_CBC_RAW                  6
1005 #define KRB5_ENCTYPE_DES_HMAC_SHA1                 8
1006 #define KRB5_ENCTYPE_DSA_SHA1_CMS                  9
1007 #define KRB5_ENCTYPE_RSA_MD5_CMS                  10
1008 #define KRB5_ENCTYPE_RSA_SHA1_CMS                 11
1009 #define KRB5_ENCTYPE_RC2_CBC_ENV                  12
1010 #define KRB5_ENCTYPE_RSA_ENV                      13
1011 #define KRB5_ENCTYPE_RSA_ES_OEAP_ENV              14
1012 #define KRB5_ENCTYPE_DES_EDE3_CBC_ENV             15
1013 #define KRB5_ENCTYPE_DES3_CBC_SHA1                16
1014 #define KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96      17
1015 #define KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96      18
1016 #define KRB5_ENCTYPE_DES_CBC_MD5_NT               20
1017 #define KERB_ENCTYPE_RC4_HMAC                     23
1018 #define KERB_ENCTYPE_RC4_HMAC_EXP                 24
1019 #define KRB5_ENCTYPE_UNKNOWN                   0x1ff
1020 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1     0x7007
1021 #define KRB5_ENCTYPE_RC4_PLAIN_EXP        0xffffff73
1022 #define KRB5_ENCTYPE_RC4_PLAIN            0xffffff74
1023 #define KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP    0xffffff78
1024 #define KRB5_ENCTYPE_RC4_HMAC_OLD_EXP     0xffffff79
1025 #define KRB5_ENCTYPE_RC4_PLAIN_OLD        0xffffff7a
1026 #define KRB5_ENCTYPE_RC4_HMAC_OLD         0xffffff7b
1027 #define KRB5_ENCTYPE_DES_PLAIN            0xffffff7c
1028 #define KRB5_ENCTYPE_RC4_SHA              0xffffff7d
1029 #define KRB5_ENCTYPE_RC4_LM               0xffffff7e
1030 #define KRB5_ENCTYPE_RC4_PLAIN2           0xffffff7f
1031 #define KRB5_ENCTYPE_RC4_MD4              0xffffff80
1032
1033 /* checksum types */
1034 #define KRB5_CHKSUM_NONE                         0
1035 #define KRB5_CHKSUM_CRC32                        1
1036 #define KRB5_CHKSUM_MD4                          2
1037 #define KRB5_CHKSUM_KRB_DES_MAC                  4
1038 #define KRB5_CHKSUM_KRB_DES_MAC_K                5
1039 #define KRB5_CHKSUM_MD5                          7
1040 #define KRB5_CHKSUM_MD5_DES                      8
1041 /* the following four come from packetcable */
1042 #define KRB5_CHKSUM_MD5_DES3                     9
1043 #define KRB5_CHKSUM_HMAC_SHA1_DES3_KD           12
1044 #define KRB5_CHKSUM_HMAC_SHA1_DES3              13
1045 #define KRB5_CHKSUM_SHA1_UNKEYED                14
1046 #define KRB5_CHKSUM_HMAC_MD5            0xffffff76
1047 #define KRB5_CHKSUM_MD5_HMAC            0xffffff77
1048 #define KRB5_CHKSUM_RC4_MD5             0xffffff78
1049 #define KRB5_CHKSUM_MD25                0xffffff79
1050 #define KRB5_CHKSUM_DES_MAC_MD5         0xffffff7a
1051 #define KRB5_CHKSUM_DES_MAC             0xffffff7b
1052 #define KRB5_CHKSUM_REAL_CRC32          0xffffff7c
1053 #define KRB5_CHKSUM_SHA1                0xffffff7d
1054 #define KRB5_CHKSUM_LM                  0xffffff7e
1055 #define KRB5_CHKSUM_GSSAPI                  0x8003
1056
1057 /*
1058  * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
1059  *
1060  *      http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
1061  *
1062  * unless it's expired.
1063  */
1064
1065 /* pre-authentication type constants */
1066 #define KRB5_PA_TGS_REQ                   1
1067 #define KRB5_PA_ENC_TIMESTAMP             2
1068 #define KRB5_PA_PW_SALT                   3
1069 #define KRB5_PA_ENC_ENCKEY                4
1070 #define KRB5_PA_ENC_UNIX_TIME             5
1071 #define KRB5_PA_ENC_SANDIA_SECURID        6
1072 #define KRB5_PA_SESAME                    7
1073 #define KRB5_PA_OSF_DCE                   8
1074 #define KRB5_PA_CYBERSAFE_SECUREID        9
1075 #define KRB5_PA_AFS3_SALT                10
1076 #define KRB5_PA_ENCTYPE_INFO             11
1077 #define KRB5_PA_SAM_CHALLENGE            12
1078 #define KRB5_PA_SAM_RESPONSE             13
1079 #define KRB5_PA_PK_AS_REQ                14
1080 #define KRB5_PA_PK_AS_REP                15
1081 #define KRB5_PA_DASS                     16
1082 #define KRB5_PA_ENCTYPE_INFO2            19
1083 #define KRB5_PA_USE_SPECIFIED_KVNO       20
1084 #define KRB5_PA_SAM_REDIRECT             21
1085 #define KRB5_PA_GET_FROM_TYPED_DATA      22
1086 #define KRB5_PA_SAM_ETYPE_INFO           23
1087 #define KRB5_PA_ALT_PRINC                24
1088 #define KRB5_PA_SAM_CHALLENGE2           30
1089 #define KRB5_PA_SAM_RESPONSE2            31
1090 #define KRB5_TD_PKINIT_CMS_CERTIFICATES 101
1091 #define KRB5_TD_KRB_PRINCIPAL           102
1092 #define KRB5_TD_KRB_REALM               103
1093 #define KRB5_TD_TRUSTED_CERTIFIERS      104
1094 #define KRB5_TD_CERTIFICATE_INDEX       105
1095 #define KRB5_TD_APP_DEFINED_ERROR       106
1096 #define KRB5_TD_REQ_NONCE               107
1097 #define KRB5_TD_REQ_SEQ                 108
1098
1099 /* preauthentication types >127 (i.e. negative ones) are app specific.
1100    however since Microsoft is the dominant(only?) user of types in this range
1101    we also treat the type as unsigned.
1102 */
1103 #define KRB5_PA_PAC_REQUEST              128    /* (Microsoft extension) */
1104 #define KRB5_PA_FOR_USER                 129    /* Impersonation (Microsoft extension) See [MS-SFU] */
1105
1106 #define KRB5_PA_PROV_SRV_LOCATION 0xffffffff    /* (gint32)0xFF) packetcable stuff */
1107
1108 /* Principal name-type */
1109 #define KRB5_NT_UNKNOWN        0
1110 #define KRB5_NT_PRINCIPAL      1
1111 #define KRB5_NT_SRV_INST       2
1112 #define KRB5_NT_SRV_HST        3
1113 #define KRB5_NT_SRV_XHST       4
1114 #define KRB5_NT_UID            5
1115 #define KRB5_NT_X500_PRINCIPAL 6
1116 #define KRB5_NT_SMTP_NAME      7
1117 #define KRB5_NT_ENTERPRISE    10
1118
1119 /*
1120  * MS specific name types, from
1121  *
1122  *      http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
1123  */
1124 #define KRB5_NT_MS_PRINCIPAL            -128
1125 #define KRB5_NT_MS_PRINCIPAL_AND_SID    -129
1126 #define KRB5_NT_ENT_PRINCIPAL_AND_SID   -130
1127 #define KRB5_NT_PRINCIPAL_AND_SID       -131
1128 #define KRB5_NT_SRV_INST_AND_SID        -132
1129
1130 /* error table constants */
1131 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
1132 #define KRB5_ET_KRB5KDC_ERR_NONE                          0
1133 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP                      1
1134 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP                   2
1135 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO                      3
1136 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO               4
1137 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO               5
1138 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN           6
1139 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN           7
1140 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE          8
1141 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY                      9
1142 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE              10
1143 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID                  11
1144 #define KRB5_ET_KRB5KDC_ERR_POLICY                       12
1145 #define KRB5_ET_KRB5KDC_ERR_BADOPTION                    13
1146 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP                 14
1147 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP               15
1148 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP           16
1149 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP                17
1150 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED               18
1151 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED              19
1152 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED                  20
1153 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET                21
1154 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET               22
1155 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP                      23
1156 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED               24
1157 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED             25
1158 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH               26
1159 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER           27
1160 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED            28
1161 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE              29
1162 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY             31
1163 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED               32
1164 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV                   33
1165 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT                    34
1166 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US                    35
1167 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH                  36
1168 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW                      37
1169 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR                   38
1170 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION                39
1171 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE                  40
1172 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED                  41
1173 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER                  42
1174 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT                43
1175 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER                 44
1176 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY                     45
1177 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL                  46
1178 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION              47
1179 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD                    48
1180 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ                    49
1181 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM               50
1182 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED             51
1183 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG             52
1184 #define KRB5_ET_KRB5KRB_ERR_GENERIC                      60
1185 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG                61
1186 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED             62
1187 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED                63
1188 #define KRB5_ET_KDC_ERROR_INVALID_SIG                    64
1189 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK                     65
1190 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH             66
1191 #define KRB5_ET_KRB_AP_ERR_NO_TGT                        67
1192 #define KRB5_ET_KDC_ERR_WRONG_REALM                      68
1193 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED         69
1194 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE          70
1195 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE              71
1196 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE              72
1197 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN        73
1198 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE    74
1199 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH             75
1200 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH                76
1201
1202 static const value_string krb5_error_codes[] = {
1203     { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
1204     { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
1205     { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
1206     { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
1207     { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
1208     { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
1209     { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
1210     { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
1211     { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
1212     { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
1213     { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
1214     { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
1215     { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
1216     { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
1217     { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
1218     { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
1219     { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
1220     { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
1221     { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
1222     { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
1223     { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
1224     { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
1225     { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
1226     { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
1227     { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
1228     { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
1229     { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1230     { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1231     { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1232     { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1233     { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1234     { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1235     { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1236     { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1237     { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1238     { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1239     { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1240     { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1241     { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1242     { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1243     { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1244     { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1245     { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1246     { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1247     { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1248     { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1249     { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1250     { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1251     { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1252     { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1253     { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1254     { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1255     { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1256     { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1257     { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1258     { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1259     { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1260     { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1261     { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1262     { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1263     { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1264     { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1265     { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1266     { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1267     { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1268     { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1269     { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1270     { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1271     { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1272     { 0, NULL }
1273 };
1274
1275
1276 #define PAC_LOGON_INFO              1
1277 #define PAC_CREDENTIAL_TYPE         2
1278 #define PAC_SERVER_CHECKSUM         6
1279 #define PAC_PRIVSVR_CHECKSUM        7
1280 #define PAC_CLIENT_INFO_TYPE       10
1281 #define PAC_S4U_DELEGATION_INFO    11
1282 #define PAC_UPN_DNS_INFO           12
1283
1284 static const value_string w2k_pac_types[] = {
1285     { PAC_LOGON_INFO            , "Logon Info" },
1286     { PAC_CREDENTIAL_TYPE       , "Credential Type" },
1287     { PAC_SERVER_CHECKSUM       , "Server Checksum" },
1288     { PAC_PRIVSVR_CHECKSUM      , "Privsvr Checksum" },
1289     { PAC_CLIENT_INFO_TYPE      , "Client Info Type" },
1290     { PAC_S4U_DELEGATION_INFO   , "S4U Delegation Info" },
1291     { PAC_UPN_DNS_INFO          , "UPN DNS Info" },
1292     { 0, NULL },
1293 };
1294
1295
1296
1297 static const value_string krb5_princ_types[] = {
1298     { KRB5_NT_UNKNOWN              , "Unknown" },
1299     { KRB5_NT_PRINCIPAL            , "Principal" },
1300     { KRB5_NT_SRV_INST             , "Service and Instance" },
1301     { KRB5_NT_SRV_HST              , "Service and Host" },
1302     { KRB5_NT_SRV_XHST             , "Service and Host Components" },
1303     { KRB5_NT_UID                  , "Unique ID" },
1304     { KRB5_NT_X500_PRINCIPAL       , "Encoded X.509 Distinguished Name" },
1305     { KRB5_NT_SMTP_NAME            , "SMTP Name" },
1306     { KRB5_NT_ENTERPRISE           , "Enterprise Name" },
1307     { KRB5_NT_MS_PRINCIPAL         , "NT 4.0 style name (MS specific)" },
1308     { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
1309     { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
1310     { KRB5_NT_PRINCIPAL_AND_SID    , "Principal name and SID (MS specific)"},
1311     { KRB5_NT_SRV_INST_AND_SID     , "SPN and SID (MS specific)"},
1312     { 0                            , NULL },
1313 };
1314
1315 static const value_string krb5_preauthentication_types[] = {
1316     { KRB5_PA_TGS_REQ              , "PA-TGS-REQ" },
1317     { KRB5_PA_ENC_TIMESTAMP        , "PA-ENC-TIMESTAMP" },
1318     { KRB5_PA_PW_SALT              , "PA-PW-SALT" },
1319     { KRB5_PA_ENC_ENCKEY           , "PA-ENC-ENCKEY" },
1320     { KRB5_PA_ENC_UNIX_TIME        , "PA-ENC-UNIX-TIME" },
1321     { KRB5_PA_ENC_SANDIA_SECURID   , "PA-PW-SALT" },
1322     { KRB5_PA_SESAME               , "PA-SESAME" },
1323     { KRB5_PA_OSF_DCE              , "PA-OSF-DCE" },
1324     { KRB5_PA_CYBERSAFE_SECUREID   , "PA-CYBERSAFE-SECURID" },
1325     { KRB5_PA_AFS3_SALT            , "PA-AFS3-SALT" },
1326     { KRB5_PA_ENCTYPE_INFO         , "PA-ENCTYPE-INFO" },
1327     { KRB5_PA_ENCTYPE_INFO2         , "PA-ENCTYPE-INFO2" },
1328     { KRB5_PA_SAM_CHALLENGE        , "PA-SAM-CHALLENGE" },
1329     { KRB5_PA_SAM_RESPONSE         , "PA-SAM-RESPONSE" },
1330     { KRB5_PA_PK_AS_REQ            , "PA-PK-AS-REQ" },
1331     { KRB5_PA_PK_AS_REP            , "PA-PK-AS-REP" },
1332     { KRB5_PA_DASS                 , "PA-DASS" },
1333     { KRB5_PA_USE_SPECIFIED_KVNO   , "PA-USE-SPECIFIED-KVNO" },
1334     { KRB5_PA_SAM_REDIRECT         , "PA-SAM-REDIRECT" },
1335     { KRB5_PA_GET_FROM_TYPED_DATA  , "PA-GET-FROM-TYPED-DATA" },
1336     { KRB5_PA_SAM_ETYPE_INFO       , "PA-SAM-ETYPE-INFO" },
1337     { KRB5_PA_ALT_PRINC            , "PA-ALT-PRINC" },
1338     { KRB5_PA_SAM_CHALLENGE2       , "PA-SAM-CHALLENGE2" },
1339     { KRB5_PA_SAM_RESPONSE2        , "PA-SAM-RESPONSE2" },
1340     { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
1341     { KRB5_TD_KRB_PRINCIPAL        , "TD-KRB-PRINCIPAL" },
1342     { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
1343     { KRB5_TD_TRUSTED_CERTIFIERS   , "TD-TRUSTED-CERTIFIERS" },
1344     { KRB5_TD_CERTIFICATE_INDEX    , "TD-CERTIFICATE-INDEX" },
1345     { KRB5_TD_APP_DEFINED_ERROR    , "TD-APP-DEFINED-ERROR" },
1346     { KRB5_TD_REQ_NONCE            , "TD-REQ-NONCE" },
1347     { KRB5_TD_REQ_SEQ              , "TD-REQ-SEQ" },
1348     { KRB5_PA_PAC_REQUEST          , "PA-PAC-REQUEST" },
1349     { KRB5_PA_FOR_USER             , "PA-FOR-USER" },
1350     { KRB5_PA_PROV_SRV_LOCATION    , "PA-PROV-SRV-LOCATION" },
1351     { 0                            , NULL },
1352 };
1353
1354 static const value_string krb5_encryption_types[] = {
1355     { KRB5_ENCTYPE_NULL           , "NULL" },
1356     { KRB5_ENCTYPE_DES_CBC_CRC    , "des-cbc-crc" },
1357     { KRB5_ENCTYPE_DES_CBC_MD4    , "des-cbc-md4" },
1358     { KRB5_ENCTYPE_DES_CBC_MD5    , "des-cbc-md5" },
1359     { KRB5_ENCTYPE_DES_CBC_RAW    , "des-cbc-raw" },
1360     { KRB5_ENCTYPE_DES3_CBC_SHA   , "des3-cbc-sha" },
1361     { KRB5_ENCTYPE_DES3_CBC_RAW   , "des3-cbc-raw" },
1362     { KRB5_ENCTYPE_DES_HMAC_SHA1  , "des-hmac-sha1" },
1363     { KRB5_ENCTYPE_DSA_SHA1_CMS   , "dsa-sha1-cms" },
1364     { KRB5_ENCTYPE_RSA_MD5_CMS    , "rsa-md5-cms" },
1365     { KRB5_ENCTYPE_RSA_SHA1_CMS   , "rsa-sha1-cms" },
1366     { KRB5_ENCTYPE_RC2_CBC_ENV    , "rc2-cbc-env" },
1367     { KRB5_ENCTYPE_RSA_ENV        , "rsa-env" },
1368     { KRB5_ENCTYPE_RSA_ES_OEAP_ENV, "rsa-es-oeap-env" },
1369     { KRB5_ENCTYPE_DES_EDE3_CBC_ENV, "des-ede3-cbc-env" },
1370     { KRB5_ENCTYPE_DES3_CBC_SHA1  , "des3-cbc-sha1" },
1371     { KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96  , "aes128-cts-hmac-sha1-96" },
1372     { KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96  , "aes256-cts-hmac-sha1-96" },
1373     { KRB5_ENCTYPE_DES_CBC_MD5_NT  , "des-cbc-md5-nt" },
1374     { KERB_ENCTYPE_RC4_HMAC       , "rc4-hmac" },
1375     { KERB_ENCTYPE_RC4_HMAC_EXP   , "rc4-hmac-exp" },
1376     { KRB5_ENCTYPE_UNKNOWN        , "unknown" },
1377     { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1    , "local-des3-hmac-sha1" },
1378     { KRB5_ENCTYPE_RC4_PLAIN_EXP  , "rc4-plain-exp" },
1379     { KRB5_ENCTYPE_RC4_PLAIN      , "rc4-plain" },
1380     { KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP, "rc4-plain-old-exp" },
1381     { KRB5_ENCTYPE_RC4_HMAC_OLD_EXP, "rc4-hmac-old-exp" },
1382     { KRB5_ENCTYPE_RC4_PLAIN_OLD  , "rc4-plain-old" },
1383     { KRB5_ENCTYPE_RC4_HMAC_OLD   , "rc4-hmac-old" },
1384     { KRB5_ENCTYPE_DES_PLAIN      , "des-plain" },
1385     { KRB5_ENCTYPE_RC4_SHA        , "rc4-sha" },
1386     { KRB5_ENCTYPE_RC4_LM         , "rc4-lm" },
1387     { KRB5_ENCTYPE_RC4_PLAIN2     , "rc4-plain2" },
1388     { KRB5_ENCTYPE_RC4_MD4        , "rc4-md4" },
1389     { 0                           , NULL },
1390 };
1391
1392 static const value_string krb5_checksum_types[] = {
1393     { KRB5_CHKSUM_NONE            , "none" },
1394     { KRB5_CHKSUM_CRC32           , "crc32" },
1395     { KRB5_CHKSUM_MD4             , "md4" },
1396     { KRB5_CHKSUM_KRB_DES_MAC     , "krb-des-mac" },
1397     { KRB5_CHKSUM_KRB_DES_MAC_K   , "krb-des-mac-k" },
1398     { KRB5_CHKSUM_MD5             , "md5" },
1399     { KRB5_CHKSUM_MD5_DES         , "md5-des" },
1400     { KRB5_CHKSUM_MD5_DES3        , "md5-des3" },
1401     { KRB5_CHKSUM_HMAC_SHA1_DES3_KD, "hmac-sha1-des3-kd" },
1402     { KRB5_CHKSUM_HMAC_SHA1_DES3  , "hmac-sha1-des3" },
1403     { KRB5_CHKSUM_SHA1_UNKEYED    , "sha1 (unkeyed)" },
1404     { KRB5_CHKSUM_HMAC_MD5        , "hmac-md5" },
1405     { KRB5_CHKSUM_MD5_HMAC        , "md5-hmac" },
1406     { KRB5_CHKSUM_RC4_MD5         , "rc5-md5" },
1407     { KRB5_CHKSUM_MD25            , "md25" },
1408     { KRB5_CHKSUM_DES_MAC_MD5     , "des-mac-md5" },
1409     { KRB5_CHKSUM_DES_MAC         , "des-mac" },
1410     { KRB5_CHKSUM_REAL_CRC32      , "real-crc32" },
1411     { KRB5_CHKSUM_SHA1            , "sha1" },
1412     { KRB5_CHKSUM_LM              , "lm" },
1413     { KRB5_CHKSUM_GSSAPI          , "gssapi-8003" },
1414     { 0                           , NULL },
1415 };
1416
1417 #define KRB5_AD_IF_RELEVANT                              1
1418 #define KRB5_AD_INTENDED_FOR_SERVER                      2
1419 #define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS           3
1420 #define KRB5_AD_KDC_ISSUED                               4
1421 #define KRB5_AD_OR                                       5
1422 #define KRB5_AD_MANDATORY_TICKET_EXTENSIONS              6
1423 #define KRB5_AD_IN_TICKET_EXTENSIONS                     7
1424 #define KRB5_AD_MANDATORY_FOR_KDC                        8
1425 #define KRB5_AD_OSF_DCE                                 64
1426 #define KRB5_AD_SESAME                                  65
1427 #define KRB5_AD_OSF_DCE_PKI_CERTID                      66
1428 #define KRB5_AD_WIN2K_PAC                              128
1429 #define KRB5_AD_SIGNTICKET                      0xffffffef
1430
1431 static const value_string krb5_ad_types[] = {
1432     { KRB5_AD_IF_RELEVANT                       , "AD-IF-RELEVANT" },
1433     { KRB5_AD_INTENDED_FOR_SERVER               , "AD-Intended-For-Server" },
1434     { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS    , "AD-Intended-For-Application-Class" },
1435     { KRB5_AD_KDC_ISSUED                        , "AD-KDCIssued" },
1436     { KRB5_AD_OR                                , "AD-AND-OR" },
1437     { KRB5_AD_MANDATORY_TICKET_EXTENSIONS       , "AD-Mandatory-Ticket-Extensions" },
1438     { KRB5_AD_IN_TICKET_EXTENSIONS              , "AD-IN-Ticket-Extensions" },
1439     { KRB5_AD_MANDATORY_FOR_KDC                 , "AD-MANDATORY-FOR-KDC" },
1440     { KRB5_AD_OSF_DCE                           , "AD-OSF-DCE" },
1441     { KRB5_AD_SESAME                            , "AD-SESAME" },
1442     { KRB5_AD_OSF_DCE_PKI_CERTID                , "AD-OSF-DCE-PKI-CertID" },
1443     { KRB5_AD_WIN2K_PAC                         , "AD-Win2k-PAC" },
1444     { KRB5_AD_SIGNTICKET                        , "AD-SignTicket" },
1445     { 0 , NULL },
1446 };
1447
1448 static const value_string krb5_transited_types[] = {
1449     { 1                           , "DOMAIN-X500-COMPRESS" },
1450     { 0                           , NULL }
1451 };
1452
1453 static const value_string krb5_address_types[] = {
1454     { KRB5_ADDR_IPv4,           "IPv4"},
1455     { KRB5_ADDR_CHAOS,          "CHAOS"},
1456     { KRB5_ADDR_XEROX,          "XEROX"},
1457     { KRB5_ADDR_ISO,            "ISO"},
1458     { KRB5_ADDR_DECNET,         "DECNET"},
1459     { KRB5_ADDR_APPLETALK,      "APPLETALK"},
1460     { KRB5_ADDR_NETBIOS,        "NETBIOS"},
1461     { KRB5_ADDR_IPv6,           "IPv6"},
1462     { 0,                        NULL },
1463 };
1464
1465 static const value_string krb5_msg_types[] = {
1466     { KRB5_MSG_TICKET,            "Ticket" },
1467     { KRB5_MSG_AUTHENTICATOR,     "Authenticator" },
1468     { KRB5_MSG_ENC_TICKET_PART,   "EncTicketPart" },
1469     { KRB5_MSG_TGS_REQ,           "TGS-REQ" },
1470     { KRB5_MSG_TGS_REP,           "TGS-REP" },
1471     { KRB5_MSG_AS_REQ,            "AS-REQ" },
1472     { KRB5_MSG_AS_REP,            "AS-REP" },
1473     { KRB5_MSG_AP_REQ,            "AP-REQ" },
1474     { KRB5_MSG_AP_REP,            "AP-REP" },
1475     { KRB5_MSG_SAFE,              "KRB-SAFE" },
1476     { KRB5_MSG_PRIV,              "KRB-PRIV" },
1477     { KRB5_MSG_CRED,              "KRB-CRED" },
1478     { KRB5_MSG_ENC_AS_REP_PART,   "EncASRepPart" },
1479     { KRB5_MSG_ENC_TGS_REP_PART,  "EncTGSRepPart" },
1480     { KRB5_MSG_ENC_AP_REP_PART,   "EncAPRepPart" },
1481     { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1482     { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1483     { KRB5_MSG_ERROR,             "KRB-ERROR" },
1484     { 0, NULL },
1485 };
1486
1487
1488
1489
1490 static int dissect_krb5_application_choice(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1491 static int dissect_krb5_Application_1(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1492 static int dissect_krb5_Authenticator(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1493 static int dissect_krb5_EncTicketPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1494 static int dissect_krb5_EncAPRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1495 static int dissect_krb5_EncKrbPrivPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1496 static int dissect_krb5_EncKrbCredPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1497 static int dissect_krb5_EncKDCRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1498 static int dissect_krb5_KDC_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1499 static int dissect_krb5_KDC_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1500 static int dissect_krb5_AP_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1501 static int dissect_krb5_AP_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1502 static int dissect_krb5_SAFE(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1503 static int dissect_krb5_PRIV(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1504 static int dissect_krb5_CRED(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1505 static int dissect_krb5_ERROR(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1506
1507 static const ber_old_choice_t kerberos_applications_choice[] = {
1508     { KRB5_MSG_TICKET,  BER_CLASS_APP,  KRB5_MSG_TICKET,        0, dissect_krb5_Application_1 },
1509     { KRB5_MSG_AUTHENTICATOR,   BER_CLASS_APP,  KRB5_MSG_AUTHENTICATOR,   0, dissect_krb5_Authenticator },
1510     { KRB5_MSG_ENC_TICKET_PART, BER_CLASS_APP,  KRB5_MSG_ENC_TICKET_PART, 0, dissect_krb5_EncTicketPart },
1511     { KRB5_MSG_AS_REQ,  BER_CLASS_APP,  KRB5_MSG_AS_REQ,        0,      dissect_krb5_KDC_REQ },
1512     { KRB5_MSG_AS_REP,  BER_CLASS_APP,  KRB5_MSG_AS_REP,        0,      dissect_krb5_KDC_REP },
1513     { KRB5_MSG_TGS_REQ, BER_CLASS_APP,  KRB5_MSG_TGS_REQ,       0,      dissect_krb5_KDC_REQ },
1514     { KRB5_MSG_TGS_REP, BER_CLASS_APP,  KRB5_MSG_TGS_REP,       0,      dissect_krb5_KDC_REP },
1515     { KRB5_MSG_AP_REQ,  BER_CLASS_APP,  KRB5_MSG_AP_REQ,        0,      dissect_krb5_AP_REQ },
1516     { KRB5_MSG_AP_REP,  BER_CLASS_APP,  KRB5_MSG_AP_REP,        0,      dissect_krb5_AP_REP },
1517     { KRB5_MSG_ENC_AS_REP_PART,   BER_CLASS_APP, KRB5_MSG_ENC_AS_REP_PART,   0, dissect_krb5_EncKDCRepPart },
1518     { KRB5_MSG_ENC_TGS_REP_PART,  BER_CLASS_APP, KRB5_MSG_ENC_TGS_REP_PART,  0, dissect_krb5_EncKDCRepPart },
1519     { KRB5_MSG_ENC_AP_REP_PART,   BER_CLASS_APP, KRB5_MSG_ENC_AP_REP_PART,   0, dissect_krb5_EncAPRepPart },
1520     { KRB5_MSG_ENC_KRB_PRIV_PART, BER_CLASS_APP, KRB5_MSG_ENC_KRB_PRIV_PART, 0, dissect_krb5_EncKrbPrivPart },
1521     { KRB5_MSG_ENC_KRB_CRED_PART, BER_CLASS_APP, KRB5_MSG_ENC_KRB_CRED_PART, 0, dissect_krb5_EncKrbCredPart },
1522     { KRB5_MSG_SAFE,    BER_CLASS_APP,  KRB5_MSG_SAFE,          0,      dissect_krb5_SAFE },
1523     { KRB5_MSG_PRIV,    BER_CLASS_APP,  KRB5_MSG_PRIV,          0,      dissect_krb5_PRIV },
1524     { KRB5_MSG_CRED,    BER_CLASS_APP,  KRB5_MSG_CRED,          0,      dissect_krb5_CRED },
1525     { KRB5_MSG_ERROR,   BER_CLASS_APP,  KRB5_MSG_ERROR,         0,      dissect_krb5_ERROR },
1526     { 0, 0, 0, 0, NULL }
1527 };
1528
1529
1530 static int
1531 dissect_krb5_application_choice(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1532 {
1533     offset=dissect_ber_old_choice(actx, tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
1534     return offset;
1535 }
1536
1537 static const true_false_string krb5_apoptions_reserved = {
1538     "RESERVED bit on",
1539     "RESERVED bit off"
1540 };
1541 static const true_false_string krb5_apoptions_use_session_key = {
1542     "USE SESSION KEY to encrypt the ticket",
1543     "Do NOT use the session key to encrypt the ticket"
1544 };
1545 static const true_false_string krb5_apoptions_mutual_required = {
1546     "MUTUAL authentication is REQUIRED",
1547     "Mutual authentication is NOT required"
1548 };
1549
1550 static int *APOptions_bits[] = {
1551     &hf_krb_APOptions_reserved,
1552     &hf_krb_APOptions_use_session_key,
1553     &hf_krb_APOptions_mutual_required,
1554     NULL
1555 };
1556 static int
1557 dissect_krb5_APOptions(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1558 {
1559     offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, APOptions_bits, hf_krb_APOptions, ett_krb_AP_Options, NULL);
1560     return offset;
1561 }
1562
1563
1564
1565 static const true_false_string krb5_kdcoptions_forwardable = {
1566     "FORWARDABLE tickets are allowed/requested",
1567     "Do NOT use forwardable tickets"
1568 };
1569 static const true_false_string krb5_kdcoptions_forwarded = {
1570     "This ticket has been FORWARDED",
1571     "This is NOT a forwarded ticket"
1572 };
1573 static const true_false_string krb5_kdcoptions_proxiable = {
1574     "PROXIABLE tickets are allowed/requested",
1575     "Do NOT use proxiable tickets"
1576 };
1577 static const true_false_string krb5_kdcoptions_proxy = {
1578     "This is a PROXY ticket",
1579     "This ticket has NOT been proxied"
1580 };
1581 static const true_false_string krb5_kdcoptions_allow_postdate = {
1582     "We allow the ticket to be POSTDATED",
1583     "We do NOT allow the ticket to be postdated"
1584 };
1585 static const true_false_string krb5_kdcoptions_postdated = {
1586     "This ticket is POSTDATED",
1587     "This ticket is NOT postdated"
1588 };
1589 static const true_false_string krb5_kdcoptions_renewable = {
1590     "This ticket is RENEWABLE",
1591     "This ticket is NOT renewable"
1592 };
1593 static const true_false_string krb5_kdcoptions_constrained_delegation = {
1594     "This is a request for a CONSTRAINED DELEGATION PAC",
1595     "This is a normal request (no constrained delegation)"
1596 };
1597 static const true_false_string krb5_kdcoptions_canonicalize = {
1598     "This is a request for a CANONICALIZED ticket",
1599     "This is NOT a canonicalized ticket request"
1600 };
1601 static const true_false_string krb5_kdcoptions_disable_transited_check = {
1602     "Transited checking is DISABLED",
1603     "Transited checking is NOT disabled"
1604 };
1605 static const true_false_string krb5_kdcoptions_renewable_ok = {
1606     "We accept RENEWED tickets",
1607     "We do NOT accept renewed tickets"
1608 };
1609 static const true_false_string krb5_kdcoptions_enc_tkt_in_skey = {
1610     "ENCrypt TKT in SKEY",
1611     "Do NOT encrypt the tkt using the skey"
1612 };
1613 static const true_false_string krb5_kdcoptions_renew = {
1614     "This is a request to RENEW a ticket",
1615     "This is NOT a request to renew a ticket"
1616 };
1617 static const true_false_string krb5_kdcoptions_validate = {
1618     "This is a request to VALIDATE a postdated ticket",
1619     "This is NOT a request to validate a postdated ticket"
1620 };
1621
1622 static int* KDCOptions_bits[] = {
1623     &hf_krb_KDCOptions_forwardable,
1624     &hf_krb_KDCOptions_forwarded,
1625     &hf_krb_KDCOptions_proxiable,
1626     &hf_krb_KDCOptions_proxy,
1627     &hf_krb_KDCOptions_allow_postdate,
1628     &hf_krb_KDCOptions_postdated,
1629     &hf_krb_KDCOptions_renewable,
1630     &hf_krb_KDCOptions_opt_hardware_auth,
1631     &hf_krb_KDCOptions_constrained_delegation,
1632     &hf_krb_KDCOptions_canonicalize,
1633     &hf_krb_KDCOptions_disable_transited_check,
1634     &hf_krb_KDCOptions_renewable_ok,
1635     &hf_krb_KDCOptions_enc_tkt_in_skey,
1636     &hf_krb_KDCOptions_renew,
1637     &hf_krb_KDCOptions_validate,
1638     NULL
1639 };
1640
1641 static int
1642 dissect_krb5_KDCOptions(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1643 {
1644     offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, KDCOptions_bits, hf_krb_KDCOptions, ett_krb_KDC_Options, NULL);
1645     return offset;
1646 }
1647
1648 static int
1649 dissect_krb5_rtime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1650 {
1651     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_rtime);
1652     return offset;
1653 }
1654
1655 int
1656 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1657 {
1658     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_ctime);
1659     return offset;
1660 }
1661 static int
1662 dissect_krb5_cusec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1663 {
1664     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_cusec, NULL);
1665     return offset;
1666 }
1667
1668 static int
1669 dissect_krb5_stime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1670 {
1671     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_stime);
1672     return offset;
1673 }
1674 static int
1675 dissect_krb5_susec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1676 {
1677     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_susec, NULL);
1678     return offset;
1679 }
1680
1681
1682 static int
1683 dissect_krb5_error_code(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1684 {
1685     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_error_code, &krb5_errorcode);
1686     if(krb5_errorcode) {
1687         col_add_fstr(actx->pinfo->cinfo, COL_INFO,
1688                      "KRB Error: %s",
1689                      val_to_str(krb5_errorcode, krb5_error_codes,
1690                                 "Unknown error code %#x"));
1691     }
1692
1693     return offset;
1694 }
1695
1696
1697 static int
1698 dissect_krb5_till(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1699 {
1700     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_till);
1701     return offset;
1702 }
1703 static int
1704 dissect_krb5_from(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1705 {
1706     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_from);
1707     return offset;
1708 }
1709
1710
1711
1712 static int
1713 dissect_krb5_nonce(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1714 {
1715     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_nonce, NULL);
1716     return offset;
1717 }
1718
1719
1720 /*
1721  *          etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
1722  */
1723 static int
1724 dissect_krb5_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1725 {
1726     guint32 etype;
1727
1728     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &etype);
1729     if(tree){
1730         proto_item_append_text(tree, " %s",
1731                                val_to_str(etype, krb5_encryption_types,
1732                                           "%d"));
1733     }
1734     return offset;
1735 }
1736 static ber_old_sequence_t etype_sequence_of[1] = {
1737     { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_krb5_etype },
1738 };
1739 static int
1740 dissect_krb5_etype_sequence_of(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1741 {
1742     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, etype_sequence_of, hf_krb_etypes, ett_krb_etypes);
1743
1744     return offset;
1745 }
1746 static guint32 authenticator_etype;
1747 static int
1748 dissect_krb5_authenticator_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1749 {
1750     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &authenticator_etype);
1751     if(tree){
1752         proto_item_append_text(tree, " %s",
1753                                val_to_str(authenticator_etype, krb5_encryption_types,
1754                                           "%#x"));
1755     }
1756     return offset;
1757 }
1758 static guint32 Ticket_etype;
1759 static int
1760 dissect_krb5_Ticket_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1761 {
1762     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &Ticket_etype);
1763     if(tree){
1764         proto_item_append_text(tree, " %s",
1765                                val_to_str(Ticket_etype, krb5_encryption_types,
1766                                           "%#x"));
1767     }
1768     return offset;
1769 }
1770 static guint32 AP_REP_etype;
1771 static int
1772 dissect_krb5_AP_REP_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1773 {
1774     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &AP_REP_etype);
1775     if(tree){
1776         proto_item_append_text(tree, " %s",
1777                                val_to_str(AP_REP_etype, krb5_encryption_types,
1778                                           "%#x"));
1779     }
1780     return offset;
1781 }
1782 static guint32 PA_ENC_TIMESTAMP_etype;
1783 static int
1784 dissect_krb5_PA_ENC_TIMESTAMP_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1785 {
1786     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &PA_ENC_TIMESTAMP_etype);
1787     if(tree){
1788         proto_item_append_text(tree, " %s",
1789                                val_to_str(PA_ENC_TIMESTAMP_etype, krb5_encryption_types,
1790                                           "%#x"));
1791     }
1792     return offset;
1793 }
1794
1795
1796 /*
1797  *  HostAddress ::=    SEQUENCE  {
1798  *                     addr-type[0]             INTEGER,
1799  *                     address[1]               OCTET STRING
1800  *  }
1801  */
1802 static guint32 addr_type;
1803 static int dissect_krb5_addr_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1804 {
1805     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_addr_type, &addr_type);
1806     return offset;
1807 }
1808
1809 #define ADDRESS_STR_BUFSIZ 256
1810 static int dissect_krb5_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1811 {
1812     gint8 appclass;
1813     gboolean pc;
1814     gint32 tag;
1815     guint32 len;
1816     char *address_str;
1817     proto_item *it=NULL;
1818
1819     /* read header and len for the octet string */
1820     offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &appclass, &pc, &tag);
1821     offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL);
1822
1823     address_str=(char *)wmem_alloc(wmem_packet_scope(), ADDRESS_STR_BUFSIZ);
1824     address_str[0]='\0';
1825     switch(addr_type){
1826     case KRB5_ADDR_IPv4:
1827         it=proto_tree_add_item(tree, hf_krb_address_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1828         g_snprintf(address_str,ADDRESS_STR_BUFSIZ,"%d.%d.%d.%d",tvb_get_guint8(tvb, offset),tvb_get_guint8(tvb, offset+1),tvb_get_guint8(tvb, offset+2),tvb_get_guint8(tvb, offset+3));
1829         break;
1830     case KRB5_ADDR_NETBIOS:
1831     {
1832         char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1833         int netbios_name_type;
1834         int netbios_name_len = (NETBIOS_NAME_LEN - 1)*4 + 1;
1835
1836         netbios_name_type = process_netbios_name(tvb_get_ptr(tvb, offset, 16), netbios_name, netbios_name_len);
1837         g_snprintf(address_str, ADDRESS_STR_BUFSIZ, "%s<%02x>", netbios_name, netbios_name_type);
1838         it=proto_tree_add_string_format(tree, hf_krb_address_netbios, tvb, offset, 16, netbios_name, "NetBIOS Name: %s (%s)", address_str, netbios_name_type_descr(netbios_name_type));
1839     }
1840     break;
1841     case KRB5_ADDR_IPv6:
1842         it=proto_tree_add_item(tree, hf_krb_address_ipv6, tvb, offset, INET6_ADDRLEN, ENC_NA);
1843         g_snprintf(address_str, ADDRESS_STR_BUFSIZ, "%s", tvb_ip6_to_str(tvb, offset));
1844         break;
1845     default:
1846         proto_tree_add_text(tree, tvb, offset, len, "KRB Address: I don't know how to parse this type of address yet");
1847
1848     }
1849
1850     /* push it up two levels in the decode pane */
1851     if(it){
1852         proto_item_append_text(proto_item_get_parent(it), " %s",address_str);
1853         proto_item_append_text(proto_item_get_parent_nth(it, 2), " %s",address_str);
1854     }
1855
1856     offset+=len;
1857     return offset;
1858 }
1859 static ber_old_sequence_t HostAddress_sequence[] = {
1860     { BER_CLASS_CON, 0, 0, dissect_krb5_addr_type },
1861     { BER_CLASS_CON, 1, 0, dissect_krb5_address },
1862     { 0, 0, 0, NULL }
1863 };
1864 static int
1865 dissect_krb5_HostAddress(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1866 {
1867
1868     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_HostAddress, ett_krb_HostAddress);
1869
1870     return offset;
1871 }
1872 static int
1873 dissect_krb5_s_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1874 {
1875
1876     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_s_address, ett_krb_s_address);
1877
1878     return offset;
1879 }
1880
1881 static int
1882 dissect_krb5_r_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1883 {
1884
1885     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_r_address, ett_krb_r_address);
1886
1887     return offset;
1888 }
1889
1890 /*
1891  *  HostAddresses ::=   SEQUENCE OF SEQUENCE {
1892  *                      addr-type[0]             INTEGER,
1893  *                      address[1]               OCTET STRING
1894  *  }
1895  *
1896  */
1897 static ber_old_sequence_t HostAddresses_sequence_of[1] = {
1898     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_HostAddress },
1899 };
1900 static int
1901 dissect_krb5_HostAddresses(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1902 {
1903     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, HostAddresses_sequence_of, hf_krb_HostAddresses, ett_krb_HostAddresses);
1904
1905     return offset;
1906 }
1907
1908
1909 /* sequence of tickets */
1910 static ber_old_sequence_t sequence_of_tickets[1] = {
1911     { BER_CLASS_APP, 1, 0, dissect_krb5_Application_1},
1912 };
1913 static int
1914 dissect_krb5_sq_tickets(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1915 {
1916     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, sequence_of_tickets, hf_krb_sq_tickets, ett_krb_sq_tickets);
1917
1918     return offset;
1919 }
1920
1921 static int
1922 dissect_krb5_msg_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1923 {
1924     guint32 msgtype;
1925
1926     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_msg_type, &msgtype);
1927
1928     if (gbl_do_col_info) {
1929         col_add_str(actx->pinfo->cinfo, COL_INFO,
1930                     val_to_str(msgtype, krb5_msg_types,
1931                                "Unknown msg type %#x"));
1932     }
1933     gbl_do_col_info=FALSE;
1934
1935     /* append the application type to the subtree */
1936     proto_item_append_text(tree, " %s", val_to_str(msgtype, krb5_msg_types, "Unknown:0x%x"));
1937
1938     return offset;
1939 }
1940
1941
1942
1943 static int
1944 dissect_krb5_pvno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1945 {
1946     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_pvno, NULL);
1947
1948     return offset;
1949 }
1950
1951
1952 /*
1953  * PrincipalName ::=   SEQUENCE {
1954  *                     name-type[0]     INTEGER,
1955  *                     name-string[1]   SEQUENCE OF GeneralString
1956  * }
1957  */
1958 static guint32 name_type;
1959 static int
1960 dissect_krb5_name_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1961 {
1962     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_name_type, &name_type);
1963     if(tree){
1964         proto_item_append_text(tree, " (%s):",
1965                                val_to_str(name_type, krb5_princ_types,
1966                                           "Unknown:%d"));
1967     }
1968     return offset;
1969 }
1970 static char name_string_separator;
1971 static int
1972 dissect_krb5_name_string(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1973 {
1974     char name_string[256];
1975
1976     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_name_string, name_string, 255);
1977     if(tree){
1978         proto_item_append_text(tree, "%c%s", name_string_separator, name_string);
1979         name_string_separator='/';
1980     }
1981
1982     return offset;
1983 }
1984 static ber_old_sequence_t name_stringe_sequence_of[1] = {
1985     { BER_CLASS_UNI, BER_UNI_TAG_GeneralString, BER_FLAGS_NOOWNTAG, dissect_krb5_name_string },
1986 };
1987 static int
1988 dissect_krb5_name_strings(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1989 {
1990     name_string_separator=' ';
1991     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, name_stringe_sequence_of, -1, -1);
1992
1993     return offset;
1994 }
1995 static ber_old_sequence_t PrincipalName_sequence[] = {
1996     { BER_CLASS_CON, 0, 0, dissect_krb5_name_type },
1997     { BER_CLASS_CON, 1, 0, dissect_krb5_name_strings },
1998     { 0, 0, 0, NULL }
1999 };
2000 static int
2001 dissect_krb5_sname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2002 {
2003
2004     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PrincipalName_sequence, hf_krb_sname, ett_krb_sname);
2005
2006     return offset;
2007 }
2008 static int
2009 dissect_krb5_pname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2010 {
2011
2012     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PrincipalName_sequence, hf_krb_pname, ett_krb_pname);
2013
2014     return offset;
2015 }
2016 int
2017 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2018 {
2019
2020     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PrincipalName_sequence, hf_krb_cname, ett_krb_cname);
2021
2022     return offset;
2023 }
2024
2025
2026 static int
2027 dissect_krb5_prealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2028 {
2029     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_prealm, NULL, 0);
2030     return offset;
2031 }
2032
2033 static int
2034 dissect_krb5_srealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2035 {
2036     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_srealm, NULL, 0);
2037     return offset;
2038 }
2039
2040 int
2041 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2042 {
2043     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_realm, NULL, 0);
2044     return offset;
2045 }
2046
2047 static int
2048 dissect_krb5_crealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2049 {
2050     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_crealm, NULL, 0);
2051     return offset;
2052 }
2053
2054
2055
2056 static int
2057 dissect_krb5_PA_PAC_REQUEST_flag(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2058 {
2059     offset=dissect_ber_boolean(FALSE, actx, tree, tvb, offset, hf_krb_PA_PAC_REQUEST_flag, NULL);
2060     return offset;
2061 }
2062
2063
2064 static ber_old_sequence_t PA_PAC_REQUEST_sequence[] = {
2065     { BER_CLASS_CON, 0, 0, dissect_krb5_PA_PAC_REQUEST_flag },
2066     { 0, 0, 0, NULL }
2067 };
2068 static int
2069 dissect_krb5_PA_PAC_REQUEST(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2070 {
2071
2072     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_PAC_REQUEST_sequence, -1, -1);
2073
2074     return offset;
2075 }
2076
2077 static int
2078 dissect_krb5_s4u2self_auth(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2079 {
2080     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_s4u2self_auth, NULL, 0);
2081     return offset;
2082 }
2083
2084 static ber_old_sequence_t PA_FOR_USER_sequence[] = {
2085     { BER_CLASS_CON, 0, 0, dissect_krb5_cname },
2086     { BER_CLASS_CON, 1, 0, dissect_krb5_realm },
2087     { BER_CLASS_CON, 2, 0, dissect_krb5_Checksum },
2088     { BER_CLASS_CON, 3, 0, dissect_krb5_s4u2self_auth },
2089     { 0, 0, 0, NULL }
2090 };
2091
2092 static int
2093 dissect_krb5_PA_FOR_USER(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2094 {
2095     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_FOR_USER_sequence, -1, -1);
2096     return offset;
2097 }
2098
2099
2100 static int
2101 dissect_krb5_PA_PROV_SRV_LOCATION(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2102 {
2103     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
2104
2105     return offset;
2106 }
2107
2108
2109
2110 static int
2111 dissect_krb5_kvno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2112 {
2113     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_kvno, NULL);
2114
2115     return offset;
2116 }
2117
2118
2119
2120 static int
2121 dissect_krb5_seq_number(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2122 {
2123     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_seq_number, NULL);
2124
2125     return offset;
2126 }
2127
2128
2129
2130 static int
2131 dissect_krb5_patimestamp(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2132 {
2133     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_patimestamp);
2134     return offset;
2135 }
2136 #ifdef HAVE_KERBEROS
2137 static int
2138 dissect_krb5_pausec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2139 {
2140     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_pausec, NULL);
2141     return offset;
2142 }
2143 static const ber_old_sequence_t PA_ENC_TS_ENC_sequence[] = {
2144     { BER_CLASS_CON, 0, 0, dissect_krb5_patimestamp },
2145     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_pausec },
2146     { 0, 0, 0, NULL }
2147 };
2148 static int
2149 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2150 {
2151     guint8 *plaintext=NULL;
2152     int length;
2153
2154     length=tvb_length_remaining(tvb, offset);
2155
2156     /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
2157      * 7.5.1
2158      * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
2159      * == 1
2160      */
2161     if(!plaintext){
2162         tvbuff_t *next_tvb;
2163
2164         next_tvb=tvb_new_subset_remaining(tvb, offset);
2165         plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, PA_ENC_TIMESTAMP_etype, NULL);
2166     }
2167
2168     if(plaintext){
2169         tvbuff_t *next_tvb;
2170         next_tvb = tvb_new_child_real_data(tvb, plaintext,
2171                                            length,
2172                                            length);
2173         tvb_set_free_cb(next_tvb, g_free);
2174
2175         /* Add the decrypted data to the data source list. */
2176         add_new_data_source(actx->pinfo, next_tvb, "Decrypted Krb5");
2177
2178
2179         offset=dissect_ber_old_sequence(FALSE, actx, tree, next_tvb, 0, PA_ENC_TS_ENC_sequence, -1, -1);
2180
2181     }
2182     return offset;
2183 }
2184 #endif
2185
2186
2187 static int
2188 dissect_krb5_encrypted_PA_ENC_TIMESTAMP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2189 {
2190 #ifdef HAVE_KERBEROS
2191     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, dissect_krb5_decrypt_PA_ENC_TIMESTAMP);
2192 #else
2193     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, NULL);
2194 #endif
2195     return offset;
2196 }
2197 static ber_old_sequence_t PA_ENC_TIMESTAMP_sequence[] = {
2198     { BER_CLASS_CON, 0, 0,
2199       dissect_krb5_PA_ENC_TIMESTAMP_etype },
2200     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2201       dissect_krb5_kvno },
2202     { BER_CLASS_CON, 2, 0,
2203       dissect_krb5_encrypted_PA_ENC_TIMESTAMP },
2204     { 0, 0, 0, NULL }
2205 };
2206 static int
2207 dissect_krb5_PA_ENC_TIMESTAMP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2208 {
2209     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENC_TIMESTAMP_sequence, -1, -1);
2210
2211     return offset;
2212 }
2213
2214
2215
2216 static int
2217 dissect_krb5_etype_info_salt(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2218 {
2219     offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_etype_info_salt, NULL);
2220     return offset;
2221 }
2222
2223 static int
2224 dissect_krb5_etype_info2_salt(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2225 {
2226     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_etype_info2_salt, NULL, 0);
2227     return offset;
2228 }
2229
2230 static int
2231 dissect_krb5_etype_info2_s2kparams(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2232 {
2233     offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_etype_info2_s2kparams, NULL);
2234     return offset;
2235 }
2236
2237 static ber_old_sequence_t PA_ENCTYPE_INFO_ENTRY_sequence[] = {
2238     { BER_CLASS_CON, 0, 0,
2239       dissect_krb5_etype },
2240     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2241       dissect_krb5_etype_info_salt },
2242     { 0, 0, 0, NULL }
2243 };
2244 static int
2245 dissect_krb5_PA_ENCTYPE_INFO_ENTRY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2246 {
2247     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO_ENTRY_sequence, -1, -1);
2248
2249     return offset;
2250 }
2251
2252 static ber_old_sequence_t PA_ENCTYPE_INFO_sequence_of[1] = {
2253     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO_ENTRY },
2254 };
2255 static int
2256 dissect_krb5_PA_ENCTYPE_INFO(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2257 {
2258     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO_sequence_of, -1, -1);
2259
2260     return offset;
2261 }
2262
2263 static ber_old_sequence_t PA_ENCTYPE_INFO2_ENTRY_sequence[] = {
2264     { BER_CLASS_CON, 0, 0,
2265       dissect_krb5_etype },
2266     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2267       dissect_krb5_etype_info2_salt },
2268     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
2269       dissect_krb5_etype_info2_s2kparams },
2270     { 0, 0, 0, NULL }
2271 };
2272 static int
2273 dissect_krb5_PA_ENCTYPE_INFO2_ENTRY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2274 {
2275     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO2_ENTRY_sequence, -1, -1);
2276
2277     return offset;
2278 }
2279
2280 static ber_old_sequence_t PA_ENCTYPE_INFO2_sequence_of[1] = {
2281     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO2_ENTRY },
2282 };
2283 static int
2284 dissect_krb5_PA_ENCTYPE_INFO2(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2285 {
2286     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO2_sequence_of, -1, -1);
2287
2288     return offset;
2289 }
2290
2291
2292 static int
2293 dissect_krb5_PW_SALT(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2294 {
2295     guint32 nt_status;
2296
2297     /* Microsoft stores a special 12 byte blob here
2298      * guint32 NT_status
2299      * guint32 unknown
2300      * guint32 unknown
2301      * decode everything as this blob for now until we see if anyone
2302      * else ever uses it   or we learn how to tell whether this
2303      * is such an MS blob or not.
2304      */
2305     proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2306     nt_status=tvb_get_letohl(tvb, offset);
2307     if(nt_status) {
2308         col_append_fstr(actx->pinfo->cinfo, COL_INFO,
2309                         " NT Status: %s",
2310                         val_to_str_ext(nt_status, &NT_errors_ext,
2311                                    "Unknown error code %#x"));
2312     }
2313     offset += 4;
2314
2315     proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2316     offset += 4;
2317
2318     proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2319     offset += 4;
2320
2321     return offset;
2322 }
2323
2324 /*
2325  * PA-DATA ::=        SEQUENCE {
2326  *          padata-type[1]        INTEGER,
2327  *          padata-value[2]       OCTET STRING,
2328  *                        -- might be encoded AP-REQ
2329  * }
2330  */
2331 static guint32 krb_PA_DATA_type;
2332 static int
2333 dissect_krb5_PA_DATA_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2334 {
2335     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_PA_DATA_type, &krb_PA_DATA_type);
2336
2337     if(tree){
2338         proto_item_append_text(tree, " %s",
2339                                val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
2340                                           "Unknown:%d"));
2341     }
2342     return offset;
2343 }
2344 static int
2345 dissect_krb5_PA_DATA_value(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2346 {
2347     proto_tree *tree=parent_tree;
2348
2349     if(actx->created_item){
2350         tree=proto_item_add_subtree(actx->created_item, ett_krb_PA_DATA_tree);
2351     }
2352
2353
2354     switch(krb_PA_DATA_type){
2355     case KRB5_PA_TGS_REQ:
2356         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_application_choice);
2357         break;
2358     case KRB5_PA_PK_AS_REQ:
2359         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REQ);
2360         break;
2361     case KRB5_PA_PK_AS_REP:
2362         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REP);
2363         break;
2364     case KRB5_PA_PAC_REQUEST:
2365         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PAC_REQUEST);
2366         break;
2367     case KRB5_PA_FOR_USER:
2368         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_FOR_USER);
2369         break;
2370     case KRB5_PA_PROV_SRV_LOCATION:
2371         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PROV_SRV_LOCATION);
2372         break;
2373     case KRB5_PA_ENC_TIMESTAMP:
2374         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENC_TIMESTAMP);
2375         break;
2376     case KRB5_PA_ENCTYPE_INFO:
2377         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO);
2378         break;
2379     case KRB5_PA_ENCTYPE_INFO2:
2380         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO2);
2381         break;
2382     case KRB5_PA_PW_SALT:
2383         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PW_SALT);
2384         break;
2385     default:
2386         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, NULL);
2387     }
2388     return offset;
2389 /*qqq*/
2390 }
2391
2392 static ber_old_sequence_t PA_DATA_sequence[] = {
2393     { BER_CLASS_CON, 1, 0, dissect_krb5_PA_DATA_type },
2394     { BER_CLASS_CON, 2, 0, dissect_krb5_PA_DATA_value },
2395     { 0, 0, 0, NULL }
2396 };
2397 static int
2398 dissect_krb5_PA_DATA(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2399 {
2400     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_DATA_sequence, -1, -1);
2401
2402     return offset;
2403 }
2404
2405
2406
2407
2408 /*
2409  * padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
2410  *
2411  */
2412 static ber_old_sequence_t PA_DATA_sequence_of[1] = {
2413     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_DATA },
2414 };
2415 static int
2416 dissect_krb5_padata(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2417 {
2418     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_DATA_sequence_of, hf_krb_padata, ett_krb_padata);
2419
2420     return offset;
2421 }
2422
2423
2424
2425 static const true_false_string krb5_ticketflags_forwardable = {
2426     "FORWARDABLE tickets are allowed/requested",
2427     "Do NOT use forwardable tickets"
2428 };
2429 static const true_false_string krb5_ticketflags_forwarded = {
2430     "This ticket has been FORWARDED",
2431     "This is NOT a forwarded ticket"
2432 };
2433 static const true_false_string krb5_ticketflags_proxiable = {
2434     "PROXIABLE tickets are allowed/requested",
2435     "Do NOT use proxiable tickets"
2436 };
2437 static const true_false_string krb5_ticketflags_proxy = {
2438     "This is a PROXY ticket",
2439     "This ticket has NOT been proxied"
2440 };
2441 static const true_false_string krb5_ticketflags_allow_postdate = {
2442     "We allow the ticket to be POSTDATED",
2443     "We do NOT allow the ticket to be postdated"
2444 };
2445 static const true_false_string krb5_ticketflags_postdated = {
2446     "This ticket is POSTDATED",
2447     "This ticket is NOT postdated"
2448 };
2449 static const true_false_string krb5_ticketflags_invalid = {
2450     "This ticket is INVALID",
2451     "This ticket is NOT invalid"
2452 };
2453 static const true_false_string krb5_ticketflags_renewable = {
2454     "This ticket is RENEWABLE",
2455     "This ticket is NOT renewable"
2456 };
2457 static const true_false_string krb5_ticketflags_initial = {
2458     "This ticket was granted by AS and not TGT protocol",
2459     "This ticket was granted by TGT and not as protocol"
2460 };
2461 static const true_false_string krb5_ticketflags_pre_auth = {
2462     "The client was PRE-AUTHenticated",
2463     "The client was NOT pre-authenticated"
2464 };
2465 static const true_false_string krb5_ticketflags_hw_auth = {
2466     "The client was authenticated by HardWare",
2467     "The client was NOT authenticated using hardware"
2468 };
2469 static const true_false_string krb5_ticketflags_transited_policy_checked = {
2470     "Kdc has performed TRANSITED POLICY CHECKING",
2471     "Kdc has NOT performed transited policy checking"
2472 };
2473 static const true_false_string krb5_ticketflags_ok_as_delegate = {
2474     "This ticket is OK AS a DELEGATED ticket",
2475     "This ticket is NOT ok as a delegated ticket"
2476 };
2477
2478 static int* TicketFlags_bits[] = {
2479     &hf_krb_TicketFlags_forwardable,
2480     &hf_krb_TicketFlags_forwarded,
2481     &hf_krb_TicketFlags_proxiable,
2482     &hf_krb_TicketFlags_proxy,
2483     &hf_krb_TicketFlags_allow_postdate,
2484     &hf_krb_TicketFlags_postdated,
2485     &hf_krb_TicketFlags_invalid,
2486     &hf_krb_TicketFlags_renewable,
2487     &hf_krb_TicketFlags_initial,
2488     &hf_krb_TicketFlags_pre_auth,
2489     &hf_krb_TicketFlags_hw_auth,
2490     &hf_krb_TicketFlags_transited_policy_checked,
2491     &hf_krb_TicketFlags_ok_as_delegate,
2492     NULL
2493 };
2494
2495 static int
2496 dissect_krb5_TicketFlags(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2497 {
2498     offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, TicketFlags_bits, hf_krb_TicketFlags, ett_krb_Ticket_Flags, NULL);
2499     return offset;
2500 }
2501
2502
2503 static guint32 keytype;
2504 static int
2505 dissect_krb5_keytype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2506 {
2507     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_keytype, &keytype);
2508     if(tree){
2509         proto_item_append_text(tree, " %s",
2510                                val_to_str(keytype, krb5_encryption_types,
2511                                           "%#x"));
2512     }
2513     return offset;
2514 }
2515 static int keylength;
2516 static const guint8 *keyvalue;
2517 static int
2518 store_keyvalue(proto_tree *tree _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2519 {
2520     keylength=tvb_length_remaining(tvb, offset);
2521     keyvalue=tvb_get_ptr(tvb, offset, keylength);
2522     return 0;
2523 }
2524 static int
2525 dissect_krb5_keyvalue(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2526 {
2527     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_keyvalue, store_keyvalue);
2528     return offset;
2529 }
2530
2531
2532 /*
2533  * EncryptionKey ::=        SEQUENCE {
2534  *     keytype  [0] int32
2535  *     keyvalue [1] octet string
2536  */
2537 static ber_old_sequence_t EncryptionKey_sequence[] = {
2538     { BER_CLASS_CON, 0, 0,
2539       dissect_krb5_keytype },
2540     { BER_CLASS_CON, 1, 0,
2541       dissect_krb5_keyvalue },
2542     { 0, 0, 0, NULL }
2543 };
2544 static int
2545 dissect_krb5_key(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2546 {
2547     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncryptionKey_sequence, hf_krb_key, ett_krb_key);
2548
2549 #ifdef HAVE_KERBEROS
2550     add_encryption_key(actx->pinfo, keytype, keylength, keyvalue, "key");
2551 #endif
2552     return offset;
2553 }
2554 static int
2555 dissect_krb5_subkey(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2556 {
2557     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncryptionKey_sequence, hf_krb_subkey, ett_krb_subkey);
2558 #ifdef HAVE_KERBEROS
2559     add_encryption_key(actx->pinfo, keytype, keylength, keyvalue, "subkey");
2560 #endif
2561     return offset;
2562 }
2563
2564 static int
2565 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
2566 {
2567     proto_item *item=NULL;
2568     proto_tree *tree=NULL;
2569     guint8 val;
2570
2571     if(parent_tree){
2572         item=proto_tree_add_text(parent_tree, tvb, offset, 16, "DREP");
2573         tree=proto_item_add_subtree(item, ett_krb_PAC_DREP);
2574     }
2575
2576     val = tvb_get_guint8(tvb, offset);
2577     proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
2578
2579     offset++;
2580
2581     if (drep) {
2582         *drep = val;
2583     }
2584
2585     return offset;
2586 }
2587
2588 /* This might be some sort of header that MIDL generates when creating
2589  * marshalling/unmarshalling code for blobs that are not to be transported
2590  * ontop of DCERPC and where the DREP fields specifying things such as
2591  * endianess and similar are not available.
2592  */
2593 static int
2594 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
2595 {
2596     proto_item *item=NULL;
2597     proto_tree *tree=NULL;
2598
2599     if(parent_tree){
2600         item=proto_tree_add_text(parent_tree, tvb, offset, 16, "MES header");
2601         tree=proto_item_add_subtree(item, ett_krb_PAC_MIDL_BLOB);
2602     }
2603
2604     /* modified DREP field that is used for stuff that is transporetd ontop
2605        of non dcerpc
2606     */
2607     proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2608     offset++;
2609
2610     offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
2611
2612
2613     proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2614     offset+=2;
2615
2616     proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2617     offset += 4;
2618
2619     /* length of blob that follows */
2620     proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2621     offset += 8;
2622
2623     return offset;
2624 }
2625
2626 static int
2627 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2628 {
2629     proto_item *item=NULL;
2630     proto_tree *tree=NULL;
2631     guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2632     static dcerpc_info di;      /* fake dcerpc_info struct */
2633     static dcerpc_call_value call_data;
2634
2635     item=proto_tree_add_item(parent_tree, hf_krb_PAC_LOGON_INFO, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2636     if(parent_tree){
2637         tree=proto_item_add_subtree(item, ett_krb_PAC_LOGON_INFO);
2638     }
2639
2640     /* skip the first 16 bytes, they are some magic created by the idl
2641      * compiler   the first 4 bytes might be flags?
2642      */
2643     offset=dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2644
2645     /* the PAC_LOGON_INFO blob */
2646     /* fake whatever state the dcerpc runtime support needs */
2647     di.conformant_run=0;
2648     /* we need di->call_data->flags.NDR64 == 0 */
2649     di.call_data=&call_data;
2650     di.dcerpc_procedure_name = "";
2651
2652     init_ndr_pointer_list(&di);
2653     offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
2654                                  netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
2655                                  "PAC_LOGON_INFO:", -1);
2656     return offset;
2657 }
2658
2659 static int
2660 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2661 {
2662     proto_item *item=NULL;
2663     proto_tree *tree=NULL;
2664     guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2665     static dcerpc_info di;      /* fake dcerpc_info struct */
2666     static dcerpc_call_value call_data;
2667
2668     item=proto_tree_add_item(parent_tree, hf_krb_PAC_S4U_DELEGATION_INFO, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2669     if(parent_tree){
2670         tree=proto_item_add_subtree(item, ett_krb_PAC_S4U_DELEGATION_INFO);
2671     }
2672
2673     /* skip the first 16 bytes, they are some magic created by the idl
2674      * compiler   the first 4 bytes might be flags?
2675      */
2676     offset=dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2677
2678
2679     /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
2680     /* fake whatever state the dcerpc runtime support needs */
2681     di.conformant_run=0;
2682     /* we need di->call_data->flags.NDR64 == 0 */
2683     di.call_data=&call_data;
2684     di.dcerpc_procedure_name = "";
2685
2686     init_ndr_pointer_list(&di);
2687     offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
2688                                  netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
2689                                  "PAC_S4U_DELEGATION_INFO:", -1);
2690
2691     return offset;
2692 }
2693
2694 static int
2695 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2696 {
2697     proto_item *item=NULL;
2698     proto_tree *tree=NULL;
2699     guint16 dns_offset, dns_len;
2700     guint16 upn_offset, upn_len;
2701     const char *dn;
2702     int dn_len;
2703     guint16 bc;
2704
2705     item=proto_tree_add_item(parent_tree, hf_krb_PAC_UPN_DNS_INFO, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2706     if(parent_tree){
2707         tree=proto_item_add_subtree(item, ett_krb_PAC_UPN_DNS_INFO);
2708     }
2709
2710     /* upn */
2711     upn_len = tvb_get_letohs(tvb, offset);
2712     proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2713     offset+=2;
2714     upn_offset = tvb_get_letohs(tvb, offset);
2715     proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2716     offset+=2;
2717
2718     /* dns */
2719     dns_len = tvb_get_letohs(tvb, offset);
2720     proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2721     offset+=2;
2722     dns_offset = tvb_get_letohs(tvb, offset);
2723     proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2724     offset+=2;
2725
2726     /* flags */
2727     proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2728
2729     /* upn */
2730     offset = upn_offset;
2731     dn_len = upn_len;
2732     bc = tvb_length_remaining(tvb, offset);
2733     dn = get_unicode_or_ascii_string(tvb, &offset,
2734                                      TRUE, &dn_len, TRUE, TRUE, &bc);
2735     proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
2736
2737     /* dns */
2738     offset = dns_offset;
2739     dn_len = dns_len;
2740     bc = tvb_length_remaining(tvb, offset);
2741     dn = get_unicode_or_ascii_string(tvb, &offset,
2742                                      TRUE, &dn_len, TRUE, TRUE, &bc);
2743     proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
2744
2745     return offset;
2746 }
2747
2748 static int
2749 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2750 {
2751     proto_tree_add_item(parent_tree, hf_krb_PAC_CREDENTIAL_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2752
2753 /*qqq*/
2754     return offset;
2755 }
2756
2757 static int
2758 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2759 {
2760     proto_item *item=NULL;
2761     proto_tree *tree=NULL;
2762
2763     item=proto_tree_add_item(parent_tree, hf_krb_PAC_SERVER_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2764     if(parent_tree){
2765         tree=proto_item_add_subtree(item, ett_krb_PAC_SERVER_CHECKSUM);
2766     }
2767
2768     /* signature type */
2769     proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2770     offset+=4;
2771
2772     /* signature data */
2773     proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2774
2775     return offset;
2776 }
2777
2778 static int
2779 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2780 {
2781     proto_item *item=NULL;
2782     proto_tree *tree=NULL;
2783
2784     item=proto_tree_add_item(parent_tree, hf_krb_PAC_PRIVSVR_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2785     if(parent_tree){
2786         tree=proto_item_add_subtree(item, ett_krb_PAC_PRIVSVR_CHECKSUM);
2787     }
2788
2789     /* signature type */
2790     proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2791     offset+=4;
2792
2793     /* signature data */
2794     proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2795
2796     return offset;
2797 }
2798
2799 /* See [MS-PAC] */
2800 static int
2801 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2802 {
2803     proto_item *item=NULL;
2804     proto_tree *tree=NULL;
2805     guint16 namelen;
2806
2807     item=proto_tree_add_item(parent_tree, hf_krb_PAC_CLIENT_INFO_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2808     if(parent_tree){
2809         tree=proto_item_add_subtree(item, ett_krb_PAC_CLIENT_INFO_TYPE);
2810     }
2811
2812     /* clientid */
2813     offset = dissect_nt_64bit_time(tvb, tree, offset,
2814                                    hf_krb_pac_clientid);
2815
2816     /* name length */
2817     namelen=tvb_get_letohs(tvb, offset);
2818     proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
2819     offset+=2;
2820
2821     /* client name */
2822     proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
2823     offset+=namelen;
2824
2825     return offset;
2826 }
2827
2828 static int
2829 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2830 {
2831     guint32 pac_type;
2832     guint32 pac_size;
2833     guint32 pac_offset;
2834     proto_item *it=NULL;
2835     proto_tree *tr=NULL;
2836     tvbuff_t *next_tvb;
2837
2838     /* type of pac data */
2839     pac_type=tvb_get_letohl(tvb, offset);
2840     it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
2841     if(it){
2842         tr=proto_item_add_subtree(it, ett_krb_PAC);
2843     }
2844
2845     offset += 4;
2846
2847     /* size of pac data */
2848     pac_size=tvb_get_letohl(tvb, offset);
2849     proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
2850     offset += 4;
2851
2852     /* offset to pac data */
2853     pac_offset=tvb_get_letohl(tvb, offset);
2854     proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
2855     offset += 8;
2856
2857
2858     next_tvb=tvb_new_subset(tvb, pac_offset, pac_size, pac_size);
2859     switch(pac_type){
2860     case PAC_LOGON_INFO:
2861         dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
2862         break;
2863     case PAC_CREDENTIAL_TYPE:
2864         dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
2865         break;
2866     case PAC_SERVER_CHECKSUM:
2867         dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
2868         break;
2869     case PAC_PRIVSVR_CHECKSUM:
2870         dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
2871         break;
2872     case PAC_CLIENT_INFO_TYPE:
2873         dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
2874         break;
2875     case PAC_S4U_DELEGATION_INFO:
2876         dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
2877         break;
2878     case PAC_UPN_DNS_INFO:
2879         dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
2880         break;
2881
2882     default:;
2883 /*qqq*/
2884     }
2885     return offset;
2886 }
2887
2888 static int
2889 dissect_krb5_AD_WIN2K_PAC(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2890 {
2891     guint32 entries;
2892     guint32 version;
2893     guint32 i;
2894
2895     /* first in the PAC structure comes the number of entries */
2896     entries=tvb_get_letohl(tvb, offset);
2897     proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
2898     offset += 4;
2899
2900     /* second comes the version */
2901     version=tvb_get_letohl(tvb, offset);
2902     proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
2903     offset += 4;
2904
2905     for(i=0;i<entries;i++){
2906         offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
2907     }
2908
2909     return offset;
2910 }
2911
2912
2913 static ber_old_sequence_t AD_SIGNTICKET_sequence[] = {
2914     { BER_CLASS_CON, 0, 0,
2915       dissect_krb5_etype },
2916     { BER_CLASS_CON, 1, 0,
2917       dissect_krb5_Checksum },
2918     { 0, 0, 0, NULL }
2919 };
2920
2921 /* first seen in traces from vista */
2922 static int
2923 dissect_krb5_AD_SIGNTICKET(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2924 {
2925     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, AD_SIGNTICKET_sequence, -1, -1);
2926
2927     return offset;
2928 }
2929
2930 static guint32 IF_RELEVANT_type;
2931 static int
2932 dissect_krb5_IF_RELEVANT_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2933 {
2934     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_IF_RELEVANT_type, &IF_RELEVANT_type);
2935     if(tree){
2936         proto_item_append_text(tree, " %s",
2937                                val_to_str(IF_RELEVANT_type, krb5_ad_types,
2938                                           "%#x"));
2939     }
2940     return offset;
2941 }
2942 static int
2943 dissect_krb5_IF_RELEVANT_value(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2944 {
2945     switch(IF_RELEVANT_type){
2946     case KRB5_AD_WIN2K_PAC:
2947         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_advalue, dissect_krb5_AD_WIN2K_PAC);
2948         break;
2949     case KRB5_AD_SIGNTICKET:
2950         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_advalue, dissect_krb5_AD_SIGNTICKET);
2951         break;
2952     default:
2953         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_IF_RELEVANT_value, NULL);
2954     }
2955     return offset;
2956 }
2957 static ber_old_sequence_t IF_RELEVANT_item_sequence[] = {
2958     { BER_CLASS_CON, 0, 0,
2959       dissect_krb5_IF_RELEVANT_type },
2960     { BER_CLASS_CON, 1, 0,
2961       dissect_krb5_IF_RELEVANT_value },
2962     { 0, 0, 0, NULL }
2963 };
2964 static int
2965 dissect_krb5_IF_RELEVANT_item(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2966 {
2967     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, IF_RELEVANT_item_sequence, hf_krb_IF_RELEVANT, ett_krb_IF_RELEVANT);
2968
2969     return offset;
2970 }
2971
2972 static ber_old_sequence_t IF_RELEVANT_sequence_of[1] = {
2973     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_IF_RELEVANT_item },
2974 };
2975
2976 static int
2977 dissect_krb5_IF_RELEVANT(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2978 {
2979     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, IF_RELEVANT_sequence_of, -1, -1);
2980
2981     return offset;
2982 }
2983
2984 static guint32 adtype;
2985 static int
2986 dissect_krb5_adtype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2987 {
2988     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_adtype, &adtype);
2989     if(tree){
2990         proto_item_append_text(tree, " %s",
2991                                val_to_str(adtype, krb5_ad_types,
2992                                           "%#x"));
2993     }
2994     return offset;
2995 }
2996 static int
2997 dissect_krb5_advalue(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2998 {
2999     switch(adtype){
3000     case KRB5_AD_IF_RELEVANT:
3001         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_advalue, dissect_krb5_IF_RELEVANT);
3002         break;
3003     default:
3004         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_advalue, NULL);
3005     }
3006     return offset;
3007 }
3008 /*
3009  * AuthorizationData ::=        SEQUENCE {
3010  *     ad-type  [0] int32
3011  *     ad-data  [1] octet string
3012  */
3013 static ber_old_sequence_t AuthorizationData_item_sequence[] = {
3014     { BER_CLASS_CON, 0, 0,
3015       dissect_krb5_adtype },
3016     { BER_CLASS_CON, 1, 0,
3017       dissect_krb5_advalue },
3018     { 0, 0, 0, NULL }
3019 };
3020 static int
3021 dissect_krb5_AuthorizationData_item(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3022 {
3023     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, AuthorizationData_item_sequence, hf_krb_AuthorizationData, ett_krb_AuthorizationData);
3024
3025     return offset;
3026 }
3027
3028 static ber_old_sequence_t AuthorizationData_sequence_of[1] = {
3029     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_AuthorizationData_item },
3030 };
3031 static int
3032 dissect_krb5_AuthorizationData(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3033 {
3034     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, AuthorizationData_sequence_of, -1, -1);
3035
3036     return offset;
3037 }
3038
3039
3040 static int
3041 dissect_krb5_transited_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3042 {
3043     guint32 trtype;
3044
3045     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_transitedtype, &trtype);
3046     if(tree){
3047         proto_item_append_text(tree, " %s",
3048                                val_to_str(trtype, krb5_transited_types,
3049                                           "%#x"));
3050     }
3051     return offset;
3052 }
3053
3054 static int
3055 dissect_krb5_transited_contents(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3056 {
3057     offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_transitedcontents, NULL);
3058     return offset;
3059 }
3060
3061 /*
3062  * TransitedEncoding ::=        SEQUENCE {
3063  *     tr-type  [0] int32
3064  *     contents [1] octet string
3065  */
3066 static ber_old_sequence_t TransitedEncoding_sequence[] = {
3067     { BER_CLASS_CON, 0, 0,
3068       dissect_krb5_transited_type },
3069     { BER_CLASS_CON, 1, 0,
3070       dissect_krb5_transited_contents },
3071     { 0, 0, 0, NULL }
3072 };
3073 static int
3074 dissect_krb5_transited(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3075 {
3076     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, TransitedEncoding_sequence, hf_krb_TransitedEncoding, ett_krb_TransitedEncoding);
3077
3078     return offset;
3079 }
3080
3081
3082 static int
3083 dissect_krb5_authtime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3084 {
3085     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_authtime);
3086     return offset;
3087 }
3088 static int
3089 dissect_krb5_starttime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3090 {
3091     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_starttime);
3092     return offset;
3093 }
3094 static int
3095 dissect_krb5_endtime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3096 {
3097     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_endtime);
3098     return offset;
3099 }
3100 static int
3101 dissect_krb5_renew_till(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3102 {
3103     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_renew_till);
3104     return offset;
3105 }
3106
3107 /*
3108  * EncTicketPart ::=        SEQUENCE {
3109  *      flags                   [0] TicketFlags,
3110  *      key                     [1] EncryptionKey,
3111  *      crealm                  [2] Realm,
3112  *      cname                   [3] PrincipalName,
3113  *      transited               [4] TransitedEncoding,
3114  *      authtime                [5] KerberosTime,
3115  *      starttime               [6] KerberosTime OPTIONAL,
3116  *      endtime                 [7] KerberosTime,
3117  *      renew-till              [8] KerberosTime OPTIONAL,
3118  *      caddr                   [9] HostAddresses OPTIONAL,
3119  *      authorization-data      [10] AuthorizationData OPTIONAL
3120  * }
3121  */
3122 static ber_old_sequence_t EncTicketPart_sequence[] = {
3123     { BER_CLASS_CON, 0, 0,
3124       dissect_krb5_TicketFlags },
3125     { BER_CLASS_CON, 1, 0,
3126       dissect_krb5_key },
3127     { BER_CLASS_CON, 2, 0,
3128       dissect_krb5_crealm },
3129     { BER_CLASS_CON, 3, 0,
3130       dissect_krb5_cname },
3131     { BER_CLASS_CON, 4, 0,
3132       dissect_krb5_transited },
3133     { BER_CLASS_CON, 5, 0,
3134       dissect_krb5_authtime },
3135     { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
3136       dissect_krb5_starttime },
3137     { BER_CLASS_CON, 7, 0,
3138       dissect_krb5_endtime },
3139     { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
3140       dissect_krb5_renew_till },
3141     { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
3142       dissect_krb5_HostAddresses },
3143     { BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL,
3144       dissect_krb5_AuthorizationData },
3145     { 0, 0, 0, NULL }
3146 };
3147 static int
3148 dissect_krb5_EncTicketPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3149 {
3150     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncTicketPart_sequence, hf_krb_EncTicketPart, ett_krb_EncTicketPart);
3151
3152     return offset;
3153 }
3154
3155
3156
3157
3158
3159
3160 /*
3161  * EncAPRepPart ::=        SEQUENCE {
3162  *     ctime                    [0] KerberosTime
3163  *     cusec                    [1] Microseconds
3164  *     subkey                   [2] encryptionKey OPTIONAL
3165  *     seq-number               [3] uint32 OPTIONAL
3166  * }
3167  */
3168 static ber_old_sequence_t EncAPRepPart_sequence[] = {
3169     { BER_CLASS_CON, 0, 0,
3170       dissect_krb5_ctime },
3171     { BER_CLASS_CON, 1, 0,
3172       dissect_krb5_cusec },
3173     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
3174       dissect_krb5_subkey },
3175     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3176       dissect_krb5_seq_number },
3177     { 0, 0, 0, NULL }
3178 };
3179 static int
3180 dissect_krb5_EncAPRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3181 {
3182     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncAPRepPart_sequence, hf_krb_EncAPRepPart, ett_krb_EncAPRepPart);
3183
3184     return offset;
3185 }
3186
3187
3188
3189 static guint32 lr_type;
3190 static const value_string krb5_lr_types[] = {
3191     { 0              , "No information available" },
3192     { 1              , "Time of last initial TGT request" },
3193     { 2              , "Time of last initial request" },
3194     { 3              , "Time of issue of latest TGT ticket" },
3195     { 4              , "Time of last renewal" },
3196     { 5              , "Time of last request" },
3197     { 6              , "Time when password will expire" },
3198     { 7              , "Time when account will expire" },
3199     { 0, NULL }
3200 };
3201 static int
3202 dissect_krb5_lr_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3203 {
3204     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_lr_type, &lr_type);
3205
3206     return offset;
3207 }
3208 static int
3209 dissect_krb5_lr_value(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3210 {
3211     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_lr_time);
3212
3213     return offset;
3214 }
3215
3216 static ber_old_sequence_t LastReq_sequence[] = {
3217     { BER_CLASS_CON, 0, 0,
3218       dissect_krb5_lr_type },
3219     { BER_CLASS_CON, 1, 0,
3220       dissect_krb5_lr_value },
3221     { 0, 0, 0, NULL }
3222 };
3223 static int
3224 dissect_krb5_LastReq(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3225 {
3226     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, LastReq_sequence, hf_krb_LastReq, ett_krb_LastReq);
3227
3228     return offset;
3229 }
3230 static ber_old_sequence_t LastReq_sequence_of[1] = {
3231     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_LastReq },
3232 };
3233 static int
3234 dissect_krb5_LastReq_sequence_of(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3235 {
3236     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, LastReq_sequence_of, hf_krb_LastReqs, ett_krb_LastReqs);
3237
3238     return offset;
3239 }
3240
3241 static int
3242 dissect_krb5_key_expiration(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3243 {
3244     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_key_expire);
3245     return offset;
3246 }
3247
3248 static ber_old_sequence_t EncKDCRepPart_sequence[] = {
3249     { BER_CLASS_CON, 0, 0,
3250       dissect_krb5_key },
3251     { BER_CLASS_CON, 1, 0,
3252       dissect_krb5_LastReq_sequence_of },
3253     { BER_CLASS_CON, 2, 0,
3254       dissect_krb5_nonce },
3255     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3256       dissect_krb5_key_expiration },
3257     { BER_CLASS_CON, 4, 0,
3258       dissect_krb5_TicketFlags },
3259     { BER_CLASS_CON, 5, 0,
3260       dissect_krb5_authtime },
3261     { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
3262       dissect_krb5_starttime },
3263     { BER_CLASS_CON, 7, 0,
3264       dissect_krb5_endtime },
3265     { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
3266       dissect_krb5_renew_till },
3267     { BER_CLASS_CON, 9, 0,
3268       dissect_krb5_realm },
3269     { BER_CLASS_CON, 10, 0,
3270       dissect_krb5_sname },
3271     { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
3272       dissect_krb5_HostAddresses },
3273     { 0, 0, 0, NULL }
3274 };
3275 static int
3276 dissect_krb5_EncKDCRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3277 {
3278     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncKDCRepPart_sequence, hf_krb_EncKDCRepPart, ett_krb_EncKDCRepPart);
3279
3280     return offset;
3281 }
3282
3283
3284 static int
3285 dissect_krb5_authenticator_vno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3286 {
3287     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_authenticator_vno, NULL);
3288
3289     return offset;
3290 }
3291
3292
3293 #define KRB5_GSS_C_DELEG_FLAG             0x01
3294 #define KRB5_GSS_C_MUTUAL_FLAG            0x02
3295 #define KRB5_GSS_C_REPLAY_FLAG            0x04
3296 #define KRB5_GSS_C_SEQUENCE_FLAG          0x08
3297 #define KRB5_GSS_C_CONF_FLAG              0x10
3298 #define KRB5_GSS_C_INTEG_FLAG             0x20
3299 #define KRB5_GSS_C_DCE_STYLE            0x1000
3300
3301 static const true_false_string tfs_gss_flags_deleg = {
3302     "Delegate credentials to remote peer",
3303     "Do NOT delegate"
3304 };
3305 static const true_false_string tfs_gss_flags_mutual = {
3306     "Request that remote peer authenticates itself",
3307     "Mutual authentication NOT required"
3308 };
3309 static const true_false_string tfs_gss_flags_replay = {
3310     "Enable replay protection for signed or sealed messages",
3311     "Do NOT enable replay protection"
3312 };
3313 static const true_false_string tfs_gss_flags_sequence = {
3314     "Enable Out-of-sequence detection for sign or sealed messages",
3315     "Do NOT enable out-of-sequence detection"
3316 };
3317 static const true_false_string tfs_gss_flags_conf = {
3318     "Confidentiality (sealing) may be invoked",
3319     "Do NOT use Confidentiality (sealing)"
3320 };
3321 static const true_false_string tfs_gss_flags_integ = {
3322     "Integrity protection (signing) may be invoked",
3323     "Do NOT use integrity protection"
3324 };
3325
3326 static const true_false_string tfs_gss_flags_dce_style = {
3327     "DCE-STYLE",
3328     "Not using DCE-STYLE"
3329 };
3330
3331 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
3332  */
3333 static int
3334 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
3335 {
3336     int offset=0;
3337     guint32 len;
3338     guint16 dlglen;
3339
3340     /* Length of Bnd field */
3341     len=tvb_get_letohl(tvb, offset);
3342     proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3343     offset += 4;
3344
3345     /* Bnd field */
3346     proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
3347     offset += len;
3348
3349
3350     /* flags */
3351     proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3352     proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3353     proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3354     proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3355     proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3356     proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3357     proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3358     offset += 4;
3359
3360     /* the next fields are optional so we have to check that we have
3361      * more data in our buffers */
3362     if(tvb_length_remaining(tvb, offset)<2){
3363         return offset;
3364     }
3365     /* dlgopt identifier */
3366     proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3367     offset += 2;
3368
3369     if(tvb_length_remaining(tvb, offset)<2){
3370         return offset;
3371     }
3372     /* dlglen identifier */
3373     dlglen=tvb_get_letohs(tvb, offset);
3374     proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3375     offset += 2;
3376
3377     if(dlglen!=tvb_length_remaining(tvb, offset)){
3378         proto_tree_add_text(tree, tvb, 0, 0, "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_length_remaining(tvb, offset));
3379         return offset;
3380     }
3381
3382     /* this should now be a KRB_CRED message */
3383     offset=dissect_ber_old_choice(actx, tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
3384
3385
3386     return offset;
3387 }
3388
3389 static guint32 checksum_type;
3390
3391 static int
3392 dissect_krb5_checksum_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3393 {
3394     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_checksum_type, &checksum_type);
3395
3396     return offset;
3397 }
3398
3399 static int
3400 dissect_krb5_checksum_checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3401 {
3402     tvbuff_t *next_tvb;
3403
3404     switch(checksum_type){
3405     case KRB5_CHKSUM_GSSAPI:
3406         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_checksum_checksum, &next_tvb);
3407         dissect_krb5_rfc1964_checksum(actx, tree, next_tvb);
3408         break;
3409     default:
3410         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_checksum_checksum, NULL);
3411     }
3412     return offset;
3413 }
3414
3415 /*
3416  * Checksum ::=        SEQUENCE {
3417  * }
3418  */
3419 static ber_old_sequence_t Checksum_sequence[] = {
3420     { BER_CLASS_CON, 0, 0,
3421       dissect_krb5_checksum_type },
3422     { BER_CLASS_CON, 1, 0,
3423       dissect_krb5_checksum_checksum },
3424     { 0, 0, 0, NULL }
3425 };
3426 int
3427 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3428 {
3429     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, Checksum_sequence, hf_krb_Checksum, ett_krb_Checksum);
3430
3431     return offset;
3432 }
3433
3434 /*
3435  * Authenticator ::=        SEQUENCE {
3436  *     authenticator-vno        [0] integer
3437  *     crealm                   [1] Realm
3438  *     cname                    [2] PrincipalName
3439  *     cksum                    [3] Checksum OPTIONAL
3440  *     cusec                    [4] Microseconds
3441  *     ctime                    [5] KerberosTime
3442  *     subkey                   [6] encryptionKey OPTIONAL
3443  *     seq-number               [7] uint32 OPTIONAL
3444  *     authorization-data       [8] AuthorizationData OPTIONAL
3445  * }
3446  */
3447 static ber_old_sequence_t Authenticator_sequence[] = {
3448     { BER_CLASS_CON, 0, 0,
3449       dissect_krb5_authenticator_vno },
3450     { BER_CLASS_CON, 1, 0,
3451       dissect_krb5_crealm },
3452     { BER_CLASS_CON, 2, 0,
3453       dissect_krb5_cname },
3454     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3455       dissect_krb5_Checksum },
3456     { BER_CLASS_CON, 4, 0,
3457       dissect_krb5_cusec },
3458     { BER_CLASS_CON, 5, 0,
3459       dissect_krb5_ctime },
3460     { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
3461       dissect_krb5_subkey },
3462     { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL,
3463       dissect_krb5_seq_number },
3464     { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
3465       dissect_krb5_AuthorizationData },
3466     { 0, 0, 0, NULL }
3467 };
3468 static int
3469 dissect_krb5_Authenticator(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3470 {
3471     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, Authenticator_sequence, hf_krb_Authenticator, ett_krb_Authenticator);
3472
3473     return offset;
3474 }
3475
3476
3477 static int
3478 dissect_krb5_PRIV_BODY_user_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
3479 {
3480     tvbuff_t *new_tvb;
3481     offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_PRIV_BODY_user_data, &new_tvb);
3482
3483     if (new_tvb)
3484         call_kerberos_callbacks(actx->pinfo, tree, new_tvb, KRB_CBTAG_PRIV_USER_DATA, (kerberos_callbacks*)actx->private_data);
3485
3486     return offset;
3487 }
3488
3489 static ber_old_sequence_t EncKrbPrivPart_sequence[] = {
3490     { BER_CLASS_CON, 0, 0,
3491       dissect_krb5_PRIV_BODY_user_data },
3492     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3493       dissect_krb5_patimestamp },
3494     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
3495       dissect_krb5_cusec },
3496     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3497       dissect_krb5_seq_number },
3498     { BER_CLASS_CON, 4, 0,
3499       dissect_krb5_s_address },
3500     { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
3501       dissect_krb5_HostAddresses },
3502     { 0, 0, 0, NULL }
3503 };
3504 static int
3505 dissect_krb5_EncKrbPrivPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3506 {
3507     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncKrbPrivPart_sequence, hf_krb_EncKrbPrivPart, ett_krb_EncKrbPrivPart);
3508
3509     return offset;
3510 }
3511
3512 static guint32 PRIV_etype;
3513 static int
3514 dissect_krb5_PRIV_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3515 {
3516     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &PRIV_etype);
3517     if(tree){
3518         proto_item_append_text(tree, " %s",
3519                                val_to_str(PRIV_etype, krb5_encryption_types,
3520                                           "%#x"));
3521     }
3522     return offset;
3523 }
3524
3525 #ifdef HAVE_KERBEROS
3526 static int
3527 dissect_krb5_decrypt_PRIV (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3528 {
3529     guint8 *plaintext=NULL;
3530     int length;
3531
3532     length=tvb_length_remaining(tvb, offset);
3533
3534     if(!plaintext){
3535         tvbuff_t *next_tvb;
3536
3537         next_tvb=tvb_new_subset_remaining(tvb, offset);
3538         plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, PRIV_etype, NULL);
3539     }
3540
3541     if(plaintext){
3542         tvbuff_t *next_tvb;
3543         next_tvb = tvb_new_child_real_data(tvb, plaintext,
3544                                            length,
3545                                            length);
3546         tvb_set_free_cb(next_tvb, g_free);
3547
3548         /* Add the decrypted data to the data source list. */
3549         add_new_data_source(actx->pinfo, next_tvb, "Decrypted Krb5");
3550
3551         offset=dissect_ber_old_choice(actx, tree, next_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
3552
3553     }
3554     return offset;
3555 }
3556 #endif
3557
3558 /*
3559  * PRIV-BODY ::=   SEQUENCE {
3560  *  KRB-PRIV ::=         [APPLICATION 21] SEQUENCE {
3561  *               pvno[0]                   INTEGER,
3562  *               msg-type[1]               INTEGER,
3563  *               enc-part[3]               EncryptedData
3564  *  }
3565  */
3566 static int
3567 dissect_krb5_encrypted_PRIV(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3568 {
3569 #ifdef HAVE_KERBEROS
3570     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PRIV, dissect_krb5_decrypt_PRIV);
3571 #else
3572     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PRIV, NULL);
3573 #endif
3574     return offset;
3575 }
3576 static ber_old_sequence_t ENC_PRIV_sequence[] = {
3577     { BER_CLASS_CON, 0, 0,
3578       dissect_krb5_PRIV_etype },
3579     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3580       dissect_krb5_kvno },
3581     { BER_CLASS_CON, 2, 0,
3582       dissect_krb5_encrypted_PRIV },
3583     { 0, 0, 0, NULL }
3584 };
3585 static int
3586 dissect_krb5_ENC_PRIV(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3587 {
3588     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, ENC_PRIV_sequence, hf_krb_ENC_PRIV, ett_krb_PRIV_enc);
3589     return offset;
3590 }
3591 static ber_old_sequence_t PRIV_BODY_sequence[] = {
3592     { BER_CLASS_CON, 0, 0,
3593       dissect_krb5_pvno },
3594     { BER_CLASS_CON, 1, 0,
3595       dissect_krb5_msg_type },
3596     { BER_CLASS_CON, 3, 0,
3597       dissect_krb5_ENC_PRIV },
3598     { 0, 0, 0, NULL }
3599 };
3600 static int
3601 dissect_krb5_PRIV(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3602 {
3603
3604     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PRIV_BODY_sequence, hf_krb_PRIV_BODY, ett_krb_PRIV);
3605
3606     return offset;
3607 }
3608
3609 static guint32 EncKrbCredPart_etype;
3610 static int
3611 dissect_krb5_EncKrbCredPart_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3612 {
3613     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &EncKrbCredPart_etype);
3614     if(tree){
3615         proto_item_append_text(tree, " %s",
3616                                val_to_str(EncKrbCredPart_etype, krb5_encryption_types,
3617                                           "%#x"));
3618     }
3619     return offset;
3620 }
3621
3622
3623
3624
3625
3626 static ber_old_sequence_t KrbCredInfo_sequence[] = {
3627     { BER_CLASS_CON, 0, 0, dissect_krb5_key },
3628     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_prealm },
3629     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, dissect_krb5_pname },
3630     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL, dissect_krb5_TicketFlags },
3631     { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL, dissect_krb5_authtime },
3632     { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL, dissect_krb5_starttime },
3633     { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL, dissect_krb5_endtime },
3634     { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL, dissect_krb5_renew_till },
3635     { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL, dissect_krb5_srealm },
3636     { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL, dissect_krb5_sname },
3637     { BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL, dissect_krb5_HostAddresses },
3638     { 0, 0, 0, NULL }
3639 };
3640 static int
3641 dissect_krb5_KrbCredInfo(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3642 {
3643
3644     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, KrbCredInfo_sequence, hf_krb_KrbCredInfo, ett_krb_KrbCredInfo);
3645
3646     return offset;
3647 }
3648
3649 static ber_old_sequence_t KrbCredInfo_sequence_of[1] = {
3650     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_KrbCredInfo },
3651 };
3652 static int
3653 dissect_krb5_KrbCredInfo_sequence_of(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3654 {
3655     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, KrbCredInfo_sequence_of, hf_krb_KrbCredInfos, ett_krb_KrbCredInfos);
3656
3657     return offset;
3658 }
3659 static const ber_old_sequence_t EncKrbCredPart_sequence[] = {
3660     { BER_CLASS_CON, 0, 0, dissect_krb5_KrbCredInfo_sequence_of },
3661     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_nonce },
3662     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, dissect_krb5_ctime },
3663     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL, dissect_krb5_cusec },
3664     { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL, dissect_krb5_s_address },
3665     { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL, dissect_krb5_r_address },
3666     { 0, 0, 0, NULL }
3667 };
3668
3669 static int
3670 dissect_krb5_EncKrbCredPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3671 {
3672     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncKrbCredPart_sequence, hf_krb_EncKrbCredPart, ett_krb_EncKrbCredPart);
3673
3674     return offset;
3675 }
3676
3677 #ifdef HAVE_KERBEROS
3678 static int
3679 dissect_krb5_decrypt_EncKrbCredPart (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3680 {
3681     guint8 *plaintext=NULL;
3682     int length;
3683     tvbuff_t *next_tvb;
3684
3685     next_tvb=tvb_new_subset_remaining(tvb, offset);
3686
3687     length=tvb_length_remaining(tvb, offset);
3688
3689     /* RFC4120 :
3690      * EncKrbCredPart encrypted with usage
3691      * == 14
3692      */
3693     if(!plaintext){
3694         plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, EncKrbCredPart_etype, NULL);
3695     }
3696
3697     if(plaintext){
3698         tvbuff_t *child_tvb;
3699         child_tvb = tvb_new_child_real_data(tvb, plaintext,
3700                                             length,
3701                                             length);
3702         tvb_set_free_cb(child_tvb, g_free);
3703
3704         /* Add the decrypted data to the data source list. */
3705         add_new_data_source(actx->pinfo, child_tvb, "EncKrbCredPart");
3706
3707         offset=dissect_ber_old_choice(actx, tree, child_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
3708     }
3709     return offset;
3710 }
3711 #endif
3712
3713 static int
3714 dissect_krb5_encrypted_CRED_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3715 {
3716 #ifdef HAVE_KERBEROS
3717     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_EncKrbCredPart, dissect_krb5_decrypt_EncKrbCredPart);
3718 #else
3719     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_EncKrbCredPart, NULL);
3720 #endif
3721     return offset;
3722 }
3723
3724 static ber_old_sequence_t encrypted_CRED_sequence[] = {
3725     { BER_CLASS_CON, 0, 0,
3726       dissect_krb5_EncKrbCredPart_etype },
3727     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3728       dissect_krb5_kvno },
3729     { BER_CLASS_CON, 2, 0,
3730       dissect_krb5_encrypted_CRED_data },
3731     { 0, 0, 0, NULL }
3732 };
3733 static int
3734 dissect_krb5_encrypted_CRED(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3735 {
3736     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, encrypted_CRED_sequence, hf_krb_CRED_enc, ett_krb_CRED_enc);
3737
3738     return offset;
3739 }
3740
3741 static ber_old_sequence_t CRED_BODY_sequence[] = {
3742     { BER_CLASS_CON, 0, 0,
3743       dissect_krb5_pvno },
3744     { BER_CLASS_CON, 1, 0,
3745       dissect_krb5_msg_type },
3746     { BER_CLASS_CON, 2, 0,
3747       dissect_krb5_sq_tickets },
3748     { BER_CLASS_CON, 3, 0,
3749       dissect_krb5_encrypted_CRED },
3750     { 0, 0, 0, NULL }
3751 };
3752 static int
3753 dissect_krb5_CRED(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3754 {
3755
3756     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, CRED_BODY_sequence, hf_krb_CRED_BODY, ett_krb_CRED);
3757
3758     return offset;
3759 }
3760
3761
3762 static int
3763 dissect_krb5_SAFE_BODY_user_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
3764 {
3765     tvbuff_t *new_tvb;
3766     offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_SAFE_BODY_user_data, &new_tvb);
3767     if (new_tvb)
3768         call_kerberos_callbacks(actx->pinfo, tree, new_tvb, KRB_CBTAG_SAFE_USER_DATA, (kerberos_callbacks*)actx->private_data);
3769     return offset;
3770 }
3771 static int
3772 dissect_krb5_SAFE_BODY_timestamp(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3773 {
3774     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_SAFE_BODY_timestamp);
3775     return offset;
3776 }
3777
3778 static int
3779 dissect_krb5_SAFE_BODY_usec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3780 {
3781     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_SAFE_BODY_usec, NULL);
3782     return offset;
3783 }
3784
3785 static ber_old_sequence_t SAFE_BODY_sequence[] = {
3786     { BER_CLASS_CON, 0, 0,
3787       dissect_krb5_SAFE_BODY_user_data },
3788     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3789       dissect_krb5_SAFE_BODY_timestamp },
3790     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
3791       dissect_krb5_SAFE_BODY_usec },
3792     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3793       dissect_krb5_seq_number },
3794     /*XXX this one is OPTIONAL in packetcable?  but mandatory in kerberos */
3795     { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
3796       dissect_krb5_s_address },
3797     { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
3798       dissect_krb5_HostAddresses },
3799     { 0, 0, 0, NULL }
3800 };
3801 static int
3802 dissect_krb5_SAFE_BODY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3803 {
3804
3805     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, SAFE_BODY_sequence, -1, -1);
3806
3807     return offset;
3808 }
3809
3810
3811
3812 static ber_old_sequence_t SAFE_sequence[] = {
3813     { BER_CLASS_CON, 0, 0,
3814       dissect_krb5_pvno },
3815     { BER_CLASS_CON, 1, 0,
3816       dissect_krb5_msg_type },
3817     { BER_CLASS_CON, 2, 0,
3818       dissect_krb5_SAFE_BODY },
3819     { BER_CLASS_CON, 3, 0,
3820       dissect_krb5_Checksum },
3821     { 0, 0, 0, NULL }
3822 };
3823 static int
3824 dissect_krb5_SAFE(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3825 {
3826
3827     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, SAFE_sequence, -1, -1);
3828
3829     return offset;
3830 }
3831
3832 #ifdef HAVE_KERBEROS
3833 static guint32 enc_authorization_data_etype;
3834
3835 static int
3836 dissect_krb5_decrypt_enc_authorization_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3837 {
3838     guint8 *plaintext=NULL;
3839     int length;
3840     tvbuff_t *next_tvb;
3841
3842     next_tvb=tvb_new_subset_remaining(tvb, offset);
3843
3844     length=tvb_length_remaining(tvb, offset);
3845
3846     /*
3847       RFC 4120 : 5.4.1
3848       The key usage value used when encrypting is 5
3849       if a sub-session key is used, or 4 if the session key is used.
3850     */
3851     if(!plaintext){
3852         plaintext=decrypt_krb5_data(tree, actx->pinfo, 4, next_tvb, enc_authorization_data_etype, NULL);
3853     }
3854     if(!plaintext){
3855         plaintext=decrypt_krb5_data(tree, actx->pinfo, 5, next_tvb, enc_authorization_data_etype, NULL);
3856     }
3857
3858     if(plaintext){
3859         tvbuff_t *child_tvb;
3860         child_tvb = tvb_new_child_real_data(tvb, plaintext,
3861                                             length,
3862                                             length);
3863         tvb_set_free_cb(child_tvb, g_free);
3864
3865         /* Add the decrypted data to the data source list. */
3866         add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
3867
3868
3869         proto_tree_add_text(tree, child_tvb, 0, length, "AtuhorizationData for TGS_REQ not implemented yet");
3870
3871     }
3872     return offset;
3873 }
3874 #endif
3875
3876 static int
3877 dissect_krb5_encrypted_enc_authorization_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3878 {
3879 #ifdef HAVE_KERBEROS
3880     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_enc_authorization_data, dissect_krb5_decrypt_enc_authorization_data);
3881 #else
3882     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_enc_authorization_data, NULL);
3883 #endif
3884     return offset;
3885 }
3886
3887 static int
3888 dissect_krb5_enc_authorization_data_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3889 {
3890 #ifndef HAVE_KERBEROS
3891     guint32 enc_authorization_data_etype;
3892 #endif
3893     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &enc_authorization_data_etype);
3894     if(tree){
3895         proto_item_append_text(tree, " %s",
3896                                val_to_str(enc_authorization_data_etype, krb5_encryption_types,
3897                                           "%#x"));
3898     }
3899     return offset;
3900 }
3901 static ber_old_sequence_t enc_authorization_data_sequence[] = {
3902     { BER_CLASS_CON, 0, 0,
3903       dissect_krb5_enc_authorization_data_etype },
3904     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3905       dissect_krb5_kvno },
3906     { BER_CLASS_CON, 2, 0,
3907       dissect_krb5_encrypted_enc_authorization_data },
3908     { 0, 0, 0, NULL }
3909 };
3910 static int
3911 dissect_krb5_enc_authorization_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3912 {
3913     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, enc_authorization_data_sequence, -1, -1);
3914
3915     return offset;
3916 }
3917
3918 /*
3919  * KDC-REQ-BODY ::=   SEQUENCE {
3920  *           kdc-options[0]       KDCOptions,
3921  *           cname[1]             PrincipalName OPTIONAL,
3922  *                        -- Used only in AS-REQ
3923  *           realm[2]             Realm, -- Server's realm
3924  *                        -- Also client's in AS-REQ
3925  *           sname[3]             PrincipalName OPTIONAL,
3926  *           from[4]              KerberosTime OPTIONAL,
3927  *           till[5]              KerberosTime,
3928  *           rtime[6]             KerberosTime OPTIONAL,
3929  *           nonce[7]             INTEGER,
3930  *           etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
3931  *                        -- in preference order
3932  *           addresses[9]         HostAddresses OPTIONAL,
3933  *           enc-authorization-data[10]   EncryptedData OPTIONAL,
3934  *                        -- Encrypted AuthorizationData encoding
3935  *           additional-tickets[11]       SEQUENCE OF Ticket OPTIONAL
3936  * }
3937  *
3938  */
3939 static ber_old_sequence_t KDC_REQ_BODY_sequence[] = {
3940     { BER_CLASS_CON, 0, 0,
3941       dissect_krb5_KDCOptions },
3942     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3943       dissect_krb5_cname },
3944     { BER_CLASS_CON, 2, 0,
3945       dissect_krb5_realm},
3946     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3947       dissect_krb5_sname },
3948     { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
3949       dissect_krb5_from },
3950     /* this field is not optional in the kerberos spec,
3951      * however, in the packetcable spec it is optional.
3952      * make it optional here since normal kerberos will
3953      * still decode the pdu correctly.
3954      */
3955     { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
3956       dissect_krb5_till },
3957     { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
3958       dissect_krb5_rtime },
3959     { BER_CLASS_CON, 7, 0,
3960       dissect_krb5_nonce },
3961     { BER_CLASS_CON, 8, 0,
3962       dissect_krb5_etype_sequence_of },
3963     { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
3964       dissect_krb5_HostAddresses },
3965     { BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL,
3966       dissect_krb5_enc_authorization_data },
3967     { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
3968       dissect_krb5_sq_tickets },
3969     { 0, 0, 0, NULL }
3970 };
3971 static int
3972 dissect_krb5_KDC_REQ_BODY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3973 {
3974     conversation_t *conversation;
3975
3976     /*
3977      * UDP replies to KDC_REQs are sent from the server back to the client's
3978      * source port, similar to the way TFTP works.  Set up a conversation
3979      * accordingly.
3980      *
3981      * Ref: Section 7.2.1 of
3982      * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-07.txt
3983      */
3984     if (actx->pinfo->destport == UDP_PORT_KERBEROS && actx->pinfo->ptype == PT_UDP) {
3985         conversation = find_conversation(actx->pinfo->fd->num, &actx->pinfo->src, &actx->pinfo->dst, PT_UDP,
3986                                          actx->pinfo->srcport, 0, NO_PORT_B);
3987         if (conversation == NULL) {
3988             conversation = conversation_new(actx->pinfo->fd->num, &actx->pinfo->src, &actx->pinfo->dst, PT_UDP,
3989                                             actx->pinfo->srcport, 0, NO_PORT2);
3990             conversation_set_dissector(conversation, kerberos_handle_udp);
3991         }
3992     }
3993
3994     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, KDC_REQ_BODY_sequence, hf_krb_KDC_REQ_BODY, ett_krb_request);
3995
3996     return offset;
3997 }
3998
3999
4000
4001 /*
4002  * KDC-REQ ::=        SEQUENCE {
4003  *          pvno[1]               INTEGER,
4004  *          msg-type[2]           INTEGER,
4005  *          padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
4006  *          req-body[4]           KDC-REQ-BODY
4007  * }
4008  */
4009 static ber_old_sequence_t KDC_REQ_sequence[] = {
4010     { BER_CLASS_CON, 1, 0,
4011       dissect_krb5_pvno },
4012     { BER_CLASS_CON, 2, 0,
4013       dissect_krb5_msg_type },
4014     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
4015       dissect_krb5_padata },
4016     { BER_CLASS_CON, 4, 0,
4017       dissect_krb5_KDC_REQ_BODY },
4018     { 0, 0, 0, NULL }
4019 };
4020 static int
4021 dissect_krb5_KDC_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4022 {
4023     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, KDC_REQ_sequence, -1, -1);
4024
4025     return offset;
4026 }
4027
4028
4029 #ifdef HAVE_KERBEROS
4030 static int
4031 dissect_krb5_decrypt_authenticator_data (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4032 {
4033     guint8 *plaintext=NULL;
4034     int length;
4035     tvbuff_t *next_tvb;
4036
4037     next_tvb=tvb_new_subset_remaining(tvb, offset);
4038
4039     length=tvb_length_remaining(tvb, offset);
4040
4041     /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
4042      * 7.5.1
4043      * Authenticators are encrypted with usage
4044      * == 7 or
4045      * == 11
4046      */
4047     if(!plaintext){
4048         plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, authenticator_etype, NULL);
4049     }
4050     if(!plaintext){
4051         plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, authenticator_etype, NULL);
4052     }
4053
4054     if(plaintext){
4055         tvbuff_t *child_tvb;
4056         child_tvb = tvb_new_child_real_data(tvb, plaintext,
4057                                             length,
4058                                             length);
4059         tvb_set_free_cb(child_tvb, g_free);
4060
4061         /* Add the decrypted data to the data source list. */
4062         add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
4063
4064
4065         offset=dissect_ber_old_choice(actx, tree, child_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
4066
4067     }
4068     return offset;
4069 }
4070 #endif
4071
4072
4073 /*
4074  *  EncryptedData ::=   SEQUENCE {
4075  *                      etype[0]     INTEGER, -- EncryptionType
4076  *                      kvno[1]      INTEGER OPTIONAL,
4077  *                      cipher[2]    OCTET STRING -- ciphertext
4078  *  }
4079  */
4080 static int
4081 dissect_krb5_encrypted_authenticator_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4082 {
4083 #ifdef HAVE_KERBEROS
4084     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_authenticator_data, dissect_krb5_decrypt_authenticator_data);
4085 #else
4086     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_authenticator_data, NULL);
4087 #endif
4088     return offset;
4089 }
4090 static ber_old_sequence_t encrypted_authenticator_sequence[] = {
4091     { BER_CLASS_CON, 0, 0,
4092       dissect_krb5_authenticator_etype },
4093     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
4094       dissect_krb5_kvno },
4095     { BER_CLASS_CON, 2, 0,
4096       dissect_krb5_encrypted_authenticator_data },
4097     { 0, 0, 0, NULL }
4098 };
4099 static int
4100 dissect_krb5_encrypted_authenticator(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4101 {
4102     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, encrypted_authenticator_sequence, hf_krb_authenticator_enc, ett_krb_authenticator_enc);
4103
4104     return offset;
4105 }
4106
4107
4108
4109
4110 static int
4111 dissect_krb5_tkt_vno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4112 {
4113     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_tkt_vno, NULL);
4114     return offset;
4115 }
4116
4117
4118 #ifdef HAVE_KERBEROS
4119 static int
4120 dissect_krb5_decrypt_Ticket_data (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4121 {
4122     guint8 *plaintext;
4123     int length;
4124     tvbuff_t *next_tvb;
4125
4126     next_tvb=tvb_new_subset_remaining(tvb, offset);
4127
4128     length=tvb_length_remaining(tvb, offset);
4129
4130     /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
4131      * 7.5.1
4132      * All Ticket encrypted parts use usage == 2
4133      */
4134     if( (plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, Ticket_etype, NULL)) ){
4135         tvbuff_t *child_tvb;
4136         child_tvb = tvb_new_child_real_data(tvb, plaintext,
4137                                             length,
4138                                             length);
4139         tvb_set_free_cb(child_tvb, g_free);
4140
4141         /* Add the decrypted data to the data source list. */
4142         add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
4143
4144
4145         offset=dissect_ber_old_choice(actx, tree, child_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
4146
4147     }
4148     return offset;
4149 }
4150 #endif
4151
4152 static int
4153 dissect_krb5_encrypted_Ticket_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4154 {
4155 #ifdef HAVE_KERBEROS
4156     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_Ticket_data, dissect_krb5_decrypt_Ticket_data);
4157 #else
4158     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_Ticket_data, NULL);
4159 #endif
4160     return offset;
4161 }
4162 static ber_old_sequence_t encrypted_Ticket_sequence[] = {
4163     { BER_CLASS_CON, 0, 0,
4164       dissect_krb5_Ticket_etype },
4165     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
4166       dissect_krb5_kvno },
4167     { BER_CLASS_CON, 2, 0,
4168       dissect_krb5_encrypted_Ticket_data },
4169     { 0, 0, 0, NULL }
4170 };
4171 static int
4172 dissect_krb5_Ticket_encrypted(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4173 {
4174     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, encrypted_Ticket_sequence, hf_krb_ticket_enc, ett_krb_ticket_enc);
4175
4176     return offset;
4177 }
4178
4179 static ber_old_sequence_t Application_1_sequence[] = {
4180     { BER_CLASS_CON, 0, 0,
4181       dissect_krb5_tkt_vno },
4182     { BER_CLASS_CON, 1, 0,
4183       dissect_krb5_realm },
4184     { BER_CLASS_CON, 2, 0,
4185       dissect_krb5_sname },
4186     { BER_CLASS_CON, 3, 0,
4187       dissect_krb5_Ticket_encrypted },
4188     { 0, 0, 0, NULL }
4189 };
4190 static int
4191 dissect_krb5_Application_1(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4192 {
4193     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, Application_1_sequence, hf_krb_ticket, ett_krb_ticket);
4194
4195     return offset;
4196 }
4197
4198
4199
4200 static const ber_old_choice_t Ticket_choice[] = {
4201     { 1, BER_CLASS_APP, 1,  0,
4202       dissect_krb5_Application_1 },
4203     { 0, 0, 0, 0, NULL }
4204 };
4205 static int
4206 dissect_krb5_Ticket(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4207 {
4208     offset=dissect_ber_old_choice(actx, tree, tvb, offset, Ticket_choice, -1, -1, NULL);
4209
4210     return offset;
4211 }
4212
4213
4214
4215
4216 /*
4217  *  AP-REQ ::=      [APPLICATION 14] SEQUENCE {
4218  *                  pvno[0]                       INTEGER,
4219  *                  msg-type[1]                   INTEGER,
4220  *                  ap-options[2]                 APOptions,
4221  *                  ticket[3]                     Ticket,
4222  *                  authenticator[4]              EncryptedData
4223  *  }
4224  */
4225 static ber_old_sequence_t AP_REQ_sequence[] = {
4226     { BER_CLASS_CON, 0, 0,
4227       dissect_krb5_pvno },
4228     { BER_CLASS_CON, 1, 0,
4229       dissect_krb5_msg_type },
4230     { BER_CLASS_CON, 2, 0,
4231       dissect_krb5_APOptions },
4232     { BER_CLASS_CON, 3, 0,
4233       dissect_krb5_Ticket },
4234     { BER_CLASS_CON, 4, 0,
4235       dissect_krb5_encrypted_authenticator },
4236     { 0, 0, 0, NULL }
4237 };
4238 static int
4239 dissect_krb5_AP_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4240 {
4241     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, AP_REQ_sequence, -1, -1);
4242
4243     return offset;
4244 }
4245
4246
4247
4248
4249 #ifdef HAVE_KERBEROS
4250 static int
4251 dissect_krb5_decrypt_AP_REP_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4252 {
4253     guint8 *plaintext=NULL;
4254     int length;
4255
4256     length=tvb_length_remaining(tvb, offset);
4257
4258     /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
4259      * 7.5.1
4260      * Authenticators are encrypted with usage
4261      * == 7 or
4262      * == 11
4263      */
4264     if(!plaintext){
4265         tvbuff_t *next_tvb;
4266
4267         next_tvb=tvb_new_subset_remaining(tvb, offset);
4268         plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, AP_REP_etype, NULL);
4269     }
4270
4271     if(plaintext){
4272         tvbuff_t *next_tvb;
4273         next_tvb = tvb_new_child_real_data(tvb, plaintext,
4274                                            length,
4275                                            length);
4276         tvb_set_free_cb(next_tvb, g_free);
4277
4278         /* Add the decrypted data to the data source list. */
4279         add_new_data_source(actx->pinfo, next_tvb, "Decrypted Krb5");
4280
4281
4282         offset=dissect_ber_old_choice(actx, tree, next_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
4283
4284     }
4285     return offset;
4286 }
4287 #endif
4288
4289
4290 static int
4291 dissect_krb5_encrypted_AP_REP_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4292 {
4293 #ifdef HAVE_KERBEROS
4294     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_AP_REP_data, dissect_krb5_decrypt_AP_REP_data);
4295 #else
4296     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_AP_REP_data, NULL);
4297 #endif
4298     return offset;
4299 }
4300 static ber_old_sequence_t encrypted_AP_REP_sequence[] = {
4301     { BER_CLASS_CON, 0, 0,
4302       dissect_krb5_AP_REP_etype },
4303     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
4304       dissect_krb5_kvno },
4305     { BER_CLASS_CON, 2, 0,
4306       dissect_krb5_encrypted_AP_REP_data },
4307     { 0, 0, 0, NULL }
4308 };
4309 static int
4310 dissect_krb5_encrypted_AP_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4311 {
4312     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, encrypted_AP_REP_sequence, hf_krb_AP_REP_enc, ett_krb_AP_REP_enc);
4313
4314     return offset;
4315 }
4316
4317 /*
4318  *  AP-REP ::=         [APPLICATION 15] SEQUENCE {
4319  *             pvno[0]                   INTEGER,
4320  *             msg-type[1]               INTEGER,
4321  *             enc-part[2]               EncryptedData
4322  *  }
4323  */
4324 static ber_old_sequence_t AP_REP_sequence[] = {
4325     { BER_CLASS_CON, 0, 0,
4326       dissect_krb5_pvno },
4327     { BER_CLASS_CON, 1, 0,
4328       dissect_krb5_msg_type },
4329     { BER_CLASS_CON, 2, 0,
4330       dissect_krb5_encrypted_AP_REP },
4331     { 0, 0, 0, NULL }
4332 };
4333 static int
4334 dissect_krb5_AP_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4335 {
4336     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, AP_REP_sequence, -1, -1);
4337
4338     return offset;
4339 }
4340
4341
4342
4343
4344
4345 static guint32 KDC_REP_etype;
4346 static int
4347 dissect_krb5_KDC_REP_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4348 {
4349     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &KDC_REP_etype);
4350     if(tree){
4351         proto_item_append_text(tree, " %s",
4352                                val_to_str(KDC_REP_etype, krb5_encryption_types,
4353                                           "%#x"));
4354     }
4355     return offset;
4356 }
4357
4358 #ifdef HAVE_KERBEROS
4359 static int
4360 dissect_krb5_decrypt_KDC_REP_data (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4361 {
4362     guint8 *plaintext=NULL;
4363     int length;
4364     tvbuff_t *next_tvb;
4365
4366     next_tvb=tvb_new_subset_remaining(tvb, offset);
4367
4368     length=tvb_length_remaining(tvb, offset);
4369
4370     /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
4371      * 7.5.1
4372      * ASREP/TGSREP encryptedparts are encrypted with usage
4373      * == 3 or
4374      * == 8 or
4375      * == 9
4376      */
4377     if(!plaintext){
4378         plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, KDC_REP_etype, NULL);
4379     }
4380     if(!plaintext){
4381         plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, KDC_REP_etype, NULL);
4382     }
4383     if(!plaintext){
4384         plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, KDC_REP_etype, NULL);
4385     }
4386
4387     if(plaintext){
4388         tvbuff_t *child_tvb;
4389         child_tvb = tvb_new_child_real_data(tvb, plaintext,
4390                                             length,
4391                                             length);
4392         tvb_set_free_cb(child_tvb, g_free);
4393
4394         /* Add the decrypted data to the data source list. */
4395         add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
4396
4397
4398         offset=dissect_ber_old_choice(actx, tree, child_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
4399
4400     }
4401     return offset;
4402 }
4403 #endif
4404
4405
4406 static int
4407 dissect_krb5_encrypted_KDC_REP_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4408 {
4409 #ifdef HAVE_KERBEROS
4410     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_KDC_REP_data, dissect_krb5_decrypt_KDC_REP_data);
4411 #else
4412     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_KDC_REP_data, NULL);
4413 #endif
4414     return offset;
4415 }
4416 static ber_old_sequence_t encrypted_KDC_REP_sequence[] = {
4417     { BER_CLASS_CON, 0, 0,
4418       dissect_krb5_KDC_REP_etype },
4419     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
4420       dissect_krb5_kvno },
4421     { BER_CLASS_CON, 2, 0,
4422       dissect_krb5_encrypted_KDC_REP_data },
4423     { 0, 0, 0, NULL }
4424 };
4425 static int
4426 dissect_krb5_encrypted_KDC_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4427 {
4428     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, encrypted_KDC_REP_sequence, hf_krb_KDC_REP_enc, ett_krb_KDC_REP_enc);
4429
4430     return offset;
4431 }
4432
4433 /*
4434  *  KDC-REP ::=   SEQUENCE {
4435  *                pvno[0]                    INTEGER,
4436  *                msg-type[1]                INTEGER,
4437  *                padata[2]                  SEQUENCE OF PA-DATA OPTIONAL,
4438  *                crealm[3]                  Realm,
4439  *                cname[4]                   PrincipalName,
4440  *                ticket[5]                  Ticket,
4441  *                enc-part[6]                EncryptedData
4442  *  }
4443  */
4444 static ber_old_sequence_t KDC_REP_sequence[] = {
4445     { BER_CLASS_CON, 0, 0,
4446       dissect_krb5_pvno },
4447     { BER_CLASS_CON, 1, 0,
4448       dissect_krb5_msg_type },
4449     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
4450       dissect_krb5_padata },
4451     { BER_CLASS_CON, 3, 0,
4452       dissect_krb5_crealm },
4453     { BER_CLASS_CON, 4, 0,
4454       dissect_krb5_cname },
4455     { BER_CLASS_CON, 5, 0,
4456       dissect_krb5_Ticket },
4457     { BER_CLASS_CON, 6, 0,
4458       dissect_krb5_encrypted_KDC_REP },
4459     { 0, 0, 0, NULL }
4460 };
4461 static int
4462 dissect_krb5_KDC_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4463 {
4464     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, KDC_REP_sequence, -1, -1);
4465
4466     return offset;
4467 }
4468
4469
4470
4471
4472 static int
4473 dissect_krb5_e_text(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4474 {
4475     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_e_text, NULL, 0);
4476     return offset;
4477 }
4478
4479 static int
4480 dissect_krb5_e_data(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4481 {
4482     switch(krb5_errorcode){
4483     case KRB5_ET_KRB5KDC_ERR_BADOPTION:
4484     case KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED:
4485     case KRB5_ET_KRB5KDC_ERR_KEY_EXP:
4486     case KRB5_ET_KRB5KDC_ERR_POLICY:
4487         /* ms windows kdc sends e-data of this type containing a "salt"
4488          * that contains the nt_status code for these error codes.
4489          */
4490         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_e_data, dissect_krb5_PA_DATA);
4491         break;
4492     case KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED:
4493     case KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED:
4494     case KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP:
4495         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_e_data, dissect_krb5_padata);
4496
4497         break;
4498     default:
4499         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_e_data, NULL);
4500     }
4501     return offset;
4502 }
4503
4504
4505 /* This optional field in KRB_ERR is used by the early drafts which
4506  * PacketCable still use.
4507  */
4508 static int
4509 dissect_krb5_e_checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4510 {
4511     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, Checksum_sequence, hf_krb_e_checksum, ett_krb_e_checksum);
4512
4513     return offset;
4514 }
4515
4516
4517 /*
4518  *  KRB-ERROR ::=   [APPLICATION 30] SEQUENCE {
4519  *                  pvno[0]               INTEGER,
4520  *                  msg-type[1]           INTEGER,
4521  *                  ctime[2]              KerberosTime OPTIONAL,
4522  *                  cusec[3]              INTEGER OPTIONAL,
4523  *                  stime[4]              KerberosTime,
4524  *                  susec[5]              INTEGER,
4525  *                  error-code[6]         INTEGER,
4526  *                  crealm[7]             Realm OPTIONAL,
4527  *                  cname[8]              PrincipalName OPTIONAL,
4528  *                  realm[9]              Realm, -- Correct realm
4529  *                  sname[10]             PrincipalName, -- Correct name
4530  *                  e-text[11]            GeneralString OPTIONAL,
4531  *                  e-data[12]            OCTET STRING OPTIONAL
4532  *  }
4533  *
4534  *  e-data    This field contains additional data about the error for use
4535  *            by the application to help it recover from or handle the
4536  *            error.  If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then
4537  *            the e-data field will contain an encoding of a sequence of
4538  *            padata fields, each corresponding to an acceptable pre-
4539  *            authentication method and optionally containing data for
4540  *            the method:
4541  */
4542 static ber_old_sequence_t ERROR_sequence[] = {
4543     { BER_CLASS_CON, 0, 0,
4544       dissect_krb5_pvno },
4545     { BER_CLASS_CON, 1, 0,
4546       dissect_krb5_msg_type },
4547     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
4548       dissect_krb5_ctime },
4549     { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
4550       dissect_krb5_cusec },
4551     { BER_CLASS_CON, 4, 0,
4552       dissect_krb5_stime },
4553     { BER_CLASS_CON, 5, 0,
4554       dissect_krb5_susec },
4555     { BER_CLASS_CON, 6, 0,
4556       dissect_krb5_error_code },
4557     { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL,
4558       dissect_krb5_crealm },
4559     { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
4560       dissect_krb5_cname },
4561     { BER_CLASS_CON, 9, 0,
4562       dissect_krb5_realm },
4563     { BER_CLASS_CON, 10, 0,
4564       dissect_krb5_sname },
4565     { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
4566       dissect_krb5_e_text },
4567     { BER_CLASS_CON, 12, BER_FLAGS_OPTIONAL,
4568       dissect_krb5_e_data },
4569     { BER_CLASS_CON, 13, BER_FLAGS_OPTIONAL,
4570       dissect_krb5_e_checksum }, /* used by PacketCable */
4571     { 0, 0, 0, NULL }
4572 };
4573 int
4574 dissect_krb5_ERROR(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
4575 {
4576     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, ERROR_sequence, -1, -1);
4577
4578     return offset;
4579 }
4580
4581
4582
4583 static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo,
4584                                     proto_tree *tree, gboolean do_col_info,
4585                                     gboolean do_col_protocol,
4586                                     gboolean have_rm,
4587                                     kerberos_callbacks *cb);
4588 static int dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo,
4589                                      proto_tree *tree, void* data _U_);
4590
4591
4592 gint
4593 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
4594 {
4595     return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
4596 }
4597
4598 guint32
4599 kerberos_output_keytype(void)
4600 {
4601     return keytype;
4602 }
4603
4604 static gint
4605 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4606 {
4607     /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
4608        Since all (except weirdo transarc krb4 stuff) use
4609        an opcode <=16 in the first byte, use this to see if it might
4610        be krb4.
4611        All krb5 commands start with an APPL tag and thus is >=0x60
4612        so if first byte is <=16  just blindly assume it is krb4 then
4613     */
4614     if(tvb_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
4615         if(krb4_handle){
4616             gboolean res;
4617
4618             res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
4619             return res;
4620         }else{
4621             return 0;
4622         }
4623     }
4624
4625
4626     return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
4627 }
4628
4629 gint
4630 kerberos_rm_to_reclen(guint krb_rm)
4631 {
4632     return (krb_rm & KRB_RM_RECLEN);
4633 }
4634
4635 guint
4636 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
4637 {
4638     guint krb_rm;
4639     gint pdulen;
4640
4641     krb_rm = tvb_get_ntohl(tvb, offset);
4642     pdulen = kerberos_rm_to_reclen(krb_rm);
4643     return (pdulen + 4);
4644 }
4645
4646 static int
4647 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4648 {
4649     pinfo->fragmented = TRUE;
4650     if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
4651         /*
4652          * The dissector failed to recognize this as a valid
4653          * Kerberos message.  Mark it as a continuation packet.
4654          */
4655         col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
4656     }
4657
4658     return tvb_length(tvb);
4659 }
4660
4661 static int
4662 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
4663 {
4664     col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
4665     col_clear(pinfo->cinfo, COL_INFO);
4666
4667     tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
4668                      dissect_kerberos_tcp_pdu, data);
4669     return tvb_length(tvb);
4670 }
4671
4672 /*
4673  * Display the TCP record mark.
4674  */
4675 void
4676 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
4677 {
4678     gint rec_len;
4679     proto_item *rm_item;
4680     proto_tree *rm_tree;
4681
4682     if (tree == NULL)
4683         return;
4684
4685     rec_len = kerberos_rm_to_reclen(krb_rm);
4686     rm_item = proto_tree_add_text(tree, tvb, start, 4,
4687                                   "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
4688     rm_tree = proto_item_add_subtree(rm_item, ett_krb_recordmark);
4689     proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
4690     proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
4691 }
4692
4693
4694 static gint
4695 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4696                         gboolean dci, gboolean do_col_protocol, gboolean have_rm,
4697                         kerberos_callbacks *cb)
4698 {
4699     volatile int offset = 0;
4700     proto_tree *volatile kerberos_tree = NULL;
4701     proto_item *volatile item = NULL;
4702     asn1_ctx_t asn1_ctx;
4703
4704     /* TCP record mark and length */
4705     guint32 krb_rm = 0;
4706     gint krb_reclen = 0;
4707
4708     gbl_do_col_info=dci;
4709
4710     if (have_rm) {
4711         krb_rm = tvb_get_ntohl(tvb, offset);
4712         krb_reclen = kerberos_rm_to_reclen(krb_rm);
4713         /*
4714          * What is a reasonable size limit?
4715          */
4716         if (krb_reclen > 10 * 1024 * 1024) {
4717             return (-1);
4718         }
4719         if (do_col_protocol) {
4720             col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
4721         }
4722         if (tree) {
4723             item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
4724             kerberos_tree = proto_item_add_subtree(item, ett_krb_kerberos);
4725         }
4726         show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
4727         offset += 4;
4728     } else {
4729         /* Do some sanity checking here,
4730          * All krb5 packets start with a TAG class that is BER_CLASS_APP
4731          * and a tag value that is either of the values below:
4732          * If it doesnt look like kerberos, return 0 and let someone else have
4733          * a go at it.
4734          */
4735         gint8 tmp_class;
4736         gboolean tmp_pc;
4737         gint32 tmp_tag;
4738
4739         get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
4740         if(tmp_class!=BER_CLASS_APP){
4741             return 0;
4742         }
4743         switch(tmp_tag){
4744         case KRB5_MSG_TICKET:
4745         case KRB5_MSG_AUTHENTICATOR:
4746         case KRB5_MSG_ENC_TICKET_PART:
4747         case KRB5_MSG_AS_REQ:
4748         case KRB5_MSG_AS_REP:
4749         case KRB5_MSG_TGS_REQ:
4750         case KRB5_MSG_TGS_REP:
4751         case KRB5_MSG_AP_REQ:
4752         case KRB5_MSG_AP_REP:
4753         case KRB5_MSG_ENC_AS_REP_PART:
4754         case KRB5_MSG_ENC_TGS_REP_PART:
4755         case KRB5_MSG_ENC_AP_REP_PART:
4756         case KRB5_MSG_ENC_KRB_PRIV_PART:
4757         case KRB5_MSG_ENC_KRB_CRED_PART:
4758         case KRB5_MSG_SAFE:
4759         case KRB5_MSG_PRIV:
4760         case KRB5_MSG_ERROR:
4761             break;
4762         default:
4763             return 0;
4764         }
4765         if (do_col_protocol) {
4766             col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
4767         }
4768         if (gbl_do_col_info) {
4769             col_clear(pinfo->cinfo, COL_INFO);
4770         }
4771         if (tree) {
4772             item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
4773             kerberos_tree = proto_item_add_subtree(item, ett_krb_kerberos);
4774         }
4775     }
4776     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
4777     asn1_ctx.private_data = cb;
4778
4779     TRY {
4780         offset=dissect_ber_old_choice(&asn1_ctx, kerberos_tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
4781     } CATCH_BOUNDS_ERRORS {
4782         RETHROW;
4783     } ENDTRY;
4784
4785     proto_item_set_len(item, offset);
4786     return offset;
4787 }
4788
4789 static void
4790 kerberos_prefs_apply_cb(void) {
4791 #ifdef HAVE_LIBNETTLE
4792     clear_keytab();
4793     read_keytab_file(keytab_filename);
4794 #endif
4795 }
4796
4797 void
4798 proto_register_kerberos(void)
4799 {
4800     static hf_register_info hf[] = {
4801         { &hf_krb_rm_reserved, {
4802                 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
4803                 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
4804         { &hf_krb_rm_reclen, {
4805                 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
4806                 NULL, KRB_RM_RECLEN, NULL, HFILL }},
4807         { &hf_krb_transitedtype, {
4808                 "Type", "kerberos.transited.type", FT_UINT32, BASE_DEC,
4809                 VALS(krb5_transited_types), 0, "Transited Type", HFILL }},
4810         { &hf_krb_transitedcontents, {
4811                 "Contents", "kerberos.transited.contents", FT_BYTES, BASE_NONE,
4812                 NULL, 0, "Transited Contents string", HFILL }},
4813         { &hf_krb_keytype, {
4814                 "Key type", "kerberos.keytype", FT_UINT32, BASE_DEC,
4815                 VALS(krb5_encryption_types), 0, NULL, HFILL }},
4816         { &hf_krb_keyvalue, {
4817                 "Key value", "kerberos.keyvalue", FT_BYTES, BASE_NONE,
4818                 NULL, 0, "Key value (encryption key)", HFILL }},
4819         { &hf_krb_adtype, {
4820                 "Type", "kerberos.adtype", FT_UINT32, BASE_DEC,
4821                 VALS(krb5_ad_types), 0, "Authorization Data Type", HFILL }},
4822         { &hf_krb_IF_RELEVANT_type, {
4823                 "Type", "kerberos.IF_RELEVANT.type", FT_UINT32, BASE_DEC,
4824                 VALS(krb5_ad_types), 0, "IF-RELEVANT Data Type", HFILL }},
4825         { &hf_krb_advalue, {
4826                 "Data", "kerberos.advalue", FT_BYTES, BASE_NONE,
4827                 NULL, 0, "Authentication Data", HFILL }},
4828         { &hf_krb_IF_RELEVANT_value, {
4829                 "Data", "kerberos.IF_RELEVANT.value", FT_BYTES, BASE_NONE,
4830                 NULL, 0, "IF_RELEVANT Data", HFILL }},
4831         { &hf_krb_etype, {
4832                 "Encryption type", "kerberos.etype", FT_INT32, BASE_DEC,
4833                 VALS(krb5_encryption_types), 0, NULL, HFILL }},
4834         { &hf_krb_addr_type, {
4835                 "Addr-type", "kerberos.addr_type", FT_UINT32, BASE_DEC,
4836                 VALS(krb5_address_types), 0, "Address Type", HFILL }},
4837         { &hf_krb_pac_signature_type, {
4838                 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
4839                 NULL, 0, "PAC Signature Type", HFILL }},
4840         { &hf_krb_name_type, {
4841                 "Name-type", "kerberos.name_type", FT_INT32, BASE_DEC,
4842                 VALS(krb5_princ_types), 0, "Type of principal name", HFILL }},
4843         { &hf_krb_lr_type, {
4844                 "Lr-type", "kerberos.lr_type", FT_UINT32, BASE_DEC,
4845                 VALS(krb5_lr_types), 0, "Type of lastreq value", HFILL }},
4846         { &hf_krb_address_ip, {
4847                 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
4848                 NULL, 0, NULL, HFILL }},
4849         { &hf_krb_address_ipv6, {
4850                 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
4851                 NULL, 0, NULL, HFILL }},
4852         { &hf_krb_address_netbios, {
4853                 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
4854                 NULL, 0, "NetBIOS Address and type", HFILL }},
4855         { &hf_krb_authtime, {
4856                 "Authtime", "kerberos.authtime", FT_STRING, BASE_NONE,
4857                 NULL, 0, "Time of initial authentication", HFILL }},
4858         { &hf_krb_SAFE_BODY_timestamp, {
4859                 "Timestamp", "kerberos.SAFE_BODY.timestamp", FT_STRING, BASE_NONE,
4860                 NULL, 0, "Timestamp of this SAFE_BODY", HFILL }},
4861         { &hf_krb_patimestamp, {
4862                 "patimestamp", "kerberos.patimestamp", FT_STRING, BASE_NONE,
4863                 NULL, 0, "Time of client", HFILL }},
4864         { &hf_krb_pausec, {
4865                 "pausec", "kerberos.pausec", FT_UINT32, BASE_DEC,
4866                 NULL, 0, "Microsecond component of client time", HFILL }},
4867         { &hf_krb_lr_time, {
4868                 "Lr-time", "kerberos.lr_time", FT_STRING, BASE_NONE,
4869                 NULL, 0, "Time of LR-entry", HFILL }},
4870         { &hf_krb_starttime, {
4871                 "Start time", "kerberos.starttime", FT_STRING, BASE_NONE,
4872                 NULL, 0, "The time after which the ticket is valid", HFILL }},
4873         { &hf_krb_endtime, {
4874                 "End time", "kerberos.endtime", FT_STRING, BASE_NONE,
4875                 NULL, 0, "The time after which the ticket has expired", HFILL }},
4876         { &hf_krb_key_expire, {
4877                 "Key Expiration", "kerberos.key_expiration", FT_STRING, BASE_NONE,
4878                 NULL, 0, "The time after which the key will expire", HFILL }},
4879         { &hf_krb_renew_till, {
4880                 "Renew-till", "kerberos.renenw_till", FT_STRING, BASE_NONE,
4881                 NULL, 0, "The maximum time we can renew the ticket until", HFILL }},
4882         { &hf_krb_rtime, {
4883                 "rtime", "kerberos.rtime", FT_STRING, BASE_NONE,
4884                 NULL, 0, "Renew Until timestamp", HFILL }},
4885         { &hf_krb_ctime, {
4886                 "ctime", "kerberos.ctime", FT_STRING, BASE_NONE,
4887                 NULL, 0, "Current Time on the client host", HFILL }},
4888         { &hf_krb_cusec, {
4889                 "cusec", "kerberos.cusec", FT_UINT32, BASE_DEC,
4890                 NULL, 0, "micro second component of client time", HFILL }},
4891         { &hf_krb_SAFE_BODY_usec, {
4892                 "usec", "kerberos.SAFE_BODY.usec", FT_UINT32, BASE_DEC,
4893                 NULL, 0, "micro second component of SAFE_BODY time", HFILL }},
4894         { &hf_krb_stime, {
4895                 "stime", "kerberos.stime", FT_STRING, BASE_NONE,
4896                 NULL, 0, "Current Time on the server host", HFILL }},
4897         { &hf_krb_susec, {
4898                 "susec", "kerberos.susec", FT_UINT32, BASE_DEC,
4899                 NULL, 0, "micro second component of server time", HFILL }},
4900         { &hf_krb_error_code, {
4901                 "error_code", "kerberos.error_code", FT_UINT32, BASE_DEC,
4902                 VALS(krb5_error_codes), 0, "Kerberos error code", HFILL }},
4903         { &hf_krb_from, {
4904                 "from", "kerberos.from", FT_STRING, BASE_NONE,
4905                 NULL, 0, "From when the ticket is to be valid (postdating)", HFILL }},
4906         { &hf_krb_till, {
4907                 "till", "kerberos.till", FT_STRING, BASE_NONE,
4908                 NULL, 0, "When the ticket will expire", HFILL }},
4909         { &hf_krb_name_string, {
4910                 "Name", "kerberos.name_string", FT_STRING, BASE_NONE,
4911                 NULL, 0, "String component that is part of a PrincipalName", HFILL }},
4912         { &hf_krb_provsrv_location, {
4913                 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
4914                 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
4915         { &hf_krb_e_text, {
4916                 "e-text", "kerberos.e_text", FT_STRING, BASE_NONE,
4917                 NULL, 0, "Additional (human readable) error description", HFILL }},
4918         { &hf_krb_s4u2self_auth, {
4919                 "S4U2Self Auth", "kerberos.s4u2self.auth", FT_STRING, BASE_NONE,
4920                 NULL, 0, "S4U2Self authentication string", HFILL }},
4921         { &hf_krb_realm, {
4922                 "Realm", "kerberos.realm", FT_STRING, BASE_NONE,
4923                 NULL, 0, "Name of the Kerberos Realm", HFILL }},
4924         { &hf_krb_srealm, {
4925                 "SRealm", "kerberos.srealm", FT_STRING, BASE_NONE,
4926                 NULL, 0, "Name of the Kerberos SRealm", HFILL }},
4927         { &hf_krb_prealm, {
4928                 "Delegated Principal Realm", "kerberos.prealm", FT_STRING, BASE_NONE,
4929                 NULL, 0, "Name of the Kerberos PRealm", HFILL }},
4930         { &hf_krb_crealm, {
4931                 "Client Realm", "kerberos.crealm", FT_STRING, BASE_NONE,
4932                 NULL, 0, "Name of the Clients Kerberos Realm", HFILL }},
4933         { &hf_krb_pac_clientname, {
4934                 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
4935                 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
4936         { &hf_krb_msg_type, {
4937                 "MSG Type", "kerberos.msg.type", FT_UINT32, BASE_DEC,
4938                 VALS(krb5_msg_types), 0, "Kerberos Message Type", HFILL }},
4939         { &hf_krb_APOptions, {
4940                 "APOptions", "kerberos.apoptions", FT_BYTES, BASE_NONE,
4941                 NULL, 0, "Kerberos APOptions bitstring", HFILL }},
4942         { &hf_krb_APOptions_reserved, {
4943                "reserved", "kerberos.apoptions.reserved", FT_BOOLEAN, 32,
4944                 TFS(&krb5_apoptions_reserved), 0x80000000, NULL, HFILL }},
4945         { &hf_krb_APOptions_use_session_key, {
4946                 "Use Session Key", "kerberos.apoptions.use_session_key", FT_BOOLEAN, 32,
4947                 TFS(&krb5_apoptions_use_session_key), 0x40000000, NULL, HFILL }},
4948         { &hf_krb_APOptions_mutual_required, {
4949                 "Mutual required", "kerberos.apoptions.mutual_required", FT_BOOLEAN, 32,
4950                 TFS(&krb5_apoptions_mutual_required), 0x20000000, NULL, HFILL }},
4951         { &hf_krb_KDCOptions, {
4952                 "KDCOptions", "kerberos.kdcoptions", FT_BYTES, BASE_NONE,
4953                 NULL, 0, "Kerberos KDCOptions bitstring", HFILL }},
4954         { &hf_krb_TicketFlags, {
4955                 "Ticket Flags", "kerberos.ticketflags", FT_NONE, BASE_NONE,
4956                 NULL, 0, "Kerberos Ticket Flags", HFILL }},
4957         { &hf_krb_TicketFlags_forwardable, {
4958                 "Forwardable", "kerberos.ticketflags.forwardable", FT_BOOLEAN, 32,
4959                 TFS(&krb5_ticketflags_forwardable), 0x40000000, "Flag controlling whether the tickets are forwardable or not", HFILL }},
4960         { &hf_krb_TicketFlags_forwarded, {
4961                 "Forwarded", "kerberos.ticketflags.forwarded", FT_BOOLEAN, 32,
4962                 TFS(&krb5_ticketflags_forwarded), 0x20000000, "Has this ticket been forwarded?", HFILL }},
4963         { &hf_krb_TicketFlags_proxiable, {
4964                 "Proxiable", "kerberos.ticketflags.proxiable", FT_BOOLEAN, 32,
4965                 TFS(&krb5_ticketflags_proxiable), 0x10000000, "Flag controlling whether the tickets are proxiable or not", HFILL }},
4966         { &hf_krb_TicketFlags_proxy, {
4967                 "Proxy", "kerberos.ticketflags.proxy", FT_BOOLEAN, 32,
4968                 TFS(&krb5_ticketflags_proxy), 0x08000000, "Has this ticket been proxied?", HFILL }},
4969         { &hf_krb_TicketFlags_allow_postdate, {
4970                 "Allow Postdate", "kerberos.ticketflags.allow_postdate", FT_BOOLEAN, 32,
4971                 TFS(&krb5_ticketflags_allow_postdate), 0x04000000, "Flag controlling whether we allow postdated tickets or not", HFILL }},
4972         { &hf_krb_TicketFlags_postdated, {
4973                 "Postdated", "kerberos.ticketflags.postdated", FT_BOOLEAN, 32,
4974                 TFS(&krb5_ticketflags_postdated), 0x02000000, "Whether this ticket is postdated or not", HFILL }},
4975         { &hf_krb_TicketFlags_invalid, {
4976                 "Invalid", "kerberos.ticketflags.invalid", FT_BOOLEAN, 32,
4977                 TFS(&krb5_ticketflags_invalid), 0x01000000, "Whether this ticket is invalid or not", HFILL }},
4978         { &hf_krb_TicketFlags_renewable, {
4979                 "Renewable", "kerberos.ticketflags.renewable", FT_BOOLEAN, 32,
4980                 TFS(&krb5_ticketflags_renewable), 0x00800000, "Whether this ticket is renewable or not", HFILL }},
4981         { &hf_krb_TicketFlags_initial, {
4982                 "Initial", "kerberos.ticketflags.initial", FT_BOOLEAN, 32,
4983                 TFS(&krb5_ticketflags_initial), 0x00400000, "Whether this ticket is an initial ticket or not", HFILL }},
4984         { &hf_krb_TicketFlags_pre_auth, {
4985                 "Pre-Auth", "kerberos.ticketflags.pre_auth", FT_BOOLEAN, 32,
4986                 TFS(&krb5_ticketflags_pre_auth), 0x00200000, "Whether this ticket is pre-authenticated or not", HFILL }},
4987         { &hf_krb_TicketFlags_hw_auth, {
4988                 "HW-Auth", "kerberos.ticketflags.hw_auth", FT_BOOLEAN, 32,
4989                 TFS(&krb5_ticketflags_hw_auth), 0x00100000, "Whether this ticket is hardware-authenticated or not", HFILL }},
4990         { &hf_krb_TicketFlags_transited_policy_checked, {
4991                 "Transited Policy Checked", "kerberos.ticketflags.transited_policy_checked", FT_BOOLEAN, 32,
4992                 TFS(&krb5_ticketflags_transited_policy_checked), 0x00080000, "Whether this ticket is transited policy checked or not", HFILL }},
4993         { &hf_krb_TicketFlags_ok_as_delegate, {
4994                 "Ok As Delegate", "kerberos.ticketflags.ok_as_delegate", FT_BOOLEAN, 32,
4995                 TFS(&krb5_ticketflags_ok_as_delegate), 0x00040000, "Whether this ticket is Ok As Delegate or not", HFILL }},
4996         { &hf_krb_KDC_REQ_BODY, {
4997                 "KDC_REQ_BODY", "kerberos.kdc_req_body", FT_NONE, BASE_NONE,
4998                 NULL, 0, "Kerberos KDC REQuest BODY", HFILL }},
4999         { &hf_krb_PRIV_BODY, {
5000                 "PRIV_BODY", "kerberos.priv_body", FT_NONE, BASE_NONE,
5001                 NULL, 0, "Kerberos PRIVate BODY", HFILL }},
5002         { &hf_krb_CRED_BODY, {
5003                 "CRED_BODY", "kerberos.cred_body", FT_NONE, BASE_NONE,
5004                 NULL, 0, "Kerberos CREDential BODY", HFILL }},
5005         { &hf_krb_encrypted_PRIV, {
5006                 "Encrypted PRIV", "kerberos.enc_priv", FT_NONE, BASE_NONE,
5007                 NULL, 0, "Kerberos Encrypted PRIVate blob data", HFILL }},
5008         { &hf_krb_KDCOptions_forwardable, {
5009                 "Forwardable", "kerberos.kdcoptions.forwardable", FT_BOOLEAN, 32,
5010                 TFS(&krb5_kdcoptions_forwardable), 0x40000000, "Flag controlling whether the tickets are forwardable or not", HFILL }},
5011         { &hf_krb_KDCOptions_forwarded, {
5012                 "Forwarded", "kerberos.kdcoptions.forwarded", FT_BOOLEAN, 32,
5013                 TFS(&krb5_kdcoptions_forwarded), 0x20000000, "Has this ticket been forwarded?", HFILL }},
5014         { &hf_krb_KDCOptions_proxiable, {
5015                 "Proxiable", "kerberos.kdcoptions.proxiable", FT_BOOLEAN, 32,
5016                 TFS(&krb5_kdcoptions_proxiable), 0x10000000, "Flag controlling whether the tickets are proxiable or not", HFILL }},
5017         { &hf_krb_KDCOptions_proxy, {
5018                 "Proxy", "kerberos.kdcoptions.proxy", FT_BOOLEAN, 32,
5019                 TFS(&krb5_kdcoptions_proxy), 0x08000000, "Has this ticket been proxied?", HFILL }},
5020         { &hf_krb_KDCOptions_allow_postdate, {
5021                 "Allow Postdate", "kerberos.kdcoptions.allow_postdate", FT_BOOLEAN, 32,
5022                 TFS(&krb5_kdcoptions_allow_postdate), 0x04000000, "Flag controlling whether we allow postdated tickets or not", HFILL }},
5023         { &hf_krb_KDCOptions_postdated, {
5024                 "Postdated", "kerberos.kdcoptions.postdated", FT_BOOLEAN, 32,
5025                 TFS(&krb5_kdcoptions_postdated), 0x02000000, "Whether this ticket is postdated or not", HFILL }},
5026         { &hf_krb_KDCOptions_renewable, {
5027                 "Renewable", "kerberos.kdcoptions.renewable", FT_BOOLEAN, 32,
5028                 TFS(&krb5_kdcoptions_renewable), 0x00800000, "Whether this ticket is renewable or not", HFILL }},
5029         { &hf_krb_KDCOptions_constrained_delegation, {
5030                 "Constrained Delegation", "kerberos.kdcoptions.constrained_delegation", FT_BOOLEAN, 32,
5031                 TFS(&krb5_kdcoptions_constrained_delegation), 0x00020000, "Do we want a PAC containing constrained delegation info or not", HFILL }},
5032         { &hf_krb_KDCOptions_canonicalize, {
5033                 "Canonicalize", "kerberos.kdcoptions.canonicalize", FT_BOOLEAN, 32,
5034                 TFS(&krb5_kdcoptions_canonicalize), 0x00010000, "Do we want the KDC to canonicalize the principal or not", HFILL }},
5035         { &hf_krb_KDCOptions_opt_hardware_auth, {
5036                 "Opt HW Auth", "kerberos.kdcoptions.opt_hardware_auth", FT_BOOLEAN, 32,
5037                 NULL, 0x00100000, "Opt HW Auth flag", HFILL }},
5038         { &hf_krb_KDCOptions_disable_transited_check, {
5039                 "Disable Transited Check", "kerberos.kdcoptions.disable_transited_check", FT_BOOLEAN, 32,
5040                 TFS(&krb5_kdcoptions_disable_transited_check), 0x00000020, "Whether we should do transited checking or not", HFILL }},
5041         { &hf_krb_KDCOptions_renewable_ok, {
5042                 "Renewable OK", "kerberos.kdcoptions.renewable_ok", FT_BOOLEAN, 32,
5043                 TFS(&krb5_kdcoptions_renewable_ok), 0x00000010, "Whether we accept renewed tickets or not", HFILL }},
5044         { &hf_krb_KDCOptions_enc_tkt_in_skey, {
5045                 "Enc-Tkt-in-Skey", "kerberos.kdcoptions.enc_tkt_in_skey", FT_BOOLEAN, 32,
5046                 TFS(&krb5_kdcoptions_enc_tkt_in_skey), 0x00000008, "Whether the ticket is encrypted in the skey or not", HFILL }},
5047         { &hf_krb_KDCOptions_renew, {
5048                 "Renew", "kerberos.kdcoptions.renew", FT_BOOLEAN, 32,
5049                 TFS(&krb5_kdcoptions_renew), 0x00000002, "Is this a request to renew a ticket?", HFILL }},
5050         { &hf_krb_KDCOptions_validate, {
5051                 "Validate", "kerberos.kdcoptions.validate", FT_BOOLEAN, 32,
5052                 TFS(&krb5_kdcoptions_validate), 0x00000001, "Is this a request to validate a postdated ticket?", HFILL }},
5053         { &hf_krb_pvno, {
5054                 "Pvno", "kerberos.pvno", FT_UINT32, BASE_DEC,
5055                 NULL, 0, "Kerberos Protocol Version Number", HFILL }},
5056         { &hf_krb_kvno, {
5057                 "Kvno", "kerberos.kvno", FT_UINT32, BASE_DEC,
5058                 NULL, 0, "Version Number for the encryption Key", HFILL }},
5059         { &hf_krb_checksum_type, {
5060                 "Type", "kerberos.checksum.type", FT_UINT32, BASE_DEC,
5061                 VALS(krb5_checksum_types), 0, "Type of checksum", HFILL }},
5062         { &hf_krb_authenticator_vno, {
5063                 "Authenticator vno", "kerberos.authenticator_vno", FT_UINT32, BASE_DEC,
5064                 NULL, 0, "Version Number for the Authenticator", HFILL }},
5065         { &hf_krb_encrypted_authenticator_data, {
5066                 "Authenticator data", "kerberos.authenticator.data", FT_BYTES, BASE_NONE,
5067                 NULL, 0, "Data content of an encrypted authenticator", HFILL }},
5068         { &hf_krb_encrypted_EncKrbCredPart, {
5069                 "enc EncKrbCredPart", "kerberos.EncKrbCredPart.encrypted", FT_BYTES, BASE_NONE,
5070                 NULL, 0, "Encrypted EncKrbCredPart blob", HFILL }},
5071         { &hf_krb_encrypted_PA_ENC_TIMESTAMP, {
5072                 "enc PA_ENC_TIMESTAMP", "kerberos.PA_ENC_TIMESTAMP.encrypted", FT_BYTES, BASE_NONE,
5073                 NULL, 0, "Encrypted PA-ENC-TIMESTAMP blob", HFILL }},
5074         { &hf_krb_encrypted_enc_authorization_data, {
5075                 "enc-authorization-data", "kerberos.enc_authorization_data.encrypted", FT_BYTES, BASE_NONE,
5076                 NULL, 0, NULL, HFILL }},
5077         { &hf_krb_PAC_LOGON_INFO, {
5078                 "PAC_LOGON_INFO", "kerberos.PAC_LOGON_INFO", FT_BYTES, BASE_NONE,
5079                 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
5080         { &hf_krb_PAC_CREDENTIAL_TYPE, {
5081                 "PAC_CREDENTIAL_TYPE", "kerberos.PAC_CREDENTIAL_TYPE", FT_BYTES, BASE_NONE,
5082                 NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
5083         { &hf_krb_PAC_SERVER_CHECKSUM, {
5084                 "PAC_SERVER_CHECKSUM", "kerberos.PAC_SERVER_CHECKSUM", FT_BYTES, BASE_NONE,
5085                 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
5086         { &hf_krb_PAC_PRIVSVR_CHECKSUM, {
5087                 "PAC_PRIVSVR_CHECKSUM", "kerberos.PAC_PRIVSVR_CHECKSUM", FT_BYTES, BASE_NONE,
5088                 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
5089         { &hf_krb_PAC_CLIENT_INFO_TYPE, {
5090                 "PAC_CLIENT_INFO_TYPE", "kerberos.PAC_CLIENT_INFO_TYPE", FT_BYTES, BASE_NONE,
5091                 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
5092         { &hf_krb_PAC_S4U_DELEGATION_INFO, {
5093                 "PAC_S4U_DELEGATION_INFO", "kerberos.PAC_S4U_DELEGATION_INFO", FT_BYTES, BASE_NONE,
5094                 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
5095         { &hf_krb_PAC_UPN_DNS_INFO, {
5096                 "UPN_DNS_INFO", "kerberos.PAC_UPN_DNS_INFO", FT_BYTES, BASE_NONE,
5097                 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
5098         { &hf_krb_checksum_checksum, {
5099                 "checksum", "kerberos.checksum.checksum", FT_BYTES, BASE_NONE,
5100                 NULL, 0, "Kerberos Checksum", HFILL }},
5101         { &hf_krb_ENC_PRIV, {
5102                 "enc PRIV", "kerberos.ENC_PRIV", FT_BYTES, BASE_NONE,
5103                 NULL, 0, "Encrypted PRIV blob", HFILL }},
5104         { &hf_krb_encrypted_Ticket_data, {
5105                 "enc-part", "kerberos.ticket.data", FT_BYTES, BASE_NONE,
5106                 NULL, 0, "The encrypted part of a ticket", HFILL }},
5107         { &hf_krb_encrypted_AP_REP_data, {
5108                 "enc-part", "kerberos.aprep.data", FT_BYTES, BASE_NONE,
5109                 NULL, 0, "The encrypted part of AP-REP", HFILL }},
5110         { &hf_krb_encrypted_KDC_REP_data, {
5111                 "enc-part", "kerberos.kdcrep.data", FT_BYTES, BASE_NONE,
5112                 NULL, 0, "The encrypted part of KDC-REP", HFILL }},
5113         { &hf_krb_PA_DATA_value, {
5114                 "Value", "kerberos.padata.value", FT_BYTES, BASE_NONE,
5115                 NULL, 0, "Content of the PADATA blob", HFILL }},
5116         { &hf_krb_etype_info_salt, {
5117                 "Salt", "kerberos.etype_info.salt", FT_BYTES, BASE_NONE,
5118                 NULL, 0, NULL, HFILL }},
5119         { &hf_krb_etype_info2_salt, {
5120                 "Salt", "kerberos.etype_info2.salt", FT_BYTES, BASE_NONE,
5121                 NULL, 0, NULL, HFILL }},
5122         { &hf_krb_etype_info2_s2kparams, {
5123                 "Salt", "kerberos.etype_info.s2kparams", FT_BYTES, BASE_NONE,
5124                 NULL, 0, "S2kparams", HFILL }},
5125         { &hf_krb_SAFE_BODY_user_data, {
5126                 "User Data", "kerberos.SAFE_BODY.user_data", FT_BYTES, BASE_NONE,
5127                 NULL, 0, "SAFE BODY userdata field", HFILL }},
5128         { &hf_krb_PRIV_BODY_user_data, {
5129                 "User Data", "kerberos.PRIV_BODY.user_data", FT_BYTES, BASE_NONE,
5130                 NULL, 0, "PRIV BODY userdata field", HFILL }},
5131         { &hf_krb_pac_signature_signature, {
5132                 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
5133                 NULL, 0, "A PAC signature blob", HFILL }},
5134         { &hf_krb_PA_DATA_type, {
5135                 "Type", "kerberos.padata.type", FT_INT32, BASE_DEC,
5136                 VALS(krb5_preauthentication_types), 0, "Type of preauthentication data", HFILL }},
5137         { &hf_krb_nonce, {
5138                 "Nonce", "kerberos.nonce", FT_UINT32, BASE_DEC,
5139                 NULL, 0, "Kerberos Nonce random number", HFILL }},
5140         { &hf_krb_tkt_vno, {
5141                 "Tkt-vno", "kerberos.tkt_vno", FT_UINT32, BASE_DEC,
5142                 NULL, 0, "Version number for the Ticket format", HFILL }},
5143         { &hf_krb_KrbCredInfo, {
5144                 "KrbCredInfo", "kerberos.KrbCredInfo", FT_NONE, BASE_NONE,
5145                 NULL, 0, "This is a Kerberos KrbCredInfo", HFILL }},
5146         { &hf_krb_HostAddress, {
5147                 "HostAddress", "kerberos.hostaddress", FT_NONE, BASE_NONE,
5148                 NULL, 0, "This is a Kerberos HostAddress sequence", HFILL }},
5149         { &hf_krb_s_address, {
5150                 "S-Address", "kerberos.s_address", FT_NONE, BASE_NONE,
5151                 NULL, 0, "This is the Senders address", HFILL }},
5152         { &hf_krb_r_address, {
5153                 "R-Address", "kerberos.r_address", FT_NONE, BASE_NONE,
5154                 NULL, 0, "This is the Recipient address", HFILL }},
5155         { &hf_krb_key, {
5156                 "key", "kerberos.key", FT_NONE, BASE_NONE,
5157                 NULL, 0, "This is a Kerberos EncryptionKey sequence", HFILL }},
5158         { &hf_krb_subkey, {
5159                 "Subkey", "kerberos.subkey", FT_NONE, BASE_NONE,
5160                 NULL, 0, "This is a Kerberos subkey", HFILL }},
5161         { &hf_krb_seq_number, {
5162                 "Seq Number", "kerberos.seq_number", FT_UINT32, BASE_DEC,
5163                 NULL, 0, "This is a Kerberos sequence number", HFILL }},
5164         { &hf_krb_AuthorizationData, {
5165                 "AuthorizationData", "kerberos.AuthorizationData", FT_NONE, BASE_NONE,
5166                 NULL, 0, "This is a Kerberos AuthorizationData sequence", HFILL }},
5167         { &hf_krb_EncTicketPart, {
5168                 "EncTicketPart", "kerberos.EncTicketPart", FT_NONE, BASE_NONE,
5169                 NULL, 0, "This is a decrypted Kerberos EncTicketPart sequence", HFILL }},
5170         { &hf_krb_EncAPRepPart, {
5171                 "EncAPRepPart", "kerberos.EncAPRepPart", FT_NONE, BASE_NONE,
5172                 NULL, 0, "This is a decrypted Kerberos EncAPRepPart sequence", HFILL }},
5173         { &hf_krb_EncKrbPrivPart, {
5174                 "EncKrbPrivPart", "kerberos.EncKrbPrivPart", FT_NONE, BASE_NONE,
5175                 NULL, 0, "This is a decrypted Kerberos EncKrbPrivPart sequence", HFILL }},
5176         { &hf_krb_EncKrbCredPart, {
5177                 "EncKrbCredPart", "kerberos.EncKrbCredPart", FT_NONE, BASE_NONE,
5178                 NULL, 0, "This is a decrypted Kerberos EncKrbCredPart sequence", HFILL }},
5179         { &hf_krb_EncKDCRepPart, {
5180                 "EncKDCRepPart", "kerberos.EncKDCRepPart", FT_NONE, BASE_NONE,
5181                 NULL, 0, "This is a decrypted Kerberos EncKDCRepPart sequence", HFILL }},
5182         { &hf_krb_LastReq, {
5183                 "LastReq", "kerberos.LastReq", FT_NONE, BASE_NONE,
5184                 NULL, 0, "This is a LastReq sequence", HFILL }},
5185         { &hf_krb_Authenticator, {
5186                 "Authenticator", "kerberos.Authenticator", FT_NONE, BASE_NONE,
5187                 NULL, 0, "This is a decrypted Kerberos Authenticator sequence", HFILL }},
5188         { &hf_krb_Checksum, {
5189                 "Checksum", "kerberos.Checksum", FT_NONE, BASE_NONE,
5190                 NULL, 0, "This is a Kerberos Checksum sequence", HFILL }},
5191         { &hf_krb_HostAddresses, {
5192                 "HostAddresses", "kerberos.hostaddresses", FT_NONE, BASE_NONE,
5193                 NULL, 0, "This is a list of Kerberos HostAddress sequences", HFILL }},
5194         { &hf_krb_IF_RELEVANT, {
5195                 "IF_RELEVANT", "kerberos.if_relevant", FT_NONE, BASE_NONE,
5196                 NULL, 0, "This is a list of IF-RELEVANT sequences", HFILL }},
5197         { &hf_krb_etypes, {
5198                 "Encryption Types", "kerberos.etypes", FT_NONE, BASE_NONE,
5199                 NULL, 0, "This is a list of Kerberos encryption types", HFILL }},
5200         { &hf_krb_KrbCredInfos, {
5201                 "Sequence of KrbCredInfo", "kerberos.KrbCredInfos", FT_NONE, BASE_NONE,
5202                 NULL, 0, "This is a list of KrbCredInfo", HFILL }},
5203         { &hf_krb_sq_tickets, {
5204                 "Tickets", "kerberos.sq.tickets", FT_NONE, BASE_NONE,
5205                 NULL, 0, "This is a list of Kerberos Tickets", HFILL }},
5206         { &hf_krb_LastReqs, {
5207                 "LastReqs", "kerberos.LastReqs", FT_NONE, BASE_NONE,
5208                 NULL, 0, "This is a list of LastReq structures", HFILL }},
5209         { &hf_krb_sname, {
5210                 "Server Name", "kerberos.sname", FT_NONE, BASE_NONE,
5211                 NULL, 0, "This is the name part server's identity", HFILL }},
5212         { &hf_krb_pname, {
5213                 "Delegated Principal Name", "kerberos.pname", FT_NONE, BASE_NONE,
5214                 NULL, 0, "Identity of the delegated principal", HFILL }},
5215         { &hf_krb_cname, {
5216                 "Client Name", "kerberos.cname", FT_NONE, BASE_NONE,
5217                 NULL, 0, "The name part of the client principal identifier", HFILL }},
5218         { &hf_krb_authenticator_enc, {
5219                 "Authenticator", "kerberos.authenticator", FT_NONE, BASE_NONE,
5220                 NULL, 0, "Encrypted authenticator blob", HFILL }},
5221         { &hf_krb_CRED_enc, {
5222                 "EncKrbCredPart", "kerberos.encrypted_cred", FT_NONE, BASE_NONE,
5223                 NULL, 0, "Encrypted Cred blob", HFILL }},
5224         { &hf_krb_ticket_enc, {
5225                 "enc-part", "kerberos.ticket.enc_part", FT_NONE, BASE_NONE,
5226                 NULL, 0, "The structure holding the encrypted part of a ticket", HFILL }},
5227         { &hf_krb_AP_REP_enc, {
5228                 "enc-part", "kerberos.aprep.enc_part", FT_NONE, BASE_NONE,
5229                 NULL, 0, "The structure holding the encrypted part of AP-REP", HFILL }},
5230         { &hf_krb_KDC_REP_enc, {
5231                 "enc-part", "kerberos.kdcrep.enc_part", FT_NONE, BASE_NONE,
5232                 NULL, 0, "The structure holding the encrypted part of KDC-REP", HFILL }},
5233         { &hf_krb_e_data, {
5234                 "e-data", "kerberos.e_data", FT_NONE, BASE_NONE,
5235                 NULL, 0, "The e-data blob", HFILL }},
5236         { &hf_krb_padata, {
5237                 "padata", "kerberos.padata", FT_NONE, BASE_NONE,
5238                 NULL, 0, "Sequence of preauthentication data", HFILL }},
5239         { &hf_krb_ticket, {
5240                 "Ticket", "kerberos.ticket", FT_NONE, BASE_NONE,
5241                 NULL, 0, "This is a Kerberos Ticket", HFILL }},
5242         { &hf_krb_TransitedEncoding, {
5243                 "TransitedEncoding", "kerberos.TransitedEncoding", FT_NONE, BASE_NONE,
5244                 NULL, 0, "This is a Kerberos TransitedEncoding sequence", HFILL }},
5245         { &hf_krb_PA_PAC_REQUEST_flag, {
5246                 "PAC Request", "kerberos.pac_request.flag", FT_BOOLEAN, BASE_NONE,
5247                 NULL, 0, "This is a MS PAC Request Flag", HFILL }},
5248         { &hf_krb_w2k_pac_entries, {
5249                 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
5250                 NULL, 0, "Number of W2k PAC entries", HFILL }},
5251         { &hf_krb_w2k_pac_version, {
5252                 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
5253                 NULL, 0, "Version of PAC structures", HFILL }},
5254         { &hf_krb_w2k_pac_type, {
5255                 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
5256                 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
5257         { &hf_krb_w2k_pac_size, {
5258                 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
5259                 NULL, 0, "Size of W2k PAC entry", HFILL }},
5260         { &hf_krb_w2k_pac_offset, {
5261                 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
5262                 NULL, 0, "Offset to W2k PAC entry", HFILL }},
5263         { &hf_krb_pac_clientid, {
5264                 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5265                 NULL, 0, "ClientID Timestamp", HFILL }},
5266         { &hf_krb_pac_namelen, {
5267                 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
5268                 NULL, 0, "Length of client name", HFILL }},
5269         { &hf_krb_pac_upn_flags, {
5270                 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
5271                 NULL, 0, "UPN flags", HFILL }},
5272         { &hf_krb_pac_upn_dns_offset, {
5273                 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
5274                 NULL, 0, NULL, HFILL }},
5275         { &hf_krb_pac_upn_dns_len, {
5276                 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
5277                 NULL, 0, NULL, HFILL }},
5278         { &hf_krb_pac_upn_upn_offset, {
5279                 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
5280                 NULL, 0, NULL, HFILL }},
5281         { &hf_krb_pac_upn_upn_len, {
5282                 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
5283                 NULL, 0, NULL, HFILL }},
5284         { &hf_krb_pac_upn_upn_name, {
5285                 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
5286                 NULL, 0, NULL, HFILL }},
5287         { &hf_krb_pac_upn_dns_name, {
5288                 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
5289                 NULL, 0, NULL, HFILL }},
5290         { &hf_krb_e_checksum, {
5291                 "e-checksum", "kerberos.e_checksum", FT_NONE, BASE_NONE,
5292                 NULL, 0, "This is a Kerberos e-checksum", HFILL }},
5293         { &hf_krb_gssapi_len, {
5294                 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
5295                 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
5296         { &hf_krb_gssapi_bnd, {
5297                 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
5298                 NULL, 0, "GSSAPI Bnd field", HFILL }},
5299         { &hf_krb_gssapi_c_flag_deleg, {
5300                 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
5301                 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
5302         { &hf_krb_gssapi_c_flag_mutual, {
5303                 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
5304                 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
5305         { &hf_krb_gssapi_c_flag_replay, {
5306                 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
5307                 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
5308         { &hf_krb_gssapi_c_flag_sequence, {
5309                 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
5310                 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
5311         { &hf_krb_gssapi_c_flag_conf, {
5312                 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
5313                 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
5314         { &hf_krb_gssapi_c_flag_integ, {
5315                 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
5316                 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
5317         { &hf_krb_gssapi_c_flag_dce_style, {
5318                 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
5319                 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
5320         { &hf_krb_gssapi_dlgopt, {
5321                 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
5322                 NULL, 0, "GSSAPI DlgOpt", HFILL }},
5323         { &hf_krb_gssapi_dlglen, {
5324                 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
5325                 NULL, 0, "GSSAPI DlgLen", HFILL }},
5326         { &hf_krb_smb_nt_status, {
5327                 "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
5328                 &NT_errors_ext, 0, "NT Status code", HFILL }},
5329         { &hf_krb_smb_unknown, {
5330                 "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
5331                 NULL, 0, NULL, HFILL }},
5332         { &hf_krb_midl_blob_len, {
5333                 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
5334                 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
5335         { &hf_krb_midl_fill_bytes, {
5336                 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
5337                 NULL, 0, "Just some fill bytes", HFILL }},
5338         { &hf_krb_midl_version, {
5339                 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
5340                 NULL, 0, "Version of pickling", HFILL }},
5341         { &hf_krb_midl_hdr_len, {
5342                 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
5343                 NULL, 0, "Length of header", HFILL }},
5344
5345     };
5346
5347     static gint *ett[] = {
5348         &ett_krb_kerberos,
5349         &ett_krb_KDC_REP_enc,
5350         &ett_krb_sname,
5351         &ett_krb_pname,
5352         &ett_krb_cname,
5353         &ett_krb_AP_REP_enc,
5354         &ett_krb_padata,
5355         &ett_krb_etypes,
5356         &ett_krb_KrbCredInfos,
5357         &ett_krb_sq_tickets,
5358         &ett_krb_LastReqs,
5359         &ett_krb_IF_RELEVANT,
5360         &ett_krb_PA_DATA_tree,
5361         &ett_krb_s_address,
5362         &ett_krb_r_address,
5363         &ett_krb_KrbCredInfo,
5364         &ett_krb_HostAddress,
5365         &ett_krb_HostAddresses,
5366         &ett_krb_authenticator_enc,
5367         &ett_krb_CRED_enc,
5368         &ett_krb_AP_Options,
5369         &ett_krb_KDC_Options,
5370         &ett_krb_Ticket_Flags,
5371         &ett_krb_request,
5372         &ett_krb_recordmark,
5373         &ett_krb_ticket,
5374         &ett_krb_ticket_enc,
5375         &ett_krb_CRED,
5376         &ett_krb_PRIV,
5377         &ett_krb_PRIV_enc,
5378         &ett_krb_EncTicketPart,
5379         &ett_krb_EncAPRepPart,
5380         &ett_krb_EncKrbPrivPart,
5381         &ett_krb_EncKrbCredPart,
5382         &ett_krb_EncKDCRepPart,
5383         &ett_krb_LastReq,
5384         &ett_krb_Authenticator,
5385         &ett_krb_Checksum,
5386         &ett_krb_key,
5387         &ett_krb_subkey,
5388         &ett_krb_AuthorizationData,
5389         &ett_krb_TransitedEncoding,
5390         &ett_krb_PAC,
5391         &ett_krb_PAC_LOGON_INFO,
5392         &ett_krb_PAC_SERVER_CHECKSUM,
5393         &ett_krb_PAC_PRIVSVR_CHECKSUM,
5394         &ett_krb_PAC_CLIENT_INFO_TYPE,
5395         &ett_krb_PAC_S4U_DELEGATION_INFO,
5396         &ett_krb_e_checksum,
5397         &ett_krb_PAC_MIDL_BLOB,
5398         &ett_krb_PAC_DREP,
5399         &ett_krb_PAC_UPN_DNS_INFO
5400     };
5401     static ei_register_info ei[] = {
5402         { &ei_krb_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decrypted keytype", EXPFILL }},
5403     };
5404     module_t *krb_module;
5405     expert_module_t *expert_krb;
5406
5407     proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
5408     proto_register_field_array(proto_kerberos, hf, array_length(hf));
5409     proto_register_subtree_array(ett, array_length(ett));
5410     expert_krb = expert_register_protocol(proto_kerberos);
5411     expert_register_field_array(expert_krb, ei, array_length(ei));
5412
5413     /* Register preferences */
5414     krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
5415     prefs_register_bool_preference(krb_module, "desegment",
5416         "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
5417         "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
5418         " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
5419         &krb_desegment);
5420 #ifdef HAVE_KERBEROS
5421     prefs_register_bool_preference(krb_module, "decrypt",
5422         "Try to decrypt Kerberos blobs",
5423         "Whether the dissector should try to decrypt "
5424         "encrypted Kerberos blobs. This requires that the proper "
5425         "keytab file is installed as well.",
5426         &krb_decrypt);
5427
5428     prefs_register_filename_preference(krb_module, "file",
5429         "Kerberos keytab file",
5430         "The keytab file containing all the secrets",
5431         &keytab_filename);
5432 #endif
5433
5434 }
5435
5436 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
5437                                  proto_tree *tree, dcerpc_info *di _U_, guint8 *drep _U_)
5438 {
5439     tvbuff_t *auth_tvb;
5440
5441     auth_tvb = tvb_new_subset_remaining(tvb, offset);
5442
5443     dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
5444
5445     return tvb_length_remaining(tvb, offset);
5446 }
5447
5448
5449 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
5450     wrap_dissect_gss_kerb,                      /* Bind */
5451     wrap_dissect_gss_kerb,                      /* Bind ACK */
5452     wrap_dissect_gss_kerb,                      /* AUTH3 */
5453     NULL,                                       /* Request verifier */
5454     NULL,                                       /* Response verifier */
5455     NULL,                                       /* Request data */
5456     NULL                                        /* Response data */
5457 };
5458
5459 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
5460     wrap_dissect_gss_kerb,                      /* Bind */
5461     wrap_dissect_gss_kerb,                      /* Bind ACK */
5462     wrap_dissect_gss_kerb,                      /* AUTH3 */
5463     wrap_dissect_gssapi_verf,                   /* Request verifier */
5464     wrap_dissect_gssapi_verf,                   /* Response verifier */
5465     NULL,                                       /* Request data */
5466     NULL                                        /* Response data */
5467 };
5468
5469 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
5470     wrap_dissect_gss_kerb,                      /* Bind */
5471     wrap_dissect_gss_kerb,                      /* Bind ACK */
5472     wrap_dissect_gss_kerb,                      /* AUTH3 */
5473     wrap_dissect_gssapi_verf,                   /* Request verifier */
5474     wrap_dissect_gssapi_verf,                   /* Response verifier */
5475     wrap_dissect_gssapi_payload,                /* Request data */
5476     wrap_dissect_gssapi_payload                 /* Response data */
5477 };
5478
5479
5480 void
5481 proto_reg_handoff_kerberos(void)
5482 {
5483     dissector_handle_t kerberos_handle_tcp;
5484
5485     krb4_handle = find_dissector("krb4");
5486
5487     kerberos_handle_udp = new_create_dissector_handle(dissect_kerberos_udp,
5488                                                       proto_kerberos);
5489     kerberos_handle_tcp = new_create_dissector_handle(dissect_kerberos_tcp,
5490                                                   proto_kerberos);
5491     dissector_add_uint("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
5492     dissector_add_uint("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
5493
5494     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
5495                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
5496                                       &gss_kerb_auth_connect_fns);
5497
5498     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
5499                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
5500                                       &gss_kerb_auth_sign_fns);
5501
5502     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
5503                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
5504                                       &gss_kerb_auth_seal_fns);
5505
5506 }
5507
5508 /*
5509
5510   MISC definitions from RFC1510:
5511
5512    Realm ::=           GeneralString
5513
5514    KerberosTime ::=   GeneralizedTime
5515
5516    AuthorizationData ::=   SEQUENCE OF SEQUENCE {
5517                            ad-type[0]               INTEGER,
5518                            ad-data[1]               OCTET STRING
5519    }
5520                    APOptions ::=   BIT STRING {
5521                                    reserved(0),
5522                                    use-session-key(1),
5523                                    mutual-required(2)
5524                    }
5525
5526
5527                    TicketFlags ::=   BIT STRING {
5528                                      reserved(0),
5529                                      forwardable(1),
5530                                      forwarded(2),
5531                                      proxiable(3),
5532                                      proxy(4),
5533                                      may-postdate(5),
5534                                      postdated(6),
5535                                      invalid(7),
5536                                      renewable(8),
5537                                      initial(9),
5538                                      pre-authent(10),
5539                                      hw-authent(11)
5540                    }
5541
5542                   KDCOptions ::=   BIT STRING {
5543                                    reserved(0),
5544                                    forwardable(1),
5545                                    forwarded(2),
5546                                    proxiable(3),
5547                                    proxy(4),
5548                                    allow-postdate(5),
5549                                    postdated(6),
5550                                    unused7(7),
5551                                    renewable(8),
5552                                    unused9(9),
5553                                    unused10(10),
5554                                    unused11(11),
5555                                    renewable-ok(27),
5556                                    enc-tkt-in-skey(28),
5557                                    renew(30),
5558                                    validate(31)
5559                   }
5560
5561
5562             LastReq ::=   SEQUENCE OF SEQUENCE {
5563                           lr-type[0]               INTEGER,
5564                           lr-value[1]              KerberosTime
5565             }
5566
5567    Ticket ::=                    [APPLICATION 1] SEQUENCE {
5568                                  tkt-vno[0]                   INTEGER,
5569                                  realm[1]                     Realm,
5570                                  sname[2]                     PrincipalName,
5571                                  enc-part[3]                  EncryptedData
5572    }
5573
5574   -- Encrypted part of ticket
5575   EncTicketPart ::=     [APPLICATION 3] SEQUENCE {
5576                         flags[0]             TicketFlags,
5577                         key[1]               EncryptionKey,
5578                         crealm[2]            Realm,
5579                         cname[3]             PrincipalName,
5580                         transited[4]         TransitedEncoding,
5581                         authtime[5]          KerberosTime,
5582                         starttime[6]         KerberosTime OPTIONAL,
5583                         endtime[7]           KerberosTime,
5584                         renew-till[8]        KerberosTime OPTIONAL,
5585                         caddr[9]             HostAddresses OPTIONAL,
5586                         authorization-data[10]   AuthorizationData OPTIONAL
5587   }
5588
5589   -- encoded Transited field
5590   TransitedEncoding ::=         SEQUENCE {
5591                                 tr-type[0]  INTEGER, -- must be registered
5592                                 contents[1]          OCTET STRING
5593   }
5594
5595   -- Unencrypted authenticator
5596   Authenticator ::=    [APPLICATION 2] SEQUENCE    {
5597                  authenticator-vno[0]          INTEGER,
5598                  crealm[1]                     Realm,
5599                  cname[2]                      PrincipalName,
5600                  cksum[3]                      Checksum OPTIONAL,
5601                  cusec[4]                      INTEGER,
5602                  ctime[5]                      KerberosTime,
5603                  subkey[6]                     EncryptionKey OPTIONAL,
5604                  seq-number[7]                 INTEGER OPTIONAL,
5605                  authorization-data[8]         AuthorizationData OPTIONAL
5606   }
5607
5608   PA-DATA ::=        SEQUENCE {
5609            padata-type[1]        INTEGER,
5610            padata-value[2]       OCTET STRING,
5611                          -- might be encoded AP-REQ
5612   }
5613
5614    padata-type     ::= PA-ENC-TIMESTAMP
5615    padata-value    ::= EncryptedData -- PA-ENC-TS-ENC
5616
5617    PA-ENC-TS-ENC   ::= SEQUENCE {
5618            patimestamp[0]               KerberosTime, -- client's time
5619            pausec[1]                    INTEGER OPTIONAL
5620    }
5621
5622    EncASRepPart ::=    [APPLICATION 25[25]] EncKDCRepPart
5623    EncTGSRepPart ::=   [APPLICATION 26] EncKDCRepPart
5624
5625    EncKDCRepPart ::=   SEQUENCE {
5626                key[0]                       EncryptionKey,
5627                last-req[1]                  LastReq,
5628                nonce[2]                     INTEGER,
5629                key-expiration[3]            KerberosTime OPTIONAL,
5630                flags[4]                     TicketFlags,
5631                authtime[5]                  KerberosTime,
5632                starttime[6]                 KerberosTime OPTIONAL,
5633                endtime[7]                   KerberosTime,
5634                renew-till[8]                KerberosTime OPTIONAL,
5635                srealm[9]                    Realm,
5636                sname[10]                    PrincipalName,
5637                caddr[11]                    HostAddresses OPTIONAL
5638    }
5639
5640    APOptions ::=   BIT STRING {
5641                    reserved(0),
5642                    use-session-key(1),
5643                    mutual-required(2)
5644    }
5645
5646    EncAPRepPart ::=   [APPLICATION 27]     SEQUENCE {
5647               ctime[0]                  KerberosTime,
5648               cusec[1]                  INTEGER,
5649               subkey[2]                 EncryptionKey OPTIONAL,
5650               seq-number[3]             INTEGER OPTIONAL
5651    }
5652
5653    KRB-SAFE ::=        [APPLICATION 20] SEQUENCE {
5654                pvno[0]               INTEGER,
5655                msg-type[1]           INTEGER,
5656                safe-body[2]          KRB-SAFE-BODY,
5657                cksum[3]              Checksum
5658    }
5659
5660    KRB-SAFE-BODY ::=   SEQUENCE {
5661                user-data[0]          OCTET STRING,
5662                timestamp[1]          KerberosTime OPTIONAL,
5663                usec[2]               INTEGER OPTIONAL,
5664                seq-number[3]         INTEGER OPTIONAL,
5665                s-address[4]          HostAddress,
5666                r-address[5]          HostAddress OPTIONAL
5667    }
5668
5669    KRB-PRIV ::=         [APPLICATION 21] SEQUENCE {
5670                 pvno[0]                   INTEGER,
5671                 msg-type[1]               INTEGER,
5672                 enc-part[3]               EncryptedData
5673    }
5674
5675    EncKrbPrivPart ::=   [APPLICATION 28] SEQUENCE {
5676                 user-data[0]              OCTET STRING,
5677                 timestamp[1]              KerberosTime OPTIONAL,
5678                 usec[2]                   INTEGER OPTIONAL,
5679                 seq-number[3]             INTEGER OPTIONAL,
5680                 s-address[4]              HostAddress, -- sender's addr
5681                 r-address[5]              HostAddress OPTIONAL
5682                                                       -- recip's addr
5683    }
5684
5685    KRB-CRED         ::= [APPLICATION 22]   SEQUENCE {
5686                     pvno[0]                INTEGER,
5687                     msg-type[1]            INTEGER, -- KRB_CRED
5688                     tickets[2]             SEQUENCE OF Ticket,
5689                     enc-part[3]            EncryptedData
5690    }
5691
5692    EncKrbCredPart   ::= [APPLICATION 29]   SEQUENCE {
5693                     ticket-info[0]         SEQUENCE OF KrbCredInfo,
5694                     nonce[1]               INTEGER OPTIONAL,
5695                     timestamp[2]           KerberosTime OPTIONAL,
5696                     usec[3]                INTEGER OPTIONAL,
5697                     s-address[4]           HostAddress OPTIONAL,
5698                     r-address[5]           HostAddress OPTIONAL
5699    }
5700
5701    KrbCredInfo      ::=                    SEQUENCE {
5702                     key[0]                 EncryptionKey,
5703                     prealm[1]              Realm OPTIONAL,
5704                     pname[2]               PrincipalName OPTIONAL,
5705                     flags[3]               TicketFlags OPTIONAL,
5706                     authtime[4]            KerberosTime OPTIONAL,
5707                     starttime[5]           KerberosTime OPTIONAL,
5708                     endtime[6]             KerberosTime OPTIONAL
5709                     renew-till[7]          KerberosTime OPTIONAL,
5710                     srealm[8]              Realm OPTIONAL,
5711                     sname[9]               PrincipalName OPTIONAL,
5712                     caddr[10]              HostAddresses OPTIONAL
5713    }
5714
5715       METHOD-DATA ::=    SEQUENCE of PA-DATA
5716
5717    If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
5718    contain an encoding of the following sequence:
5719
5720       METHOD-DATA ::=    SEQUENCE {
5721                          method-type[0]   INTEGER,
5722                          method-data[1]   OCTET STRING OPTIONAL
5723       }
5724
5725       EncryptionKey ::=   SEQUENCE {
5726                          keytype[0]    INTEGER,
5727                          keyvalue[1]   OCTET STRING
5728       }
5729
5730       Checksum ::=   SEQUENCE {
5731                          cksumtype[0]   INTEGER,
5732                          checksum[1]    OCTET STRING
5733       }
5734
5735 */