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