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