smb2-dissector: learn the "REPLAY_OPERATION" flag
[obnox/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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 #ifdef HAVE_CONFIG_H
63 # include "config.h"
64 #endif
65
66 #include <stdio.h>
67 #include <string.h>
68 #include <glib.h>
69 #include <ctype.h>
70
71 #ifdef HAVE_LIBNETTLE
72 #define HAVE_KERBEROS
73 #ifdef _WIN32
74 #include <des.h>
75 #include <cbc.h>
76 #else
77 #include <nettle/des.h>
78 #include <nettle/cbc.h>
79 #endif
80 #include <epan/crypt/md5.h>
81 #include <sys/stat.h>   /* For keyfile manipulation */
82 #endif
83
84 #include <epan/packet.h>
85
86 #include <epan/strutil.h>
87
88 #include <epan/conversation.h>
89 #include <epan/emem.h>
90 #include <epan/asn1.h>
91 #include <epan/expert.h>
92 #include <epan/dissectors/packet-kerberos.h>
93 #include <epan/dissectors/packet-netbios.h>
94 #include <epan/dissectors/packet-tcp.h>
95 #include <epan/prefs.h>
96 #include <epan/dissectors/packet-ber.h>
97 #include <epan/dissectors/packet-pkinit.h>
98 #include <epan/dissectors/packet-cms.h>
99 #include <epan/dissectors/packet-windows-common.h>
100
101 #include <epan/dissectors/packet-dcerpc-netlogon.h>
102 #include <epan/dissectors/packet-dcerpc.h>
103
104 #include <epan/dissectors/packet-gssapi.h>
105 #include <epan/dissectors/packet-smb-common.h>
106
107 #include <wsutil/file_util.h>
108
109 #define UDP_PORT_KERBEROS               88
110 #define TCP_PORT_KERBEROS               88
111
112 static dissector_handle_t kerberos_handle_udp;
113
114 /* Desegment Kerberos over TCP messages */
115 static gboolean krb_desegment = TRUE;
116
117 static gint proto_kerberos = -1;
118 static gint hf_krb_rm_reserved = -1;
119 static gint hf_krb_rm_reclen = -1;
120
121 static gint hf_krb_pac_signature_type = -1;
122 static gint hf_krb_pac_signature_signature = -1;
123 static gint hf_krb_pac_clientid = -1;
124 static gint hf_krb_pac_namelen = -1;
125 static gint hf_krb_pac_clientname = -1;
126 static gint hf_krb_pac_upn_flags = -1;
127 static gint hf_krb_pac_upn_upn_name = -1;
128 static gint hf_krb_pac_upn_dns_name = -1;
129 static gint hf_krb_pac_upn_dns_offset = -1;
130 static gint hf_krb_pac_upn_dns_len = -1;
131 static gint hf_krb_pac_upn_upn_offset = -1;
132 static gint hf_krb_pac_upn_upn_len = -1;
133 static gint hf_krb_w2k_pac_entries = -1;
134 static gint hf_krb_w2k_pac_version = -1;
135 static gint hf_krb_w2k_pac_type = -1;
136 static gint hf_krb_w2k_pac_size = -1;
137 static gint hf_krb_w2k_pac_offset = -1;
138 static gint hf_krb_padata = -1;
139 static gint hf_krb_error_code = -1;
140 static gint hf_krb_ticket = -1;
141 static gint hf_krb_AP_REP_enc = -1;
142 static gint hf_krb_KDC_REP_enc = -1;
143 static gint hf_krb_tkt_vno = -1;
144 static gint hf_krb_e_data = -1;
145 static gint hf_krb_TransitedEncoding = -1;
146 static gint hf_krb_PA_PAC_REQUEST_flag = -1;
147 static gint hf_krb_encrypted_authenticator_data = -1;
148 static gint hf_krb_PAC_LOGON_INFO = -1;
149 static gint hf_krb_PAC_CREDENTIAL_TYPE = -1;
150 static gint hf_krb_PAC_SERVER_CHECKSUM = -1;
151 static gint hf_krb_PAC_PRIVSVR_CHECKSUM = -1;
152 static gint hf_krb_PAC_CLIENT_INFO_TYPE = -1;
153 static gint hf_krb_PAC_S4U_DELEGATION_INFO = -1;
154 static gint hf_krb_PAC_UPN_DNS_INFO = -1;
155 static gint hf_krb_encrypted_PA_ENC_TIMESTAMP = -1;
156 static gint hf_krb_encrypted_enc_authorization_data = -1;
157 static gint hf_krb_encrypted_EncKrbCredPart = -1;
158 static gint hf_krb_checksum_checksum = -1;
159 static gint hf_krb_encrypted_PRIV = -1;
160 static gint hf_krb_encrypted_Ticket_data = -1;
161 static gint hf_krb_encrypted_AP_REP_data = -1;
162 static gint hf_krb_encrypted_KDC_REP_data = -1;
163 static gint hf_krb_PA_DATA_type = -1;
164 static gint hf_krb_PA_DATA_value = -1;
165 static gint hf_krb_etype_info_salt = -1;
166 static gint hf_krb_etype_info2_salt = -1;
167 static gint hf_krb_etype_info2_s2kparams = -1;
168 static gint hf_krb_SAFE_BODY_user_data = -1;
169 static gint hf_krb_PRIV_BODY_user_data = -1;
170 static gint hf_krb_realm = -1;
171 static gint hf_krb_srealm = -1;
172 static gint hf_krb_prealm = -1;
173 static gint hf_krb_crealm = -1;
174 static gint hf_krb_sname = -1;
175 static gint hf_krb_pname = -1;
176 static gint hf_krb_cname = -1;
177 static gint hf_krb_name_string = -1;
178 static gint hf_krb_provsrv_location = -1;
179 static gint hf_krb_e_text = -1;
180 static gint hf_krb_s4u2self_auth = -1;
181 static gint hf_krb_name_type = -1;
182 static gint hf_krb_lr_type = -1;
183 static gint hf_krb_from = -1;
184 static gint hf_krb_till = -1;
185 static gint hf_krb_authtime = -1;
186 static gint hf_krb_patimestamp = -1;
187 static gint hf_krb_SAFE_BODY_timestamp = -1;
188 static gint hf_krb_pausec = -1;
189 static gint hf_krb_lr_time = -1;
190 static gint hf_krb_starttime = -1;
191 static gint hf_krb_endtime = -1;
192 static gint hf_krb_key_expire = -1;
193 static gint hf_krb_renew_till = -1;
194 static gint hf_krb_rtime = -1;
195 static gint hf_krb_ctime = -1;
196 static gint hf_krb_cusec = -1;
197 static gint hf_krb_stime = -1;
198 static gint hf_krb_susec = -1;
199 static gint hf_krb_SAFE_BODY_usec = -1;
200 static gint hf_krb_nonce = -1;
201 static gint hf_krb_transitedtype = -1;
202 static gint hf_krb_transitedcontents = -1;
203 static gint hf_krb_keytype = -1;
204 static gint hf_krb_keyvalue = -1;
205 static gint hf_krb_IF_RELEVANT_type = -1;
206 static gint hf_krb_IF_RELEVANT_value = -1;
207 static gint hf_krb_adtype = -1;
208 static gint hf_krb_advalue = -1;
209 static gint hf_krb_etype = -1;
210 static gint hf_krb_etypes = -1;
211 static gint hf_krb_KrbCredInfos = -1;
212 static gint hf_krb_sq_tickets = -1;
213 static gint hf_krb_LastReqs = -1;
214 static gint hf_krb_IF_RELEVANT = -1;
215 static gint hf_krb_addr_type = -1;
216 static gint hf_krb_address_ip = -1;
217 static gint hf_krb_address_ipv6 = -1;
218 static gint hf_krb_address_netbios = -1;
219 static gint hf_krb_msg_type = -1;
220 static gint hf_krb_pvno = -1;
221 static gint hf_krb_kvno = -1;
222 static gint hf_krb_checksum_type = -1;
223 static gint hf_krb_authenticator_vno = -1;
224 static gint hf_krb_AuthorizationData = -1;
225 static gint hf_krb_key = -1;
226 static gint hf_krb_subkey = -1;
227 static gint hf_krb_seq_number = -1;
228 static gint hf_krb_EncTicketPart = -1;
229 static gint hf_krb_EncAPRepPart = -1;
230 static gint hf_krb_EncKrbPrivPart = -1;
231 static gint hf_krb_EncKrbCredPart = -1;
232 static gint hf_krb_EncKDCRepPart = -1;
233 static gint hf_krb_LastReq = -1;
234 static gint hf_krb_Authenticator = -1;
235 static gint hf_krb_Checksum = -1;
236 static gint hf_krb_s_address = -1;
237 static gint hf_krb_r_address = -1;
238 static gint hf_krb_KrbCredInfo = -1;
239 static gint hf_krb_HostAddress = -1;
240 static gint hf_krb_HostAddresses = -1;
241 static gint hf_krb_APOptions = -1;
242 static gint hf_krb_APOptions_reserved = -1;
243 static gint hf_krb_APOptions_use_session_key = -1;
244 static gint hf_krb_APOptions_mutual_required = -1;
245 static gint hf_krb_TicketFlags = -1;
246 static gint hf_krb_TicketFlags_forwardable = -1;
247 static gint hf_krb_TicketFlags_forwarded = -1;
248 static gint hf_krb_TicketFlags_proxiable = -1;
249 static gint hf_krb_TicketFlags_proxy = -1;
250 static gint hf_krb_TicketFlags_allow_postdate = -1;
251 static gint hf_krb_TicketFlags_postdated = -1;
252 static gint hf_krb_TicketFlags_invalid = -1;
253 static gint hf_krb_TicketFlags_renewable = -1;
254 static gint hf_krb_TicketFlags_initial = -1;
255 static gint hf_krb_TicketFlags_pre_auth = -1;
256 static gint hf_krb_TicketFlags_hw_auth = -1;
257 static gint hf_krb_TicketFlags_transited_policy_checked = -1;
258 static gint hf_krb_TicketFlags_ok_as_delegate = -1;
259 static gint hf_krb_KDCOptions = -1;
260 static gint hf_krb_KDCOptions_forwardable = -1;
261 static gint hf_krb_KDCOptions_forwarded = -1;
262 static gint hf_krb_KDCOptions_proxiable = -1;
263 static gint hf_krb_KDCOptions_proxy = -1;
264 static gint hf_krb_KDCOptions_allow_postdate = -1;
265 static gint hf_krb_KDCOptions_postdated = -1;
266 static gint hf_krb_KDCOptions_renewable = -1;
267 static gint hf_krb_KDCOptions_constrained_delegation = -1;
268 static gint hf_krb_KDCOptions_canonicalize = -1;
269 static gint hf_krb_KDCOptions_opt_hardware_auth = -1;
270 static gint hf_krb_KDCOptions_disable_transited_check = -1;
271 static gint hf_krb_KDCOptions_renewable_ok = -1;
272 static gint hf_krb_KDCOptions_enc_tkt_in_skey = -1;
273 static gint hf_krb_KDCOptions_renew = -1;
274 static gint hf_krb_KDCOptions_validate = -1;
275 static gint hf_krb_KDC_REQ_BODY = -1;
276 static gint hf_krb_PRIV_BODY = -1;
277 static gint hf_krb_CRED_BODY = -1;
278 static gint hf_krb_ENC_PRIV = -1;
279 static gint hf_krb_authenticator_enc = -1;
280 static gint hf_krb_CRED_enc = -1;
281 static gint hf_krb_ticket_enc = -1;
282 static gint hf_krb_e_checksum = -1;
283 static gint hf_krb_gssapi_len = -1;
284 static gint hf_krb_gssapi_bnd = -1;
285 static gint hf_krb_gssapi_dlgopt = -1;
286 static gint hf_krb_gssapi_dlglen = -1;
287 static gint hf_krb_gssapi_c_flag_deleg = -1;
288 static gint hf_krb_gssapi_c_flag_mutual = -1;
289 static gint hf_krb_gssapi_c_flag_replay = -1;
290 static gint hf_krb_gssapi_c_flag_sequence = -1;
291 static gint hf_krb_gssapi_c_flag_conf = -1;
292 static gint hf_krb_gssapi_c_flag_integ = -1;
293 static gint hf_krb_gssapi_c_flag_dce_style = -1;
294 static gint hf_krb_smb_nt_status = -1;
295 static gint hf_krb_smb_unknown = -1;
296 static gint hf_krb_midl_blob_len = -1;
297 static gint hf_krb_midl_fill_bytes = -1;
298 static gint hf_krb_midl_version = -1;
299 static gint hf_krb_midl_hdr_len = -1;
300
301 static gint ett_krb_kerberos = -1;
302 static gint ett_krb_TransitedEncoding = -1;
303 static gint ett_krb_PAC_LOGON_INFO = -1;
304 static gint ett_krb_PAC_SERVER_CHECKSUM = -1;
305 static gint ett_krb_PAC_PRIVSVR_CHECKSUM = -1;
306 static gint ett_krb_PAC_CLIENT_INFO_TYPE = -1;
307 static gint ett_krb_PAC_S4U_DELEGATION_INFO = -1;
308 static gint ett_krb_KDC_REP_enc = -1;
309 static gint ett_krb_EncTicketPart = -1;
310 static gint ett_krb_EncAPRepPart = -1;
311 static gint ett_krb_EncKrbPrivPart = -1;
312 static gint ett_krb_EncKrbCredPart = -1;
313 static gint ett_krb_EncKDCRepPart = -1;
314 static gint ett_krb_LastReq = -1;
315 static gint ett_krb_Authenticator = -1;
316 static gint ett_krb_Checksum = -1;
317 static gint ett_krb_key = -1;
318 static gint ett_krb_subkey = -1;
319 static gint ett_krb_AuthorizationData = -1;
320 static gint ett_krb_sname = -1;
321 static gint ett_krb_pname = -1;
322 static gint ett_krb_cname = -1;
323 static gint ett_krb_AP_REP_enc = -1;
324 static gint ett_krb_padata = -1;
325 static gint ett_krb_etypes = -1;
326 static gint ett_krb_KrbCredInfos = -1;
327 static gint ett_krb_sq_tickets = -1;
328 static gint ett_krb_LastReqs = -1;
329 static gint ett_krb_IF_RELEVANT = -1;
330 static gint ett_krb_PA_DATA_tree = -1;
331 static gint ett_krb_PAC = -1;
332 static gint ett_krb_s_address = -1;
333 static gint ett_krb_r_address = -1;
334 static gint ett_krb_KrbCredInfo = -1;
335 static gint ett_krb_HostAddress = -1;
336 static gint ett_krb_HostAddresses = -1;
337 static gint ett_krb_authenticator_enc = -1;
338 static gint ett_krb_CRED_enc = -1;
339 static gint ett_krb_AP_Options = -1;
340 static gint ett_krb_KDC_Options = -1;
341 static gint ett_krb_Ticket_Flags = -1;
342 static gint ett_krb_request = -1;
343 static gint ett_krb_recordmark = -1;
344 static gint ett_krb_ticket = -1;
345 static gint ett_krb_ticket_enc = -1;
346 static gint ett_krb_CRED = -1;
347 static gint ett_krb_PRIV = -1;
348 static gint ett_krb_PRIV_enc = -1;
349 static gint ett_krb_e_checksum = -1;
350 static gint ett_krb_PAC_MIDL_BLOB = -1;
351 static gint ett_krb_PAC_DREP = -1;
352 static gint ett_krb_PAC_UPN_DNS_INFO = -1;
353
354 static guint32 krb5_errorcode;
355
356
357 static dissector_handle_t krb4_handle=NULL;
358
359 static gboolean gbl_do_col_info;
360
361
362 static void
363 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag)
364 {
365     kerberos_callbacks *cb=(kerberos_callbacks *)pinfo->private_data;
366
367     if(!cb){
368         return;
369     }
370
371     while(cb->tag){
372         if(cb->tag==tag){
373             cb->callback(pinfo, tvb, tree);
374             return;
375         }
376         cb++;
377     }
378     return;
379 }
380
381
382
383 #ifdef HAVE_KERBEROS
384
385 /* Decrypt Kerberos blobs */
386 gboolean krb_decrypt = FALSE;
387
388 /* keytab filename */
389 static const char *keytab_filename = "insert filename here";
390
391 void read_keytab_file(const char *);
392
393 void
394 read_keytab_file_from_preferences(void)
395 {
396     static char *last_keytab = NULL;
397
398     if (!krb_decrypt) {
399         return;
400     }
401
402     if (keytab_filename == NULL) {
403         return;
404     }
405
406     if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
407         return;
408     }
409
410     if (last_keytab != NULL) {
411         g_free(last_keytab);
412         last_keytab = NULL;
413     }
414     last_keytab = g_strdup(keytab_filename);
415
416     read_keytab_file(last_keytab);
417 }
418
419 #elif defined(_WIN32)
420
421 /*  Dummy version to allow us to put this function in libwireshark.def--even
422  *  on systems without KERBEROS.
423  */
424 void
425 read_keytab_file_from_preferences(void)
426 {
427 }
428
429 #endif
430
431 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
432 #ifdef _WIN32
433 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
434 #undef HAVE_STDARG_H
435 #undef HAVE_SYS_TYPES_H
436 #endif
437 #include <krb5.h>
438 enc_key_t *enc_key_list=NULL;
439
440 static void
441 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
442 {
443     enc_key_t *new_key;
444
445     if(pinfo->fd->flags.visited){
446         return;
447     }
448 printf("added key in %u    keytype:%d len:%d\n",pinfo->fd->num, keytype, keylength);
449
450     new_key=g_malloc(sizeof(enc_key_t));
451     g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->fd->num);
452     new_key->next=enc_key_list;
453     enc_key_list=new_key;
454     new_key->keytype=keytype;
455     new_key->keylength=keylength;
456     /*XXX this needs to be freed later */
457     new_key->keyvalue=g_memdup(keyvalue, keylength);
458 }
459 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
460
461 #if defined(_WIN32) && !defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_MIT_KERBEROS) && !defined(HAVE_LIBNETTLE)
462 void
463 read_keytab_file(const char *filename _U_)
464 {
465 }
466 #endif
467
468 #ifdef HAVE_MIT_KERBEROS
469
470 static krb5_context krb5_ctx;
471
472 void
473 read_keytab_file(const char *filename)
474 {
475     krb5_keytab keytab;
476     krb5_error_code ret;
477     krb5_keytab_entry key;
478     krb5_kt_cursor cursor;
479     enc_key_t *new_key;
480     static gboolean first_time=TRUE;
481
482 printf("read keytab file %s\n", filename);
483     if(first_time){
484         first_time=FALSE;
485         ret = krb5_init_context(&krb5_ctx);
486         if(ret && ret != KRB5_CONFIG_CANTOPEN){
487             return;
488         }
489     }
490
491     /* should use a file in the wireshark users dir */
492     ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
493     if(ret){
494         fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
495
496         return;
497     }
498
499     ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
500     if(ret){
501         fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
502         return;
503     }
504
505     do{
506         new_key=g_malloc(sizeof(enc_key_t));
507         new_key->next=enc_key_list;
508         ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
509         if(ret==0){
510             int i;
511             char *pos;
512
513             /* generate origin string, describing where this key came from */
514             pos=new_key->key_origin;
515             pos+=MIN(KRB_MAX_ORIG_LEN,
516                      g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
517             for(i=0;i<key.principal->length;i++){
518                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
519                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),(key.principal->data[i]).data));
520             }
521             pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
522                      g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm.data));
523             *pos=0;
524 /*printf("added key for principal :%s\n", new_key->key_origin);*/
525             new_key->keytype=key.key.enctype;
526             new_key->keylength=key.key.length;
527             new_key->keyvalue=g_memdup(key.key.contents, key.key.length);
528             enc_key_list=new_key;
529         }
530     }while(ret==0);
531
532     ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
533     if(ret){
534         krb5_kt_close(krb5_ctx, keytab);
535     }
536
537 }
538
539
540 guint8 *
541 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
542                   int usage,
543                   tvbuff_t *cryptotvb,
544                   int keytype,
545                   int *datalen)
546 {
547     krb5_error_code ret;
548     enc_key_t *ek;
549     krb5_data data = {0,0,NULL};
550     krb5_keytab_entry key;
551     int length = tvb_length(cryptotvb);
552     const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
553
554     /* don't do anything if we are not attempting to decrypt data */
555     if(!krb_decrypt || length < 1){
556         return NULL;
557     }
558
559     /* make sure we have all the data we need */
560     if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
561         return NULL;
562     }
563
564     read_keytab_file_from_preferences();
565     data.data = g_malloc(length);
566     data.length = length;
567
568     for(ek=enc_key_list;ek;ek=ek->next){
569         krb5_enc_data input;
570
571         /* shortcircuit and bail out if enctypes are not matching */
572         if((keytype != -1) && (ek->keytype != keytype)) {
573             continue;
574         }
575
576         input.enctype = ek->keytype;
577         input.ciphertext.length = length;
578         input.ciphertext.data = (guint8 *)cryptotext;
579
580         key.key.enctype=ek->keytype;
581         key.key.length=ek->keylength;
582         key.key.contents=ek->keyvalue;
583         ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
584         if(ret == 0){
585             char *user_data;
586
587             expert_add_info_format(pinfo, NULL, PI_SECURITY, PI_CHAT,
588                                    "Decrypted keytype %d in frame %u using %s",
589                                    ek->keytype, pinfo->fd->num, ek->key_origin);
590
591             proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
592             /* return a private g_malloced blob to the caller */
593             user_data=data.data;
594             if (datalen) {
595                 *datalen = data.length;
596             }
597             return user_data;
598         }
599     }
600     g_free(data.data);
601
602     return NULL;
603 }
604
605 #elif defined(HAVE_HEIMDAL_KERBEROS)
606 static krb5_context krb5_ctx;
607
608 void
609 read_keytab_file(const char *filename)
610 {
611     krb5_keytab keytab;
612     krb5_error_code ret;
613     krb5_keytab_entry key;
614     krb5_kt_cursor cursor;
615     enc_key_t *new_key;
616     static gboolean first_time=TRUE;
617
618     if(first_time){
619         first_time=FALSE;
620         ret = krb5_init_context(&krb5_ctx);
621         if(ret){
622             return;
623         }
624     }
625
626     /* should use a file in the wireshark users dir */
627     ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
628     if(ret){
629         fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
630
631         return;
632     }
633
634     ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
635     if(ret){
636         fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
637         return;
638     }
639
640     do{
641         new_key=g_malloc(sizeof(enc_key_t));
642         new_key->next=enc_key_list;
643         ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
644         if(ret==0){
645             unsigned int i;
646             char *pos;
647
648             /* generate origin string, describing where this key came from */
649             pos=new_key->key_origin;
650             pos+=MIN(KRB_MAX_ORIG_LEN,
651                      g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
652             for(i=0;i<key.principal->name.name_string.len;i++){
653                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
654                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
655             }
656             pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
657                      g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
658             *pos=0;
659             new_key->keytype=key.keyblock.keytype;
660             new_key->keylength=key.keyblock.keyvalue.length;
661             new_key->keyvalue=g_memdup(key.keyblock.keyvalue.data, key.keyblock.keyvalue.length);
662             enc_key_list=new_key;
663         }
664     }while(ret==0);
665
666     ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
667     if(ret){
668         krb5_kt_close(krb5_ctx, keytab);
669     }
670
671 }
672
673
674 guint8 *
675 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
676                   int usage,
677                   tvbuff_t *cryptotvb,
678                   int keytype,
679                   int *datalen)
680 {
681     krb5_error_code ret;
682     krb5_data data;
683     enc_key_t *ek;
684     int length = tvb_length(cryptotvb);
685     const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
686
687     /* don't do anything if we are not attempting to decrypt data */
688     if(!krb_decrypt){
689         return NULL;
690     }
691
692     /* make sure we have all the data we need */
693     if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
694         return NULL;
695     }
696
697     read_keytab_file_from_preferences();
698
699     for(ek=enc_key_list;ek;ek=ek->next){
700         krb5_keytab_entry key;
701         krb5_crypto crypto;
702         guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
703
704         /* shortcircuit and bail out if enctypes are not matching */
705         if((keytype != -1) && (ek->keytype != keytype)) {
706             continue;
707         }
708
709         key.keyblock.keytype=ek->keytype;
710         key.keyblock.keyvalue.length=ek->keylength;
711         key.keyblock.keyvalue.data=ek->keyvalue;
712         ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), 0, &crypto);
713         if(ret){
714             return NULL;
715         }
716
717         /* pre-0.6.1 versions of Heimdal would sometimes change
718            the cryptotext data even when the decryption failed.
719            This would obviously not work since we iterate over the
720            keys. So just give it a copy of the crypto data instead.
721            This has been seen for RC4-HMAC blobs.
722         */
723         cryptocopy=g_memdup(cryptotext, length);
724         ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
725                                 cryptocopy, length,
726                                 &data,
727                                 NULL);
728         g_free(cryptocopy);
729         if((ret == 0) && (length>0)){
730             char *user_data;
731
732 printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
733             proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
734             krb5_crypto_destroy(krb5_ctx, crypto);
735             /* return a private g_malloced blob to the caller */
736             user_data=g_memdup(data.data, data.length);
737             if (datalen) {
738                 *datalen = data.length;
739             }
740             return user_data;
741         }
742         krb5_crypto_destroy(krb5_ctx, crypto);
743     }
744     return NULL;
745 }
746
747 #elif defined (HAVE_LIBNETTLE)
748
749 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
750 #define KEYTYPE_DES3_CBC_MD5 5  /* Currently the only one supported */
751
752 typedef struct _service_key_t {
753     guint16 kvno;
754     int     keytype;
755     int     length;
756     guint8 *contents;
757     char    origin[KRB_MAX_ORIG_LEN+1];
758 } service_key_t;
759 GSList *service_key_list = NULL;
760
761
762 static void
763 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
764 {
765     service_key_t *new_key;
766
767     if(pinfo->fd->flags.visited){
768         return;
769     }
770 printf("added key in %u\n",pinfo->fd->num);
771
772     new_key = g_malloc(sizeof(service_key_t));
773     new_key->kvno = 0;
774     new_key->keytype = keytype;
775     new_key->length = keylength;
776     new_key->contents = g_memdup(keyvalue, keylength);
777     g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->fd->num);
778     service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
779 }
780
781 static void
782 clear_keytab(void) {
783     GSList *ske;
784     service_key_t *sk;
785
786     for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
787         sk = (service_key_t *) ske->data;
788         if (sk) {
789             g_free(sk->contents);
790             g_free(sk);
791         }
792     }
793     g_slist_free(service_key_list);
794     service_key_list = NULL;
795 }
796
797 static void
798 read_keytab_file(const char *service_key_file)
799 {
800     FILE *skf;
801     ws_statb64 st;
802     service_key_t *sk;
803     unsigned char buf[SERVICE_KEY_SIZE];
804     int newline_skip = 0, count = 0;
805
806     if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
807
808         /* The service key file contains raw 192-bit (24 byte) 3DES keys.
809          * There can be zero, one (\n), or two (\r\n) characters between
810          * keys.  Trailing characters are ignored.
811          */
812
813         /* XXX We should support the standard keytab format instead */
814         if (st.st_size > SERVICE_KEY_SIZE) {
815             if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
816                  (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
817                 newline_skip = 1;
818             } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
819                         (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
820                 newline_skip = 2;
821             }
822         }
823
824         skf = ws_fopen(service_key_file, "rb");
825         if (! skf) return;
826
827         while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
828             sk = g_malloc(sizeof(service_key_t));
829             sk->kvno = buf[0] << 8 | buf[1];
830             sk->keytype = KEYTYPE_DES3_CBC_MD5;
831             sk->length = DES3_KEY_SIZE;
832             sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
833             g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
834             service_key_list = g_slist_append(service_key_list, (gpointer) sk);
835             fseek(skf, newline_skip, SEEK_CUR);
836             count++;
837 g_warning("added key: %s", sk->origin);
838         }
839         fclose(skf);
840     }
841 }
842
843 #define CONFOUNDER_PLUS_CHECKSUM 24
844
845 guint8 *
846 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
847                   int _U_ usage,
848                   tvbuff_t *cryptotvb,
849                   int keytype,
850                   int *datalen)
851 {
852     tvbuff_t *encr_tvb;
853     guint8 *decrypted_data = NULL, *plaintext = NULL;
854     int res;
855     guint8 cls;
856     gboolean pc;
857     guint32 tag, item_len, data_len;
858     int id_offset, offset;
859     guint8 key[DES3_KEY_SIZE];
860     guint8 initial_vector[DES_BLOCK_SIZE];
861     md5_state_t md5s;
862     md5_byte_t digest[16];
863     md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
864     md5_byte_t confounder[8];
865     gboolean ind;
866     GSList *ske;
867     service_key_t *sk;
868     struct des3_ctx ctx;
869     int length = tvb_length(cryptotvb);
870     const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
871
872
873     /* don't do anything if we are not attempting to decrypt data */
874     if(!krb_decrypt){
875         return NULL;
876     }
877
878     /* make sure we have all the data we need */
879     if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
880         return NULL;
881     }
882
883     if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
884         return NULL;
885     }
886
887     decrypted_data = g_malloc(length);
888     for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
889         gboolean do_continue = FALSE;
890         sk = (service_key_t *) ske->data;
891
892         des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
893
894         md5_init(&md5s);
895         memset(initial_vector, 0, DES_BLOCK_SIZE);
896         res = des3_set_key(&ctx, key);
897         cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
898                     length, decrypted_data, cryptotext);
899         encr_tvb = tvb_new_real_data(decrypted_data, length, length);
900
901         tvb_memcpy(encr_tvb, confounder, 0, 8);
902
903         /* We have to pull the decrypted data length from the decrypted
904          * content.  If the key doesn't match or we otherwise get garbage,
905          * an exception may get thrown while decoding the ASN.1 header.
906          * Catch it, just in case.
907          */
908         TRY {
909             id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
910             offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
911         }
912         CATCH (BoundsError) {
913             tvb_free(encr_tvb);
914             do_continue = TRUE;
915         }
916         ENDTRY;
917
918         if (do_continue) continue;
919
920         data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
921         if ((int) item_len + offset > length) {
922             tvb_free(encr_tvb);
923             continue;
924         }
925
926         md5_append(&md5s, confounder, 8);
927         md5_append(&md5s, zero_fill, 16);
928         md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
929         md5_finish(&md5s, digest);
930
931         if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) {
932 g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
933             plaintext = g_malloc(data_len);
934             tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
935             tvb_free(encr_tvb);
936
937             if (datalen) {
938                 *datalen = data_len;
939             }
940             g_free(decrypted_data);
941             return(plaintext);
942         }
943         tvb_free(encr_tvb);
944     }
945
946     g_free(decrypted_data);
947     return NULL;
948 }
949
950
951 #endif  /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
952
953 #define INET6_ADDRLEN   16
954
955 /* TCP Record Mark */
956 #define KRB_RM_RESERVED 0x80000000L
957 #define KRB_RM_RECLEN   0x7fffffffL
958
959 #define KRB5_MSG_TICKET                  1      /* Ticket */
960 #define KRB5_MSG_AUTHENTICATOR           2      /* Authenticator */
961 #define KRB5_MSG_ENC_TICKET_PART         3      /* EncTicketPart */
962 #define KRB5_MSG_AS_REQ                 10      /* AS-REQ type */
963 #define KRB5_MSG_AS_REP                 11      /* AS-REP type */
964 #define KRB5_MSG_TGS_REQ                12      /* TGS-REQ type */
965 #define KRB5_MSG_TGS_REP                13      /* TGS-REP type */
966 #define KRB5_MSG_AP_REQ                 14      /* AP-REQ type */
967 #define KRB5_MSG_AP_REP                 15      /* AP-REP type */
968
969 #define KRB5_MSG_SAFE                   20      /* KRB-SAFE type */
970 #define KRB5_MSG_PRIV                   21      /* KRB-PRIV type */
971 #define KRB5_MSG_CRED                   22      /* KRB-CRED type */
972 #define KRB5_MSG_ENC_AS_REP_PART        25      /* EncASRepPart */
973 #define KRB5_MSG_ENC_TGS_REP_PART       26      /* EncTGSRepPart */
974 #define KRB5_MSG_ENC_AP_REP_PART        27      /* EncAPRepPart */
975 #define KRB5_MSG_ENC_KRB_PRIV_PART      28      /* EncKrbPrivPart */
976 #define KRB5_MSG_ENC_KRB_CRED_PART      29      /* EncKrbCredPart */
977 #define KRB5_MSG_ERROR                  30      /* KRB-ERROR type */
978
979 /* address type constants */
980 #define KRB5_ADDR_IPv4       0x02
981 #define KRB5_ADDR_CHAOS      0x05
982 #define KRB5_ADDR_XEROX      0x06
983 #define KRB5_ADDR_ISO        0x07
984 #define KRB5_ADDR_DECNET     0x0c
985 #define KRB5_ADDR_APPLETALK  0x10
986 #define KRB5_ADDR_NETBIOS    0x14
987 #define KRB5_ADDR_IPv6       0x18
988
989 /* encryption type constants */
990 #define KRB5_ENCTYPE_NULL                          0
991 #define KRB5_ENCTYPE_DES_CBC_CRC                   1
992 #define KRB5_ENCTYPE_DES_CBC_MD4                   2
993 #define KRB5_ENCTYPE_DES_CBC_MD5                   3
994 #define KRB5_ENCTYPE_DES_CBC_RAW                   4
995 #define KRB5_ENCTYPE_DES3_CBC_SHA                  5
996 #define KRB5_ENCTYPE_DES3_CBC_RAW                  6
997 #define KRB5_ENCTYPE_DES_HMAC_SHA1                 8
998 #define KRB5_ENCTYPE_DSA_SHA1_CMS                  9
999 #define KRB5_ENCTYPE_RSA_MD5_CMS                  10
1000 #define KRB5_ENCTYPE_RSA_SHA1_CMS                 11
1001 #define KRB5_ENCTYPE_RC2_CBC_ENV                  12
1002 #define KRB5_ENCTYPE_RSA_ENV                      13
1003 #define KRB5_ENCTYPE_RSA_ES_OEAP_ENV              14
1004 #define KRB5_ENCTYPE_DES_EDE3_CBC_ENV             15
1005 #define KRB5_ENCTYPE_DES3_CBC_SHA1                16
1006 #define KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96      17
1007 #define KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96      18
1008 #define KRB5_ENCTYPE_DES_CBC_MD5_NT               20
1009 #define KERB_ENCTYPE_RC4_HMAC                     23
1010 #define KERB_ENCTYPE_RC4_HMAC_EXP                 24
1011 #define KRB5_ENCTYPE_UNKNOWN                   0x1ff
1012 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1     0x7007
1013 #define KRB5_ENCTYPE_RC4_PLAIN_EXP        0xffffff73
1014 #define KRB5_ENCTYPE_RC4_PLAIN            0xffffff74
1015 #define KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP    0xffffff78
1016 #define KRB5_ENCTYPE_RC4_HMAC_OLD_EXP     0xffffff79
1017 #define KRB5_ENCTYPE_RC4_PLAIN_OLD        0xffffff7a
1018 #define KRB5_ENCTYPE_RC4_HMAC_OLD         0xffffff7b
1019 #define KRB5_ENCTYPE_DES_PLAIN            0xffffff7c
1020 #define KRB5_ENCTYPE_RC4_SHA              0xffffff7d
1021 #define KRB5_ENCTYPE_RC4_LM               0xffffff7e
1022 #define KRB5_ENCTYPE_RC4_PLAIN2           0xffffff7f
1023 #define KRB5_ENCTYPE_RC4_MD4              0xffffff80
1024
1025 /* checksum types */
1026 #define KRB5_CHKSUM_NONE                         0
1027 #define KRB5_CHKSUM_CRC32                        1
1028 #define KRB5_CHKSUM_MD4                          2
1029 #define KRB5_CHKSUM_KRB_DES_MAC                  4
1030 #define KRB5_CHKSUM_KRB_DES_MAC_K                5
1031 #define KRB5_CHKSUM_MD5                          7
1032 #define KRB5_CHKSUM_MD5_DES                      8
1033 /* the following four come from packetcable */
1034 #define KRB5_CHKSUM_MD5_DES3                     9
1035 #define KRB5_CHKSUM_HMAC_SHA1_DES3_KD           12
1036 #define KRB5_CHKSUM_HMAC_SHA1_DES3              13
1037 #define KRB5_CHKSUM_SHA1_UNKEYED                14
1038 #define KRB5_CHKSUM_HMAC_MD5            0xffffff76
1039 #define KRB5_CHKSUM_MD5_HMAC            0xffffff77
1040 #define KRB5_CHKSUM_RC4_MD5             0xffffff78
1041 #define KRB5_CHKSUM_MD25                0xffffff79
1042 #define KRB5_CHKSUM_DES_MAC_MD5         0xffffff7a
1043 #define KRB5_CHKSUM_DES_MAC             0xffffff7b
1044 #define KRB5_CHKSUM_REAL_CRC32          0xffffff7c
1045 #define KRB5_CHKSUM_SHA1                0xffffff7d
1046 #define KRB5_CHKSUM_LM                  0xffffff7e
1047 #define KRB5_CHKSUM_GSSAPI                  0x8003
1048
1049 /*
1050  * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
1051  *
1052  *      http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
1053  *
1054  * unless it's expired.
1055  */
1056
1057 /* pre-authentication type constants */
1058 #define KRB5_PA_TGS_REQ                   1
1059 #define KRB5_PA_ENC_TIMESTAMP             2
1060 #define KRB5_PA_PW_SALT                   3
1061 #define KRB5_PA_ENC_ENCKEY                4
1062 #define KRB5_PA_ENC_UNIX_TIME             5
1063 #define KRB5_PA_ENC_SANDIA_SECURID        6
1064 #define KRB5_PA_SESAME                    7
1065 #define KRB5_PA_OSF_DCE                   8
1066 #define KRB5_PA_CYBERSAFE_SECUREID        9
1067 #define KRB5_PA_AFS3_SALT                10
1068 #define KRB5_PA_ENCTYPE_INFO             11
1069 #define KRB5_PA_SAM_CHALLENGE            12
1070 #define KRB5_PA_SAM_RESPONSE             13
1071 #define KRB5_PA_PK_AS_REQ                14
1072 #define KRB5_PA_PK_AS_REP                15
1073 #define KRB5_PA_DASS                     16
1074 #define KRB5_PA_ENCTYPE_INFO2            19
1075 #define KRB5_PA_USE_SPECIFIED_KVNO       20
1076 #define KRB5_PA_SAM_REDIRECT             21
1077 #define KRB5_PA_GET_FROM_TYPED_DATA      22
1078 #define KRB5_PA_SAM_ETYPE_INFO           23
1079 #define KRB5_PA_ALT_PRINC                24
1080 #define KRB5_PA_SAM_CHALLENGE2           30
1081 #define KRB5_PA_SAM_RESPONSE2            31
1082 #define KRB5_TD_PKINIT_CMS_CERTIFICATES 101
1083 #define KRB5_TD_KRB_PRINCIPAL           102
1084 #define KRB5_TD_KRB_REALM               103
1085 #define KRB5_TD_TRUSTED_CERTIFIERS      104
1086 #define KRB5_TD_CERTIFICATE_INDEX       105
1087 #define KRB5_TD_APP_DEFINED_ERROR       106
1088 #define KRB5_TD_REQ_NONCE               107
1089 #define KRB5_TD_REQ_SEQ                 108
1090
1091 /* preauthentication types >127 (i.e. negative ones) are app specific.
1092    however since Microsoft is the dominant(only?) user of types in this range
1093    we also treat the type as unsigned.
1094 */
1095 #define KRB5_PA_PAC_REQUEST              128    /* (Microsoft extension) */
1096 #define KRB5_PA_FOR_USER                 129    /* Impersonation (Microsoft extension) See [MS-SFU] */
1097
1098 #define KRB5_PA_PROV_SRV_LOCATION 0xffffffff    /* (gint32)0xFF) packetcable stuff */
1099
1100 /* Principal name-type */
1101 #define KRB5_NT_UNKNOWN        0
1102 #define KRB5_NT_PRINCIPAL      1
1103 #define KRB5_NT_SRV_INST       2
1104 #define KRB5_NT_SRV_HST        3
1105 #define KRB5_NT_SRV_XHST       4
1106 #define KRB5_NT_UID            5
1107 #define KRB5_NT_X500_PRINCIPAL 6
1108 #define KRB5_NT_SMTP_NAME      7
1109 #define KRB5_NT_ENTERPRISE    10
1110
1111 /*
1112  * MS specific name types, from
1113  *
1114  *      http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
1115  */
1116 #define KRB5_NT_MS_PRINCIPAL            -128
1117 #define KRB5_NT_MS_PRINCIPAL_AND_SID    -129
1118 #define KRB5_NT_ENT_PRINCIPAL_AND_SID   -130
1119 #define KRB5_NT_PRINCIPAL_AND_SID       -131
1120 #define KRB5_NT_SRV_INST_AND_SID        -132
1121
1122 /* error table constants */
1123 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
1124 #define KRB5_ET_KRB5KDC_ERR_NONE                          0
1125 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP                      1
1126 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP                   2
1127 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO                      3
1128 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO               4
1129 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO               5
1130 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN           6
1131 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN           7
1132 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE          8
1133 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY                      9
1134 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE              10
1135 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID                  11
1136 #define KRB5_ET_KRB5KDC_ERR_POLICY                       12
1137 #define KRB5_ET_KRB5KDC_ERR_BADOPTION                    13
1138 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP                 14
1139 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP               15
1140 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP           16
1141 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP                17
1142 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED               18
1143 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED              19
1144 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED                  20
1145 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET                21
1146 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET               22
1147 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP                      23
1148 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED               24
1149 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED             25
1150 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH               26
1151 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER           27
1152 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED            28
1153 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE              29
1154 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY             31
1155 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED               32
1156 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV                   33
1157 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT                    34
1158 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US                    35
1159 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH                  36
1160 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW                      37
1161 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR                   38
1162 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION                39
1163 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE                  40
1164 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED                  41
1165 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER                  42
1166 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT                43
1167 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER                 44
1168 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY                     45
1169 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL                  46
1170 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION              47
1171 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD                    48
1172 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ                    49
1173 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM               50
1174 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED             51
1175 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG             52
1176 #define KRB5_ET_KRB5KRB_ERR_GENERIC                      60
1177 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG                61
1178 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED             62
1179 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED                63
1180 #define KRB5_ET_KDC_ERROR_INVALID_SIG                    64
1181 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK                     65
1182 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH             66
1183 #define KRB5_ET_KRB_AP_ERR_NO_TGT                        67
1184 #define KRB5_ET_KDC_ERR_WRONG_REALM                      68
1185 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED         69
1186 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE          70
1187 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE              71
1188 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE              72
1189 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN        73
1190 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE    74
1191 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH             75
1192 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH                76
1193
1194 static const value_string krb5_error_codes[] = {
1195     { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
1196     { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
1197     { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
1198     { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
1199     { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
1200     { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
1201     { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
1202     { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
1203     { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
1204     { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
1205     { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
1206     { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
1207     { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
1208     { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
1209     { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
1210     { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
1211     { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
1212     { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
1213     { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
1214     { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
1215     { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
1216     { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
1217     { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
1218     { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
1219     { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
1220     { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
1221     { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1222     { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1223     { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1224     { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1225     { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1226     { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1227     { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1228     { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1229     { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1230     { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1231     { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1232     { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1233     { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1234     { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1235     { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1236     { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1237     { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1238     { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1239     { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1240     { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1241     { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1242     { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1243     { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1244     { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1245     { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1246     { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1247     { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1248     { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1249     { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1250     { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1251     { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1252     { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1253     { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1254     { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1255     { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1256     { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1257     { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1258     { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1259     { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1260     { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1261     { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1262     { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1263     { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1264     { 0, NULL }
1265 };
1266
1267
1268 #define PAC_LOGON_INFO              1
1269 #define PAC_CREDENTIAL_TYPE         2
1270 #define PAC_SERVER_CHECKSUM         6
1271 #define PAC_PRIVSVR_CHECKSUM        7
1272 #define PAC_CLIENT_INFO_TYPE       10
1273 #define PAC_S4U_DELEGATION_INFO    11
1274 #define PAC_UPN_DNS_INFO           12
1275
1276 static const value_string w2k_pac_types[] = {
1277     { PAC_LOGON_INFO            , "Logon Info" },
1278     { PAC_CREDENTIAL_TYPE       , "Credential Type" },
1279     { PAC_SERVER_CHECKSUM       , "Server Checksum" },
1280     { PAC_PRIVSVR_CHECKSUM      , "Privsvr Checksum" },
1281     { PAC_CLIENT_INFO_TYPE      , "Client Info Type" },
1282     { PAC_S4U_DELEGATION_INFO   , "S4U Delegation Info" },
1283     { PAC_UPN_DNS_INFO          , "UPN DNS Info" },
1284     { 0, NULL },
1285 };
1286
1287
1288
1289 static const value_string krb5_princ_types[] = {
1290     { KRB5_NT_UNKNOWN              , "Unknown" },
1291     { KRB5_NT_PRINCIPAL            , "Principal" },
1292     { KRB5_NT_SRV_INST             , "Service and Instance" },
1293     { KRB5_NT_SRV_HST              , "Service and Host" },
1294     { KRB5_NT_SRV_XHST             , "Service and Host Components" },
1295     { KRB5_NT_UID                  , "Unique ID" },
1296     { KRB5_NT_X500_PRINCIPAL       , "Encoded X.509 Distinguished Name" },
1297     { KRB5_NT_SMTP_NAME            , "SMTP Name" },
1298     { KRB5_NT_ENTERPRISE           , "Enterprise Name" },
1299     { KRB5_NT_MS_PRINCIPAL         , "NT 4.0 style name (MS specific)" },
1300     { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
1301     { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
1302     { KRB5_NT_PRINCIPAL_AND_SID    , "Principal name and SID (MS specific)"},
1303     { KRB5_NT_SRV_INST_AND_SID     , "SPN and SID (MS specific)"},
1304     { 0                            , NULL },
1305 };
1306
1307 static const value_string krb5_preauthentication_types[] = {
1308     { KRB5_PA_TGS_REQ              , "PA-TGS-REQ" },
1309     { KRB5_PA_ENC_TIMESTAMP        , "PA-ENC-TIMESTAMP" },
1310     { KRB5_PA_PW_SALT              , "PA-PW-SALT" },
1311     { KRB5_PA_ENC_ENCKEY           , "PA-ENC-ENCKEY" },
1312     { KRB5_PA_ENC_UNIX_TIME        , "PA-ENC-UNIX-TIME" },
1313     { KRB5_PA_ENC_SANDIA_SECURID   , "PA-PW-SALT" },
1314     { KRB5_PA_SESAME               , "PA-SESAME" },
1315     { KRB5_PA_OSF_DCE              , "PA-OSF-DCE" },
1316     { KRB5_PA_CYBERSAFE_SECUREID   , "PA-CYBERSAFE-SECURID" },
1317     { KRB5_PA_AFS3_SALT            , "PA-AFS3-SALT" },
1318     { KRB5_PA_ENCTYPE_INFO         , "PA-ENCTYPE-INFO" },
1319     { KRB5_PA_ENCTYPE_INFO2         , "PA-ENCTYPE-INFO2" },
1320     { KRB5_PA_SAM_CHALLENGE        , "PA-SAM-CHALLENGE" },
1321     { KRB5_PA_SAM_RESPONSE         , "PA-SAM-RESPONSE" },
1322     { KRB5_PA_PK_AS_REQ            , "PA-PK-AS-REQ" },
1323     { KRB5_PA_PK_AS_REP            , "PA-PK-AS-REP" },
1324     { KRB5_PA_DASS                 , "PA-DASS" },
1325     { KRB5_PA_USE_SPECIFIED_KVNO   , "PA-USE-SPECIFIED-KVNO" },
1326     { KRB5_PA_SAM_REDIRECT         , "PA-SAM-REDIRECT" },
1327     { KRB5_PA_GET_FROM_TYPED_DATA  , "PA-GET-FROM-TYPED-DATA" },
1328     { KRB5_PA_SAM_ETYPE_INFO       , "PA-SAM-ETYPE-INFO" },
1329     { KRB5_PA_ALT_PRINC            , "PA-ALT-PRINC" },
1330     { KRB5_PA_SAM_CHALLENGE2       , "PA-SAM-CHALLENGE2" },
1331     { KRB5_PA_SAM_RESPONSE2        , "PA-SAM-RESPONSE2" },
1332     { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
1333     { KRB5_TD_KRB_PRINCIPAL        , "TD-KRB-PRINCIPAL" },
1334     { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
1335     { KRB5_TD_TRUSTED_CERTIFIERS   , "TD-TRUSTED-CERTIFIERS" },
1336     { KRB5_TD_CERTIFICATE_INDEX    , "TD-CERTIFICATE-INDEX" },
1337     { KRB5_TD_APP_DEFINED_ERROR    , "TD-APP-DEFINED-ERROR" },
1338     { KRB5_TD_REQ_NONCE            , "TD-REQ-NONCE" },
1339     { KRB5_TD_REQ_SEQ              , "TD-REQ-SEQ" },
1340     { KRB5_PA_PAC_REQUEST          , "PA-PAC-REQUEST" },
1341     { KRB5_PA_FOR_USER             , "PA-FOR-USER" },
1342     { KRB5_PA_PROV_SRV_LOCATION    , "PA-PROV-SRV-LOCATION" },
1343     { 0                            , NULL },
1344 };
1345
1346 static const value_string krb5_encryption_types[] = {
1347     { KRB5_ENCTYPE_NULL           , "NULL" },
1348     { KRB5_ENCTYPE_DES_CBC_CRC    , "des-cbc-crc" },
1349     { KRB5_ENCTYPE_DES_CBC_MD4    , "des-cbc-md4" },
1350     { KRB5_ENCTYPE_DES_CBC_MD5    , "des-cbc-md5" },
1351     { KRB5_ENCTYPE_DES_CBC_RAW    , "des-cbc-raw" },
1352     { KRB5_ENCTYPE_DES3_CBC_SHA   , "des3-cbc-sha" },
1353     { KRB5_ENCTYPE_DES3_CBC_RAW   , "des3-cbc-raw" },
1354     { KRB5_ENCTYPE_DES_HMAC_SHA1  , "des-hmac-sha1" },
1355     { KRB5_ENCTYPE_DSA_SHA1_CMS   , "dsa-sha1-cms" },
1356     { KRB5_ENCTYPE_RSA_MD5_CMS    , "rsa-md5-cms" },
1357     { KRB5_ENCTYPE_RSA_SHA1_CMS   , "rsa-sha1-cms" },
1358     { KRB5_ENCTYPE_RC2_CBC_ENV    , "rc2-cbc-env" },
1359     { KRB5_ENCTYPE_RSA_ENV        , "rsa-env" },
1360     { KRB5_ENCTYPE_RSA_ES_OEAP_ENV, "rsa-es-oeap-env" },
1361     { KRB5_ENCTYPE_DES_EDE3_CBC_ENV, "des-ede3-cbc-env" },
1362     { KRB5_ENCTYPE_DES3_CBC_SHA1  , "des3-cbc-sha1" },
1363     { KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96  , "aes128-cts-hmac-sha1-96" },
1364     { KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96  , "aes256-cts-hmac-sha1-96" },
1365     { KRB5_ENCTYPE_DES_CBC_MD5_NT  , "des-cbc-md5-nt" },
1366     { KERB_ENCTYPE_RC4_HMAC       , "rc4-hmac" },
1367     { KERB_ENCTYPE_RC4_HMAC_EXP   , "rc4-hmac-exp" },
1368     { KRB5_ENCTYPE_UNKNOWN        , "unknown" },
1369     { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1    , "local-des3-hmac-sha1" },
1370     { KRB5_ENCTYPE_RC4_PLAIN_EXP  , "rc4-plain-exp" },
1371     { KRB5_ENCTYPE_RC4_PLAIN      , "rc4-plain" },
1372     { KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP, "rc4-plain-old-exp" },
1373     { KRB5_ENCTYPE_RC4_HMAC_OLD_EXP, "rc4-hmac-old-exp" },
1374     { KRB5_ENCTYPE_RC4_PLAIN_OLD  , "rc4-plain-old" },
1375     { KRB5_ENCTYPE_RC4_HMAC_OLD   , "rc4-hmac-old" },
1376     { KRB5_ENCTYPE_DES_PLAIN      , "des-plain" },
1377     { KRB5_ENCTYPE_RC4_SHA        , "rc4-sha" },
1378     { KRB5_ENCTYPE_RC4_LM         , "rc4-lm" },
1379     { KRB5_ENCTYPE_RC4_PLAIN2     , "rc4-plain2" },
1380     { KRB5_ENCTYPE_RC4_MD4        , "rc4-md4" },
1381     { 0                           , NULL },
1382 };
1383
1384 static const value_string krb5_checksum_types[] = {
1385     { KRB5_CHKSUM_NONE            , "none" },
1386     { KRB5_CHKSUM_CRC32           , "crc32" },
1387     { KRB5_CHKSUM_MD4             , "md4" },
1388     { KRB5_CHKSUM_KRB_DES_MAC     , "krb-des-mac" },
1389     { KRB5_CHKSUM_KRB_DES_MAC_K   , "krb-des-mac-k" },
1390     { KRB5_CHKSUM_MD5             , "md5" },
1391     { KRB5_CHKSUM_MD5_DES         , "md5-des" },
1392     { KRB5_CHKSUM_MD5_DES3        , "md5-des3" },
1393     { KRB5_CHKSUM_HMAC_SHA1_DES3_KD, "hmac-sha1-des3-kd" },
1394     { KRB5_CHKSUM_HMAC_SHA1_DES3  , "hmac-sha1-des3" },
1395     { KRB5_CHKSUM_SHA1_UNKEYED    , "sha1 (unkeyed)" },
1396     { KRB5_CHKSUM_HMAC_MD5        , "hmac-md5" },
1397     { KRB5_CHKSUM_MD5_HMAC        , "md5-hmac" },
1398     { KRB5_CHKSUM_RC4_MD5         , "rc5-md5" },
1399     { KRB5_CHKSUM_MD25            , "md25" },
1400     { KRB5_CHKSUM_DES_MAC_MD5     , "des-mac-md5" },
1401     { KRB5_CHKSUM_DES_MAC         , "des-mac" },
1402     { KRB5_CHKSUM_REAL_CRC32      , "real-crc32" },
1403     { KRB5_CHKSUM_SHA1            , "sha1" },
1404     { KRB5_CHKSUM_LM              , "lm" },
1405     { KRB5_CHKSUM_GSSAPI          , "gssapi-8003" },
1406     { 0                           , NULL },
1407 };
1408
1409 #define KRB5_AD_IF_RELEVANT                              1
1410 #define KRB5_AD_INTENDED_FOR_SERVER                      2
1411 #define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS           3
1412 #define KRB5_AD_KDC_ISSUED                               4
1413 #define KRB5_AD_OR                                       5
1414 #define KRB5_AD_MANDATORY_TICKET_EXTENSIONS              6
1415 #define KRB5_AD_IN_TICKET_EXTENSIONS                     7
1416 #define KRB5_AD_MANDATORY_FOR_KDC                        8
1417 #define KRB5_AD_OSF_DCE                                 64
1418 #define KRB5_AD_SESAME                                  65
1419 #define KRB5_AD_OSF_DCE_PKI_CERTID                      66
1420 #define KRB5_AD_WIN2K_PAC                              128
1421 #define KRB5_AD_SIGNTICKET                      0xffffffef
1422
1423 static const value_string krb5_ad_types[] = {
1424     { KRB5_AD_IF_RELEVANT                       , "AD-IF-RELEVANT" },
1425     { KRB5_AD_INTENDED_FOR_SERVER               , "AD-Intended-For-Server" },
1426     { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS    , "AD-Intended-For-Application-Class" },
1427     { KRB5_AD_KDC_ISSUED                        , "AD-KDCIssued" },
1428     { KRB5_AD_OR                                , "AD-AND-OR" },
1429     { KRB5_AD_MANDATORY_TICKET_EXTENSIONS       , "AD-Mandatory-Ticket-Extensions" },
1430     { KRB5_AD_IN_TICKET_EXTENSIONS              , "AD-IN-Ticket-Extensions" },
1431     { KRB5_AD_MANDATORY_FOR_KDC                 , "AD-MANDATORY-FOR-KDC" },
1432     { KRB5_AD_OSF_DCE                           , "AD-OSF-DCE" },
1433     { KRB5_AD_SESAME                            , "AD-SESAME" },
1434     { KRB5_AD_OSF_DCE_PKI_CERTID                , "AD-OSF-DCE-PKI-CertID" },
1435     { KRB5_AD_WIN2K_PAC                         , "AD-Win2k-PAC" },
1436     { KRB5_AD_SIGNTICKET                        , "AD-SignTicket" },
1437     { 0 , NULL },
1438 };
1439
1440 static const value_string krb5_transited_types[] = {
1441     { 1                           , "DOMAIN-X500-COMPRESS" },
1442     { 0                           , NULL }
1443 };
1444
1445 static const value_string krb5_address_types[] = {
1446     { KRB5_ADDR_IPv4,           "IPv4"},
1447     { KRB5_ADDR_CHAOS,          "CHAOS"},
1448     { KRB5_ADDR_XEROX,          "XEROX"},
1449     { KRB5_ADDR_ISO,            "ISO"},
1450     { KRB5_ADDR_DECNET,         "DECNET"},
1451     { KRB5_ADDR_APPLETALK,      "APPLETALK"},
1452     { KRB5_ADDR_NETBIOS,        "NETBIOS"},
1453     { KRB5_ADDR_IPv6,           "IPv6"},
1454     { 0,                        NULL },
1455 };
1456
1457 static const value_string krb5_msg_types[] = {
1458     { KRB5_MSG_TICKET,            "Ticket" },
1459     { KRB5_MSG_AUTHENTICATOR,     "Authenticator" },
1460     { KRB5_MSG_ENC_TICKET_PART,   "EncTicketPart" },
1461     { KRB5_MSG_TGS_REQ,           "TGS-REQ" },
1462     { KRB5_MSG_TGS_REP,           "TGS-REP" },
1463     { KRB5_MSG_AS_REQ,            "AS-REQ" },
1464     { KRB5_MSG_AS_REP,            "AS-REP" },
1465     { KRB5_MSG_AP_REQ,            "AP-REQ" },
1466     { KRB5_MSG_AP_REP,            "AP-REP" },
1467     { KRB5_MSG_SAFE,              "KRB-SAFE" },
1468     { KRB5_MSG_PRIV,              "KRB-PRIV" },
1469     { KRB5_MSG_CRED,              "KRB-CRED" },
1470     { KRB5_MSG_ENC_AS_REP_PART,   "EncASRepPart" },
1471     { KRB5_MSG_ENC_TGS_REP_PART,  "EncTGSRepPart" },
1472     { KRB5_MSG_ENC_AP_REP_PART,   "EncAPRepPart" },
1473     { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1474     { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1475     { KRB5_MSG_ERROR,             "KRB-ERROR" },
1476     { 0, NULL },
1477 };
1478
1479
1480
1481
1482 static int dissect_krb5_application_choice(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1483 static int dissect_krb5_Application_1(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1484 static int dissect_krb5_Authenticator(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1485 static int dissect_krb5_EncTicketPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1486 static int dissect_krb5_EncAPRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1487 static int dissect_krb5_EncKrbPrivPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1488 static int dissect_krb5_EncKrbCredPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1489 static int dissect_krb5_EncKDCRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1490 static int dissect_krb5_KDC_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1491 static int dissect_krb5_KDC_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1492 static int dissect_krb5_AP_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1493 static int dissect_krb5_AP_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1494 static int dissect_krb5_SAFE(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1495 static int dissect_krb5_PRIV(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1496 static int dissect_krb5_CRED(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1497 static int dissect_krb5_ERROR(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1498
1499 static const ber_old_choice_t kerberos_applications_choice[] = {
1500     { KRB5_MSG_TICKET,  BER_CLASS_APP,  KRB5_MSG_TICKET,        0, dissect_krb5_Application_1 },
1501     { KRB5_MSG_AUTHENTICATOR,   BER_CLASS_APP,  KRB5_MSG_AUTHENTICATOR,   0, dissect_krb5_Authenticator },
1502     { KRB5_MSG_ENC_TICKET_PART, BER_CLASS_APP,  KRB5_MSG_ENC_TICKET_PART, 0, dissect_krb5_EncTicketPart },
1503     { KRB5_MSG_AS_REQ,  BER_CLASS_APP,  KRB5_MSG_AS_REQ,        0,      dissect_krb5_KDC_REQ },
1504     { KRB5_MSG_AS_REP,  BER_CLASS_APP,  KRB5_MSG_AS_REP,        0,      dissect_krb5_KDC_REP },
1505     { KRB5_MSG_TGS_REQ, BER_CLASS_APP,  KRB5_MSG_TGS_REQ,       0,      dissect_krb5_KDC_REQ },
1506     { KRB5_MSG_TGS_REP, BER_CLASS_APP,  KRB5_MSG_TGS_REP,       0,      dissect_krb5_KDC_REP },
1507     { KRB5_MSG_AP_REQ,  BER_CLASS_APP,  KRB5_MSG_AP_REQ,        0,      dissect_krb5_AP_REQ },
1508     { KRB5_MSG_AP_REP,  BER_CLASS_APP,  KRB5_MSG_AP_REP,        0,      dissect_krb5_AP_REP },
1509     { KRB5_MSG_ENC_AS_REP_PART,   BER_CLASS_APP, KRB5_MSG_ENC_AS_REP_PART,   0, dissect_krb5_EncKDCRepPart },
1510     { KRB5_MSG_ENC_TGS_REP_PART,  BER_CLASS_APP, KRB5_MSG_ENC_TGS_REP_PART,  0, dissect_krb5_EncKDCRepPart },
1511     { KRB5_MSG_ENC_AP_REP_PART,   BER_CLASS_APP, KRB5_MSG_ENC_AP_REP_PART,   0, dissect_krb5_EncAPRepPart },
1512     { KRB5_MSG_ENC_KRB_PRIV_PART, BER_CLASS_APP, KRB5_MSG_ENC_KRB_PRIV_PART, 0, dissect_krb5_EncKrbPrivPart },
1513     { KRB5_MSG_ENC_KRB_CRED_PART, BER_CLASS_APP, KRB5_MSG_ENC_KRB_CRED_PART, 0, dissect_krb5_EncKrbCredPart },
1514     { KRB5_MSG_SAFE,    BER_CLASS_APP,  KRB5_MSG_SAFE,          0,      dissect_krb5_SAFE },
1515     { KRB5_MSG_PRIV,    BER_CLASS_APP,  KRB5_MSG_PRIV,          0,      dissect_krb5_PRIV },
1516     { KRB5_MSG_CRED,    BER_CLASS_APP,  KRB5_MSG_CRED,          0,      dissect_krb5_CRED },
1517     { KRB5_MSG_ERROR,   BER_CLASS_APP,  KRB5_MSG_ERROR,         0,      dissect_krb5_ERROR },
1518     { 0, 0, 0, 0, NULL }
1519 };
1520
1521
1522 static int
1523 dissect_krb5_application_choice(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1524 {
1525     offset=dissect_ber_old_choice(actx, tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
1526     return offset;
1527 }
1528
1529 static const true_false_string krb5_apoptions_reserved = {
1530     "RESERVED bit on",
1531     "RESERVED bit off"
1532 };
1533 static const true_false_string krb5_apoptions_use_session_key = {
1534     "USE SESSION KEY to encrypt the ticket",
1535     "Do NOT use the session key to encrypt the ticket"
1536 };
1537 static const true_false_string krb5_apoptions_mutual_required = {
1538     "MUTUAL authentication is REQUIRED",
1539     "Mutual authentication is NOT required"
1540 };
1541
1542 static int *APOptions_bits[] = {
1543     &hf_krb_APOptions_reserved,
1544     &hf_krb_APOptions_use_session_key,
1545     &hf_krb_APOptions_mutual_required,
1546     NULL
1547 };
1548 static int
1549 dissect_krb5_APOptions(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1550 {
1551     offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, APOptions_bits, hf_krb_APOptions, ett_krb_AP_Options, NULL);
1552     return offset;
1553 }
1554
1555
1556
1557 static const true_false_string krb5_kdcoptions_forwardable = {
1558     "FORWARDABLE tickets are allowed/requested",
1559     "Do NOT use forwardable tickets"
1560 };
1561 static const true_false_string krb5_kdcoptions_forwarded = {
1562     "This ticket has been FORWARDED",
1563     "This is NOT a forwarded ticket"
1564 };
1565 static const true_false_string krb5_kdcoptions_proxiable = {
1566     "PROXIABLE tickets are allowed/requested",
1567     "Do NOT use proxiable tickets"
1568 };
1569 static const true_false_string krb5_kdcoptions_proxy = {
1570     "This is a PROXY ticket",
1571     "This ticket has NOT been proxied"
1572 };
1573 static const true_false_string krb5_kdcoptions_allow_postdate = {
1574     "We allow the ticket to be POSTDATED",
1575     "We do NOT allow the ticket to be postdated"
1576 };
1577 static const true_false_string krb5_kdcoptions_postdated = {
1578     "This ticket is POSTDATED",
1579     "This ticket is NOT postdated"
1580 };
1581 static const true_false_string krb5_kdcoptions_renewable = {
1582     "This ticket is RENEWABLE",
1583     "This ticket is NOT renewable"
1584 };
1585 static const true_false_string krb5_kdcoptions_constrained_delegation = {
1586     "This is a request for a CONSTRAINED DELEGATION PAC",
1587     "This is a normal request (no constrained delegation)"
1588 };
1589 static const true_false_string krb5_kdcoptions_canonicalize = {
1590     "This is a request for a CANONICALIZED ticket",
1591     "This is NOT a canonicalized ticket request"
1592 };
1593 static const true_false_string krb5_kdcoptions_disable_transited_check = {
1594     "Transited checking is DISABLED",
1595     "Transited checking is NOT disabled"
1596 };
1597 static const true_false_string krb5_kdcoptions_renewable_ok = {
1598     "We accept RENEWED tickets",
1599     "We do NOT accept renewed tickets"
1600 };
1601 static const true_false_string krb5_kdcoptions_enc_tkt_in_skey = {
1602     "ENCrypt TKT in SKEY",
1603     "Do NOT encrypt the tkt inside the skey"
1604 };
1605 static const true_false_string krb5_kdcoptions_renew = {
1606     "This is a request to RENEW a ticket",
1607     "This is NOT a request to renew a ticket"
1608 };
1609 static const true_false_string krb5_kdcoptions_validate = {
1610     "This is a request to VALIDATE a postdated ticket",
1611     "This is NOT a request to validate a postdated ticket"
1612 };
1613
1614 static int* KDCOptions_bits[] = {
1615     &hf_krb_KDCOptions_forwardable,
1616     &hf_krb_KDCOptions_forwarded,
1617     &hf_krb_KDCOptions_proxiable,
1618     &hf_krb_KDCOptions_proxy,
1619     &hf_krb_KDCOptions_allow_postdate,
1620     &hf_krb_KDCOptions_postdated,
1621     &hf_krb_KDCOptions_renewable,
1622     &hf_krb_KDCOptions_opt_hardware_auth,
1623     &hf_krb_KDCOptions_constrained_delegation,
1624     &hf_krb_KDCOptions_canonicalize,
1625     &hf_krb_KDCOptions_disable_transited_check,
1626     &hf_krb_KDCOptions_renewable_ok,
1627     &hf_krb_KDCOptions_enc_tkt_in_skey,
1628     &hf_krb_KDCOptions_renew,
1629     &hf_krb_KDCOptions_validate,
1630     NULL
1631 };
1632
1633 static int
1634 dissect_krb5_KDCOptions(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1635 {
1636     offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, KDCOptions_bits, hf_krb_KDCOptions, ett_krb_KDC_Options, NULL);
1637     return offset;
1638 }
1639
1640 static int
1641 dissect_krb5_rtime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1642 {
1643     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_rtime);
1644     return offset;
1645 }
1646
1647 int
1648 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1649 {
1650     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_ctime);
1651     return offset;
1652 }
1653 static int
1654 dissect_krb5_cusec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1655 {
1656     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_cusec, NULL);
1657     return offset;
1658 }
1659
1660 static int
1661 dissect_krb5_stime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1662 {
1663     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_stime);
1664     return offset;
1665 }
1666 static int
1667 dissect_krb5_susec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1668 {
1669     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_susec, NULL);
1670     return offset;
1671 }
1672
1673
1674 static int
1675 dissect_krb5_error_code(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_error_code, &krb5_errorcode);
1678     if(krb5_errorcode && check_col(actx->pinfo->cinfo, COL_INFO)) {
1679         col_add_fstr(actx->pinfo->cinfo, COL_INFO,
1680                      "KRB Error: %s",
1681                      val_to_str(krb5_errorcode, krb5_error_codes,
1682                                 "Unknown error code %#x"));
1683     }
1684
1685     return offset;
1686 }
1687
1688
1689 static int
1690 dissect_krb5_till(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1691 {
1692     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_till);
1693     return offset;
1694 }
1695 static int
1696 dissect_krb5_from(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1697 {
1698     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_from);
1699     return offset;
1700 }
1701
1702
1703
1704 static int
1705 dissect_krb5_nonce(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1706 {
1707     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_nonce, NULL);
1708     return offset;
1709 }
1710
1711
1712 /*
1713  *          etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
1714  */
1715 static int
1716 dissect_krb5_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1717 {
1718     guint32 etype;
1719
1720     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &etype);
1721     if(tree){
1722         proto_item_append_text(tree, " %s",
1723                                val_to_str(etype, krb5_encryption_types,
1724                                           "%d"));
1725     }
1726     return offset;
1727 }
1728 static ber_old_sequence_t etype_sequence_of[1] = {
1729     { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_krb5_etype },
1730 };
1731 static int
1732 dissect_krb5_etype_sequence_of(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1733 {
1734     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, etype_sequence_of, hf_krb_etypes, ett_krb_etypes);
1735
1736     return offset;
1737 }
1738 static guint32 authenticator_etype;
1739 static int
1740 dissect_krb5_authenticator_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1741 {
1742     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &authenticator_etype);
1743     if(tree){
1744         proto_item_append_text(tree, " %s",
1745                                val_to_str(authenticator_etype, krb5_encryption_types,
1746                                           "%#x"));
1747     }
1748     return offset;
1749 }
1750 static guint32 Ticket_etype;
1751 static int
1752 dissect_krb5_Ticket_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1753 {
1754     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &Ticket_etype);
1755     if(tree){
1756         proto_item_append_text(tree, " %s",
1757                                val_to_str(Ticket_etype, krb5_encryption_types,
1758                                           "%#x"));
1759     }
1760     return offset;
1761 }
1762 static guint32 AP_REP_etype;
1763 static int
1764 dissect_krb5_AP_REP_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1765 {
1766     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &AP_REP_etype);
1767     if(tree){
1768         proto_item_append_text(tree, " %s",
1769                                val_to_str(AP_REP_etype, krb5_encryption_types,
1770                                           "%#x"));
1771     }
1772     return offset;
1773 }
1774 static guint32 PA_ENC_TIMESTAMP_etype;
1775 static int
1776 dissect_krb5_PA_ENC_TIMESTAMP_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1777 {
1778     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &PA_ENC_TIMESTAMP_etype);
1779     if(tree){
1780         proto_item_append_text(tree, " %s",
1781                                val_to_str(PA_ENC_TIMESTAMP_etype, krb5_encryption_types,
1782                                           "%#x"));
1783     }
1784     return offset;
1785 }
1786
1787
1788 /*
1789  *  HostAddress ::=    SEQUENCE  {
1790  *                     addr-type[0]             INTEGER,
1791  *                     address[1]               OCTET STRING
1792  *  }
1793  */
1794 static guint32 addr_type;
1795 static int dissect_krb5_addr_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1796 {
1797     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_addr_type, &addr_type);
1798     return offset;
1799 }
1800
1801 #define ADDRESS_STR_BUFSIZ 256
1802 static int dissect_krb5_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1803 {
1804     gint8 class;
1805     gboolean pc;
1806     gint32 tag;
1807     guint32 len;
1808     char *address_str;
1809     proto_item *it=NULL;
1810
1811     /* read header and len for the octet string */
1812     offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
1813     offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL);
1814
1815     address_str=ep_alloc(ADDRESS_STR_BUFSIZ);
1816     address_str[0]='\0';
1817     switch(addr_type){
1818     case KRB5_ADDR_IPv4:
1819         it=proto_tree_add_item(tree, hf_krb_address_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1820         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));
1821         break;
1822     case KRB5_ADDR_NETBIOS:
1823     {
1824         char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1825         int netbios_name_type;
1826         int netbios_name_len = (NETBIOS_NAME_LEN - 1)*4 + 1;
1827
1828         netbios_name_type = process_netbios_name(tvb_get_ptr(tvb, offset, 16), netbios_name, netbios_name_len);
1829         g_snprintf(address_str, ADDRESS_STR_BUFSIZ, "%s<%02x>", netbios_name, netbios_name_type);
1830         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));
1831     }
1832     break;
1833     case KRB5_ADDR_IPv6:
1834         it=proto_tree_add_item(tree, hf_krb_address_ipv6, tvb, offset, INET6_ADDRLEN, ENC_NA);
1835         g_snprintf(address_str, ADDRESS_STR_BUFSIZ, "%s", tvb_ip6_to_str(tvb, offset));
1836         break;
1837     default:
1838         proto_tree_add_text(tree, tvb, offset, len, "KRB Address: I don't know how to parse this type of address yet");
1839
1840     }
1841
1842     /* push it up two levels in the decode pane */
1843     if(it){
1844         proto_item_append_text(proto_item_get_parent(it), " %s",address_str);
1845         proto_item_append_text(proto_item_get_parent_nth(it, 2), " %s",address_str);
1846     }
1847
1848     offset+=len;
1849     return offset;
1850 }
1851 static ber_old_sequence_t HostAddress_sequence[] = {
1852     { BER_CLASS_CON, 0, 0, dissect_krb5_addr_type },
1853     { BER_CLASS_CON, 1, 0, dissect_krb5_address },
1854     { 0, 0, 0, NULL }
1855 };
1856 static int
1857 dissect_krb5_HostAddress(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1858 {
1859
1860     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_HostAddress, ett_krb_HostAddress);
1861
1862     return offset;
1863 }
1864 static int
1865 dissect_krb5_s_address(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_s_address, ett_krb_s_address);
1869
1870     return offset;
1871 }
1872
1873 static int
1874 dissect_krb5_r_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1875 {
1876
1877     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_r_address, ett_krb_r_address);
1878
1879     return offset;
1880 }
1881
1882 /*
1883  *  HostAddresses ::=   SEQUENCE OF SEQUENCE {
1884  *                      addr-type[0]             INTEGER,
1885  *                      address[1]               OCTET STRING
1886  *  }
1887  *
1888  */
1889 static ber_old_sequence_t HostAddresses_sequence_of[1] = {
1890     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_HostAddress },
1891 };
1892 static int
1893 dissect_krb5_HostAddresses(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1894 {
1895     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, HostAddresses_sequence_of, hf_krb_HostAddresses, ett_krb_HostAddresses);
1896
1897     return offset;
1898 }
1899
1900
1901 /* sequence of tickets */
1902 static ber_old_sequence_t sequence_of_tickets[1] = {
1903     { BER_CLASS_APP, 1, 0, dissect_krb5_Application_1},
1904 };
1905 static int
1906 dissect_krb5_sq_tickets(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1907 {
1908     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, sequence_of_tickets, hf_krb_sq_tickets, ett_krb_sq_tickets);
1909
1910     return offset;
1911 }
1912
1913 static int
1914 dissect_krb5_msg_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1915 {
1916     guint32 msgtype;
1917
1918     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_msg_type, &msgtype);
1919
1920     if (gbl_do_col_info & check_col(actx->pinfo->cinfo, COL_INFO)) {
1921         col_add_str(actx->pinfo->cinfo, COL_INFO,
1922                     val_to_str(msgtype, krb5_msg_types,
1923                                "Unknown msg type %#x"));
1924     }
1925     gbl_do_col_info=FALSE;
1926
1927     /* append the application type to the subtree */
1928     proto_item_append_text(tree, " %s", val_to_str(msgtype, krb5_msg_types, "Unknown:0x%x"));
1929
1930     return offset;
1931 }
1932
1933
1934
1935 static int
1936 dissect_krb5_pvno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1937 {
1938     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_pvno, NULL);
1939
1940     return offset;
1941 }
1942
1943
1944 /*
1945  * PrincipalName ::=   SEQUENCE {
1946  *                     name-type[0]     INTEGER,
1947  *                     name-string[1]   SEQUENCE OF GeneralString
1948  * }
1949  */
1950 static guint32 name_type;
1951 static int
1952 dissect_krb5_name_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1953 {
1954     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_name_type, &name_type);
1955     if(tree){
1956         proto_item_append_text(tree, " (%s):",
1957                                val_to_str(name_type, krb5_princ_types,
1958                                           "Unknown:%d"));
1959     }
1960     return offset;
1961 }
1962 static char name_string_separator;
1963 static int
1964 dissect_krb5_name_string(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1965 {
1966     char name_string[256];
1967
1968     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_name_string, name_string, 255);
1969     if(tree){
1970         proto_item_append_text(tree, "%c%s", name_string_separator, name_string);
1971         name_string_separator='/';
1972     }
1973
1974     return offset;
1975 }
1976 static ber_old_sequence_t name_stringe_sequence_of[1] = {
1977     { BER_CLASS_UNI, BER_UNI_TAG_GeneralString, BER_FLAGS_NOOWNTAG, dissect_krb5_name_string },
1978 };
1979 static int
1980 dissect_krb5_name_strings(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1981 {
1982     name_string_separator=' ';
1983     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, name_stringe_sequence_of, -1, -1);
1984
1985     return offset;
1986 }
1987 static ber_old_sequence_t PrincipalName_sequence[] = {
1988     { BER_CLASS_CON, 0, 0, dissect_krb5_name_type },
1989     { BER_CLASS_CON, 1, 0, dissect_krb5_name_strings },
1990     { 0, 0, 0, NULL }
1991 };
1992 static int
1993 dissect_krb5_sname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1994 {
1995
1996     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PrincipalName_sequence, hf_krb_sname, ett_krb_sname);
1997
1998     return offset;
1999 }
2000 static int
2001 dissect_krb5_pname(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_pname, ett_krb_pname);
2005
2006     return offset;
2007 }
2008 int
2009 dissect_krb5_cname(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_cname, ett_krb_cname);
2013
2014     return offset;
2015 }
2016
2017
2018 int
2019 dissect_krb5_prealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2020 {
2021     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_prealm, NULL, 0);
2022     return offset;
2023 }
2024
2025 int
2026 dissect_krb5_srealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2027 {
2028     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_srealm, NULL, 0);
2029     return offset;
2030 }
2031
2032 int
2033 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2034 {
2035     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_realm, NULL, 0);
2036     return offset;
2037 }
2038
2039 static int
2040 dissect_krb5_crealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2041 {
2042     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_crealm, NULL, 0);
2043     return offset;
2044 }
2045
2046
2047
2048 static int
2049 dissect_krb5_PA_PAC_REQUEST_flag(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2050 {
2051     offset=dissect_ber_boolean(FALSE, actx, tree, tvb, offset, hf_krb_PA_PAC_REQUEST_flag, NULL);
2052     return offset;
2053 }
2054
2055
2056 static ber_old_sequence_t PA_PAC_REQUEST_sequence[] = {
2057     { BER_CLASS_CON, 0, 0, dissect_krb5_PA_PAC_REQUEST_flag },
2058     { 0, 0, 0, NULL }
2059 };
2060 static int
2061 dissect_krb5_PA_PAC_REQUEST(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2062 {
2063
2064     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_PAC_REQUEST_sequence, -1, -1);
2065
2066     return offset;
2067 }
2068
2069 static int
2070 dissect_krb5_s4u2self_auth(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2071 {
2072     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_s4u2self_auth, NULL, 0);
2073     return offset;
2074 }
2075
2076 static ber_old_sequence_t PA_FOR_USER_sequence[] = {
2077     { BER_CLASS_CON, 0, 0, dissect_krb5_cname },
2078     { BER_CLASS_CON, 1, 0, dissect_krb5_realm },
2079     { BER_CLASS_CON, 2, 0, dissect_krb5_Checksum },
2080     { BER_CLASS_CON, 3, 0, dissect_krb5_s4u2self_auth },
2081     { 0, 0, 0, NULL }
2082 };
2083
2084 static int
2085 dissect_krb5_PA_FOR_USER(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2086 {
2087     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_FOR_USER_sequence, -1, -1);
2088     return offset;
2089 }
2090
2091
2092 static int
2093 dissect_krb5_PA_PROV_SRV_LOCATION(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2094 {
2095     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
2096
2097     return offset;
2098 }
2099
2100
2101
2102 static int
2103 dissect_krb5_kvno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2104 {
2105     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_kvno, NULL);
2106
2107     return offset;
2108 }
2109
2110
2111
2112 static int
2113 dissect_krb5_seq_number(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2114 {
2115     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_seq_number, NULL);
2116
2117     return offset;
2118 }
2119
2120
2121
2122 static int
2123 dissect_krb5_patimestamp(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2124 {
2125     offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_patimestamp);
2126     return offset;
2127 }
2128 #ifdef HAVE_KERBEROS
2129 static int
2130 dissect_krb5_pausec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2131 {
2132     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_pausec, NULL);
2133     return offset;
2134 }
2135 static const ber_old_sequence_t PA_ENC_TS_ENC_sequence[] = {
2136     { BER_CLASS_CON, 0, 0, dissect_krb5_patimestamp },
2137     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_pausec },
2138     { 0, 0, 0, NULL }
2139 };
2140 static int
2141 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2142 {
2143     guint8 *plaintext=NULL;
2144     int length;
2145
2146     length=tvb_length_remaining(tvb, offset);
2147
2148     /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
2149      * 7.5.1
2150      * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
2151      * == 1
2152      */
2153     if(!plaintext){
2154         tvbuff_t *next_tvb;
2155
2156         next_tvb=tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_remaining(tvb, offset));
2157         plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, PA_ENC_TIMESTAMP_etype, NULL);
2158     }
2159
2160     if(plaintext){
2161         tvbuff_t *next_tvb;
2162         next_tvb = tvb_new_child_real_data(tvb, plaintext,
2163                                            length,
2164                                            length);
2165         tvb_set_free_cb(next_tvb, g_free);
2166
2167         /* Add the decrypted data to the data source list. */
2168         add_new_data_source(actx->pinfo, next_tvb, "Decrypted Krb5");
2169
2170
2171         offset=dissect_ber_old_sequence(FALSE, actx, tree, next_tvb, 0, PA_ENC_TS_ENC_sequence, -1, -1);
2172
2173     }
2174     return offset;
2175 }
2176 #endif
2177
2178
2179 static int
2180 dissect_krb5_encrypted_PA_ENC_TIMESTAMP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2181 {
2182 #ifdef HAVE_KERBEROS
2183     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, dissect_krb5_decrypt_PA_ENC_TIMESTAMP);
2184 #else
2185     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, NULL);
2186 #endif
2187     return offset;
2188 }
2189 static ber_old_sequence_t PA_ENC_TIMESTAMP_sequence[] = {
2190     { BER_CLASS_CON, 0, 0,
2191       dissect_krb5_PA_ENC_TIMESTAMP_etype },
2192     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2193       dissect_krb5_kvno },
2194     { BER_CLASS_CON, 2, 0,
2195       dissect_krb5_encrypted_PA_ENC_TIMESTAMP },
2196     { 0, 0, 0, NULL }
2197 };
2198 static int
2199 dissect_krb5_PA_ENC_TIMESTAMP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2200 {
2201     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENC_TIMESTAMP_sequence, -1, -1);
2202
2203     return offset;
2204 }
2205
2206
2207
2208 static int
2209 dissect_krb5_etype_info_salt(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2210 {
2211     offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_etype_info_salt, NULL);
2212     return offset;
2213 }
2214
2215 static int
2216 dissect_krb5_etype_info2_salt(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2217 {
2218     offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_etype_info2_salt, NULL, 0);
2219     return offset;
2220 }
2221
2222 static int
2223 dissect_krb5_etype_info2_s2kparams(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2224 {
2225     offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_etype_info2_s2kparams, NULL);
2226     return offset;
2227 }
2228
2229 static ber_old_sequence_t PA_ENCTYPE_INFO_ENTRY_sequence[] = {
2230     { BER_CLASS_CON, 0, 0,
2231       dissect_krb5_etype },
2232     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2233       dissect_krb5_etype_info_salt },
2234     { 0, 0, 0, NULL }
2235 };
2236 static int
2237 dissect_krb5_PA_ENCTYPE_INFO_ENTRY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2238 {
2239     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO_ENTRY_sequence, -1, -1);
2240
2241     return offset;
2242 }
2243
2244 static ber_old_sequence_t PA_ENCTYPE_INFO_sequence_of[1] = {
2245     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO_ENTRY },
2246 };
2247 static int
2248 dissect_krb5_PA_ENCTYPE_INFO(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2249 {
2250     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO_sequence_of, -1, -1);
2251
2252     return offset;
2253 }
2254
2255 static ber_old_sequence_t PA_ENCTYPE_INFO2_ENTRY_sequence[] = {
2256     { BER_CLASS_CON, 0, 0,
2257       dissect_krb5_etype },
2258     { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2259       dissect_krb5_etype_info2_salt },
2260     { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
2261       dissect_krb5_etype_info2_s2kparams },
2262     { 0, 0, 0, NULL }
2263 };
2264 static int
2265 dissect_krb5_PA_ENCTYPE_INFO2_ENTRY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2266 {
2267     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO2_ENTRY_sequence, -1, -1);
2268
2269     return offset;
2270 }
2271
2272 static ber_old_sequence_t PA_ENCTYPE_INFO2_sequence_of[1] = {
2273     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO2_ENTRY },
2274 };
2275 static int
2276 dissect_krb5_PA_ENCTYPE_INFO2(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2277 {
2278     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO2_sequence_of, -1, -1);
2279
2280     return offset;
2281 }
2282
2283
2284 static int
2285 dissect_krb5_PW_SALT(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2286 {
2287     guint32 nt_status;
2288
2289     /* Microsoft stores a special 12 byte blob here
2290      * guint32 NT_status
2291      * guint32 unknown
2292      * guint32 unknown
2293      * decode everything as this blob for now until we see if anyone
2294      * else ever uses it   or we learn how to tell whether this
2295      * is such an MS blob or not.
2296      */
2297     proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2298     nt_status=tvb_get_letohl(tvb, offset);
2299     if(nt_status && check_col(actx->pinfo->cinfo, COL_INFO)) {
2300         col_append_fstr(actx->pinfo->cinfo, COL_INFO,
2301                         " NT Status: %s",
2302                         val_to_str(nt_status, NT_errors,
2303                                    "Unknown error code %#x"));
2304     }
2305     offset += 4;
2306
2307     proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2308     offset += 4;
2309
2310     proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2311     offset += 4;
2312
2313     return offset;
2314 }
2315
2316 /*
2317  * PA-DATA ::=        SEQUENCE {
2318  *          padata-type[1]        INTEGER,
2319  *          padata-value[2]       OCTET STRING,
2320  *                        -- might be encoded AP-REQ
2321  * }
2322  */
2323 static guint32 krb_PA_DATA_type;
2324 static int
2325 dissect_krb5_PA_DATA_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2326 {
2327     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_PA_DATA_type, &krb_PA_DATA_type);
2328
2329     if(tree){
2330         proto_item_append_text(tree, " %s",
2331                                val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
2332                                           "Unknown:%d"));
2333     }
2334     return offset;
2335 }
2336 static int
2337 dissect_krb5_PA_DATA_value(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2338 {
2339     proto_tree *tree=parent_tree;
2340
2341     if(actx->created_item){
2342         tree=proto_item_add_subtree(actx->created_item, ett_krb_PA_DATA_tree);
2343     }
2344
2345
2346     switch(krb_PA_DATA_type){
2347     case KRB5_PA_TGS_REQ:
2348         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_application_choice);
2349         break;
2350     case KRB5_PA_PK_AS_REQ:
2351         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REQ);
2352         break;
2353     case KRB5_PA_PK_AS_REP:
2354         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REP);
2355         break;
2356     case KRB5_PA_PAC_REQUEST:
2357         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PAC_REQUEST);
2358         break;
2359     case KRB5_PA_FOR_USER:
2360         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_FOR_USER);
2361         break;
2362     case KRB5_PA_PROV_SRV_LOCATION:
2363         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PROV_SRV_LOCATION);
2364         break;
2365     case KRB5_PA_ENC_TIMESTAMP:
2366         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENC_TIMESTAMP);
2367         break;
2368     case KRB5_PA_ENCTYPE_INFO:
2369         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO);
2370         break;
2371     case KRB5_PA_ENCTYPE_INFO2:
2372         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO2);
2373         break;
2374     case KRB5_PA_PW_SALT:
2375         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PW_SALT);
2376         break;
2377     default:
2378         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, NULL);
2379     }
2380     return offset;
2381 /*qqq*/
2382 }
2383
2384 static ber_old_sequence_t PA_DATA_sequence[] = {
2385     { BER_CLASS_CON, 1, 0, dissect_krb5_PA_DATA_type },
2386     { BER_CLASS_CON, 2, 0, dissect_krb5_PA_DATA_value },
2387     { 0, 0, 0, NULL }
2388 };
2389 static int
2390 dissect_krb5_PA_DATA(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2391 {
2392     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_DATA_sequence, -1, -1);
2393
2394     return offset;
2395 }
2396
2397
2398
2399
2400 /*
2401  * padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
2402  *
2403  */
2404 static ber_old_sequence_t PA_DATA_sequence_of[1] = {
2405     { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_DATA },
2406 };
2407 static int
2408 dissect_krb5_padata(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2409 {
2410     offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_DATA_sequence_of, hf_krb_padata, ett_krb_padata);
2411
2412     return offset;
2413 }
2414
2415
2416
2417 static const true_false_string krb5_ticketflags_forwardable = {
2418     "FORWARDABLE tickets are allowed/requested",
2419     "Do NOT use forwardable tickets"
2420 };
2421 static const true_false_string krb5_ticketflags_forwarded = {
2422     "This ticket has been FORWARDED",
2423     "This is NOT a forwarded ticket"
2424 };
2425 static const true_false_string krb5_ticketflags_proxiable = {
2426     "PROXIABLE tickets are allowed/requested",
2427     "Do NOT use proxiable tickets"
2428 };
2429 static const true_false_string krb5_ticketflags_proxy = {
2430     "This is a PROXY ticket",
2431     "This ticket has NOT been proxied"
2432 };
2433 static const true_false_string krb5_ticketflags_allow_postdate = {
2434     "We allow the ticket to be POSTDATED",
2435     "We do NOT allow the ticket to be postdated"
2436 };
2437 static const true_false_string krb5_ticketflags_postdated = {
2438     "This ticket is POSTDATED",
2439     "This ticket is NOT postdated"
2440 };
2441 static const true_false_string krb5_ticketflags_invalid = {
2442     "This ticket is INVALID",
2443     "This ticket is NOT invalid"
2444 };
2445 static const true_false_string krb5_ticketflags_renewable = {
2446     "This ticket is RENEWABLE",
2447     "This ticket is NOT renewable"
2448 };
2449 static const true_false_string krb5_ticketflags_initial = {
2450     "This ticket was granted by AS and not TGT protocol",
2451     "This ticket was granted by TGT and not as protocol"
2452 };
2453 static const true_false_string krb5_ticketflags_pre_auth = {
2454     "The client was PRE-AUTHenticated",
2455     "The client was NOT pre-authenticated"
2456 };
2457 static const true_false_string krb5_ticketflags_hw_auth = {
2458     "The client was authenticated by HardWare",
2459     "The client was NOT authenticated using hardware"
2460 };
2461 static const true_false_string krb5_ticketflags_transited_policy_checked = {
2462     "Kdc has performed TRANSITED POLICY CHECKING",
2463     "Kdc has NOT performed transited policy checking"
2464 };
2465 static const true_false_string krb5_ticketflags_ok_as_delegate = {
2466     "This ticket is OK AS a DELEGATED ticket",
2467     "This ticket is NOT ok as a delegated ticket"
2468 };
2469
2470 static int* TicketFlags_bits[] = {
2471     &hf_krb_TicketFlags_forwardable,
2472     &hf_krb_TicketFlags_forwarded,
2473     &hf_krb_TicketFlags_proxiable,
2474     &hf_krb_TicketFlags_proxy,
2475     &hf_krb_TicketFlags_allow_postdate,
2476     &hf_krb_TicketFlags_postdated,
2477     &hf_krb_TicketFlags_invalid,
2478     &hf_krb_TicketFlags_renewable,
2479     &hf_krb_TicketFlags_initial,
2480     &hf_krb_TicketFlags_pre_auth,
2481     &hf_krb_TicketFlags_hw_auth,
2482     &hf_krb_TicketFlags_transited_policy_checked,
2483     &hf_krb_TicketFlags_ok_as_delegate,
2484     NULL
2485 };
2486
2487 static int
2488 dissect_krb5_TicketFlags(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2489 {
2490     offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, TicketFlags_bits, hf_krb_TicketFlags, ett_krb_Ticket_Flags, NULL);
2491     return offset;
2492 }
2493
2494
2495 static guint32 keytype;
2496 static int
2497 dissect_krb5_keytype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2498 {
2499     offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_keytype, &keytype);
2500     if(tree){
2501         proto_item_append_text(tree, " %s",
2502                                val_to_str(keytype, krb5_encryption_types,
2503                                           "%#x"));
2504     }
2505     return offset;
2506 }
2507 static int keylength;
2508 static const guint8 *keyvalue;
2509 static int
2510 store_keyvalue(proto_tree *tree _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2511 {
2512     keylength=tvb_length_remaining(tvb, offset);
2513     keyvalue=tvb_get_ptr(tvb, offset, keylength);
2514     return 0;
2515 }
2516 static int
2517 dissect_krb5_keyvalue(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2518 {
2519     offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_keyvalue, store_keyvalue);
2520     return offset;
2521 }
2522
2523
2524 /*
2525  * EncryptionKey ::=        SEQUENCE {
2526  *     keytype  [0] int32
2527  *     keyvalue [1] octet string
2528  */
2529 static ber_old_sequence_t EncryptionKey_sequence[] = {
2530     { BER_CLASS_CON, 0, 0,
2531       dissect_krb5_keytype },
2532     { BER_CLASS_CON, 1, 0,
2533       dissect_krb5_keyvalue },
2534     { 0, 0, 0, NULL }
2535 };
2536 static int
2537 dissect_krb5_key(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2538 {
2539     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncryptionKey_sequence, hf_krb_key, ett_krb_key);
2540
2541 #ifdef HAVE_KERBEROS
2542     add_encryption_key(actx->pinfo, keytype, keylength, keyvalue, "key");
2543 #endif
2544     return offset;
2545 }
2546 static int
2547 dissect_krb5_subkey(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2548 {
2549     offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncryptionKey_sequence, hf_krb_subkey, ett_krb_subkey);
2550 #ifdef HAVE_KERBEROS
2551     add_encryption_key(actx->pinfo, keytype, keylength, keyvalue, "subkey");
2552 #endif
2553     return offset;
2554 }
2555
2556 static int
2557 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
2558 {
2559     proto_item *item=NULL;
2560     proto_tree *tree=NULL;
2561     guint8 val;
2562
2563     if(parent_tree){
2564         item=proto_tree_add_text(parent_tree, tvb, offset, 16, "DREP");
2565         tree=proto_item_add_subtree(item, ett_krb_PAC_DREP);
2566     }
2567
2568     val = tvb_get_guint8(tvb, offset);
2569     proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
2570
2571     offset++;
2572
2573     if (drep) {
2574         *drep = val;
2575     }
2576
2577     return offset;
2578 }
2579
2580 /* This might be some sort of header that MIDL generates when creating
2581  * marshalling/unmarshalling code for blobs that are not to be transported
2582  * ontop of DCERPC and where the DREP fields specifying things such as
2583  * endianess and similar are not available.
2584  */
2585 static int
2586 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
2587 {
2588     proto_item *item=NULL;
2589     proto_tree *tree=NULL;
2590
2591     if(parent_tree){
2592         item=proto_tree_add_text(parent_tree, tvb, offset, 16, "MES header");
2593         tree=proto_item_add_subtree(item, ett_krb_PAC_MIDL_BLOB);
2594     }
2595
2596     /* modified DREP field that is used for stuff that is transporetd ontop
2597        of non dcerpc
2598     */
2599     proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2600     offset++;
2601
2602     offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
2603
2604
2605     proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2606     offset+=2;
2607
2608     proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2609     offset += 4;
2610
2611     /* length of blob that follows */
2612     proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2613     offset += 8;
2614
2615     return offset;
2616 }
2617
2618 static int
2619 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2620 {
2621     proto_item *item=NULL;
2622     proto_tree *tree=NULL;
2623     guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2624     static dcerpc_info di;      /* fake dcerpc_info struct */
2625     static dcerpc_call_value call_data;
2626     void *old_private_data;
2627
2628     item=proto_tree_add_item(parent_tree, hf_krb_PAC_LOGON_INFO, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2629     if(parent_tree){
2630         tree=proto_item_add_subtree(item, ett_krb_PAC_LOGON_INFO);
2631     }
2632
2633     /* skip the first 16 bytes, they are some magic created by the idl
2634      * compiler   the first 4 bytes might be flags?
2635      */
2636     offset=dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2637
2638     /* the PAC_LOGON_INFO blob */
2639     /* fake whatever state the dcerpc runtime support needs */
2640     di.conformant_run=0;
2641     /* we need di->call_data->flags.NDR64 == 0 */
2642     di.call_data=&call_data;
2643     old_private_data=actx->pinfo->private_data;
2644     actx->pinfo->private_data=&di;
2645     init_ndr_pointer_list(actx->pinfo);
2646     offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, drep,
2647                                  netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
2648                                  "PAC_LOGON_INFO:", -1);
2649     actx->pinfo->private_data=old_private_data;
2650
2651     return offset;
2652 }
2653
2654 static int
2655 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2656 {
2657     proto_item *item=NULL;
2658     proto_tree *tree=NULL;
2659     guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2660     static dcerpc_info di;      /* fake dcerpc_info struct */
2661     static dcerpc_call_value call_data;
2662     void *old_private_data;
2663
2664     item=proto_tree_add_item(parent_tree, hf_krb_PAC_S4U_DELEGATION_INFO, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2665     if(parent_tree){
2666         tree=proto_item_add_subtree(item, ett_krb_PAC_S4U_DELEGATION_INFO);
2667     }
2668
2669     /* skip the first 16 bytes, they are some magic created by the idl
2670      * compiler   the first 4 bytes might be flags?
2671      */
2672     offset=dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2673
2674
2675     /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
2676     /* fake whatever state the dcerpc runtime support needs */
2677     di.conformant_run=0;
2678     /* we need di->call_data->flags.NDR64 == 0 */
2679     di.call_data=&call_data;
2680     old_private_data=actx->pinfo->private_data;
2681     actx->pinfo->private_data=&di;
2682     init_ndr_pointer_list(actx->pinfo);
2683     offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, drep,
2684                                  netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
2685                                  "PAC_S4U_DELEGATION_INFO:", -1);
2686     actx->pinfo->private_data=old_private_data;
2687
2688     return offset;
2689 }
2690
2691 static int
2692 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2693 {
2694     proto_item *item=NULL;
2695     proto_tree *tree=NULL;
2696     guint16 dns_offset, dns_len;
2697     guint16 upn_offset, upn_len;
2698     const char *dn;
2699     int dn_len;
2700     guint16 bc;
2701
2702     item=proto_tree_add_item(parent_tree, hf_krb_PAC_UPN_DNS_INFO, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2703     if(parent_tree){
2704         tree=proto_item_add_subtree(item, ett_krb_PAC_UPN_DNS_INFO);
2705     }
2706
2707     /* upn */
2708     upn_len = tvb_get_letohs(tvb, offset);
2709     proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2710     offset+=2;
2711     upn_offset = tvb_get_letohs(tvb, offset);
2712     proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2713     offset+=2;
2714
2715     /* dns */
2716     dns_len = tvb_get_letohs(tvb, offset);
2717     proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2718     offset+=2;
2719     dns_offset = tvb_get_letohs(tvb, offset);
2720     proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2721     offset+=2;
2722
2723     /* flags */
2724     proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2725
2726     /* upn */
2727     offset = upn_offset;
2728     dn_len = upn_len;
2729     bc = tvb_length_remaining(tvb, offset);
2730     dn = get_unicode_or_ascii_string(tvb, &offset,
2731                                      TRUE, &dn_len, TRUE, TRUE, &bc);
2732     proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
2733
2734     /* dns */
2735     offset = dns_offset;
2736     dn_len = dns_len;
2737     bc = tvb_length_remaining(tvb, offset);
2738     dn = get_unicode_or_ascii_string(tvb, &offset,
2739                                      TRUE, &dn_len, TRUE, TRUE, &bc);
2740     proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
2741
2742     return offset;
2743 }
2744
2745 static int
2746 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2747 {
2748     proto_tree_add_item(parent_tree, hf_krb_PAC_CREDENTIAL_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2749
2750 /*qqq*/
2751     return offset;
2752 }
2753
2754 static int
2755 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2756 {
2757     proto_item *item=NULL;
2758     proto_tree *tree=NULL;
2759
2760     item=proto_tree_add_item(parent_tree, hf_krb_PAC_SERVER_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2761     if(parent_tree){
2762         tree=proto_item_add_subtree(item, ett_krb_PAC_SERVER_CHECKSUM);
2763     }
2764
2765     /* signature type */
2766     proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2767     offset+=4;
2768
2769     /* signature data */
2770     proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2771
2772     return offset;
2773 }
2774
2775 static int
2776 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2777 {
2778     proto_item *item=NULL;
2779     proto_tree *tree=NULL;
2780
2781     item=proto_tree_add_item(parent_tree, hf_krb_PAC_PRIVSVR_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2782     if(parent_tree){
2783         tree=proto_item_add_subtree(item, ett_krb_PAC_PRIVSVR_CHECKSUM);
2784     }
2785
2786     /* signature type */
2787     proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2788     offset+=4;
2789
2790     /* signature data */
2791     proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2792
2793     return offset;
2794 }
2795
2796 static int
2797 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2798 {
2799     proto_item *item=NULL;
2800     proto_tree *tree=NULL;
2801     guint16 namelen;
2802     char *name;
2803
2804     item=proto_tree_add_item(parent_tree, hf_krb_PAC_CLIENT_INFO_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
2805     if(parent_tree){
2806         tree=proto_item_add_subtree(item, ett_krb_PAC_CLIENT_INFO_TYPE);
2807     }
2808
2809     /* clientid */
2810     offset = dissect_nt_64bit_time(tvb, tree, offset,
2811                                    hf_krb_pac_clientid);
2812
2813     /* name length */
2814     namelen=tvb_get_letohs(tvb, offset);
2815     proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
2816     offset+=2;
2817
2818     /* client name */
2819     name=tvb_get_ephemeral_unicode_string(tvb, offset, namelen/2, ENC_LITTLE_ENDIAN);
2820     proto_tree_add_string(tree, hf_krb_pac_clientname, tvb, offset, namelen, name);
2821     offset+=namelen;
2822
2823     return offset;
2824 }
2825
2826 static int
2827 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2828 {
2829     guint32 pac_type;
2830     guint32 pac_size;
2831     guint32 pac_offset;
2832     proto_item *it=NULL;
2833     proto_tree *tr=NULL;
2834     tvbuff_t *next_tvb;
2835
2836     /* type of pac data */
2837     pac_type=tvb_get_letohl(tvb, offset);
2838     it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
2839     if(it){
2840         tr=proto_item_add_subtree(it, ett_krb_PAC);
2841     }
2842
2843     offset += 4;
2844
2845     /* size of pac data */
2846     pac_size=tvb_get_letohl(tvb, offset);
2847     proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
2848     offset += 4;
2849
2850     /* offset to pac data */
2851     pac_offset=tvb_get_letohl(tvb, offset);
2852     proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
2853     offset += 8;
2854
2855
2856     next_tvb=tvb_new_subset(tvb, pac_offset, pac_size, pac_size);
2857     switch(pac_type){
2858     case PAC_LOGON_INFO:
2859         dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
2860         break;
2861     case PAC_CREDENTIAL_TYPE:
2862         dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
2863         break;
2864     case PAC_SERVER_CHECKSUM:
2865         dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
2866         break;
2867     case PAC_PRIVSVR_CHECKSUM:
2868         dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
2869         break;
2870     case PAC_CLIENT_INFO_TYPE:
2871         dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
2872         break;
2873     case PAC_S4U_DELEGATION_INFO:
2874         dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
2875         break;
2876     case PAC_UPN_DNS_INFO:
2877         dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
2878         break;
2879
2880     default:;
2881 /*qqq*/
2882     }
2883     return offset;
2884 }
2885
2886 static int
2887 dissect_krb5_AD_WIN2K_PAC(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2888 {
2889     guint32 entries;
2890     guint32 version;
2891     guint32 i;
2892
2893     /* first in the PAC structure comes the number of entries */
2894     entries=tvb_get_letohl(tvb, offset);
2895     proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
2896     offset += 4;
2897
2898     /* second comes the version */
2899     version=tvb_get_letohl(tvb, offset);
2900     proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
2901     offset += 4;
2902
2903     for(i=0;i<entries;i++){
2904         offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
2905     }
2906
2907     return offset;
2908 }
2909
2910
2911 int dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx);
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 _U_)
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);
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(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_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(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_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 _U_)
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);
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(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_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(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_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(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_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(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_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(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_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_udp(tvbuff_t *tvb, packet_info *pinfo,
4584                                  proto_tree *tree);
4585 static void dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo,
4586                                  proto_tree *tree);
4587 static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo,
4588                                     proto_tree *tree, gboolean do_col_info,
4589                                     gboolean do_col_protocol,
4590                                     gboolean have_rm,
4591                                     kerberos_callbacks *cb);
4592 static void dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo,
4593                                      proto_tree *tree);
4594
4595
4596 gint
4597 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
4598 {
4599     return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
4600 }
4601
4602 guint32
4603 kerberos_output_keytype(void)
4604 {
4605     return keytype;
4606 }
4607
4608 static gint
4609 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4610 {
4611     /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
4612        Since all (except weirdo transarc krb4 stuff) use
4613        an opcode <=16 in the first byte, use this to see if it might
4614        be krb4.
4615        All krb5 commands start with an APPL tag and thus is >=0x60
4616        so if first byte is <=16  just blindly assume it is krb4 then
4617     */
4618     if(tvb_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
4619         if(krb4_handle){
4620             gboolean res;
4621
4622             res=call_dissector_only(krb4_handle, tvb, pinfo, tree);
4623             return res;
4624         }else{
4625             return 0;
4626         }
4627     }
4628
4629
4630     return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
4631 }
4632
4633 gint
4634 kerberos_rm_to_reclen(guint krb_rm)
4635 {
4636     return (krb_rm & KRB_RM_RECLEN);
4637 }
4638
4639 guint
4640 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
4641 {
4642     guint krb_rm;
4643     gint pdulen;
4644
4645     krb_rm = tvb_get_ntohl(tvb, offset);
4646     pdulen = kerberos_rm_to_reclen(krb_rm);
4647     return (pdulen + 4);
4648 }
4649
4650 static void
4651 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4652 {
4653     pinfo->fragmented = TRUE;
4654     if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
4655         /*
4656          * The dissector failed to recognize this as a valid
4657          * Kerberos message.  Mark it as a continuation packet.
4658          */
4659         col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
4660     }
4661 }
4662
4663 static void
4664 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4665 {
4666     col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
4667     col_clear(pinfo->cinfo, COL_INFO);
4668
4669     tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
4670                      dissect_kerberos_tcp_pdu);
4671 }
4672
4673 /*
4674  * Display the TCP record mark.
4675  */
4676 void
4677 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
4678 {
4679     gint rec_len;
4680     proto_item *rm_item;
4681     proto_tree *rm_tree;
4682
4683     if (tree == NULL)
4684         return;
4685
4686     rec_len = kerberos_rm_to_reclen(krb_rm);
4687     rm_item = proto_tree_add_text(tree, tvb, start, 4,
4688                                   "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
4689     rm_tree = proto_item_add_subtree(rm_item, ett_krb_recordmark);
4690     proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
4691     proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
4692 }
4693
4694
4695 static gint
4696 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4697                         gboolean dci, gboolean do_col_protocol, gboolean have_rm,
4698                         kerberos_callbacks *cb)
4699 {
4700     volatile int offset = 0;
4701     proto_tree *volatile kerberos_tree = NULL;
4702     proto_item *volatile item = NULL;
4703     void *saved_private_data;
4704     asn1_ctx_t asn1_ctx;
4705
4706     /* TCP record mark and length */
4707     guint32 krb_rm = 0;
4708     gint krb_reclen = 0;
4709
4710     saved_private_data=pinfo->private_data;
4711     pinfo->private_data=cb;
4712     gbl_do_col_info=dci;
4713
4714     if (have_rm) {
4715         krb_rm = tvb_get_ntohl(tvb, offset);
4716         krb_reclen = kerberos_rm_to_reclen(krb_rm);
4717         /*
4718          * What is a reasonable size limit?
4719          */
4720         if (krb_reclen > 10 * 1024 * 1024) {
4721             pinfo->private_data=saved_private_data;
4722             return (-1);
4723         }
4724         if (do_col_protocol) {
4725             col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
4726         }
4727         if (tree) {
4728             item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
4729             kerberos_tree = proto_item_add_subtree(item, ett_krb_kerberos);
4730         }
4731         show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
4732         offset += 4;
4733     } else {
4734         /* Do some sanity checking here,
4735          * All krb5 packets start with a TAG class that is BER_CLASS_APP
4736          * and a tag value that is either of the values below:
4737          * If it doesnt look like kerberos, return 0 and let someone else have
4738          * a go at it.
4739          */
4740         gint8 tmp_class;
4741         gboolean tmp_pc;
4742         gint32 tmp_tag;
4743
4744         get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
4745         if(tmp_class!=BER_CLASS_APP){
4746             pinfo->private_data=saved_private_data;
4747             return 0;
4748         }
4749         switch(tmp_tag){
4750         case KRB5_MSG_TICKET:
4751         case KRB5_MSG_AUTHENTICATOR:
4752         case KRB5_MSG_ENC_TICKET_PART:
4753         case KRB5_MSG_AS_REQ:
4754         case KRB5_MSG_AS_REP:
4755         case KRB5_MSG_TGS_REQ:
4756         case KRB5_MSG_TGS_REP:
4757         case KRB5_MSG_AP_REQ:
4758         case KRB5_MSG_AP_REP:
4759         case KRB5_MSG_ENC_AS_REP_PART:
4760         case KRB5_MSG_ENC_TGS_REP_PART:
4761         case KRB5_MSG_ENC_AP_REP_PART:
4762         case KRB5_MSG_ENC_KRB_PRIV_PART:
4763         case KRB5_MSG_ENC_KRB_CRED_PART:
4764         case KRB5_MSG_SAFE:
4765         case KRB5_MSG_PRIV:
4766         case KRB5_MSG_ERROR:
4767             break;
4768         default:
4769             pinfo->private_data=saved_private_data;
4770             return 0;
4771         }
4772         if (do_col_protocol) {
4773             col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
4774         }
4775         if (gbl_do_col_info) {
4776             col_clear(pinfo->cinfo, COL_INFO);
4777         }
4778         if (tree) {
4779             item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
4780             kerberos_tree = proto_item_add_subtree(item, ett_krb_kerberos);
4781         }
4782     }
4783     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
4784
4785     TRY {
4786         offset=dissect_ber_old_choice(&asn1_ctx, kerberos_tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
4787     } CATCH_ALL {
4788         pinfo->private_data=saved_private_data;
4789         RETHROW;
4790     } ENDTRY;
4791
4792     proto_item_set_len(item, offset);
4793     pinfo->private_data=saved_private_data;
4794     return offset;
4795 }
4796
4797 static void
4798 kerberos_prefs_apply_cb(void) {
4799 #ifdef HAVE_LIBNETTLE
4800     clear_keytab();
4801     read_keytab_file(keytab_filename);
4802 #endif
4803 }
4804
4805 void
4806 proto_register_kerberos(void)
4807 {
4808     static hf_register_info hf[] = {
4809         { &hf_krb_rm_reserved, {
4810                 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
4811                 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
4812         { &hf_krb_rm_reclen, {
4813                 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
4814                 NULL, KRB_RM_RECLEN, NULL, HFILL }},
4815         { &hf_krb_transitedtype, {
4816                 "Type", "kerberos.transited.type", FT_UINT32, BASE_DEC,
4817                 VALS(krb5_transited_types), 0, "Transited Type", HFILL }},
4818         { &hf_krb_transitedcontents, {
4819                 "Contents", "kerberos.transited.contents", FT_BYTES, BASE_NONE,
4820                 NULL, 0, "Transited Contents string", HFILL }},
4821         { &hf_krb_keytype, {
4822                 "Key type", "kerberos.keytype", FT_UINT32, BASE_DEC,
4823                 VALS(krb5_encryption_types), 0, NULL, HFILL }},
4824         { &hf_krb_keyvalue, {
4825                 "Key value", "kerberos.keyvalue", FT_BYTES, BASE_NONE,
4826                 NULL, 0, "Key value (encryption key)", HFILL }},
4827         { &hf_krb_adtype, {
4828                 "Type", "kerberos.adtype", FT_UINT32, BASE_DEC,
4829                 VALS(krb5_ad_types), 0, "Authorization Data Type", HFILL }},
4830         { &hf_krb_IF_RELEVANT_type, {
4831                 "Type", "kerberos.IF_RELEVANT.type", FT_UINT32, BASE_DEC,
4832                 VALS(krb5_ad_types), 0, "IF-RELEVANT Data Type", HFILL }},
4833         { &hf_krb_advalue, {
4834                 "Data", "kerberos.advalue", FT_BYTES, BASE_NONE,
4835                 NULL, 0, "Authentication Data", HFILL }},
4836         { &hf_krb_IF_RELEVANT_value, {
4837                 "Data", "kerberos.IF_RELEVANT.value", FT_BYTES, BASE_NONE,
4838                 NULL, 0, "IF_RELEVANT Data", HFILL }},
4839         { &hf_krb_etype, {
4840                 "Encryption type", "kerberos.etype", FT_INT32, BASE_DEC,
4841                 VALS(krb5_encryption_types), 0, NULL, HFILL }},
4842         { &hf_krb_addr_type, {
4843                 "Addr-type", "kerberos.addr_type", FT_UINT32, BASE_DEC,
4844                 VALS(krb5_address_types), 0, "Address Type", HFILL }},
4845         { &hf_krb_pac_signature_type, {
4846                 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
4847                 NULL, 0, "PAC Signature Type", HFILL }},
4848         { &hf_krb_name_type, {
4849                 "Name-type", "kerberos.name_type", FT_INT32, BASE_DEC,
4850                 VALS(krb5_princ_types), 0, "Type of principal name", HFILL }},
4851         { &hf_krb_lr_type, {
4852                 "Lr-type", "kerberos.lr_type", FT_UINT32, BASE_DEC,
4853                 VALS(krb5_lr_types), 0, "Type of lastreq value", HFILL }},
4854         { &hf_krb_address_ip, {
4855                 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
4856                 NULL, 0, NULL, HFILL }},
4857         { &hf_krb_address_ipv6, {
4858                 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
4859                 NULL, 0, NULL, HFILL }},
4860         { &hf_krb_address_netbios, {
4861                 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
4862                 NULL, 0, "NetBIOS Address and type", HFILL }},
4863         { &hf_krb_authtime, {
4864                 "Authtime", "kerberos.authtime", FT_STRING, BASE_NONE,
4865                 NULL, 0, "Time of initial authentication", HFILL }},
4866         { &hf_krb_SAFE_BODY_timestamp, {
4867                 "Timestamp", "kerberos.SAFE_BODY.timestamp", FT_STRING, BASE_NONE,
4868                 NULL, 0, "Timestamp of this SAFE_BODY", HFILL }},
4869         { &hf_krb_patimestamp, {
4870                 "patimestamp", "kerberos.patimestamp", FT_STRING, BASE_NONE,
4871                 NULL, 0, "Time of client", HFILL }},
4872         { &hf_krb_pausec, {
4873                 "pausec", "kerberos.pausec", FT_UINT32, BASE_DEC,
4874                 NULL, 0, "Microsecond component of client time", HFILL }},
4875         { &hf_krb_lr_time, {
4876                 "Lr-time", "kerberos.lr_time", FT_STRING, BASE_NONE,
4877                 NULL, 0, "Time of LR-entry", HFILL }},
4878         { &hf_krb_starttime, {
4879                 "Start time", "kerberos.starttime", FT_STRING, BASE_NONE,
4880                 NULL, 0, "The time after which the ticket is valid", HFILL }},
4881         { &hf_krb_endtime, {
4882                 "End time", "kerberos.endtime", FT_STRING, BASE_NONE,
4883                 NULL, 0, "The time after which the ticket has expired", HFILL }},
4884         { &hf_krb_key_expire, {
4885                 "Key Expiration", "kerberos.key_expiration", FT_STRING, BASE_NONE,
4886                 NULL, 0, "The time after which the key will expire", HFILL }},
4887         { &hf_krb_renew_till, {
4888                 "Renew-till", "kerberos.renenw_till", FT_STRING, BASE_NONE,
4889                 NULL, 0, "The maximum time we can renew the ticket until", HFILL }},
4890         { &hf_krb_rtime, {
4891                 "rtime", "kerberos.rtime", FT_STRING, BASE_NONE,
4892                 NULL, 0, "Renew Until timestamp", HFILL }},
4893         { &hf_krb_ctime, {
4894                 "ctime", "kerberos.ctime", FT_STRING, BASE_NONE,
4895                 NULL, 0, "Current Time on the client host", HFILL }},
4896         { &hf_krb_cusec, {
4897                 "cusec", "kerberos.cusec", FT_UINT32, BASE_DEC,
4898                 NULL, 0, "micro second component of client time", HFILL }},
4899         { &hf_krb_SAFE_BODY_usec, {
4900                 "usec", "kerberos.SAFE_BODY.usec", FT_UINT32, BASE_DEC,
4901                 NULL, 0, "micro second component of SAFE_BODY time", HFILL }},
4902         { &hf_krb_stime, {
4903                 "stime", "kerberos.stime", FT_STRING, BASE_NONE,
4904                 NULL, 0, "Current Time on the server host", HFILL }},
4905         { &hf_krb_susec, {
4906                 "susec", "kerberos.susec", FT_UINT32, BASE_DEC,
4907                 NULL, 0, "micro second component of server time", HFILL }},
4908         { &hf_krb_error_code, {
4909                 "error_code", "kerberos.error_code", FT_UINT32, BASE_DEC,
4910                 VALS(krb5_error_codes), 0, "Kerberos error code", HFILL }},
4911         { &hf_krb_from, {
4912                 "from", "kerberos.from", FT_STRING, BASE_NONE,
4913                 NULL, 0, "From when the ticket is to be valid (postdating)", HFILL }},
4914         { &hf_krb_till, {
4915                 "till", "kerberos.till", FT_STRING, BASE_NONE,
4916                 NULL, 0, "When the ticket will expire", HFILL }},
4917         { &hf_krb_name_string, {
4918                 "Name", "kerberos.name_string", FT_STRING, BASE_NONE,
4919                 NULL, 0, "String component that is part of a PrincipalName", HFILL }},
4920         { &hf_krb_provsrv_location, {
4921                 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
4922                 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
4923         { &hf_krb_e_text, {
4924                 "e-text", "kerberos.e_text", FT_STRING, BASE_NONE,
4925                 NULL, 0, "Additional (human readable) error description", HFILL }},
4926         { &hf_krb_s4u2self_auth, {
4927                 "S4U2Self Auth", "kerberos.s4u2self.auth", FT_STRING, BASE_NONE,
4928                 NULL, 0, "S4U2Self authentication string", HFILL }},
4929         { &hf_krb_realm, {
4930                 "Realm", "kerberos.realm", FT_STRING, BASE_NONE,
4931                 NULL, 0, "Name of the Kerberos Realm", HFILL }},
4932         { &hf_krb_srealm, {
4933                 "SRealm", "kerberos.srealm", FT_STRING, BASE_NONE,
4934                 NULL, 0, "Name of the Kerberos SRealm", HFILL }},
4935         { &hf_krb_prealm, {
4936                 "Delegated Principal Realm", "kerberos.prealm", FT_STRING, BASE_NONE,
4937                 NULL, 0, "Name of the Kerberos PRealm", HFILL }},
4938         { &hf_krb_crealm, {
4939                 "Client Realm", "kerberos.crealm", FT_STRING, BASE_NONE,
4940                 NULL, 0, "Name of the Clients Kerberos Realm", HFILL }},
4941         { &hf_krb_pac_clientname, {
4942                 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
4943                 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
4944         { &hf_krb_msg_type, {
4945                 "MSG Type", "kerberos.msg.type", FT_UINT32, BASE_DEC,
4946                 VALS(krb5_msg_types), 0, "Kerberos Message Type", HFILL }},
4947         { &hf_krb_APOptions, {
4948                 "APOptions", "kerberos.apoptions", FT_BYTES, BASE_NONE,
4949                 NULL, 0, "Kerberos APOptions bitstring", HFILL }},
4950         { &hf_krb_APOptions_reserved, {
4951                "reserved", "kerberos.apoptions.reserved", FT_BOOLEAN, 32,
4952                 TFS(&krb5_apoptions_reserved), 0x80000000, NULL, HFILL }},
4953         { &hf_krb_APOptions_use_session_key, {
4954                 "Use Session Key", "kerberos.apoptions.use_session_key", FT_BOOLEAN, 32,
4955                 TFS(&krb5_apoptions_use_session_key), 0x40000000, NULL, HFILL }},
4956         { &hf_krb_APOptions_mutual_required, {
4957                 "Mutual required", "kerberos.apoptions.mutual_required", FT_BOOLEAN, 32,
4958                 TFS(&krb5_apoptions_mutual_required), 0x20000000, NULL, HFILL }},
4959         { &hf_krb_KDCOptions, {
4960                 "KDCOptions", "kerberos.kdcoptions", FT_BYTES, BASE_NONE,
4961                 NULL, 0, "Kerberos KDCOptions bitstring", HFILL }},
4962         { &hf_krb_TicketFlags, {
4963                 "Ticket Flags", "kerberos.ticketflags", FT_NONE, BASE_NONE,
4964                 NULL, 0, "Kerberos Ticket Flags", HFILL }},
4965         { &hf_krb_TicketFlags_forwardable, {
4966                 "Forwardable", "kerberos.ticketflags.forwardable", FT_BOOLEAN, 32,
4967                 TFS(&krb5_ticketflags_forwardable), 0x40000000, "Flag controlling whether the tickets are forwardable or not", HFILL }},
4968         { &hf_krb_TicketFlags_forwarded, {
4969                 "Forwarded", "kerberos.ticketflags.forwarded", FT_BOOLEAN, 32,
4970                 TFS(&krb5_ticketflags_forwarded), 0x20000000, "Has this ticket been forwarded?", HFILL }},
4971         { &hf_krb_TicketFlags_proxiable, {
4972                 "Proxiable", "kerberos.ticketflags.proxiable", FT_BOOLEAN, 32,
4973                 TFS(&krb5_ticketflags_proxiable), 0x10000000, "Flag controlling whether the tickets are proxiable or not", HFILL }},
4974         { &hf_krb_TicketFlags_proxy, {
4975                 "Proxy", "kerberos.ticketflags.proxy", FT_BOOLEAN, 32,
4976                 TFS(&krb5_ticketflags_proxy), 0x08000000, "Has this ticket been proxied?", HFILL }},
4977         { &hf_krb_TicketFlags_allow_postdate, {
4978                 "Allow Postdate", "kerberos.ticketflags.allow_postdate", FT_BOOLEAN, 32,
4979                 TFS(&krb5_ticketflags_allow_postdate), 0x04000000, "Flag controlling whether we allow postdated tickets or not", HFILL }},
4980         { &hf_krb_TicketFlags_postdated, {
4981                 "Postdated", "kerberos.ticketflags.postdated", FT_BOOLEAN, 32,
4982                 TFS(&krb5_ticketflags_postdated), 0x02000000, "Whether this ticket is postdated or not", HFILL }},
4983         { &hf_krb_TicketFlags_invalid, {
4984                 "Invalid", "kerberos.ticketflags.invalid", FT_BOOLEAN, 32,
4985                 TFS(&krb5_ticketflags_invalid), 0x01000000, "Whether this ticket is invalid or not", HFILL }},
4986         { &hf_krb_TicketFlags_renewable, {
4987                 "Renewable", "kerberos.ticketflags.renewable", FT_BOOLEAN, 32,
4988                 TFS(&krb5_ticketflags_renewable), 0x00800000, "Whether this ticket is renewable or not", HFILL }},
4989         { &hf_krb_TicketFlags_initial, {
4990                 "Initial", "kerberos.ticketflags.initial", FT_BOOLEAN, 32,
4991                 TFS(&krb5_ticketflags_initial), 0x00400000, "Whether this ticket is an initial ticket or not", HFILL }},
4992         { &hf_krb_TicketFlags_pre_auth, {
4993                 "Pre-Auth", "kerberos.ticketflags.pre_auth", FT_BOOLEAN, 32,
4994                 TFS(&krb5_ticketflags_pre_auth), 0x00200000, "Whether this ticket is pre-authenticated or not", HFILL }},
4995         { &hf_krb_TicketFlags_hw_auth, {
4996                 "HW-Auth", "kerberos.ticketflags.hw_auth", FT_BOOLEAN, 32,
4997                 TFS(&krb5_ticketflags_hw_auth), 0x00100000, "Whether this ticket is hardware-authenticated or not", HFILL }},
4998         { &hf_krb_TicketFlags_transited_policy_checked, {
4999                 "Transited Policy Checked", "kerberos.ticketflags.transited_policy_checked", FT_BOOLEAN, 32,
5000                 TFS(&krb5_ticketflags_transited_policy_checked), 0x00080000, "Whether this ticket is transited policy checked or not", HFILL }},
5001         { &hf_krb_TicketFlags_ok_as_delegate, {
5002                 "Ok As Delegate", "kerberos.ticketflags.ok_as_delegate", FT_BOOLEAN, 32,
5003                 TFS(&krb5_ticketflags_ok_as_delegate), 0x00040000, "Whether this ticket is Ok As Delegate or not", HFILL }},
5004         { &hf_krb_KDC_REQ_BODY, {
5005                 "KDC_REQ_BODY", "kerberos.kdc_req_body", FT_NONE, BASE_NONE,
5006                 NULL, 0, "Kerberos KDC REQuest BODY", HFILL }},
5007         { &hf_krb_PRIV_BODY, {
5008                 "PRIV_BODY", "kerberos.priv_body", FT_NONE, BASE_NONE,
5009                 NULL, 0, "Kerberos PRIVate BODY", HFILL }},
5010         { &hf_krb_CRED_BODY, {
5011                 "CRED_BODY", "kerberos.cred_body", FT_NONE, BASE_NONE,
5012                 NULL, 0, "Kerberos CREDential BODY", HFILL }},
5013         { &hf_krb_encrypted_PRIV, {
5014                 "Encrypted PRIV", "kerberos.enc_priv", FT_NONE, BASE_NONE,
5015                 NULL, 0, "Kerberos Encrypted PRIVate blob data", HFILL }},
5016         { &hf_krb_KDCOptions_forwardable, {
5017                 "Forwardable", "kerberos.kdcoptions.forwardable", FT_BOOLEAN, 32,
5018                 TFS(&krb5_kdcoptions_forwardable), 0x40000000, "Flag controlling whether the tickets are forwardable or not", HFILL }},
5019         { &hf_krb_KDCOptions_forwarded, {
5020                 "Forwarded", "kerberos.kdcoptions.forwarded", FT_BOOLEAN, 32,
5021                 TFS(&krb5_kdcoptions_forwarded), 0x20000000, "Has this ticket been forwarded?", HFILL }},
5022         { &hf_krb_KDCOptions_proxiable, {
5023                 "Proxiable", "kerberos.kdcoptions.proxiable", FT_BOOLEAN, 32,
5024                 TFS(&krb5_kdcoptions_proxiable), 0x10000000, "Flag controlling whether the tickets are proxiable or not", HFILL }},
5025         { &hf_krb_KDCOptions_proxy, {
5026                 "Proxy", "kerberos.kdcoptions.proxy", FT_BOOLEAN, 32,
5027                 TFS(&krb5_kdcoptions_proxy), 0x08000000, "Has this ticket been proxied?", HFILL }},
5028         { &hf_krb_KDCOptions_allow_postdate, {
5029                 "Allow Postdate", "kerberos.kdcoptions.allow_postdate", FT_BOOLEAN, 32,
5030                 TFS(&krb5_kdcoptions_allow_postdate), 0x04000000, "Flag controlling whether we allow postdated tickets or not", HFILL }},
5031         { &hf_krb_KDCOptions_postdated, {
5032                 "Postdated", "kerberos.kdcoptions.postdated", FT_BOOLEAN, 32,
5033                 TFS(&krb5_kdcoptions_postdated), 0x02000000, "Whether this ticket is postdated or not", HFILL }},
5034         { &hf_krb_KDCOptions_renewable, {
5035                 "Renewable", "kerberos.kdcoptions.renewable", FT_BOOLEAN, 32,
5036                 TFS(&krb5_kdcoptions_renewable), 0x00800000, "Whether this ticket is renewable or not", HFILL }},
5037         { &hf_krb_KDCOptions_constrained_delegation, {
5038                 "Constrained Delegation", "kerberos.kdcoptions.constrained_delegation", FT_BOOLEAN, 32,
5039                 TFS(&krb5_kdcoptions_constrained_delegation), 0x00020000, "Do we want a PAC containing constrained delegation info or not", HFILL }},
5040         { &hf_krb_KDCOptions_canonicalize, {
5041                 "Canonicalize", "kerberos.kdcoptions.canonicalize", FT_BOOLEAN, 32,
5042                 TFS(&krb5_kdcoptions_canonicalize), 0x00010000, "Do we want the KDC to canonicalize the principal or not", HFILL }},
5043         { &hf_krb_KDCOptions_opt_hardware_auth, {
5044                 "Opt HW Auth", "kerberos.kdcoptions.opt_hardware_auth", FT_BOOLEAN, 32,
5045                 NULL, 0x00100000, "Opt HW Auth flag", HFILL }},
5046         { &hf_krb_KDCOptions_disable_transited_check, {
5047                 "Disable Transited Check", "kerberos.kdcoptions.disable_transited_check", FT_BOOLEAN, 32,
5048                 TFS(&krb5_kdcoptions_disable_transited_check), 0x00000020, "Whether we should do transited checking or not", HFILL }},
5049         { &hf_krb_KDCOptions_renewable_ok, {
5050                 "Renewable OK", "kerberos.kdcoptions.renewable_ok", FT_BOOLEAN, 32,
5051                 TFS(&krb5_kdcoptions_renewable_ok), 0x00000010, "Whether we accept renewed tickets or not", HFILL }},
5052         { &hf_krb_KDCOptions_enc_tkt_in_skey, {
5053                 "Enc-Tkt-in-Skey", "kerberos.kdcoptions.enc_tkt_in_skey", FT_BOOLEAN, 32,
5054                 TFS(&krb5_kdcoptions_enc_tkt_in_skey), 0x00000008, "Whether the ticket is encrypted in the skey or not", HFILL }},
5055         { &hf_krb_KDCOptions_renew, {
5056                 "Renew", "kerberos.kdcoptions.renew", FT_BOOLEAN, 32,
5057                 TFS(&krb5_kdcoptions_renew), 0x00000002, "Is this a request to renew a ticket?", HFILL }},
5058         { &hf_krb_KDCOptions_validate, {
5059                 "Validate", "kerberos.kdcoptions.validate", FT_BOOLEAN, 32,
5060                 TFS(&krb5_kdcoptions_validate), 0x00000001, "Is this a request to validate a postdated ticket?", HFILL }},
5061         { &hf_krb_pvno, {
5062                 "Pvno", "kerberos.pvno", FT_UINT32, BASE_DEC,
5063                 NULL, 0, "Kerberos Protocol Version Number", HFILL }},
5064         { &hf_krb_kvno, {
5065                 "Kvno", "kerberos.kvno", FT_UINT32, BASE_DEC,
5066                 NULL, 0, "Version Number for the encryption Key", HFILL }},
5067         { &hf_krb_checksum_type, {
5068                 "Type", "kerberos.checksum.type", FT_UINT32, BASE_DEC,
5069                 VALS(krb5_checksum_types), 0, "Type of checksum", HFILL }},
5070         { &hf_krb_authenticator_vno, {
5071                 "Authenticator vno", "kerberos.authenticator_vno", FT_UINT32, BASE_DEC,
5072                 NULL, 0, "Version Number for the Authenticator", HFILL }},
5073         { &hf_krb_encrypted_authenticator_data, {
5074                 "Authenticator data", "kerberos.authenticator.data", FT_BYTES, BASE_NONE,
5075                 NULL, 0, "Data content of an encrypted authenticator", HFILL }},
5076         { &hf_krb_encrypted_EncKrbCredPart, {
5077                 "enc EncKrbCredPart", "kerberos.EncKrbCredPart.encrypted", FT_BYTES, BASE_NONE,
5078                 NULL, 0, "Encrypted EncKrbCredPart blob", HFILL }},
5079         { &hf_krb_encrypted_PA_ENC_TIMESTAMP, {
5080                 "enc PA_ENC_TIMESTAMP", "kerberos.PA_ENC_TIMESTAMP.encrypted", FT_BYTES, BASE_NONE,
5081                 NULL, 0, "Encrypted PA-ENC-TIMESTAMP blob", HFILL }},
5082         { &hf_krb_encrypted_enc_authorization_data, {
5083                 "enc-authorization-data", "kerberos.enc_authorization_data.encrypted", FT_BYTES, BASE_NONE,
5084                 NULL, 0, NULL, HFILL }},
5085         { &hf_krb_PAC_LOGON_INFO, {
5086                 "PAC_LOGON_INFO", "kerberos.PAC_LOGON_INFO", FT_BYTES, BASE_NONE,
5087                 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
5088         { &hf_krb_PAC_CREDENTIAL_TYPE, {
5089                 "PAC_CREDENTIAL_TYPE", "kerberos.PAC_CREDENTIAL_TYPE", FT_BYTES, BASE_NONE,
5090                 NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
5091         { &hf_krb_PAC_SERVER_CHECKSUM, {
5092                 "PAC_SERVER_CHECKSUM", "kerberos.PAC_SERVER_CHECKSUM", FT_BYTES, BASE_NONE,
5093                 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
5094         { &hf_krb_PAC_PRIVSVR_CHECKSUM, {
5095                 "PAC_PRIVSVR_CHECKSUM", "kerberos.PAC_PRIVSVR_CHECKSUM", FT_BYTES, BASE_NONE,
5096                 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
5097         { &hf_krb_PAC_CLIENT_INFO_TYPE, {
5098                 "PAC_CLIENT_INFO_TYPE", "kerberos.PAC_CLIENT_INFO_TYPE", FT_BYTES, BASE_NONE,
5099                 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
5100         { &hf_krb_PAC_S4U_DELEGATION_INFO, {
5101                 "PAC_S4U_DELEGATION_INFO", "kerberos.PAC_S4U_DELEGATION_INFO", FT_BYTES, BASE_NONE,
5102                 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
5103         { &hf_krb_PAC_UPN_DNS_INFO, {
5104                 "UPN_DNS_INFO", "kerberos.PAC_UPN_DNS_INFO", FT_BYTES, BASE_NONE,
5105                 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
5106         { &hf_krb_checksum_checksum, {
5107                 "checksum", "kerberos.checksum.checksum", FT_BYTES, BASE_NONE,
5108                 NULL, 0, "Kerberos Checksum", HFILL }},
5109         { &hf_krb_ENC_PRIV, {
5110                 "enc PRIV", "kerberos.ENC_PRIV", FT_BYTES, BASE_NONE,
5111                 NULL, 0, "Encrypted PRIV blob", HFILL }},
5112         { &hf_krb_encrypted_Ticket_data, {
5113                 "enc-part", "kerberos.ticket.data", FT_BYTES, BASE_NONE,
5114                 NULL, 0, "The encrypted part of a ticket", HFILL }},
5115         { &hf_krb_encrypted_AP_REP_data, {
5116                 "enc-part", "kerberos.aprep.data", FT_BYTES, BASE_NONE,
5117                 NULL, 0, "The encrypted part of AP-REP", HFILL }},
5118         { &hf_krb_encrypted_KDC_REP_data, {
5119                 "enc-part", "kerberos.kdcrep.data", FT_BYTES, BASE_NONE,
5120                 NULL, 0, "The encrypted part of KDC-REP", HFILL }},
5121         { &hf_krb_PA_DATA_value, {
5122                 "Value", "kerberos.padata.value", FT_BYTES, BASE_NONE,
5123                 NULL, 0, "Content of the PADATA blob", HFILL }},
5124         { &hf_krb_etype_info_salt, {
5125                 "Salt", "kerberos.etype_info.salt", FT_BYTES, BASE_NONE,
5126                 NULL, 0, NULL, HFILL }},
5127         { &hf_krb_etype_info2_salt, {
5128                 "Salt", "kerberos.etype_info2.salt", FT_BYTES, BASE_NONE,
5129                 NULL, 0, NULL, HFILL }},
5130         { &hf_krb_etype_info2_s2kparams, {
5131                 "Salt", "kerberos.etype_info.s2kparams", FT_BYTES, BASE_NONE,
5132                 NULL, 0, "S2kparams", HFILL }},
5133         { &hf_krb_SAFE_BODY_user_data, {
5134                 "User Data", "kerberos.SAFE_BODY.user_data", FT_BYTES, BASE_NONE,
5135                 NULL, 0, "SAFE BODY userdata field", HFILL }},
5136         { &hf_krb_PRIV_BODY_user_data, {
5137                 "User Data", "kerberos.PRIV_BODY.user_data", FT_BYTES, BASE_NONE,
5138                 NULL, 0, "PRIV BODY userdata field", HFILL }},
5139         { &hf_krb_pac_signature_signature, {
5140                 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
5141                 NULL, 0, "A PAC signature blob", HFILL }},
5142         { &hf_krb_PA_DATA_type, {
5143                 "Type", "kerberos.padata.type", FT_INT32, BASE_DEC,
5144                 VALS(krb5_preauthentication_types), 0, "Type of preauthentication data", HFILL }},
5145         { &hf_krb_nonce, {
5146                 "Nonce", "kerberos.nonce", FT_UINT32, BASE_DEC,
5147                 NULL, 0, "Kerberos Nonce random number", HFILL }},
5148         { &hf_krb_tkt_vno, {
5149                 "Tkt-vno", "kerberos.tkt_vno", FT_UINT32, BASE_DEC,
5150                 NULL, 0, "Version number for the Ticket format", HFILL }},
5151         { &hf_krb_KrbCredInfo, {
5152                 "KrbCredInfo", "kerberos.KrbCredInfo", FT_NONE, BASE_NONE,
5153                 NULL, 0, "This is a Kerberos KrbCredInfo", HFILL }},
5154         { &hf_krb_HostAddress, {
5155                 "HostAddress", "kerberos.hostaddress", FT_NONE, BASE_NONE,
5156                 NULL, 0, "This is a Kerberos HostAddress sequence", HFILL }},
5157         { &hf_krb_s_address, {
5158                 "S-Address", "kerberos.s_address", FT_NONE, BASE_NONE,
5159                 NULL, 0, "This is the Senders address", HFILL }},
5160         { &hf_krb_r_address, {
5161                 "R-Address", "kerberos.r_address", FT_NONE, BASE_NONE,
5162                 NULL, 0, "This is the Recipient address", HFILL }},
5163         { &hf_krb_key, {
5164                 "key", "kerberos.key", FT_NONE, BASE_NONE,
5165                 NULL, 0, "This is a Kerberos EncryptionKey sequence", HFILL }},
5166         { &hf_krb_subkey, {
5167                 "Subkey", "kerberos.subkey", FT_NONE, BASE_NONE,
5168                 NULL, 0, "This is a Kerberos subkey", HFILL }},
5169         { &hf_krb_seq_number, {
5170                 "Seq Number", "kerberos.seq_number", FT_UINT32, BASE_DEC,
5171                 NULL, 0, "This is a Kerberos sequence number", HFILL }},
5172         { &hf_krb_AuthorizationData, {
5173                 "AuthorizationData", "kerberos.AuthorizationData", FT_NONE, BASE_NONE,
5174                 NULL, 0, "This is a Kerberos AuthorizationData sequence", HFILL }},
5175         { &hf_krb_EncTicketPart, {
5176                 "EncTicketPart", "kerberos.EncTicketPart", FT_NONE, BASE_NONE,
5177                 NULL, 0, "This is a decrypted Kerberos EncTicketPart sequence", HFILL }},
5178         { &hf_krb_EncAPRepPart, {
5179                 "EncAPRepPart", "kerberos.EncAPRepPart", FT_NONE, BASE_NONE,
5180                 NULL, 0, "This is a decrypted Kerberos EncAPRepPart sequence", HFILL }},
5181         { &hf_krb_EncKrbPrivPart, {
5182                 "EncKrbPrivPart", "kerberos.EncKrbPrivPart", FT_NONE, BASE_NONE,
5183                 NULL, 0, "This is a decrypted Kerberos EncKrbPrivPart sequence", HFILL }},
5184         { &hf_krb_EncKrbCredPart, {
5185                 "EncKrbCredPart", "kerberos.EncKrbCredPart", FT_NONE, BASE_NONE,
5186                 NULL, 0, "This is a decrypted Kerberos EncKrbCredPart sequence", HFILL }},
5187         { &hf_krb_EncKDCRepPart, {
5188                 "EncKDCRepPart", "kerberos.EncKDCRepPart", FT_NONE, BASE_NONE,
5189                 NULL, 0, "This is a decrypted Kerberos EncKDCRepPart sequence", HFILL }},
5190         { &hf_krb_LastReq, {
5191                 "LastReq", "kerberos.LastReq", FT_NONE, BASE_NONE,
5192                 NULL, 0, "This is a LastReq sequence", HFILL }},
5193         { &hf_krb_Authenticator, {
5194                 "Authenticator", "kerberos.Authenticator", FT_NONE, BASE_NONE,
5195                 NULL, 0, "This is a decrypted Kerberos Authenticator sequence", HFILL }},
5196         { &hf_krb_Checksum, {
5197                 "Checksum", "kerberos.Checksum", FT_NONE, BASE_NONE,
5198                 NULL, 0, "This is a Kerberos Checksum sequence", HFILL }},
5199         { &hf_krb_HostAddresses, {
5200                 "HostAddresses", "kerberos.hostaddresses", FT_NONE, BASE_NONE,
5201                 NULL, 0, "This is a list of Kerberos HostAddress sequences", HFILL }},
5202         { &hf_krb_IF_RELEVANT, {
5203                 "IF_RELEVANT", "kerberos.if_relevant", FT_NONE, BASE_NONE,
5204                 NULL, 0, "This is a list of IF-RELEVANT sequences", HFILL }},
5205         { &hf_krb_etypes, {
5206                 "Encryption Types", "kerberos.etypes", FT_NONE, BASE_NONE,
5207                 NULL, 0, "This is a list of Kerberos encryption types", HFILL }},
5208         { &hf_krb_KrbCredInfos, {
5209                 "Sequence of KrbCredInfo", "kerberos.KrbCredInfos", FT_NONE, BASE_NONE,
5210                 NULL, 0, "This is a list of KrbCredInfo", HFILL }},
5211         { &hf_krb_sq_tickets, {
5212                 "Tickets", "kerberos.sq.tickets", FT_NONE, BASE_NONE,
5213                 NULL, 0, "This is a list of Kerberos Tickets", HFILL }},
5214         { &hf_krb_LastReqs, {
5215                 "LastReqs", "kerberos.LastReqs", FT_NONE, BASE_NONE,
5216                 NULL, 0, "This is a list of LastReq structures", HFILL }},
5217         { &hf_krb_sname, {
5218                 "Server Name", "kerberos.sname", FT_NONE, BASE_NONE,
5219                 NULL, 0, "This is the name part server's identity", HFILL }},
5220         { &hf_krb_pname, {
5221                 "Delegated Principal Name", "kerberos.pname", FT_NONE, BASE_NONE,
5222                 NULL, 0, "Identity of the delegated principal", HFILL }},
5223         { &hf_krb_cname, {
5224                 "Client Name", "kerberos.cname", FT_NONE, BASE_NONE,
5225                 NULL, 0, "The name part of the client principal identifier", HFILL }},
5226         { &hf_krb_authenticator_enc, {
5227                 "Authenticator", "kerberos.authenticator", FT_NONE, BASE_NONE,
5228                 NULL, 0, "Encrypted authenticator blob", HFILL }},
5229         { &hf_krb_CRED_enc, {
5230                 "EncKrbCredPart", "kerberos.encrypted_cred", FT_NONE, BASE_NONE,
5231                 NULL, 0, "Encrypted Cred blob", HFILL }},
5232         { &hf_krb_ticket_enc, {
5233                 "enc-part", "kerberos.ticket.enc_part", FT_NONE, BASE_NONE,
5234                 NULL, 0, "The structure holding the encrypted part of a ticket", HFILL }},
5235         { &hf_krb_AP_REP_enc, {
5236                 "enc-part", "kerberos.aprep.enc_part", FT_NONE, BASE_NONE,
5237                 NULL, 0, "The structure holding the encrypted part of AP-REP", HFILL }},
5238         { &hf_krb_KDC_REP_enc, {
5239                 "enc-part", "kerberos.kdcrep.enc_part", FT_NONE, BASE_NONE,
5240                 NULL, 0, "The structure holding the encrypted part of KDC-REP", HFILL }},
5241         { &hf_krb_e_data, {
5242                 "e-data", "kerberos.e_data", FT_NONE, BASE_NONE,
5243                 NULL, 0, "The e-data blob", HFILL }},
5244         { &hf_krb_padata, {
5245                 "padata", "kerberos.padata", FT_NONE, BASE_NONE,
5246                 NULL, 0, "Sequence of preauthentication data", HFILL }},
5247         { &hf_krb_ticket, {
5248                 "Ticket", "kerberos.ticket", FT_NONE, BASE_NONE,
5249                 NULL, 0, "This is a Kerberos Ticket", HFILL }},
5250         { &hf_krb_TransitedEncoding, {
5251                 "TransitedEncoding", "kerberos.TransitedEncoding", FT_NONE, BASE_NONE,
5252                 NULL, 0, "This is a Kerberos TransitedEncoding sequence", HFILL }},
5253         { &hf_krb_PA_PAC_REQUEST_flag, {
5254                 "PAC Request", "kerberos.pac_request.flag", FT_BOOLEAN, 32,
5255                 NULL, 0, "This is a MS PAC Request Flag", HFILL }},
5256         { &hf_krb_w2k_pac_entries, {
5257                 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
5258                 NULL, 0, "Number of W2k PAC entries", HFILL }},
5259         { &hf_krb_w2k_pac_version, {
5260                 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
5261                 NULL, 0, "Version of PAC structures", HFILL }},
5262         { &hf_krb_w2k_pac_type, {
5263                 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
5264                 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
5265         { &hf_krb_w2k_pac_size, {
5266                 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
5267                 NULL, 0, "Size of W2k PAC entry", HFILL }},
5268         { &hf_krb_w2k_pac_offset, {
5269                 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
5270                 NULL, 0, "Offset to W2k PAC entry", HFILL }},
5271         { &hf_krb_pac_clientid, {
5272                 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5273                 NULL, 0, "ClientID Timestamp", HFILL }},
5274         { &hf_krb_pac_namelen, {
5275                 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
5276                 NULL, 0, "Length of client name", HFILL }},
5277         { &hf_krb_pac_upn_flags, {
5278                 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
5279                 NULL, 0, "UPN flags", HFILL }},
5280         { &hf_krb_pac_upn_dns_offset, {
5281                 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
5282                 NULL, 0, NULL, HFILL }},
5283         { &hf_krb_pac_upn_dns_len, {
5284                 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
5285                 NULL, 0, NULL, HFILL }},
5286         { &hf_krb_pac_upn_upn_offset, {
5287                 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
5288                 NULL, 0, NULL, HFILL }},
5289         { &hf_krb_pac_upn_upn_len, {
5290                 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
5291                 NULL, 0, NULL, HFILL }},
5292         { &hf_krb_pac_upn_upn_name, {
5293                 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
5294                 NULL, 0, NULL, HFILL }},
5295         { &hf_krb_pac_upn_dns_name, {
5296                 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
5297                 NULL, 0, NULL, HFILL }},
5298         { &hf_krb_e_checksum, {
5299                 "e-checksum", "kerberos.e_checksum", FT_NONE, BASE_NONE,
5300                 NULL, 0, "This is a Kerberos e-checksum", HFILL }},
5301         { &hf_krb_gssapi_len, {
5302                 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
5303                 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
5304         { &hf_krb_gssapi_bnd, {
5305                 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
5306                 NULL, 0, "GSSAPI Bnd field", HFILL }},
5307         { &hf_krb_gssapi_c_flag_deleg, {
5308                 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
5309                 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
5310         { &hf_krb_gssapi_c_flag_mutual, {
5311                 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
5312                 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
5313         { &hf_krb_gssapi_c_flag_replay, {
5314                 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
5315                 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
5316         { &hf_krb_gssapi_c_flag_sequence, {
5317                 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
5318                 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
5319         { &hf_krb_gssapi_c_flag_conf, {
5320                 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
5321                 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
5322         { &hf_krb_gssapi_c_flag_integ, {
5323                 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
5324                 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
5325         { &hf_krb_gssapi_c_flag_dce_style, {
5326                 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
5327                 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
5328         { &hf_krb_gssapi_dlgopt, {
5329                 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
5330                 NULL, 0, "GSSAPI DlgOpt", HFILL }},
5331         { &hf_krb_gssapi_dlglen, {
5332                 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
5333                 NULL, 0, "GSSAPI DlgLen", HFILL }},
5334         { &hf_krb_smb_nt_status, {
5335                 "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
5336                 VALS(NT_errors), 0, "NT Status code", HFILL }},
5337         { &hf_krb_smb_unknown, {
5338                 "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
5339                 NULL, 0, NULL, HFILL }},
5340         { &hf_krb_midl_blob_len, {
5341                 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
5342                 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
5343         { &hf_krb_midl_fill_bytes, {
5344                 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
5345                 NULL, 0, "Just some fill bytes", HFILL }},
5346         { &hf_krb_midl_version, {
5347                 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
5348                 NULL, 0, "Version of pickling", HFILL }},
5349         { &hf_krb_midl_hdr_len, {
5350                 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
5351                 NULL, 0, "Length of header", HFILL }},
5352
5353     };
5354
5355     static gint *ett[] = {
5356         &ett_krb_kerberos,
5357         &ett_krb_KDC_REP_enc,
5358         &ett_krb_sname,
5359         &ett_krb_pname,
5360         &ett_krb_cname,
5361         &ett_krb_AP_REP_enc,
5362         &ett_krb_padata,
5363         &ett_krb_etypes,
5364         &ett_krb_KrbCredInfos,
5365         &ett_krb_sq_tickets,
5366         &ett_krb_LastReqs,
5367         &ett_krb_IF_RELEVANT,
5368         &ett_krb_PA_DATA_tree,
5369         &ett_krb_s_address,
5370         &ett_krb_r_address,
5371         &ett_krb_KrbCredInfo,
5372         &ett_krb_HostAddress,
5373         &ett_krb_HostAddresses,
5374         &ett_krb_authenticator_enc,
5375         &ett_krb_CRED_enc,
5376         &ett_krb_AP_Options,
5377         &ett_krb_KDC_Options,
5378         &ett_krb_Ticket_Flags,
5379         &ett_krb_request,
5380         &ett_krb_recordmark,
5381         &ett_krb_ticket,
5382         &ett_krb_ticket_enc,
5383         &ett_krb_CRED,
5384         &ett_krb_PRIV,
5385         &ett_krb_PRIV_enc,
5386         &ett_krb_EncTicketPart,
5387         &ett_krb_EncAPRepPart,
5388         &ett_krb_EncKrbPrivPart,
5389         &ett_krb_EncKrbCredPart,
5390         &ett_krb_EncKDCRepPart,
5391         &ett_krb_LastReq,
5392         &ett_krb_Authenticator,
5393         &ett_krb_Checksum,
5394         &ett_krb_key,
5395         &ett_krb_subkey,
5396         &ett_krb_AuthorizationData,
5397         &ett_krb_TransitedEncoding,
5398         &ett_krb_PAC,
5399         &ett_krb_PAC_LOGON_INFO,
5400         &ett_krb_PAC_SERVER_CHECKSUM,
5401         &ett_krb_PAC_PRIVSVR_CHECKSUM,
5402         &ett_krb_PAC_CLIENT_INFO_TYPE,
5403         &ett_krb_PAC_S4U_DELEGATION_INFO,
5404         &ett_krb_e_checksum,
5405         &ett_krb_PAC_MIDL_BLOB,
5406         &ett_krb_PAC_DREP,
5407         &ett_krb_PAC_UPN_DNS_INFO
5408     };
5409     module_t *krb_module;
5410
5411     proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
5412     proto_register_field_array(proto_kerberos, hf, array_length(hf));
5413     proto_register_subtree_array(ett, array_length(ett));
5414
5415     /* Register preferences */
5416     krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
5417     prefs_register_bool_preference(krb_module, "desegment",
5418         "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
5419         "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
5420         " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
5421         &krb_desegment);
5422 #ifdef HAVE_KERBEROS
5423     prefs_register_bool_preference(krb_module, "decrypt",
5424         "Try to decrypt Kerberos blobs",
5425         "Whether the dissector should try to decrypt "
5426         "encrypted Kerberos blobs. This requires that the proper "
5427         "keytab file is installed as well.",
5428         &krb_decrypt);
5429
5430     prefs_register_string_preference(krb_module, "file",
5431         "Kerberos keytab file",
5432         "The keytab file containing all the secrets",
5433         &keytab_filename);
5434 #endif
5435
5436 }
5437
5438 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
5439                                  proto_tree *tree, guint8 *drep _U_)
5440 {
5441     tvbuff_t *auth_tvb;
5442
5443     auth_tvb = tvb_new_subset(
5444         tvb, offset, tvb_length_remaining(tvb, offset),
5445         tvb_reported_length_remaining(tvb, offset));
5446
5447     dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
5448
5449     return tvb_length_remaining(tvb, offset);
5450 }
5451
5452
5453 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
5454     wrap_dissect_gss_kerb,                      /* Bind */
5455     wrap_dissect_gss_kerb,                      /* Bind ACK */
5456     wrap_dissect_gss_kerb,                      /* AUTH3 */
5457     NULL,                                       /* Request verifier */
5458     NULL,                                       /* Response verifier */
5459     NULL,                                       /* Request data */
5460     NULL                                        /* Response data */
5461 };
5462
5463 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
5464     wrap_dissect_gss_kerb,                      /* Bind */
5465     wrap_dissect_gss_kerb,                      /* Bind ACK */
5466     wrap_dissect_gss_kerb,                      /* AUTH3 */
5467     wrap_dissect_gssapi_verf,                   /* Request verifier */
5468     wrap_dissect_gssapi_verf,                   /* Response verifier */
5469     NULL,                                       /* Request data */
5470     NULL                                        /* Response data */
5471 };
5472
5473 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
5474     wrap_dissect_gss_kerb,                      /* Bind */
5475     wrap_dissect_gss_kerb,                      /* Bind ACK */
5476     wrap_dissect_gss_kerb,                      /* AUTH3 */
5477     wrap_dissect_gssapi_verf,                   /* Request verifier */
5478     wrap_dissect_gssapi_verf,                   /* Response verifier */
5479     wrap_dissect_gssapi_payload,                /* Request data */
5480     wrap_dissect_gssapi_payload                 /* Response data */
5481 };
5482
5483
5484 void
5485 proto_reg_handoff_kerberos(void)
5486 {
5487     dissector_handle_t kerberos_handle_tcp;
5488
5489     krb4_handle = find_dissector("krb4");
5490
5491     kerberos_handle_udp = new_create_dissector_handle(dissect_kerberos_udp,
5492                                                       proto_kerberos);
5493     kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
5494                                                   proto_kerberos);
5495     dissector_add_uint("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
5496     dissector_add_uint("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
5497
5498     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
5499                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
5500                                       &gss_kerb_auth_connect_fns);
5501
5502     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
5503                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
5504                                       &gss_kerb_auth_sign_fns);
5505
5506     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
5507                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
5508                                       &gss_kerb_auth_seal_fns);
5509
5510 }
5511
5512 /*
5513
5514   MISC definitions from RFC1510:
5515
5516    Realm ::=           GeneralString
5517
5518    KerberosTime ::=   GeneralizedTime
5519
5520    AuthorizationData ::=   SEQUENCE OF SEQUENCE {
5521                            ad-type[0]               INTEGER,
5522                            ad-data[1]               OCTET STRING
5523    }
5524                    APOptions ::=   BIT STRING {
5525                                    reserved(0),
5526                                    use-session-key(1),
5527                                    mutual-required(2)
5528                    }
5529
5530
5531                    TicketFlags ::=   BIT STRING {
5532                                      reserved(0),
5533                                      forwardable(1),
5534                                      forwarded(2),
5535                                      proxiable(3),
5536                                      proxy(4),
5537                                      may-postdate(5),
5538                                      postdated(6),
5539                                      invalid(7),
5540                                      renewable(8),
5541                                      initial(9),
5542                                      pre-authent(10),
5543                                      hw-authent(11)
5544                    }
5545
5546                   KDCOptions ::=   BIT STRING {
5547                                    reserved(0),
5548                                    forwardable(1),
5549                                    forwarded(2),
5550                                    proxiable(3),
5551                                    proxy(4),
5552                                    allow-postdate(5),
5553                                    postdated(6),
5554                                    unused7(7),
5555                                    renewable(8),
5556                                    unused9(9),
5557                                    unused10(10),
5558                                    unused11(11),
5559                                    renewable-ok(27),
5560                                    enc-tkt-in-skey(28),
5561                                    renew(30),
5562                                    validate(31)
5563                   }
5564
5565
5566             LastReq ::=   SEQUENCE OF SEQUENCE {
5567                           lr-type[0]               INTEGER,
5568                           lr-value[1]              KerberosTime
5569             }
5570
5571    Ticket ::=                    [APPLICATION 1] SEQUENCE {
5572                                  tkt-vno[0]                   INTEGER,
5573                                  realm[1]                     Realm,
5574                                  sname[2]                     PrincipalName,
5575                                  enc-part[3]                  EncryptedData
5576    }
5577
5578   -- Encrypted part of ticket
5579   EncTicketPart ::=     [APPLICATION 3] SEQUENCE {
5580                         flags[0]             TicketFlags,
5581                         key[1]               EncryptionKey,
5582                         crealm[2]            Realm,
5583                         cname[3]             PrincipalName,
5584                         transited[4]         TransitedEncoding,
5585                         authtime[5]          KerberosTime,
5586                         starttime[6]         KerberosTime OPTIONAL,
5587                         endtime[7]           KerberosTime,
5588                         renew-till[8]        KerberosTime OPTIONAL,
5589                         caddr[9]             HostAddresses OPTIONAL,
5590                         authorization-data[10]   AuthorizationData OPTIONAL
5591   }
5592
5593   -- encoded Transited field
5594   TransitedEncoding ::=         SEQUENCE {
5595                                 tr-type[0]  INTEGER, -- must be registered
5596                                 contents[1]          OCTET STRING
5597   }
5598
5599   -- Unencrypted authenticator
5600   Authenticator ::=    [APPLICATION 2] SEQUENCE    {
5601                  authenticator-vno[0]          INTEGER,
5602                  crealm[1]                     Realm,
5603                  cname[2]                      PrincipalName,
5604                  cksum[3]                      Checksum OPTIONAL,
5605                  cusec[4]                      INTEGER,
5606                  ctime[5]                      KerberosTime,
5607                  subkey[6]                     EncryptionKey OPTIONAL,
5608                  seq-number[7]                 INTEGER OPTIONAL,
5609                  authorization-data[8]         AuthorizationData OPTIONAL
5610   }
5611
5612   PA-DATA ::=        SEQUENCE {
5613            padata-type[1]        INTEGER,
5614            padata-value[2]       OCTET STRING,
5615                          -- might be encoded AP-REQ
5616   }
5617
5618    padata-type     ::= PA-ENC-TIMESTAMP
5619    padata-value    ::= EncryptedData -- PA-ENC-TS-ENC
5620
5621    PA-ENC-TS-ENC   ::= SEQUENCE {
5622            patimestamp[0]               KerberosTime, -- client's time
5623            pausec[1]                    INTEGER OPTIONAL
5624    }
5625
5626    EncASRepPart ::=    [APPLICATION 25[25]] EncKDCRepPart
5627    EncTGSRepPart ::=   [APPLICATION 26] EncKDCRepPart
5628
5629    EncKDCRepPart ::=   SEQUENCE {
5630                key[0]                       EncryptionKey,
5631                last-req[1]                  LastReq,
5632                nonce[2]                     INTEGER,
5633                key-expiration[3]            KerberosTime OPTIONAL,
5634                flags[4]                     TicketFlags,
5635                authtime[5]                  KerberosTime,
5636                starttime[6]                 KerberosTime OPTIONAL,
5637                endtime[7]                   KerberosTime,
5638                renew-till[8]                KerberosTime OPTIONAL,
5639                srealm[9]                    Realm,
5640                sname[10]                    PrincipalName,
5641                caddr[11]                    HostAddresses OPTIONAL
5642    }
5643
5644    APOptions ::=   BIT STRING {
5645                    reserved(0),
5646                    use-session-key(1),
5647                    mutual-required(2)
5648    }
5649
5650    EncAPRepPart ::=   [APPLICATION 27]     SEQUENCE {
5651               ctime[0]                  KerberosTime,
5652               cusec[1]                  INTEGER,
5653               subkey[2]                 EncryptionKey OPTIONAL,
5654               seq-number[3]             INTEGER OPTIONAL
5655    }
5656
5657    KRB-SAFE ::=        [APPLICATION 20] SEQUENCE {
5658                pvno[0]               INTEGER,
5659                msg-type[1]           INTEGER,
5660                safe-body[2]          KRB-SAFE-BODY,
5661                cksum[3]              Checksum
5662    }
5663
5664    KRB-SAFE-BODY ::=   SEQUENCE {
5665                user-data[0]          OCTET STRING,
5666                timestamp[1]          KerberosTime OPTIONAL,
5667                usec[2]               INTEGER OPTIONAL,
5668                seq-number[3]         INTEGER OPTIONAL,
5669                s-address[4]          HostAddress,
5670                r-address[5]          HostAddress OPTIONAL
5671    }
5672
5673    KRB-PRIV ::=         [APPLICATION 21] SEQUENCE {
5674                 pvno[0]                   INTEGER,
5675                 msg-type[1]               INTEGER,
5676                 enc-part[3]               EncryptedData
5677    }
5678
5679    EncKrbPrivPart ::=   [APPLICATION 28] SEQUENCE {
5680                 user-data[0]              OCTET STRING,
5681                 timestamp[1]              KerberosTime OPTIONAL,
5682                 usec[2]                   INTEGER OPTIONAL,
5683                 seq-number[3]             INTEGER OPTIONAL,
5684                 s-address[4]              HostAddress, -- sender's addr
5685                 r-address[5]              HostAddress OPTIONAL
5686                                                       -- recip's addr
5687    }
5688
5689    KRB-CRED         ::= [APPLICATION 22]   SEQUENCE {
5690                     pvno[0]                INTEGER,
5691                     msg-type[1]            INTEGER, -- KRB_CRED
5692                     tickets[2]             SEQUENCE OF Ticket,
5693                     enc-part[3]            EncryptedData
5694    }
5695
5696    EncKrbCredPart   ::= [APPLICATION 29]   SEQUENCE {
5697                     ticket-info[0]         SEQUENCE OF KrbCredInfo,
5698                     nonce[1]               INTEGER OPTIONAL,
5699                     timestamp[2]           KerberosTime OPTIONAL,
5700                     usec[3]                INTEGER OPTIONAL,
5701                     s-address[4]           HostAddress OPTIONAL,
5702                     r-address[5]           HostAddress OPTIONAL
5703    }
5704
5705    KrbCredInfo      ::=                    SEQUENCE {
5706                     key[0]                 EncryptionKey,
5707                     prealm[1]              Realm OPTIONAL,
5708                     pname[2]               PrincipalName OPTIONAL,
5709                     flags[3]               TicketFlags OPTIONAL,
5710                     authtime[4]            KerberosTime OPTIONAL,
5711                     starttime[5]           KerberosTime OPTIONAL,
5712                     endtime[6]             KerberosTime OPTIONAL
5713                     renew-till[7]          KerberosTime OPTIONAL,
5714                     srealm[8]              Realm OPTIONAL,
5715                     sname[9]               PrincipalName OPTIONAL,
5716                     caddr[10]              HostAddresses OPTIONAL
5717    }
5718
5719       METHOD-DATA ::=    SEQUENCE of PA-DATA
5720
5721    If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
5722    contain an encoding of the following sequence:
5723
5724       METHOD-DATA ::=    SEQUENCE {
5725                          method-type[0]   INTEGER,
5726                          method-data[1]   OCTET STRING OPTIONAL
5727       }
5728
5729       EncryptionKey ::=   SEQUENCE {
5730                          keytype[0]    INTEGER,
5731                          keyvalue[1]   OCTET STRING
5732       }
5733
5734       Checksum ::=   SEQUENCE {
5735                          cksumtype[0]   INTEGER,
5736                          checksum[1]    OCTET STRING
5737       }
5738
5739 */