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