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