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