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