Fix handling of pa-data-type KRB5_PA_PAC_REQUEST (& KRB5_PA_S4U2SELF).
[obnox/wireshark/wip.git] / epan / dissectors / packet-kerberos.c
1 /* packet-kerberos.c
2  * Routines for Kerberos
3  * Wes Hardaker (c) 2000
4  * wjhardaker@ucdavis.edu
5  * Richard Sharpe (C) 2002, rsharpe@samba.org, modularized a bit more and
6  *                          added AP-REQ and AP-REP dissection
7  *
8  * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API.
9  *                           decryption of kerberos blobs if keytab is provided
10  *
11  * See RFC 1510, and various I-Ds and other documents showing additions,
12  * e.g. ones listed under
13  *
14  *      http://www.isi.edu/people/bcn/krb-revisions/
15  *
16  * and
17  *
18  *      http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-07.txt
19  *
20  * and
21  *
22  *      http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-referrals-05.txt
23  *
24  * Some structures from RFC2630
25  *
26  * Ted Percival ted[AT]midg3t.net
27  *      Support for PA-S4U2Self Kerberos packet type based on ASN.1 description
28  *      in Heimdal:
29  *      http://loka.it.su.se/source/xref/heimdal/heimdal/lib/asn1/k5.asn1
30  *
31  * $Id$
32  *
33  * Wireshark - Network traffic analyzer
34  * By Gerald Combs <gerald@wireshark.org>
35  * Copyright 1998 Gerald Combs
36  *
37  * This program is free software; you can redistribute it and/or
38  * modify it under the terms of the GNU General Public License
39  * as published by the Free Software Foundation; either version 2
40  * of the License, or (at your option) any later version.
41  *
42  * This program is distributed in the hope that it will be useful,
43  * but WITHOUT ANY WARRANTY; without even the implied warranty of
44  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45  * GNU General Public License for more details.
46  *
47  * You should have received a copy of the GNU General Public License
48  * along with this program; if not, write to the Free Software
49  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
50  */
51
52 /*
53  * Some of the development of the Kerberos protocol decoder was sponsored by
54  * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
55  * CableLabs' specifications. Your license and use of this protocol decoder
56  * does not mean that you are licensed to use the CableLabs'
57  * specifications.  If you have questions about this protocol, contact
58  * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
59  * information.
60  */
61
62 #ifdef HAVE_CONFIG_H
63 # include "config.h"
64 #endif
65
66 #include <stdio.h>
67 #include <string.h>
68 #include <glib.h>
69 #include <ctype.h>
70
71 #ifdef HAVE_LIBNETTLE
72 #define HAVE_KERBEROS
73 #ifdef _WIN32
74 #include <des.h>
75 #include <cbc.h>
76 #else
77 #include <nettle/des.h>
78 #include <nettle/cbc.h>
79 #endif
80 #include <epan/crypt/crypt-md5.h>
81 #include <sys/stat.h>   /* For keyfile manipulation */
82 #endif
83
84 #include <epan/packet.h>
85
86 #include <epan/strutil.h>
87
88 #include <epan/conversation.h>
89 #include <epan/emem.h>
90 #include <epan/asn1.h>
91 #include <epan/expert.h>
92 #include <epan/dissectors/packet-kerberos.h>
93 #include <epan/dissectors/packet-netbios.h>
94 #include <epan/dissectors/packet-tcp.h>
95 #include <epan/prefs.h>
96 #include <epan/dissectors/packet-ber.h>
97 #include <epan/dissectors/packet-pkinit.h>
98 #include <epan/dissectors/packet-cms.h>
99 #include <epan/dissectors/packet-windows-common.h>
100
101 #include <epan/dissectors/packet-dcerpc-netlogon.h>
102 #include <epan/dissectors/packet-dcerpc.h>
103
104 #include <epan/dissectors/packet-gssapi.h>
105 #include <epan/dissectors/packet-smb-common.h>
106
107 #include <wsutil/file_util.h>
108
109 #define UDP_PORT_KERBEROS               88
110 #define TCP_PORT_KERBEROS               88
111
112 static dissector_handle_t kerberos_handle_udp;
113
114 /* Desegment Kerberos over TCP messages */
115 static gboolean krb_desegment = TRUE;
116
117 static gint proto_kerberos = -1;
118 static gint hf_krb_rm_reserved = -1;
119 static gint hf_krb_rm_reclen = -1;
120
121 static gint hf_krb_pac_signature_type = -1;
122 static gint hf_krb_pac_signature_signature = -1;
123 static gint hf_krb_pac_clientid = -1;
124 static gint hf_krb_pac_namelen = -1;
125 static gint hf_krb_pac_clientname = -1;
126 static gint hf_krb_pac_upn_flags = -1;
127 static gint hf_krb_pac_upn_upn_name = -1;
128 static gint hf_krb_pac_upn_dns_name = -1;
129 static gint hf_krb_pac_upn_dns_offset = -1;
130 static gint hf_krb_pac_upn_dns_len = -1;
131 static gint hf_krb_pac_upn_upn_offset = -1;
132 static gint hf_krb_pac_upn_upn_len = -1;
133 static gint hf_krb_w2k_pac_entries = -1;
134 static gint hf_krb_w2k_pac_version = -1;
135 static gint hf_krb_w2k_pac_type = -1;
136 static gint hf_krb_w2k_pac_size = -1;
137 static gint hf_krb_w2k_pac_offset = -1;
138 static gint hf_krb_padata = -1;
139 static gint hf_krb_error_code = -1;
140 static gint hf_krb_ticket = -1;
141 static gint hf_krb_AP_REP_enc = -1;
142 static gint hf_krb_KDC_REP_enc = -1;
143 static gint hf_krb_tkt_vno = -1;
144 static gint hf_krb_e_data = -1;
145 static gint hf_krb_TransitedEncoding = -1;
146 static gint hf_krb_PA_PAC_REQUEST_flag = -1;
147 static gint hf_krb_encrypted_authenticator_data = -1;
148 static gint hf_krb_PAC_LOGON_INFO = -1;
149 static gint hf_krb_PAC_CREDENTIAL_TYPE = -1;
150 static gint hf_krb_PAC_SERVER_CHECKSUM = -1;
151 static gint hf_krb_PAC_PRIVSVR_CHECKSUM = -1;
152 static gint hf_krb_PAC_CLIENT_INFO_TYPE = -1;
153 static gint hf_krb_PAC_CONSTRAINED_DELEGATION = -1;
154 static gint hf_krb_PAC_UPN_DNS_INFO = -1;
155 static gint hf_krb_encrypted_PA_ENC_TIMESTAMP = -1;
156 static gint hf_krb_encrypted_enc_authorization_data = -1;
157 static gint hf_krb_encrypted_EncKrbCredPart = -1;
158 static gint hf_krb_checksum_checksum = -1;
159 static gint hf_krb_encrypted_PRIV = -1;
160 static gint hf_krb_encrypted_Ticket_data = -1;
161 static gint hf_krb_encrypted_AP_REP_data = -1;
162 static gint hf_krb_encrypted_KDC_REP_data = -1;
163 static gint hf_krb_PA_DATA_type = -1;
164 static gint hf_krb_PA_DATA_value = -1;
165 static gint hf_krb_etype_info_salt = -1;
166 static gint hf_krb_etype_info2_salt = -1;
167 static gint hf_krb_etype_info2_s2kparams = -1;
168 static gint hf_krb_SAFE_BODY_user_data = -1;
169 static gint hf_krb_PRIV_BODY_user_data = -1;
170 static gint hf_krb_realm = -1;
171 static gint hf_krb_srealm = -1;
172 static gint hf_krb_prealm = -1;
173 static gint hf_krb_crealm = -1;
174 static gint hf_krb_sname = -1;
175 static gint hf_krb_pname = -1;
176 static gint hf_krb_cname = -1;
177 static gint hf_krb_name_string = -1;
178 static gint hf_krb_provsrv_location = -1;
179 static gint hf_krb_e_text = -1;
180 static gint hf_krb_s4u2self_auth = -1;
181 static gint hf_krb_name_type = -1;
182 static gint hf_krb_lr_type = -1;
183 static gint hf_krb_from = -1;
184 static gint hf_krb_till = -1;
185 static gint hf_krb_authtime = -1;
186 static gint hf_krb_patimestamp = -1;
187 static gint hf_krb_SAFE_BODY_timestamp = -1;
188 static gint hf_krb_pausec = -1;
189 static gint hf_krb_lr_time = -1;
190 static gint hf_krb_starttime = -1;
191 static gint hf_krb_endtime = -1;
192 static gint hf_krb_key_expire = -1;
193 static gint hf_krb_renew_till = -1;
194 static gint hf_krb_rtime = -1;
195 static gint hf_krb_ctime = -1;
196 static gint hf_krb_cusec = -1;
197 static gint hf_krb_stime = -1;
198 static gint hf_krb_susec = -1;
199 static gint hf_krb_SAFE_BODY_usec = -1;
200 static gint hf_krb_nonce = -1;
201 static gint hf_krb_transitedtype = -1;
202 static gint hf_krb_transitedcontents = -1;
203 static gint hf_krb_keytype = -1;
204 static gint hf_krb_keyvalue = -1;
205 static gint hf_krb_IF_RELEVANT_type = -1;
206 static gint hf_krb_IF_RELEVANT_value = -1;
207 static gint hf_krb_adtype = -1;
208 static gint hf_krb_advalue = -1;
209 static gint hf_krb_etype = -1;
210 static gint hf_krb_etypes = -1;
211 static gint hf_krb_KrbCredInfos = -1;
212 static gint hf_krb_sq_tickets = -1;
213 static gint hf_krb_LastReqs = -1;
214 static gint hf_krb_IF_RELEVANT = -1;
215 static gint hf_krb_addr_type = -1;
216 static gint hf_krb_address_ip = -1;
217 static gint hf_krb_address_ipv6 = -1;
218 static gint hf_krb_address_netbios = -1;
219 static gint hf_krb_msg_type = -1;
220 static gint hf_krb_pvno = -1;
221 static gint hf_krb_kvno = -1;
222 static gint hf_krb_checksum_type = -1;
223 static gint hf_krb_authenticator_vno = -1;
224 static gint hf_krb_AuthorizationData = -1;
225 static gint hf_krb_key = -1;
226 static gint hf_krb_subkey = -1;
227 static gint hf_krb_seq_number = -1;
228 static gint hf_krb_EncTicketPart = -1;
229 static gint hf_krb_EncAPRepPart = -1;
230 static gint hf_krb_EncKrbPrivPart = -1;
231 static gint hf_krb_EncKrbCredPart = -1;
232 static gint hf_krb_EncKDCRepPart = -1;
233 static gint hf_krb_LastReq = -1;
234 static gint hf_krb_Authenticator = -1;
235 static gint hf_krb_Checksum = -1;
236 static gint hf_krb_s_address = -1;
237 static gint hf_krb_r_address = -1;
238 static gint hf_krb_KrbCredInfo = -1;
239 static gint hf_krb_HostAddress = -1;
240 static gint hf_krb_HostAddresses = -1;
241 static gint hf_krb_APOptions = -1;
242 static gint hf_krb_APOptions_use_session_key = -1;
243 static gint hf_krb_APOptions_mutual_required = -1;
244 static gint hf_krb_TicketFlags = -1;
245 static gint hf_krb_TicketFlags_forwardable = -1;
246 static gint hf_krb_TicketFlags_forwarded = -1;
247 static gint hf_krb_TicketFlags_proxiable = -1;
248 static gint hf_krb_TicketFlags_proxy = -1;
249 static gint hf_krb_TicketFlags_allow_postdate = -1;
250 static gint hf_krb_TicketFlags_postdated = -1;
251 static gint hf_krb_TicketFlags_invalid = -1;
252 static gint hf_krb_TicketFlags_renewable = -1;
253 static gint hf_krb_TicketFlags_initial = -1;
254 static gint hf_krb_TicketFlags_pre_auth = -1;
255 static gint hf_krb_TicketFlags_hw_auth = -1;
256 static gint hf_krb_TicketFlags_transited_policy_checked = -1;
257 static gint hf_krb_TicketFlags_ok_as_delegate = -1;
258 static gint hf_krb_KDCOptions = -1;
259 static gint hf_krb_KDCOptions_forwardable = -1;
260 static gint hf_krb_KDCOptions_forwarded = -1;
261 static gint hf_krb_KDCOptions_proxiable = -1;
262 static gint hf_krb_KDCOptions_proxy = -1;
263 static gint hf_krb_KDCOptions_allow_postdate = -1;
264 static gint hf_krb_KDCOptions_postdated = -1;
265 static gint hf_krb_KDCOptions_renewable = -1;
266 static gint hf_krb_KDCOptions_constrained_delegation = -1;
267 static gint hf_krb_KDCOptions_canonicalize = -1;
268 static gint hf_krb_KDCOptions_opt_hardware_auth = -1;
269 static gint hf_krb_KDCOptions_disable_transited_check = -1;
270 static gint hf_krb_KDCOptions_renewable_ok = -1;
271 static gint hf_krb_KDCOptions_enc_tkt_in_skey = -1;
272 static gint hf_krb_KDCOptions_renew = -1;
273 static gint hf_krb_KDCOptions_validate = -1;
274 static gint hf_krb_KDC_REQ_BODY = -1;
275 static gint hf_krb_PRIV_BODY = -1;
276 static gint hf_krb_CRED_BODY = -1;
277 static gint hf_krb_ENC_PRIV = -1;
278 static gint hf_krb_authenticator_enc = -1;
279 static gint hf_krb_CRED_enc = -1;
280 static gint hf_krb_ticket_enc = -1;
281 static gint hf_krb_e_checksum = -1;
282 static gint hf_krb_gssapi_len = -1;
283 static gint hf_krb_gssapi_bnd = -1;
284 static gint hf_krb_gssapi_dlgopt = -1;
285 static gint hf_krb_gssapi_dlglen = -1;
286 static gint hf_krb_gssapi_c_flag_deleg = -1;
287 static gint hf_krb_gssapi_c_flag_mutual = -1;
288 static gint hf_krb_gssapi_c_flag_replay = -1;
289 static gint hf_krb_gssapi_c_flag_sequence = -1;
290 static gint hf_krb_gssapi_c_flag_conf = -1;
291 static gint hf_krb_gssapi_c_flag_integ = -1;
292 static gint hf_krb_gssapi_c_flag_dce_style = -1;
293 static gint hf_krb_smb_nt_status = -1;
294 static gint hf_krb_smb_unknown = -1;
295 static gint hf_krb_midl_blob_len = -1;
296 static gint hf_krb_midl_fill_bytes = -1;
297 static gint hf_krb_midl_version = -1;
298 static gint hf_krb_midl_hdr_len = -1;
299
300 static gint ett_krb_kerberos = -1;
301 static gint ett_krb_TransitedEncoding = -1;
302 static gint ett_krb_PAC_LOGON_INFO = -1;
303 static gint ett_krb_PAC_CREDENTIAL_TYPE = -1;
304 static gint ett_krb_PAC_SERVER_CHECKSUM = -1;
305 static gint ett_krb_PAC_PRIVSVR_CHECKSUM = -1;
306 static gint ett_krb_PAC_CLIENT_INFO_TYPE = -1;
307 static gint ett_krb_PAC_CONSTRAINED_DELEGATION = -1;
308 static gint ett_krb_KDC_REP_enc = -1;
309 static gint ett_krb_EncTicketPart = -1;
310 static gint ett_krb_EncAPRepPart = -1;
311 static gint ett_krb_EncKrbPrivPart = -1;
312 static gint ett_krb_EncKrbCredPart = -1;
313 static gint ett_krb_EncKDCRepPart = -1;
314 static gint ett_krb_LastReq = -1;
315 static gint ett_krb_Authenticator = -1;
316 static gint ett_krb_Checksum = -1;
317 static gint ett_krb_key = -1;
318 static gint ett_krb_subkey = -1;
319 static gint ett_krb_AuthorizationData = -1;
320 static gint ett_krb_sname = -1;
321 static gint ett_krb_pname = -1;
322 static gint ett_krb_cname = -1;
323 static gint ett_krb_AP_REP_enc = -1;
324 static gint ett_krb_padata = -1;
325 static gint ett_krb_etypes = -1;
326 static gint ett_krb_KrbCredInfos = -1;
327 static gint ett_krb_sq_tickets = -1;
328 static gint ett_krb_LastReqs = -1;
329 static gint ett_krb_IF_RELEVANT = -1;
330 static gint ett_krb_PA_DATA_tree = -1;
331 static gint ett_krb_PAC = -1;
332 static gint ett_krb_s_address = -1;
333 static gint ett_krb_r_address = -1;
334 static gint ett_krb_KrbCredInfo = -1;
335 static gint ett_krb_HostAddress = -1;
336 static gint ett_krb_HostAddresses = -1;
337 static gint ett_krb_authenticator_enc = -1;
338 static gint ett_krb_CRED_enc = -1;
339 static gint ett_krb_AP_Options = -1;
340 static gint ett_krb_KDC_Options = -1;
341 static gint ett_krb_Ticket_Flags = -1;
342 static gint ett_krb_request = -1;
343 static gint ett_krb_recordmark = -1;
344 static gint ett_krb_ticket = -1;
345 static gint ett_krb_ticket_enc = -1;
346 static gint ett_krb_CRED = -1;
347 static gint ett_krb_PRIV = -1;
348 static gint ett_krb_PRIV_enc = -1;
349 static gint ett_krb_e_checksum = -1;
350 static gint ett_krb_PAC_MIDL_BLOB = -1;
351 static gint ett_krb_PAC_DREP = -1;
352 static gint ett_krb_PAC_UPN_DNS_INFO = -1;
353
354 guint32 krb5_errorcode;
355
356
357 static dissector_handle_t krb4_handle=NULL;
358
359 static gboolean gbl_do_col_info;
360
361
362 static void
363 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag)
364 {
365         kerberos_callbacks *cb=(kerberos_callbacks *)pinfo->private_data;
366
367         if(!cb){
368                 return;
369         }
370
371         while(cb->tag){
372                 if(cb->tag==tag){
373                         cb->callback(pinfo, tvb, tree);
374                         return;
375                 }
376                 cb++;
377         }
378         return;
379 }
380
381
382
383 #ifdef HAVE_KERBEROS
384
385 /* Decrypt Kerberos blobs */
386 gboolean krb_decrypt = FALSE;
387
388 /* keytab filename */
389 static const char *keytab_filename = "insert filename here";
390
391 void read_keytab_file(const char *);
392
393 void
394 read_keytab_file_from_preferences(void)
395 {
396         static char *last_keytab = NULL;
397
398         if (!krb_decrypt) {
399                 return;
400         }
401
402         if (keytab_filename == NULL) {
403                 return;
404         }
405
406         if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
407                 return;
408         }
409
410         if (last_keytab != NULL) {
411                 g_free(last_keytab);
412                 last_keytab = NULL;
413         }
414         last_keytab = g_strdup(keytab_filename);
415
416         read_keytab_file(last_keytab);
417 }
418
419 #elif defined(_WIN32)
420
421 /*  Dummy version to allow us to put this function in libwireshark.def--even
422  *  on systems without KERBEROS.
423  */
424 void
425 read_keytab_file_from_preferences(void)
426 {
427 }
428
429 #endif
430
431 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
432 #ifdef _WIN32
433 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
434 #undef HAVE_STDARG_H
435 #undef HAVE_SYS_TYPES_H
436 #endif
437 #include <krb5.h>
438 enc_key_t *enc_key_list=NULL;
439
440 static void
441 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
442 {
443         enc_key_t *new_key;
444
445         if(pinfo->fd->flags.visited){
446                 return;
447         }
448 printf("added key in %u    keytype:%d len:%d\n",pinfo->fd->num, keytype, keylength);
449
450         new_key=g_malloc(sizeof(enc_key_t));
451         g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->fd->num);
452         new_key->next=enc_key_list;
453         enc_key_list=new_key;
454         new_key->keytype=keytype;
455         new_key->keylength=keylength;
456         /*XXX this needs to be freed later */
457         new_key->keyvalue=g_memdup(keyvalue, keylength);
458 }
459 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
460
461 #if defined(_WIN32) && !defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_MIT_KERBEROS) && !defined(HAVE_LIBNETTLE)
462 void
463 read_keytab_file(const char *filename _U_)
464 {
465 }
466 #endif
467
468 #ifdef HAVE_MIT_KERBEROS
469
470 static krb5_context krb5_ctx;
471
472 void
473 read_keytab_file(const char *filename)
474 {
475         krb5_keytab keytab;
476         krb5_error_code ret;
477         krb5_keytab_entry key;
478         krb5_kt_cursor cursor;
479         enc_key_t *new_key;
480         static gboolean first_time=TRUE;
481
482         printf("read keytab file %s\n", filename);
483         if(first_time){
484                 first_time=FALSE;
485                 ret = krb5_init_context(&krb5_ctx);
486                 if(ret && ret != KRB5_CONFIG_CANTOPEN){
487                         return;
488                 }
489         }
490
491         /* should use a file in the wireshark users dir */
492         ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
493         if(ret){
494                 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
495
496                 return;
497         }
498
499         ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
500         if(ret){
501                 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
502                 return;
503         }
504
505         do{
506                 new_key=g_malloc(sizeof(enc_key_t));
507                 new_key->next=enc_key_list;
508                 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
509                 if(ret==0){
510                         int i;
511                         char *pos;
512
513                         /* generate origin string, describing where this key came from */
514                         pos=new_key->key_origin;
515                         pos+=MIN(KRB_MAX_ORIG_LEN,
516                                  g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
517                         for(i=0;i<key.principal->length;i++){
518                                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
519                                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),(key.principal->data[i]).data));
520                         }
521                         pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
522                                  g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm.data));
523                         *pos=0;
524 /*printf("added key for principal :%s\n", new_key->key_origin);*/
525                         new_key->keytype=key.key.enctype;
526                         new_key->keylength=key.key.length;
527                         new_key->keyvalue=g_memdup(key.key.contents, key.key.length);
528                         enc_key_list=new_key;
529                 }
530         }while(ret==0);
531
532         ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
533         if(ret){
534                 krb5_kt_close(krb5_ctx, keytab);
535         }
536
537 }
538
539
540 guint8 *
541 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
542                         int usage,
543                         tvbuff_t *cryptotvb,
544                         int keytype,
545                         int *datalen)
546 {
547         krb5_error_code ret;
548         enc_key_t *ek;
549         krb5_data data = {0,0,NULL};
550         krb5_keytab_entry key;
551         int length = tvb_length(cryptotvb);
552         const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
553
554         /* don't do anything if we are not attempting to decrypt data */
555         if(!krb_decrypt || length < 1){
556                 return NULL;
557         }
558
559         /* make sure we have all the data we need */
560         if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
561                 return NULL;
562         }
563
564         read_keytab_file_from_preferences();
565         data.data = g_malloc(length);
566         data.length = length;
567
568         for(ek=enc_key_list;ek;ek=ek->next){
569                 krb5_enc_data input;
570
571                 /* shortcircuit and bail out if enctypes are not matching */
572                 if((keytype != -1) && (ek->keytype != keytype)) {
573                         continue;
574                 }
575
576                 input.enctype = ek->keytype;
577                 input.ciphertext.length = length;
578                 input.ciphertext.data = (guint8 *)cryptotext;
579
580                 key.key.enctype=ek->keytype;
581                 key.key.length=ek->keylength;
582                 key.key.contents=ek->keyvalue;
583                 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
584                 if(ret == 0){
585                         char *user_data;
586                         
587                         expert_add_info_format(pinfo, NULL, PI_SECURITY, PI_CHAT,
588                                                "Decrypted keytype %d in frame %u using %s",
589                                                ek->keytype, pinfo->fd->num, ek->key_origin);
590
591                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
592                         /* return a private g_malloced blob to the caller */
593                         user_data=data.data;
594                         if (datalen) {
595                                 *datalen = data.length;
596                         }
597                         return user_data;
598                 }
599         }
600         g_free(data.data);
601
602         return NULL;
603 }
604
605 #elif defined(HAVE_HEIMDAL_KERBEROS)
606 static krb5_context krb5_ctx;
607
608 void
609 read_keytab_file(const char *filename)
610 {
611         krb5_keytab keytab;
612         krb5_error_code ret;
613         krb5_keytab_entry key;
614         krb5_kt_cursor cursor;
615         enc_key_t *new_key;
616         static gboolean first_time=TRUE;
617
618         if(first_time){
619                 first_time=FALSE;
620                 ret = krb5_init_context(&krb5_ctx);
621                 if(ret){
622                         return;
623                 }
624         }
625
626         /* should use a file in the wireshark users dir */
627         ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
628         if(ret){
629                 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
630
631                 return;
632         }
633
634         ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
635         if(ret){
636                 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
637                 return;
638         }
639
640         do{
641                 new_key=g_malloc(sizeof(enc_key_t));
642                 new_key->next=enc_key_list;
643                 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
644                 if(ret==0){
645                         unsigned int i;
646                         char *pos;
647
648                         /* generate origin string, describing where this key came from */
649                         pos=new_key->key_origin;
650                         pos+=MIN(KRB_MAX_ORIG_LEN,
651                                  g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
652                         for(i=0;i<key.principal->name.name_string.len;i++){
653                                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
654                                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
655                         }
656                         pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
657                                  g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
658                         *pos=0;
659                         new_key->keytype=key.keyblock.keytype;
660                         new_key->keylength=key.keyblock.keyvalue.length;
661                         new_key->keyvalue=g_memdup(key.keyblock.keyvalue.data, key.keyblock.keyvalue.length);
662                         enc_key_list=new_key;
663                 }
664         }while(ret==0);
665
666         ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
667         if(ret){
668                 krb5_kt_close(krb5_ctx, keytab);
669         }
670
671 }
672
673
674 guint8 *
675 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
676                         int usage,
677                         tvbuff_t *cryptotvb,
678                         int keytype,
679                         int *datalen)
680 {
681         krb5_error_code ret;
682         krb5_data data;
683         enc_key_t *ek;
684         int length = tvb_length(cryptotvb);
685         const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
686
687         /* don't do anything if we are not attempting to decrypt data */
688         if(!krb_decrypt){
689                 return NULL;
690         }
691
692         /* make sure we have all the data we need */
693         if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
694                 return NULL;
695         }
696
697         read_keytab_file_from_preferences();
698
699         for(ek=enc_key_list;ek;ek=ek->next){
700                 krb5_keytab_entry key;
701                 krb5_crypto crypto;
702                 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
703
704                 /* shortcircuit and bail out if enctypes are not matching */
705                 if((keytype != -1) && (ek->keytype != keytype)) {
706                         continue;
707                 }
708
709                 key.keyblock.keytype=ek->keytype;
710                 key.keyblock.keyvalue.length=ek->keylength;
711                 key.keyblock.keyvalue.data=ek->keyvalue;
712                 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), 0, &crypto);
713                 if(ret){
714                         return NULL;
715                 }
716
717                 /* pre-0.6.1 versions of Heimdal would sometimes change
718                   the cryptotext data even when the decryption failed.
719                   This would obviously not work since we iterate over the
720                   keys. So just give it a copy of the crypto data instead.
721                   This has been seen for RC4-HMAC blobs.
722                 */
723                 cryptocopy=g_memdup(cryptotext, length);
724                 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
725                                 cryptocopy, length,
726                                 &data,
727                                 NULL);
728                 g_free(cryptocopy);
729                 if((ret == 0) && (length>0)){
730                         char *user_data;
731
732 printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
733                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
734                         krb5_crypto_destroy(krb5_ctx, crypto);
735                         /* return a private g_malloced blob to the caller */
736                         user_data=g_memdup(data.data, data.length);
737                         if (datalen) {
738                                 *datalen = data.length;
739                         }
740                         return user_data;
741                 }
742                 krb5_crypto_destroy(krb5_ctx, crypto);
743         }
744         return NULL;
745 }
746
747 #elif defined (HAVE_LIBNETTLE)
748
749 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
750 #define KEYTYPE_DES3_CBC_MD5 5  /* Currently the only one supported */
751
752 typedef struct _service_key_t {
753     guint16 kvno;
754     int     keytype;
755     int     length;
756     guint8 *contents;
757     char    origin[KRB_MAX_ORIG_LEN+1];
758 } service_key_t;
759 GSList *service_key_list = NULL;
760
761
762 static void
763 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
764 {
765         service_key_t *new_key;
766
767         if(pinfo->fd->flags.visited){
768                 return;
769         }
770 printf("added key in %u\n",pinfo->fd->num);
771
772         new_key = g_malloc(sizeof(service_key_t));
773         new_key->kvno = 0;
774         new_key->keytype = keytype;
775         new_key->length = keylength;
776         new_key->contents = g_memdup(keyvalue, keylength);
777         g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->fd->num);
778         service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
779 }
780
781 static void
782 clear_keytab(void) {
783         GSList *ske;
784         service_key_t *sk;
785
786         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
787                 sk = (service_key_t *) ske->data;
788                 if (sk) {
789                         g_free(sk->contents);
790                         g_free(sk);
791                 }
792         }
793         g_slist_free(service_key_list);
794         service_key_list = NULL;
795 }
796
797 static void
798 read_keytab_file(const char *service_key_file)
799 {
800         FILE *skf;
801         struct stat st;
802         service_key_t *sk;
803         unsigned char buf[SERVICE_KEY_SIZE];
804         int newline_skip = 0, count = 0;
805
806         if (service_key_file != NULL && ws_stat (service_key_file, &st) == 0) {
807
808                 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
809                  * There can be zero, one (\n), or two (\r\n) characters between
810                  * keys.  Trailing characters are ignored.
811                  */
812
813                 /* XXX We should support the standard keytab format instead */
814                 if (st.st_size > SERVICE_KEY_SIZE) {
815                         if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
816                              (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
817                             newline_skip = 1;
818                         } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
819                              (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
820                             newline_skip = 2;
821                         }
822                 }
823
824                 skf = ws_fopen(service_key_file, "rb");
825                 if (! skf) return;
826
827                 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
828                         sk = g_malloc(sizeof(service_key_t));
829                         sk->kvno = buf[0] << 8 | buf[1];
830                         sk->keytype = KEYTYPE_DES3_CBC_MD5;
831                         sk->length = DES3_KEY_SIZE;
832                         sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
833                         g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
834                         service_key_list = g_slist_append(service_key_list, (gpointer) sk);
835                         fseek(skf, newline_skip, SEEK_CUR);
836                         count++;
837 g_warning("added key: %s", sk->origin);
838                 }
839                 fclose(skf);
840         }
841 }
842
843 #define CONFOUNDER_PLUS_CHECKSUM 24
844
845 guint8 *
846 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
847                         int _U_ usage,
848                         tvbuff_t *cryptotvb,
849                         int keytype,
850                         int *datalen)
851 {
852         tvbuff_t *encr_tvb;
853         guint8 *decrypted_data = NULL, *plaintext = NULL;
854         int res;
855         guint8 cls;
856         gboolean pc;
857         guint32 tag, item_len, data_len;
858         int id_offset, offset;
859         guint8 key[DES3_KEY_SIZE];
860         guint8 initial_vector[DES_BLOCK_SIZE];
861         md5_state_t md5s;
862         md5_byte_t digest[16];
863         md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
864         md5_byte_t confounder[8];
865         gboolean ind;
866         GSList *ske;
867         service_key_t *sk;
868         struct des3_ctx ctx;
869         int length = tvb_length(cryptotvb);
870         const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
871
872
873         /* don't do anything if we are not attempting to decrypt data */
874         if(!krb_decrypt){
875                 return NULL;
876         }
877
878         /* make sure we have all the data we need */
879         if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
880                 return NULL;
881         }
882
883         if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
884                 return NULL;
885         }
886
887         decrypted_data = g_malloc(length);
888         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
889                 gboolean do_continue = FALSE;
890                 sk = (service_key_t *) ske->data;
891
892                 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
893
894                 md5_init(&md5s);
895                 memset(initial_vector, 0, DES_BLOCK_SIZE);
896                 res = des3_set_key(&ctx, key);
897                 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
898                     length, decrypted_data, cryptotext);
899                 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
900
901                 tvb_memcpy(encr_tvb, confounder, 0, 8);
902
903                 /* We have to pull the decrypted data length from the decrypted
904                  * content.  If the key doesn't match or we otherwise get garbage,
905                  * an exception may get thrown while decoding the ASN.1 header.
906                  * Catch it, just in case.
907                  */
908                 TRY {
909                         id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
910                         offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
911                 }
912                 CATCH (BoundsError) {
913                         tvb_free(encr_tvb);
914                         do_continue = TRUE;
915                 }
916                 ENDTRY;
917
918                 if (do_continue) continue;
919
920                 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
921                 if ((int) item_len + offset > length) {
922                         tvb_free(encr_tvb);
923                         continue;
924                 }
925
926                 md5_append(&md5s, confounder, 8);
927                 md5_append(&md5s, zero_fill, 16);
928                 md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
929                 md5_finish(&md5s, digest);
930
931                 if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) {
932 g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
933                         plaintext = g_malloc(data_len);
934                         tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
935                         tvb_free(encr_tvb);
936
937                         if (datalen) {
938                                 *datalen = data_len;
939                         }
940                         g_free(decrypted_data);
941                         return(plaintext);
942                 }
943         }
944
945         g_free(decrypted_data);
946         return NULL;
947 }
948
949
950 #endif  /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
951
952 #define INET6_ADDRLEN   16
953
954 /* TCP Record Mark */
955 #define KRB_RM_RESERVED 0x80000000L
956 #define KRB_RM_RECLEN   0x7fffffffL
957
958 #define KRB5_MSG_TICKET                 1       /* Ticket */
959 #define KRB5_MSG_AUTHENTICATOR          2       /* Authenticator */
960 #define KRB5_MSG_ENC_TICKET_PART        3       /* EncTicketPart */
961 #define KRB5_MSG_AS_REQ                 10      /* AS-REQ type */
962 #define KRB5_MSG_AS_REP                 11      /* AS-REP type */
963 #define KRB5_MSG_TGS_REQ                12      /* TGS-REQ type */
964 #define KRB5_MSG_TGS_REP                13      /* TGS-REP type */
965 #define KRB5_MSG_AP_REQ                 14      /* AP-REQ type */
966 #define KRB5_MSG_AP_REP                 15      /* AP-REP type */
967
968 #define KRB5_MSG_SAFE                   20      /* KRB-SAFE type */
969 #define KRB5_MSG_PRIV                   21      /* KRB-PRIV type */
970 #define KRB5_MSG_CRED                   22      /* KRB-CRED type */
971 #define KRB5_MSG_ENC_AS_REP_PART        25      /* EncASRepPart */
972 #define KRB5_MSG_ENC_TGS_REP_PART       26      /* EncTGSRepPart */
973 #define KRB5_MSG_ENC_AP_REP_PART        27      /* EncAPRepPart */
974 #define KRB5_MSG_ENC_KRB_PRIV_PART      28      /* EncKrbPrivPart */
975 #define KRB5_MSG_ENC_KRB_CRED_PART      29      /* EncKrbCredPart */
976 #define KRB5_MSG_ERROR                  30      /* KRB-ERROR type */
977
978 /* address type constants */
979 #define KRB5_ADDR_IPv4       0x02
980 #define KRB5_ADDR_CHAOS      0x05
981 #define KRB5_ADDR_XEROX      0x06
982 #define KRB5_ADDR_ISO        0x07
983 #define KRB5_ADDR_DECNET     0x0c
984 #define KRB5_ADDR_APPLETALK  0x10
985 #define KRB5_ADDR_NETBIOS    0x14
986 #define KRB5_ADDR_IPv6       0x18
987
988 /* encryption type constants */
989 #define KRB5_ENCTYPE_NULL                0
990 #define KRB5_ENCTYPE_DES_CBC_CRC         1
991 #define KRB5_ENCTYPE_DES_CBC_MD4         2
992 #define KRB5_ENCTYPE_DES_CBC_MD5         3
993 #define KRB5_ENCTYPE_DES_CBC_RAW         4
994 #define KRB5_ENCTYPE_DES3_CBC_SHA        5
995 #define KRB5_ENCTYPE_DES3_CBC_RAW        6
996 #define KRB5_ENCTYPE_DES_HMAC_SHA1       8
997 #define KRB5_ENCTYPE_DSA_SHA1_CMS        9
998 #define KRB5_ENCTYPE_RSA_MD5_CMS         10
999 #define KRB5_ENCTYPE_RSA_SHA1_CMS        11
1000 #define KRB5_ENCTYPE_RC2_CBC_ENV         12
1001 #define KRB5_ENCTYPE_RSA_ENV             13
1002 #define KRB5_ENCTYPE_RSA_ES_OEAP_ENV     14
1003 #define KRB5_ENCTYPE_DES_EDE3_CBC_ENV    15
1004 #define KRB5_ENCTYPE_DES3_CBC_SHA1       16
1005 #define KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96 17
1006 #define KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96 18
1007 #define KRB5_ENCTYPE_DES_CBC_MD5_NT      20
1008 #define KERB_ENCTYPE_RC4_HMAC            23
1009 #define KERB_ENCTYPE_RC4_HMAC_EXP        24
1010 #define KRB5_ENCTYPE_UNKNOWN                0x1ff
1011 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1   0x7007
1012 #define KRB5_ENCTYPE_RC4_PLAIN_EXP      0xffffff73
1013 #define KRB5_ENCTYPE_RC4_PLAIN          0xffffff74
1014 #define KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP  0xffffff78
1015 #define KRB5_ENCTYPE_RC4_HMAC_OLD_EXP   0xffffff79
1016 #define KRB5_ENCTYPE_RC4_PLAIN_OLD      0xffffff7a
1017 #define KRB5_ENCTYPE_RC4_HMAC_OLD       0xffffff7b
1018 #define KRB5_ENCTYPE_DES_PLAIN          0xffffff7c
1019 #define KRB5_ENCTYPE_RC4_SHA            0xffffff7d
1020 #define KRB5_ENCTYPE_RC4_LM             0xffffff7e
1021 #define KRB5_ENCTYPE_RC4_PLAIN2         0xffffff7f
1022 #define KRB5_ENCTYPE_RC4_MD4            0xffffff80
1023
1024 /* checksum types */
1025 #define KRB5_CHKSUM_NONE                0
1026 #define KRB5_CHKSUM_CRC32               1
1027 #define KRB5_CHKSUM_MD4                 2
1028 #define KRB5_CHKSUM_KRB_DES_MAC         4
1029 #define KRB5_CHKSUM_KRB_DES_MAC_K       5
1030 #define KRB5_CHKSUM_MD5                 7
1031 #define KRB5_CHKSUM_MD5_DES             8
1032 /* the following four come from packetcable */
1033 #define KRB5_CHKSUM_MD5_DES3            9
1034 #define KRB5_CHKSUM_HMAC_SHA1_DES3_KD   12
1035 #define KRB5_CHKSUM_HMAC_SHA1_DES3      13
1036 #define KRB5_CHKSUM_SHA1_UNKEYED        14
1037 #define KRB5_CHKSUM_HMAC_MD5            0xffffff76
1038 #define KRB5_CHKSUM_MD5_HMAC            0xffffff77
1039 #define KRB5_CHKSUM_RC4_MD5             0xffffff78
1040 #define KRB5_CHKSUM_MD25                0xffffff79
1041 #define KRB5_CHKSUM_DES_MAC_MD5         0xffffff7a
1042 #define KRB5_CHKSUM_DES_MAC             0xffffff7b
1043 #define KRB5_CHKSUM_REAL_CRC32          0xffffff7c
1044 #define KRB5_CHKSUM_SHA1                0xffffff7d
1045 #define KRB5_CHKSUM_LM                  0xffffff7e
1046 #define KRB5_CHKSUM_GSSAPI              0x8003
1047
1048 /*
1049  * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
1050  *
1051  *      http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
1052  *
1053  * unless it's expired.
1054  */
1055
1056 /* pre-authentication type constants */
1057 #define KRB5_PA_TGS_REQ                1
1058 #define KRB5_PA_ENC_TIMESTAMP          2
1059 #define KRB5_PA_PW_SALT                3
1060 #define KRB5_PA_ENC_ENCKEY             4
1061 #define KRB5_PA_ENC_UNIX_TIME          5
1062 #define KRB5_PA_ENC_SANDIA_SECURID     6
1063 #define KRB5_PA_SESAME                 7
1064 #define KRB5_PA_OSF_DCE                8
1065 #define KRB5_PA_CYBERSAFE_SECUREID     9
1066 #define KRB5_PA_AFS3_SALT              10
1067 #define KRB5_PA_ENCTYPE_INFO           11
1068 #define KRB5_PA_SAM_CHALLENGE          12
1069 #define KRB5_PA_SAM_RESPONSE           13
1070 #define KRB5_PA_PK_AS_REQ              14
1071 #define KRB5_PA_PK_AS_REP              15
1072 #define KRB5_PA_DASS                   16
1073 #define KRB5_PA_ENCTYPE_INFO2          19
1074 #define KRB5_PA_USE_SPECIFIED_KVNO     20
1075 #define KRB5_PA_SAM_REDIRECT           21
1076 #define KRB5_PA_GET_FROM_TYPED_DATA    22
1077 #define KRB5_PA_SAM_ETYPE_INFO         23
1078 #define KRB5_PA_ALT_PRINC              24
1079 #define KRB5_PA_SAM_CHALLENGE2         30
1080 #define KRB5_PA_SAM_RESPONSE2          31
1081 #define KRB5_TD_PKINIT_CMS_CERTIFICATES 101
1082 #define KRB5_TD_KRB_PRINCIPAL          102
1083 #define KRB5_TD_KRB_REALM              103
1084 #define KRB5_TD_TRUSTED_CERTIFIERS     104
1085 #define KRB5_TD_CERTIFICATE_INDEX      105
1086 #define KRB5_TD_APP_DEFINED_ERROR      106
1087 #define KRB5_TD_REQ_NONCE              107
1088 #define KRB5_TD_REQ_SEQ                108
1089 /* preauthentication types >127 (i.e. negative ones) are app specific.
1090    Hopefully there will be no collisions here or we will have to
1091    come up with something better.
1092    XXX: Although KRB5_PA_PAC_REQUEST is " >127 " and thus presumably
1093          would be encoded as a negative number, various captures seen all
1094          have this pa-data-type encoded as a positive number (0x0080).
1095          We'll assume that KRB5_PA_S4U2SELF is also encoded as a positive number.
1096 */
1097 #define KRB5_PA_PAC_REQUEST              128    /* (Microsoft extension) */
1098 #define KRB5_PA_S4U2SELF                 129    /* Impersonation (Microsoft extension) */
1099
1100 #define KRB5_PA_PROV_SRV_LOCATION 0xffffffff    /* (gint32)0xFF) packetcable stuff */
1101
1102 /* Principal name-type */
1103 #define KRB5_NT_UNKNOWN        0
1104 #define KRB5_NT_PRINCIPAL      1
1105 #define KRB5_NT_SRV_INST       2
1106 #define KRB5_NT_SRV_HST        3
1107 #define KRB5_NT_SRV_XHST       4
1108 #define KRB5_NT_UID            5
1109 #define KRB5_NT_X500_PRINCIPAL 6
1110 #define KRB5_NT_SMTP_NAME      7
1111 #define KRB5_NT_ENTERPRISE    10
1112
1113 /*
1114  * MS specific name types, from
1115  *
1116  *      http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
1117  */
1118 #define KRB5_NT_MS_PRINCIPAL            -128
1119 #define KRB5_NT_MS_PRINCIPAL_AND_SID    -129
1120 #define KRB5_NT_ENT_PRINCIPAL_AND_SID   -130
1121 #define KRB5_NT_PRINCIPAL_AND_SID       -131
1122 #define KRB5_NT_SRV_INST_AND_SID        -132
1123
1124 /* error table constants */
1125 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
1126 #define KRB5_ET_KRB5KDC_ERR_NONE                         0
1127 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP                     1
1128 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP                  2
1129 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO                     3
1130 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO              4
1131 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO              5
1132 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN          6
1133 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN          7
1134 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE         8
1135 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY                     9
1136 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE              10
1137 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID                  11
1138 #define KRB5_ET_KRB5KDC_ERR_POLICY                       12
1139 #define KRB5_ET_KRB5KDC_ERR_BADOPTION                    13
1140 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP                 14
1141 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP               15
1142 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP           16
1143 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP                17
1144 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED               18
1145 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED              19
1146 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED                  20
1147 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET                21
1148 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET               22
1149 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP                      23
1150 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED               24
1151 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED             25
1152 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH               26
1153 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER           27
1154 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED            28
1155 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE              29
1156 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY             31
1157 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED               32
1158 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV                   33
1159 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT                    34
1160 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US                    35
1161 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH                  36
1162 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW                      37
1163 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR                   38
1164 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION                39
1165 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE                  40
1166 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED                  41
1167 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER                  42
1168 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT                43
1169 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER                 44
1170 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY                     45
1171 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL                  46
1172 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION              47
1173 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD                    48
1174 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ                    49
1175 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM               50
1176 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED             51
1177 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG             52
1178 #define KRB5_ET_KRB5KRB_ERR_GENERIC                      60
1179 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG                61
1180 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED             62
1181 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED                63
1182 #define KRB5_ET_KDC_ERROR_INVALID_SIG                    64
1183 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK                     65
1184 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH             66
1185 #define KRB5_ET_KRB_AP_ERR_NO_TGT                        67
1186 #define KRB5_ET_KDC_ERR_WRONG_REALM                      68
1187 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED         69
1188 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE          70
1189 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE              71
1190 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE              72
1191 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN        73
1192 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE    74
1193 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH             75
1194 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH                76
1195
1196 static const value_string krb5_error_codes[] = {
1197         { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
1198         { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
1199         { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
1200         { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
1201         { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
1202         { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
1203         { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
1204         { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
1205         { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
1206         { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
1207         { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
1208         { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
1209         { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
1210         { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
1211         { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
1212         { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
1213         { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
1214         { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
1215         { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
1216         { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
1217         { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
1218         { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
1219         { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
1220         { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
1221         { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
1222         { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
1223         { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1224         { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1225         { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1226         { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1227         { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1228         { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1229         { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1230         { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1231         { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1232         { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1233         { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1234         { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1235         { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1236         { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1237         { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1238         { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1239         { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1240         { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1241         { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1242         { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1243         { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1244         { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1245         { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1246         { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1247         { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1248         { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1249         { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1250         { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1251         { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1252         { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1253         { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1254         { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1255         { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1256         { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1257         { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1258         { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1259         { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1260         { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1261         { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1262         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1263         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1264         { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1265         { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1266         { 0, NULL }
1267 };
1268
1269
1270 #define PAC_LOGON_INFO          1
1271 #define PAC_CREDENTIAL_TYPE     2
1272 #define PAC_SERVER_CHECKSUM     6
1273 #define PAC_PRIVSVR_CHECKSUM    7
1274 #define PAC_CLIENT_INFO_TYPE    10
1275 #define PAC_CONSTRAINED_DELEGATION 11
1276 #define PAC_UPN_DNS_INFO        12
1277 static const value_string w2k_pac_types[] = {
1278     { PAC_LOGON_INFO            , "Logon Info" },
1279     { PAC_CREDENTIAL_TYPE       , "Credential Type" },
1280     { PAC_SERVER_CHECKSUM       , "Server Checksum" },
1281     { PAC_PRIVSVR_CHECKSUM      , "Privsvr Checksum" },
1282     { PAC_CLIENT_INFO_TYPE      , "Client Info Type" },
1283     { PAC_CONSTRAINED_DELEGATION, "Constrained Delegation" },
1284     { PAC_UPN_DNS_INFO          , "UPN DNS Info" },
1285     { 0, NULL },
1286 };
1287
1288
1289
1290 static const value_string krb5_princ_types[] = {
1291     { KRB5_NT_UNKNOWN              , "Unknown" },
1292     { KRB5_NT_PRINCIPAL            , "Principal" },
1293     { KRB5_NT_SRV_INST             , "Service and Instance" },
1294     { KRB5_NT_SRV_HST              , "Service and Host" },
1295     { KRB5_NT_SRV_XHST             , "Service and Host Components" },
1296     { KRB5_NT_UID                  , "Unique ID" },
1297     { KRB5_NT_X500_PRINCIPAL       , "Encoded X.509 Distinguished Name" },
1298     { KRB5_NT_SMTP_NAME            , "SMTP Name" },
1299     { KRB5_NT_ENTERPRISE           , "Enterprise Name" },
1300     { KRB5_NT_MS_PRINCIPAL         , "NT 4.0 style name (MS specific)" },
1301     { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
1302     { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
1303     { KRB5_NT_PRINCIPAL_AND_SID    , "Principal name and SID (MS specific)"},
1304     { KRB5_NT_SRV_INST_AND_SID     , "SPN and SID (MS specific)"},
1305     { 0                            , NULL },
1306 };
1307
1308 static const value_string krb5_preauthentication_types[] = {
1309     { KRB5_PA_TGS_REQ              , "PA-TGS-REQ" },
1310     { KRB5_PA_ENC_TIMESTAMP        , "PA-ENC-TIMESTAMP" },
1311     { KRB5_PA_PW_SALT              , "PA-PW-SALT" },
1312     { KRB5_PA_ENC_ENCKEY           , "PA-ENC-ENCKEY" },
1313     { KRB5_PA_ENC_UNIX_TIME        , "PA-ENC-UNIX-TIME" },
1314     { KRB5_PA_ENC_SANDIA_SECURID   , "PA-PW-SALT" },
1315     { KRB5_PA_SESAME               , "PA-SESAME" },
1316     { KRB5_PA_OSF_DCE              , "PA-OSF-DCE" },
1317     { KRB5_PA_CYBERSAFE_SECUREID   , "PA-CYBERSAFE-SECURID" },
1318     { KRB5_PA_AFS3_SALT            , "PA-AFS3-SALT" },
1319     { KRB5_PA_ENCTYPE_INFO         , "PA-ENCTYPE-INFO" },
1320     { KRB5_PA_ENCTYPE_INFO2         , "PA-ENCTYPE-INFO2" },
1321     { KRB5_PA_SAM_CHALLENGE        , "PA-SAM-CHALLENGE" },
1322     { KRB5_PA_SAM_RESPONSE         , "PA-SAM-RESPONSE" },
1323     { KRB5_PA_PK_AS_REQ            , "PA-PK-AS-REQ" },
1324     { KRB5_PA_PK_AS_REP            , "PA-PK-AS-REP" },
1325     { KRB5_PA_DASS                 , "PA-DASS" },
1326     { KRB5_PA_USE_SPECIFIED_KVNO   , "PA-USE-SPECIFIED-KVNO" },
1327     { KRB5_PA_SAM_REDIRECT         , "PA-SAM-REDIRECT" },
1328     { KRB5_PA_GET_FROM_TYPED_DATA  , "PA-GET-FROM-TYPED-DATA" },
1329     { KRB5_PA_SAM_ETYPE_INFO       , "PA-SAM-ETYPE-INFO" },
1330     { KRB5_PA_ALT_PRINC            , "PA-ALT-PRINC" },
1331     { KRB5_PA_SAM_CHALLENGE2       , "PA-SAM-CHALLENGE2" },
1332     { KRB5_PA_SAM_RESPONSE2        , "PA-SAM-RESPONSE2" },
1333     { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
1334     { KRB5_TD_KRB_PRINCIPAL        , "TD-KRB-PRINCIPAL" },
1335     { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
1336     { KRB5_TD_TRUSTED_CERTIFIERS   , "TD-TRUSTED-CERTIFIERS" },
1337     { KRB5_TD_CERTIFICATE_INDEX    , "TD-CERTIFICATE-INDEX" },
1338     { KRB5_TD_APP_DEFINED_ERROR    , "TD-APP-DEFINED-ERROR" },
1339     { KRB5_TD_REQ_NONCE            , "TD-REQ-NONCE" },
1340     { KRB5_TD_REQ_SEQ              , "TD-REQ-SEQ" },
1341     { KRB5_PA_PAC_REQUEST          , "PA-PAC-REQUEST" },
1342     { KRB5_PA_S4U2SELF             , "PA-S4U2SELF" },
1343     { KRB5_PA_PROV_SRV_LOCATION    , "PA-PROV-SRV-LOCATION" },
1344     { 0                            , NULL },
1345 };
1346
1347 static const value_string krb5_encryption_types[] = {
1348     { KRB5_ENCTYPE_NULL           , "NULL" },
1349     { KRB5_ENCTYPE_DES_CBC_CRC    , "des-cbc-crc" },
1350     { KRB5_ENCTYPE_DES_CBC_MD4    , "des-cbc-md4" },
1351     { KRB5_ENCTYPE_DES_CBC_MD5    , "des-cbc-md5" },
1352     { KRB5_ENCTYPE_DES_CBC_RAW    , "des-cbc-raw" },
1353     { KRB5_ENCTYPE_DES3_CBC_SHA   , "des3-cbc-sha" },
1354     { KRB5_ENCTYPE_DES3_CBC_RAW   , "des3-cbc-raw" },
1355     { KRB5_ENCTYPE_DES_HMAC_SHA1  , "des-hmac-sha1" },
1356     { KRB5_ENCTYPE_DSA_SHA1_CMS   , "dsa-sha1-cms" },
1357     { KRB5_ENCTYPE_RSA_MD5_CMS    , "rsa-md5-cms" },
1358     { KRB5_ENCTYPE_RSA_SHA1_CMS   , "rsa-sha1-cms" },
1359     { KRB5_ENCTYPE_RC2_CBC_ENV    , "rc2-cbc-env" },
1360     { KRB5_ENCTYPE_RSA_ENV        , "rsa-env" },
1361     { KRB5_ENCTYPE_RSA_ES_OEAP_ENV, "rsa-es-oeap-env" },
1362     { KRB5_ENCTYPE_DES_EDE3_CBC_ENV, "des-ede3-cbc-env" },
1363     { KRB5_ENCTYPE_DES3_CBC_SHA1  , "des3-cbc-sha1" },
1364     { KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96  , "aes128-cts-hmac-sha1-96" },
1365     { KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96  , "aes256-cts-hmac-sha1-96" },
1366     { KRB5_ENCTYPE_DES_CBC_MD5_NT  , "des-cbc-md5-nt" },
1367     { KERB_ENCTYPE_RC4_HMAC       , "rc4-hmac" },
1368     { KERB_ENCTYPE_RC4_HMAC_EXP   , "rc4-hmac-exp" },
1369     { KRB5_ENCTYPE_UNKNOWN        , "unknown" },
1370     { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1    , "local-des3-hmac-sha1" },
1371     { KRB5_ENCTYPE_RC4_PLAIN_EXP  , "rc4-plain-exp" },
1372     { KRB5_ENCTYPE_RC4_PLAIN      , "rc4-plain" },
1373     { KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP, "rc4-plain-old-exp" },
1374     { KRB5_ENCTYPE_RC4_HMAC_OLD_EXP, "rc4-hmac-old-exp" },
1375     { KRB5_ENCTYPE_RC4_PLAIN_OLD  , "rc4-plain-old" },
1376     { KRB5_ENCTYPE_RC4_HMAC_OLD   , "rc4-hmac-old" },
1377     { KRB5_ENCTYPE_DES_PLAIN      , "des-plain" },
1378     { KRB5_ENCTYPE_RC4_SHA        , "rc4-sha" },
1379     { KRB5_ENCTYPE_RC4_LM         , "rc4-lm" },
1380     { KRB5_ENCTYPE_RC4_PLAIN2     , "rc4-plain2" },
1381     { KRB5_ENCTYPE_RC4_MD4        , "rc4-md4" },
1382     { 0                           , NULL },
1383 };
1384
1385 static const value_string krb5_checksum_types[] = {
1386     { KRB5_CHKSUM_NONE            , "none" },
1387     { KRB5_CHKSUM_CRC32           , "crc32" },
1388     { KRB5_CHKSUM_MD4             , "md4" },
1389     { KRB5_CHKSUM_KRB_DES_MAC     , "krb-des-mac" },
1390     { KRB5_CHKSUM_KRB_DES_MAC_K   , "krb-des-mac-k" },
1391     { KRB5_CHKSUM_MD5             , "md5" },
1392     { KRB5_CHKSUM_MD5_DES         , "md5-des" },
1393     { KRB5_CHKSUM_MD5_DES3        , "md5-des3" },
1394     { KRB5_CHKSUM_HMAC_SHA1_DES3_KD, "hmac-sha1-des3-kd" },
1395     { KRB5_CHKSUM_HMAC_SHA1_DES3  , "hmac-sha1-des3" },
1396     { KRB5_CHKSUM_SHA1_UNKEYED    , "sha1 (unkeyed)" },
1397     { KRB5_CHKSUM_HMAC_MD5        , "hmac-md5" },
1398     { KRB5_CHKSUM_MD5_HMAC        , "md5-hmac" },
1399     { KRB5_CHKSUM_RC4_MD5         , "rc5-md5" },
1400     { KRB5_CHKSUM_MD25            , "md25" },
1401     { KRB5_CHKSUM_DES_MAC_MD5     , "des-mac-md5" },
1402     { KRB5_CHKSUM_DES_MAC         , "des-mac" },
1403     { KRB5_CHKSUM_REAL_CRC32      , "real-crc32" },
1404     { KRB5_CHKSUM_SHA1            , "sha1" },
1405     { KRB5_CHKSUM_LM              , "lm" },
1406     { KRB5_CHKSUM_GSSAPI          , "gssapi-8003" },
1407     { 0                           , NULL },
1408 };
1409
1410 #define KRB5_AD_IF_RELEVANT                     1
1411 #define KRB5_AD_INTENDED_FOR_SERVER             2
1412 #define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS  3
1413 #define KRB5_AD_KDC_ISSUED                      4
1414 #define KRB5_AD_OR                              5
1415 #define KRB5_AD_MANDATORY_TICKET_EXTENSIONS     6
1416 #define KRB5_AD_IN_TICKET_EXTENSIONS            7
1417 #define KRB5_AD_MANDATORY_FOR_KDC               8
1418 #define KRB5_AD_OSF_DCE                         64
1419 #define KRB5_AD_SESAME                          65
1420 #define KRB5_AD_OSF_DCE_PKI_CERTID              66
1421 #define KRB5_AD_WIN2K_PAC                               128
1422 #define KRB5_AD_SIGNTICKET                      0xffffffef
1423 static const value_string krb5_ad_types[] = {
1424     { KRB5_AD_IF_RELEVANT                       , "AD-IF-RELEVANT" },
1425     { KRB5_AD_INTENDED_FOR_SERVER               , "AD-Intended-For-Server" },
1426     { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS    , "AD-Intended-For-Application-Class" },
1427     { KRB5_AD_KDC_ISSUED                        , "AD-KDCIssued" },
1428     { KRB5_AD_OR                                , "AD-AND-OR" },
1429     { KRB5_AD_MANDATORY_TICKET_EXTENSIONS       , "AD-Mandatory-Ticket-Extensions" },
1430     { KRB5_AD_IN_TICKET_EXTENSIONS              , "AD-IN-Ticket-Extensions" },
1431     { KRB5_AD_MANDATORY_FOR_KDC                 , "AD-MANDATORY-FOR-KDC" },
1432     { KRB5_AD_OSF_DCE                           , "AD-OSF-DCE" },
1433     { KRB5_AD_SESAME                            , "AD-SESAME" },
1434     { KRB5_AD_OSF_DCE_PKI_CERTID                , "AD-OSF-DCE-PKI-CertID" },
1435     { KRB5_AD_WIN2K_PAC                         , "AD-Win2k-PAC" },
1436     { KRB5_AD_SIGNTICKET                        , "AD-SignTicket" },
1437     { 0 , NULL },
1438 };
1439
1440 static const value_string krb5_transited_types[] = {
1441     { 1                           , "DOMAIN-X500-COMPRESS" },
1442     { 0                           , NULL }
1443 };
1444
1445 static const value_string krb5_address_types[] = {
1446     { KRB5_ADDR_IPv4,           "IPv4"},
1447     { KRB5_ADDR_CHAOS,          "CHAOS"},
1448     { KRB5_ADDR_XEROX,          "XEROX"},
1449     { KRB5_ADDR_ISO,            "ISO"},
1450     { KRB5_ADDR_DECNET,         "DECNET"},
1451     { KRB5_ADDR_APPLETALK,      "APPLETALK"},
1452     { KRB5_ADDR_NETBIOS,        "NETBIOS"},
1453     { KRB5_ADDR_IPv6,           "IPv6"},
1454     { 0,                        NULL },
1455 };
1456
1457 static const value_string krb5_msg_types[] = {
1458         { KRB5_MSG_TICKET,              "Ticket" },
1459         { KRB5_MSG_AUTHENTICATOR,       "Authenticator" },
1460         { KRB5_MSG_ENC_TICKET_PART,     "EncTicketPart" },
1461         { KRB5_MSG_TGS_REQ,             "TGS-REQ" },
1462         { KRB5_MSG_TGS_REP,             "TGS-REP" },
1463         { KRB5_MSG_AS_REQ,              "AS-REQ" },
1464         { KRB5_MSG_AS_REP,              "AS-REP" },
1465         { KRB5_MSG_AP_REQ,              "AP-REQ" },
1466         { KRB5_MSG_AP_REP,              "AP-REP" },
1467         { KRB5_MSG_SAFE,                "KRB-SAFE" },
1468         { KRB5_MSG_PRIV,                "KRB-PRIV" },
1469         { KRB5_MSG_CRED,                "KRB-CRED" },
1470         { KRB5_MSG_ENC_AS_REP_PART,     "EncASRepPart" },
1471         { KRB5_MSG_ENC_TGS_REP_PART,    "EncTGSRepPart" },
1472         { KRB5_MSG_ENC_AP_REP_PART,     "EncAPRepPart" },
1473         { KRB5_MSG_ENC_KRB_PRIV_PART,   "EncKrbPrivPart" },
1474         { KRB5_MSG_ENC_KRB_CRED_PART,   "EncKrbCredPart" },
1475         { KRB5_MSG_ERROR,               "KRB-ERROR" },
1476         { 0, NULL },
1477 };
1478
1479
1480
1481
1482 static int dissect_krb5_application_choice(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1483 static int dissect_krb5_Application_1(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1484 static int dissect_krb5_Authenticator(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1485 static int dissect_krb5_EncTicketPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1486 static int dissect_krb5_EncAPRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1487 static int dissect_krb5_EncKrbPrivPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1488 static int dissect_krb5_EncKrbCredPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1489 static int dissect_krb5_EncKDCRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1490 static int dissect_krb5_KDC_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1491 static int dissect_krb5_KDC_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1492 static int dissect_krb5_AP_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1493 static int dissect_krb5_AP_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1494 static int dissect_krb5_SAFE(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1495 static int dissect_krb5_PRIV(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1496 static int dissect_krb5_CRED(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1497 static int dissect_krb5_ERROR(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
1498
1499 static const ber_old_choice_t kerberos_applications_choice[] = {
1500         { KRB5_MSG_TICKET,      BER_CLASS_APP,  KRB5_MSG_TICKET,        0, dissect_krb5_Application_1 },
1501         { KRB5_MSG_AUTHENTICATOR,       BER_CLASS_APP,  KRB5_MSG_AUTHENTICATOR, 0, dissect_krb5_Authenticator },
1502         { KRB5_MSG_ENC_TICKET_PART, BER_CLASS_APP,      KRB5_MSG_ENC_TICKET_PART, 0, dissect_krb5_EncTicketPart },
1503         { KRB5_MSG_AS_REQ,      BER_CLASS_APP,  KRB5_MSG_AS_REQ,        0,      dissect_krb5_KDC_REQ },
1504         { KRB5_MSG_AS_REP,      BER_CLASS_APP,  KRB5_MSG_AS_REP,        0,      dissect_krb5_KDC_REP },
1505         { KRB5_MSG_TGS_REQ,     BER_CLASS_APP,  KRB5_MSG_TGS_REQ,       0,      dissect_krb5_KDC_REQ },
1506         { KRB5_MSG_TGS_REP,     BER_CLASS_APP,  KRB5_MSG_TGS_REP,       0,      dissect_krb5_KDC_REP },
1507         { KRB5_MSG_AP_REQ,      BER_CLASS_APP,  KRB5_MSG_AP_REQ,        0,      dissect_krb5_AP_REQ },
1508         { KRB5_MSG_AP_REP,      BER_CLASS_APP,  KRB5_MSG_AP_REP,        0,      dissect_krb5_AP_REP },
1509         { KRB5_MSG_ENC_AS_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_AS_REP_PART, 0, dissect_krb5_EncKDCRepPart },
1510         { KRB5_MSG_ENC_TGS_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_TGS_REP_PART, 0, dissect_krb5_EncKDCRepPart },
1511         { KRB5_MSG_ENC_AP_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_AP_REP_PART, 0, dissect_krb5_EncAPRepPart },
1512         { KRB5_MSG_ENC_KRB_PRIV_PART, BER_CLASS_APP, KRB5_MSG_ENC_KRB_PRIV_PART, 0, dissect_krb5_EncKrbPrivPart },
1513         { KRB5_MSG_ENC_KRB_CRED_PART, BER_CLASS_APP, KRB5_MSG_ENC_KRB_CRED_PART, 0, dissect_krb5_EncKrbCredPart },
1514         { KRB5_MSG_SAFE,        BER_CLASS_APP,  KRB5_MSG_SAFE,          0,      dissect_krb5_SAFE },
1515         { KRB5_MSG_PRIV,        BER_CLASS_APP,  KRB5_MSG_PRIV,          0,      dissect_krb5_PRIV },
1516         { KRB5_MSG_CRED,        BER_CLASS_APP,  KRB5_MSG_CRED,          0,      dissect_krb5_CRED },
1517         { KRB5_MSG_ERROR,       BER_CLASS_APP,  KRB5_MSG_ERROR,         0,      dissect_krb5_ERROR },
1518         { 0, 0, 0, 0, NULL }
1519 };
1520
1521
1522 static int
1523 dissect_krb5_application_choice(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1524 {
1525         offset=dissect_ber_old_choice(actx, tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
1526         return offset;
1527 }
1528
1529
1530 static const true_false_string krb5_apoptions_use_session_key = {
1531         "USE SESSION KEY to encrypt the ticket",
1532         "Do NOT use the session key to encrypt the ticket"
1533 };
1534 static const true_false_string krb5_apoptions_mutual_required = {
1535         "MUTUAL authentication is REQUIRED",
1536         "Mutual authentication is NOT required"
1537 };
1538
1539 static int *APOptions_bits[] = {
1540   &hf_krb_APOptions_use_session_key,
1541   &hf_krb_APOptions_mutual_required,
1542   NULL
1543 };
1544 static int
1545 dissect_krb5_APOptions(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1546 {
1547         offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, APOptions_bits, hf_krb_APOptions, ett_krb_AP_Options, NULL);
1548         return offset;
1549 }
1550
1551
1552
1553 static const true_false_string krb5_kdcoptions_forwardable = {
1554         "FORWARDABLE tickets are allowed/requested",
1555         "Do NOT use forwardable tickets"
1556 };
1557 static const true_false_string krb5_kdcoptions_forwarded = {
1558         "This ticket has been FORWARDED",
1559         "This is NOT a forwarded ticket"
1560 };
1561 static const true_false_string krb5_kdcoptions_proxiable = {
1562         "PROXIABLE tickets are allowed/requested",
1563         "Do NOT use proxiable tickets"
1564 };
1565 static const true_false_string krb5_kdcoptions_proxy = {
1566         "This is a PROXY ticket",
1567         "This ticket has NOT been proxied"
1568 };
1569 static const true_false_string krb5_kdcoptions_allow_postdate = {
1570         "We allow the ticket to be POSTDATED",
1571         "We do NOT allow the ticket to be postdated"
1572 };
1573 static const true_false_string krb5_kdcoptions_postdated = {
1574         "This ticket is POSTDATED",
1575         "This ticket is NOT postdated"
1576 };
1577 static const true_false_string krb5_kdcoptions_renewable = {
1578         "This ticket is RENEWABLE",
1579         "This ticket is NOT renewable"
1580 };
1581 static const true_false_string krb5_kdcoptions_constrained_delegation = {
1582         "This is a request for a CONSTRAINED DELEGATION PAC",
1583         "This is a normal request (no constrained delegation)"
1584 };
1585 static const true_false_string krb5_kdcoptions_canonicalize = {
1586         "This is a request for a CANONICALIZED ticket",
1587         "This is NOT a canonicalized ticket request"
1588 };
1589 static const true_false_string krb5_kdcoptions_disable_transited_check = {
1590         "Transited checking is DISABLED",
1591         "Transited checking is NOT disabled"
1592 };
1593 static const true_false_string krb5_kdcoptions_renewable_ok = {
1594         "We accept RENEWED tickets",
1595         "We do NOT accept renewed tickets"
1596 };
1597 static const true_false_string krb5_kdcoptions_enc_tkt_in_skey = {
1598         "ENCrypt TKT in SKEY",
1599         "Do NOT encrypt the tkt inside the skey"
1600 };
1601 static const true_false_string krb5_kdcoptions_renew = {
1602         "This is a request to RENEW a ticket",
1603         "This is NOT a request to renew a ticket"
1604 };
1605 static const true_false_string krb5_kdcoptions_validate = {
1606         "This is a request to VALIDATE a postdated ticket",
1607         "This is NOT a request to validate a postdated ticket"
1608 };
1609
1610 static int* KDCOptions_bits[] = {
1611   &hf_krb_KDCOptions_forwardable,
1612   &hf_krb_KDCOptions_forwarded,
1613   &hf_krb_KDCOptions_proxiable,
1614   &hf_krb_KDCOptions_proxy,
1615   &hf_krb_KDCOptions_allow_postdate,
1616   &hf_krb_KDCOptions_postdated,
1617   &hf_krb_KDCOptions_renewable,
1618   &hf_krb_KDCOptions_opt_hardware_auth,
1619   &hf_krb_KDCOptions_constrained_delegation,
1620   &hf_krb_KDCOptions_canonicalize,
1621   &hf_krb_KDCOptions_disable_transited_check,
1622   &hf_krb_KDCOptions_renewable_ok,
1623   &hf_krb_KDCOptions_enc_tkt_in_skey,
1624   &hf_krb_KDCOptions_renew,
1625   &hf_krb_KDCOptions_validate,
1626   NULL
1627 };
1628
1629 static int
1630 dissect_krb5_KDCOptions(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1631 {
1632         offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, KDCOptions_bits, hf_krb_KDCOptions, ett_krb_KDC_Options, NULL);
1633         return offset;
1634 }
1635
1636 static int
1637 dissect_krb5_rtime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1638 {
1639         offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_rtime);
1640         return offset;
1641 }
1642
1643 int
1644 dissect_krb5_ctime(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_ctime);
1647         return offset;
1648 }
1649 static int
1650 dissect_krb5_cusec(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_cusec, NULL);
1653         return offset;
1654 }
1655
1656 static int
1657 dissect_krb5_stime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1658 {
1659         offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_stime);
1660         return offset;
1661 }
1662 static int
1663 dissect_krb5_susec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1664 {
1665         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_susec, NULL);
1666         return offset;
1667 }
1668
1669
1670 static int
1671 dissect_krb5_error_code(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1672 {
1673         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_error_code, &krb5_errorcode);
1674         if(krb5_errorcode && check_col(actx->pinfo->cinfo, COL_INFO)) {
1675                 col_add_fstr(actx->pinfo->cinfo, COL_INFO,
1676                         "KRB Error: %s",
1677                         val_to_str(krb5_errorcode, krb5_error_codes,
1678                         "Unknown error code %#x"));
1679         }
1680
1681         return offset;
1682 }
1683
1684
1685 static int
1686 dissect_krb5_till(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1687 {
1688         offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_till);
1689         return offset;
1690 }
1691 static int
1692 dissect_krb5_from(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1693 {
1694         offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_from);
1695         return offset;
1696 }
1697
1698
1699
1700 static int
1701 dissect_krb5_nonce(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1702 {
1703         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_nonce, NULL);
1704         return offset;
1705 }
1706
1707
1708 /*
1709  *          etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
1710  */
1711 static int
1712 dissect_krb5_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1713 {
1714         guint32 etype;
1715
1716         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &etype);
1717         if(tree){
1718                 proto_item_append_text(tree, " %s",
1719                         val_to_str(etype, krb5_encryption_types,
1720                         "%d"));
1721         }
1722         return offset;
1723 }
1724 static ber_old_sequence_t etype_sequence_of[1] = {
1725   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_krb5_etype },
1726 };
1727 static int
1728 dissect_krb5_etype_sequence_of(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1729 {
1730         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, etype_sequence_of, hf_krb_etypes, ett_krb_etypes);
1731
1732         return offset;
1733 }
1734 static guint32 authenticator_etype;
1735 static int
1736 dissect_krb5_authenticator_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1737 {
1738         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &authenticator_etype);
1739         if(tree){
1740                 proto_item_append_text(tree, " %s",
1741                         val_to_str(authenticator_etype, krb5_encryption_types,
1742                         "%#x"));
1743         }
1744         return offset;
1745 }
1746 static guint32 Ticket_etype;
1747 static int
1748 dissect_krb5_Ticket_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1749 {
1750         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &Ticket_etype);
1751         if(tree){
1752                 proto_item_append_text(tree, " %s",
1753                         val_to_str(Ticket_etype, krb5_encryption_types,
1754                         "%#x"));
1755         }
1756         return offset;
1757 }
1758 static guint32 AP_REP_etype;
1759 static int
1760 dissect_krb5_AP_REP_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1761 {
1762         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &AP_REP_etype);
1763         if(tree){
1764                 proto_item_append_text(tree, " %s",
1765                         val_to_str(AP_REP_etype, krb5_encryption_types,
1766                         "%#x"));
1767         }
1768         return offset;
1769 }
1770 static guint32 PA_ENC_TIMESTAMP_etype;
1771 static int
1772 dissect_krb5_PA_ENC_TIMESTAMP_etype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1773 {
1774         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_etype, &PA_ENC_TIMESTAMP_etype);
1775         if(tree){
1776                 proto_item_append_text(tree, " %s",
1777                         val_to_str(PA_ENC_TIMESTAMP_etype, krb5_encryption_types,
1778                         "%#x"));
1779         }
1780         return offset;
1781 }
1782
1783
1784 /*
1785  *  HostAddress ::=    SEQUENCE  {
1786  *                     addr-type[0]             INTEGER,
1787  *                     address[1]               OCTET STRING
1788  *  }
1789  */
1790 static guint32 addr_type;
1791 static int dissect_krb5_addr_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1792 {
1793         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_addr_type, &addr_type);
1794         return offset;
1795 }
1796
1797 #define ADDRESS_STR_BUFSIZ 256
1798 static int dissect_krb5_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1799 {
1800         gint8 class;
1801         gboolean pc;
1802         gint32 tag;
1803         guint32 len;
1804         char *address_str;
1805         proto_item *it=NULL;
1806
1807         /* read header and len for the octet string */
1808         offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
1809         offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL);
1810
1811         address_str=ep_alloc(ADDRESS_STR_BUFSIZ);
1812         address_str[0]='\0';
1813         switch(addr_type){
1814         case KRB5_ADDR_IPv4:
1815                 it=proto_tree_add_item(tree, hf_krb_address_ip, tvb, offset, 4, FALSE);
1816                 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));
1817                 break;
1818         case KRB5_ADDR_NETBIOS:
1819                 {
1820                 char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1821                 int netbios_name_type;
1822                 int netbios_name_len = (NETBIOS_NAME_LEN - 1)*4 + 1;
1823
1824                 netbios_name_type = process_netbios_name(tvb_get_ptr(tvb, offset, 16), netbios_name, netbios_name_len);
1825                 g_snprintf(address_str, ADDRESS_STR_BUFSIZ, "%s<%02x>", netbios_name, netbios_name_type);
1826                 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));
1827                 }
1828                 break;
1829         case KRB5_ADDR_IPv6:
1830                 it=proto_tree_add_item(tree, hf_krb_address_ipv6, tvb, offset, INET6_ADDRLEN, FALSE);
1831                 g_snprintf(address_str, ADDRESS_STR_BUFSIZ, "%s", ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, INET6_ADDRLEN)));
1832                 break;
1833         default:
1834                 proto_tree_add_text(tree, tvb, offset, len, "KRB Address: I don't know how to parse this type of address yet");
1835
1836         }
1837
1838         /* push it up two levels in the decode pane */
1839         if(it){
1840                 proto_item_append_text(proto_item_get_parent(it), " %s",address_str);
1841                 proto_item_append_text(proto_item_get_parent_nth(it, 2), " %s",address_str);
1842         }
1843
1844         offset+=len;
1845         return offset;
1846 }
1847 static ber_old_sequence_t HostAddress_sequence[] = {
1848         { BER_CLASS_CON, 0, 0, dissect_krb5_addr_type },
1849         { BER_CLASS_CON, 1, 0, dissect_krb5_address },
1850         { 0, 0, 0, NULL }
1851 };
1852 static int
1853 dissect_krb5_HostAddress(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1854 {
1855
1856         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_HostAddress, ett_krb_HostAddress);
1857
1858         return offset;
1859 }
1860 static int
1861 dissect_krb5_s_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1862 {
1863
1864         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_s_address, ett_krb_s_address);
1865
1866         return offset;
1867 }
1868
1869 static int
1870 dissect_krb5_r_address(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1871 {
1872
1873         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, HostAddress_sequence, hf_krb_r_address, ett_krb_r_address);
1874
1875         return offset;
1876 }
1877
1878 /*
1879  *  HostAddresses ::=   SEQUENCE OF SEQUENCE {
1880  *                      addr-type[0]             INTEGER,
1881  *                      address[1]               OCTET STRING
1882  *  }
1883  *
1884  */
1885 static ber_old_sequence_t HostAddresses_sequence_of[1] = {
1886   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_HostAddress },
1887 };
1888 static int
1889 dissect_krb5_HostAddresses(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, HostAddresses_sequence_of, hf_krb_HostAddresses, ett_krb_HostAddresses);
1892
1893         return offset;
1894 }
1895
1896
1897 /* sequence of tickets */
1898 static ber_old_sequence_t sequence_of_tickets[1] = {
1899   { BER_CLASS_APP, 1, 0, dissect_krb5_Application_1},
1900 };
1901 static int
1902 dissect_krb5_sq_tickets(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1903 {
1904         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, sequence_of_tickets, hf_krb_sq_tickets, ett_krb_sq_tickets);
1905
1906         return offset;
1907 }
1908
1909 static int
1910 dissect_krb5_msg_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1911 {
1912         guint32 msgtype;
1913
1914         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_msg_type, &msgtype);
1915
1916         if (gbl_do_col_info & check_col(actx->pinfo->cinfo, COL_INFO)) {
1917                 col_add_str(actx->pinfo->cinfo, COL_INFO,
1918                         val_to_str(msgtype, krb5_msg_types,
1919                         "Unknown msg type %#x"));
1920         }
1921         gbl_do_col_info=FALSE;
1922
1923         /* append the application type to the subtree */
1924         proto_item_append_text(tree, " %s", val_to_str(msgtype, krb5_msg_types, "Unknown:0x%x"));
1925
1926         return offset;
1927 }
1928
1929
1930
1931 static int
1932 dissect_krb5_pvno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1933 {
1934         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_pvno, NULL);
1935
1936         return offset;
1937 }
1938
1939
1940 /*
1941  * PrincipalName ::=   SEQUENCE {
1942  *                     name-type[0]     INTEGER,
1943  *                     name-string[1]   SEQUENCE OF GeneralString
1944  * }
1945  */
1946 guint32 name_type;
1947 static int
1948 dissect_krb5_name_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1949 {
1950
1951         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_name_type, &name_type);
1952         if(tree){
1953                 proto_item_append_text(tree, " (%s):",
1954                         val_to_str(name_type, krb5_princ_types,
1955                         "Unknown:%d"));
1956         }
1957         return offset;
1958 }
1959 static char name_string_separator;
1960 static int
1961 dissect_krb5_name_string(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1962 {
1963         char name_string[256];
1964
1965         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_name_string, name_string, 255);
1966         if(tree){
1967                 proto_item_append_text(tree, "%c%s", name_string_separator, name_string);
1968                 name_string_separator='/';
1969         }
1970
1971         return offset;
1972 }
1973 static ber_old_sequence_t name_stringe_sequence_of[1] = {
1974   { BER_CLASS_UNI, BER_UNI_TAG_GeneralString, BER_FLAGS_NOOWNTAG, dissect_krb5_name_string },
1975 };
1976 static int
1977 dissect_krb5_name_strings(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1978 {
1979         name_string_separator=' ';
1980         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, name_stringe_sequence_of, -1, -1);
1981
1982         return offset;
1983 }
1984 static ber_old_sequence_t PrincipalName_sequence[] = {
1985         { BER_CLASS_CON, 0, 0, dissect_krb5_name_type },
1986         { BER_CLASS_CON, 1, 0, dissect_krb5_name_strings },
1987         { 0, 0, 0, NULL }
1988 };
1989 static int
1990 dissect_krb5_sname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1991 {
1992
1993         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PrincipalName_sequence, hf_krb_sname, ett_krb_sname);
1994
1995         return offset;
1996 }
1997 static int
1998 dissect_krb5_pname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1999 {
2000
2001         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PrincipalName_sequence, hf_krb_pname, ett_krb_pname);
2002
2003         return offset;
2004 }
2005 int
2006 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2007 {
2008
2009         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PrincipalName_sequence, hf_krb_cname, ett_krb_cname);
2010
2011         return offset;
2012 }
2013
2014
2015 int
2016 dissect_krb5_prealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2017 {
2018         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_prealm, NULL, 0);
2019         return offset;
2020 }
2021
2022 int
2023 dissect_krb5_srealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2024 {
2025         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_srealm, NULL, 0);
2026         return offset;
2027 }
2028
2029 int
2030 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2031 {
2032         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_realm, NULL, 0);
2033         return offset;
2034 }
2035
2036 static int
2037 dissect_krb5_crealm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2038 {
2039         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_crealm, NULL, 0);
2040         return offset;
2041 }
2042
2043
2044
2045 static int
2046 dissect_krb5_PA_PAC_REQUEST_flag(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2047 {
2048         offset=dissect_ber_boolean(FALSE, actx, tree, tvb, offset, hf_krb_PA_PAC_REQUEST_flag, NULL);
2049         return offset;
2050 }
2051
2052
2053 static ber_old_sequence_t PA_PAC_REQUEST_sequence[] = {
2054         { BER_CLASS_CON, 0, 0, dissect_krb5_PA_PAC_REQUEST_flag },
2055         { 0, 0, 0, NULL }
2056 };
2057 static int
2058 dissect_krb5_PA_PAC_REQUEST(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2059 {
2060
2061         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_PAC_REQUEST_sequence, -1, -1);
2062
2063         return offset;
2064 }
2065
2066 static int
2067 dissect_krb5_s4u2self_auth(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2068 {
2069         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_s4u2self_auth, NULL, 0);
2070         return offset;
2071 }
2072
2073 static ber_old_sequence_t PA_S4U2SELF_sequence[] = {
2074         { BER_CLASS_CON, 0, 0, dissect_krb5_cname },
2075         { BER_CLASS_CON, 1, 0, dissect_krb5_realm },
2076         { BER_CLASS_CON, 2, 0, dissect_krb5_Checksum },
2077         { BER_CLASS_CON, 3, 0, dissect_krb5_s4u2self_auth },
2078         { 0, 0, 0, NULL }
2079 };
2080
2081 static int
2082 dissect_krb5_PA_S4U2SELF(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2083 {
2084         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_S4U2SELF_sequence, -1, -1);
2085         return offset;
2086 }
2087
2088
2089 static int
2090 dissect_krb5_PA_PROV_SRV_LOCATION(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2091 {
2092         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
2093
2094         return offset;
2095 }
2096
2097
2098
2099 static int
2100 dissect_krb5_kvno(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2101 {
2102         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_kvno, NULL);
2103
2104         return offset;
2105 }
2106
2107
2108
2109 static int
2110 dissect_krb5_seq_number(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2111 {
2112         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_seq_number, NULL);
2113
2114         return offset;
2115 }
2116
2117
2118
2119 static int
2120 dissect_krb5_patimestamp(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2121 {
2122         offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_patimestamp);
2123         return offset;
2124 }
2125 #ifdef HAVE_KERBEROS
2126 static int
2127 dissect_krb5_pausec(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2128 {
2129         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_pausec, NULL);
2130         return offset;
2131 }
2132 static const ber_old_sequence_t PA_ENC_TS_ENC_sequence[] = {
2133         { BER_CLASS_CON, 0, 0, dissect_krb5_patimestamp },
2134         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_pausec },
2135         { 0, 0, 0, NULL }
2136 };
2137 static int
2138 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2139 {
2140         guint8 *plaintext=NULL;
2141         int length;
2142
2143         length=tvb_length_remaining(tvb, offset);
2144
2145         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
2146          * 7.5.1
2147          * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
2148          * == 1
2149          */
2150         if(!plaintext){
2151                 tvbuff_t *next_tvb;
2152
2153                 next_tvb=tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_remaining(tvb, offset));
2154                 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, PA_ENC_TIMESTAMP_etype, NULL);
2155         }
2156
2157         if(plaintext){
2158                 tvbuff_t *next_tvb;
2159                 next_tvb = tvb_new_child_real_data(tvb, plaintext,
2160                                           length,
2161                                           length);
2162                 tvb_set_free_cb(next_tvb, g_free);
2163
2164                 /* Add the decrypted data to the data source list. */
2165                 add_new_data_source(actx->pinfo, next_tvb, "Decrypted Krb5");
2166
2167
2168                 offset=dissect_ber_old_sequence(FALSE, actx, tree, next_tvb, 0, PA_ENC_TS_ENC_sequence, -1, -1);
2169
2170         }
2171         return offset;
2172 }
2173 #endif
2174
2175
2176 static int
2177 dissect_krb5_encrypted_PA_ENC_TIMESTAMP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2178 {
2179 #ifdef HAVE_KERBEROS
2180         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, dissect_krb5_decrypt_PA_ENC_TIMESTAMP);
2181 #else
2182         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, NULL);
2183 #endif
2184         return offset;
2185 }
2186 static ber_old_sequence_t PA_ENC_TIMESTAMP_sequence[] = {
2187         { BER_CLASS_CON, 0, 0,
2188                 dissect_krb5_PA_ENC_TIMESTAMP_etype },
2189         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2190                 dissect_krb5_kvno },
2191         { BER_CLASS_CON, 2, 0,
2192                 dissect_krb5_encrypted_PA_ENC_TIMESTAMP },
2193         { 0, 0, 0, NULL }
2194 };
2195 static int
2196 dissect_krb5_PA_ENC_TIMESTAMP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2197 {
2198         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENC_TIMESTAMP_sequence, -1, -1);
2199
2200         return offset;
2201 }
2202
2203
2204
2205 static int
2206 dissect_krb5_etype_info_salt(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2207 {
2208         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_etype_info_salt, NULL);
2209         return offset;
2210 }
2211
2212 static int
2213 dissect_krb5_etype_info2_salt(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2214 {
2215         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_etype_info2_salt, NULL, 0);
2216         return offset;
2217 }
2218
2219 static int
2220 dissect_krb5_etype_info2_s2kparams(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2221 {
2222         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_etype_info2_s2kparams, NULL);
2223         return offset;
2224 }
2225
2226 static ber_old_sequence_t PA_ENCTYPE_INFO_ENTRY_sequence[] = {
2227         { BER_CLASS_CON, 0, 0,
2228                 dissect_krb5_etype },
2229         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2230                 dissect_krb5_etype_info_salt },
2231         { 0, 0, 0, NULL }
2232 };
2233 static int
2234 dissect_krb5_PA_ENCTYPE_INFO_ENTRY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2235 {
2236         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO_ENTRY_sequence, -1, -1);
2237
2238         return offset;
2239 }
2240
2241 static ber_old_sequence_t PA_ENCTYPE_INFO_sequence_of[1] = {
2242   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO_ENTRY },
2243 };
2244 static int
2245 dissect_krb5_PA_ENCTYPE_INFO(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2246 {
2247         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO_sequence_of, -1, -1);
2248
2249         return offset;
2250 }
2251
2252 static ber_old_sequence_t PA_ENCTYPE_INFO2_ENTRY_sequence[] = {
2253         { BER_CLASS_CON, 0, 0,
2254                 dissect_krb5_etype },
2255         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2256                 dissect_krb5_etype_info2_salt },
2257         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
2258                 dissect_krb5_etype_info2_s2kparams },
2259         { 0, 0, 0, NULL }
2260 };
2261 static int
2262 dissect_krb5_PA_ENCTYPE_INFO2_ENTRY(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2263 {
2264         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO2_ENTRY_sequence, -1, -1);
2265
2266         return offset;
2267 }
2268
2269 static ber_old_sequence_t PA_ENCTYPE_INFO2_sequence_of[1] = {
2270   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO2_ENTRY },
2271 };
2272 static int
2273 dissect_krb5_PA_ENCTYPE_INFO2(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2274 {
2275         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_ENCTYPE_INFO2_sequence_of, -1, -1);
2276
2277         return offset;
2278 }
2279
2280
2281 static int
2282 dissect_krb5_PW_SALT(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2283 {
2284         guint32 nt_status;
2285
2286         /* Microsoft stores a special 12 byte blob here
2287          * guint32 NT_status
2288          * guint32 unknown
2289          * guint32 unknown
2290          * decode everything as this blob for now until we see if anyone
2291          * else ever uses it   or we learn how to tell whether this
2292          * is such an MS blob or not.
2293          */
2294         proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
2295                         TRUE);
2296         nt_status=tvb_get_letohl(tvb, offset);
2297         if(nt_status && check_col(actx->pinfo->cinfo, COL_INFO)) {
2298                 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
2299                         " NT Status: %s",
2300                         val_to_str(nt_status, NT_errors,
2301                         "Unknown error code %#x"));
2302         }
2303         offset += 4;
2304
2305         proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
2306                         TRUE);
2307         offset += 4;
2308
2309         proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
2310                         TRUE);
2311         offset += 4;
2312
2313         return offset;
2314 }
2315
2316 /*
2317  * PA-DATA ::=        SEQUENCE {
2318  *          padata-type[1]        INTEGER,
2319  *          padata-value[2]       OCTET STRING,
2320  *                        -- might be encoded AP-REQ
2321  * }
2322  */
2323 guint32 krb_PA_DATA_type;
2324 static int
2325 dissect_krb5_PA_DATA_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2326 {
2327         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_PA_DATA_type, &krb_PA_DATA_type);
2328
2329         if(tree){
2330                 proto_item_append_text(tree, " %s",
2331                         val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
2332                         "Unknown:%d"));
2333         }
2334         return offset;
2335 }
2336 static int
2337 dissect_krb5_PA_DATA_value(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2338 {
2339         proto_tree *tree=parent_tree;
2340
2341         if(actx->created_item){
2342                 tree=proto_item_add_subtree(actx->created_item, ett_krb_PA_DATA_tree);
2343         }
2344
2345
2346         switch(krb_PA_DATA_type){
2347         case KRB5_PA_TGS_REQ:
2348                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_application_choice);
2349                 break;
2350         case KRB5_PA_PK_AS_REQ:
2351                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REQ);
2352                 break;
2353         case KRB5_PA_PK_AS_REP:
2354                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REP);
2355                 break;
2356         case KRB5_PA_PAC_REQUEST:
2357                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PAC_REQUEST);
2358                 break;
2359         case KRB5_PA_S4U2SELF:
2360                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_S4U2SELF);
2361                 break;
2362         case KRB5_PA_PROV_SRV_LOCATION:
2363                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PROV_SRV_LOCATION);
2364                 break;
2365         case KRB5_PA_ENC_TIMESTAMP:
2366                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENC_TIMESTAMP);
2367                 break;
2368         case KRB5_PA_ENCTYPE_INFO:
2369                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO);
2370                 break;
2371         case KRB5_PA_ENCTYPE_INFO2:
2372                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO2);
2373                 break;
2374         case KRB5_PA_PW_SALT:
2375                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PW_SALT);
2376                 break;
2377         default:
2378                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset,hf_krb_PA_DATA_value, NULL);
2379         }
2380         return offset;
2381 /*qqq*/
2382 }
2383
2384 static ber_old_sequence_t PA_DATA_sequence[] = {
2385         { BER_CLASS_CON, 1, 0, dissect_krb5_PA_DATA_type },
2386         { BER_CLASS_CON, 2, 0, dissect_krb5_PA_DATA_value },
2387         { 0, 0, 0, NULL }
2388 };
2389 static int
2390 dissect_krb5_PA_DATA(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2391 {
2392         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, PA_DATA_sequence, -1, -1);
2393
2394         return offset;
2395 }
2396
2397
2398
2399
2400 /*
2401  * padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
2402  *
2403  */
2404 static ber_old_sequence_t PA_DATA_sequence_of[1] = {
2405   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_DATA },
2406 };
2407 static int
2408 dissect_krb5_padata(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2409 {
2410         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, PA_DATA_sequence_of, hf_krb_padata, ett_krb_padata);
2411
2412         return offset;
2413 }
2414
2415
2416
2417 static const true_false_string krb5_ticketflags_forwardable = {
2418         "FORWARDABLE tickets are allowed/requested",
2419         "Do NOT use forwardable tickets"
2420 };
2421 static const true_false_string krb5_ticketflags_forwarded = {
2422         "This ticket has been FORWARDED",
2423         "This is NOT a forwarded ticket"
2424 };
2425 static const true_false_string krb5_ticketflags_proxiable = {
2426         "PROXIABLE tickets are allowed/requested",
2427         "Do NOT use proxiable tickets"
2428 };
2429 static const true_false_string krb5_ticketflags_proxy = {
2430         "This is a PROXY ticket",
2431         "This ticket has NOT been proxied"
2432 };
2433 static const true_false_string krb5_ticketflags_allow_postdate = {
2434         "We allow the ticket to be POSTDATED",
2435         "We do NOT allow the ticket to be postdated"
2436 };
2437 static const true_false_string krb5_ticketflags_postdated = {
2438         "This ticket is POSTDATED",
2439         "This ticket is NOT postdated"
2440 };
2441 static const true_false_string krb5_ticketflags_invalid = {
2442         "This ticket is INVALID",
2443         "This ticket is NOT invalid"
2444 };
2445 static const true_false_string krb5_ticketflags_renewable = {
2446         "This ticket is RENEWABLE",
2447         "This ticket is NOT renewable"
2448 };
2449 static const true_false_string krb5_ticketflags_initial = {
2450         "This ticket was granted by AS and not TGT protocol",
2451         "This ticket was granted by TGT and not as protocol"
2452 };
2453 static const true_false_string krb5_ticketflags_pre_auth = {
2454         "The client was PRE-AUTHenticated",
2455         "The client was NOT pre-authenticated"
2456 };
2457 static const true_false_string krb5_ticketflags_hw_auth = {
2458         "The client was authenticated by HardWare",
2459         "The client was NOT authenticated using hardware"
2460 };
2461 static const true_false_string krb5_ticketflags_transited_policy_checked = {
2462         "Kdc has performed TRANSITED POLICY CHECKING",
2463         "Kdc has NOT performed transited policy checking"
2464 };
2465 static const true_false_string krb5_ticketflags_ok_as_delegate = {
2466         "This ticket is OK AS a DELEGATED ticket",
2467         "This ticket is NOT ok as a delegated ticket"
2468 };
2469
2470 static int* TicketFlags_bits[] = {
2471   &hf_krb_TicketFlags_forwardable,
2472   &hf_krb_TicketFlags_forwarded,
2473   &hf_krb_TicketFlags_proxiable,
2474   &hf_krb_TicketFlags_proxy,
2475   &hf_krb_TicketFlags_allow_postdate,
2476   &hf_krb_TicketFlags_postdated,
2477   &hf_krb_TicketFlags_invalid,
2478   &hf_krb_TicketFlags_renewable,
2479   &hf_krb_TicketFlags_initial,
2480   &hf_krb_TicketFlags_pre_auth,
2481   &hf_krb_TicketFlags_hw_auth,
2482   &hf_krb_TicketFlags_transited_policy_checked,
2483   &hf_krb_TicketFlags_ok_as_delegate,
2484   NULL
2485 };
2486
2487 static int
2488 dissect_krb5_TicketFlags(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2489 {
2490         offset=dissect_ber_bitstring32(FALSE, actx, tree, tvb, offset, TicketFlags_bits, hf_krb_TicketFlags, ett_krb_Ticket_Flags, NULL);
2491         return offset;
2492 }
2493
2494
2495 static guint32 keytype;
2496 static int
2497 dissect_krb5_keytype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2498 {
2499         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_keytype, &keytype);
2500         if(tree){
2501                 proto_item_append_text(tree, " %s",
2502                         val_to_str(keytype, krb5_encryption_types,
2503                         "%#x"));
2504         }
2505         return offset;
2506 }
2507 static int keylength;
2508 static const guint8 *keyvalue;
2509 static int
2510 store_keyvalue(proto_tree *tree _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2511 {
2512         keylength=tvb_length_remaining(tvb, offset);
2513         keyvalue=tvb_get_ptr(tvb, offset, keylength);
2514         return 0;
2515 }
2516 static int
2517 dissect_krb5_keyvalue(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2518 {
2519         offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_keyvalue, store_keyvalue);
2520         return offset;
2521 }
2522
2523
2524 /*
2525  * EncryptionKey ::=        SEQUENCE {
2526  *     keytype  [0] int32
2527  *     keyvalue [1] octet string
2528  */
2529 static ber_old_sequence_t EncryptionKey_sequence[] = {
2530         { BER_CLASS_CON, 0, 0,
2531                 dissect_krb5_keytype },
2532         { BER_CLASS_CON, 1, 0,
2533                 dissect_krb5_keyvalue },
2534         { 0, 0, 0, NULL }
2535 };
2536 static int
2537 dissect_krb5_key(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2538 {
2539         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncryptionKey_sequence, hf_krb_key, ett_krb_key);
2540
2541 #ifdef HAVE_KERBEROS
2542         add_encryption_key(actx->pinfo, keytype, keylength, keyvalue, "key");
2543 #endif
2544         return offset;
2545 }
2546 static int
2547 dissect_krb5_subkey(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2548 {
2549         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncryptionKey_sequence, hf_krb_subkey, ett_krb_subkey);
2550 #ifdef HAVE_KERBEROS
2551         add_encryption_key(actx->pinfo, keytype, keylength, keyvalue, "subkey");
2552 #endif
2553         return offset;
2554 }
2555
2556 static int
2557 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
2558 {
2559         proto_item *item=NULL;
2560         proto_tree *tree=NULL;
2561         guint8 val;
2562
2563         if(parent_tree){
2564                 item=proto_tree_add_text(parent_tree, tvb, offset, 16, "DREP");
2565                 tree=proto_item_add_subtree(item, ett_krb_PAC_DREP);
2566         }
2567
2568         val = tvb_get_guint8(tvb, offset);
2569         proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
2570
2571         offset++;
2572
2573         if (drep) {
2574                 *drep = val;
2575         }
2576
2577         return offset;
2578 }
2579
2580 /* This might be some sort of header that MIDL generates when creating
2581  * marshalling/unmarshalling code for blobs that are not to be transported
2582  * ontop of DCERPC and where the DREP fields specifying things such as
2583  * endianess and similar are not available.
2584  */
2585 static int
2586 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
2587 {
2588         proto_item *item=NULL;
2589         proto_tree *tree=NULL;
2590
2591         if(parent_tree){
2592                 item=proto_tree_add_text(parent_tree, tvb, offset, 16, "MES header");
2593                 tree=proto_item_add_subtree(item, ett_krb_PAC_MIDL_BLOB);
2594         }
2595
2596         /* modified DREP field that is used for stuff that is transporetd ontop
2597            of non dcerpc
2598         */
2599         proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, TRUE);
2600         offset++;
2601
2602         offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
2603
2604
2605         proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, TRUE);
2606         offset+=2;
2607
2608         proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4,
2609                         TRUE);
2610         offset += 4;
2611
2612         /* length of blob that follows */
2613         proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8,
2614                         TRUE);
2615         offset += 8;
2616
2617         return offset;
2618 }
2619
2620 static int
2621 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2622 {
2623         proto_item *item=NULL;
2624         proto_tree *tree=NULL;
2625         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2626         static dcerpc_info di;  /* fake dcerpc_info struct */
2627         static dcerpc_call_value call_data;
2628         void *old_private_data;
2629
2630         item=proto_tree_add_item(parent_tree, hf_krb_PAC_LOGON_INFO, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2631         if(parent_tree){
2632                 tree=proto_item_add_subtree(item, ett_krb_PAC_LOGON_INFO);
2633         }
2634
2635         /* skip the first 16 bytes, they are some magic created by the idl
2636          * compiler   the first 4 bytes might be flags?
2637          */
2638         offset=dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2639
2640         /* the PAC_LOGON_INFO blob */
2641         /* fake whatever state the dcerpc runtime support needs */
2642         di.conformant_run=0;
2643         /* we need di->call_data->flags.NDR64 == 0 */
2644         di.call_data=&call_data;
2645         old_private_data=actx->pinfo->private_data;
2646         actx->pinfo->private_data=&di;
2647         init_ndr_pointer_list(actx->pinfo);
2648         offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, drep,
2649                 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
2650                 "PAC_LOGON_INFO:", -1);
2651         actx->pinfo->private_data=old_private_data;
2652
2653         return offset;
2654 }
2655
2656 static int
2657 dissect_krb5_PAC_CONSTRAINED_DELEGATION(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2658 {
2659         proto_item *item=NULL;
2660         proto_tree *tree=NULL;
2661         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2662         static dcerpc_info di;  /* fake dcerpc_info struct */
2663         static dcerpc_call_value call_data;
2664         void *old_private_data;
2665
2666         item=proto_tree_add_item(parent_tree, hf_krb_PAC_CONSTRAINED_DELEGATION, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2667         if(parent_tree){
2668                 tree=proto_item_add_subtree(item, ett_krb_PAC_CONSTRAINED_DELEGATION);
2669         }
2670
2671         /* skip the first 16 bytes, they are some magic created by the idl
2672          * compiler   the first 4 bytes might be flags?
2673          */
2674         offset=dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2675
2676
2677         /* the PAC_CONSTRAINED_DELEGATION blob */
2678         /* fake whatever state the dcerpc runtime support needs */
2679         di.conformant_run=0;
2680         /* we need di->call_data->flags.NDR64 == 0 */
2681         di.call_data=&call_data;
2682         old_private_data=actx->pinfo->private_data;
2683         actx->pinfo->private_data=&di;
2684         init_ndr_pointer_list(actx->pinfo);
2685         offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, drep,
2686                 netlogon_dissect_PAC_CONSTRAINED_DELEGATION, NDR_POINTER_UNIQUE,
2687                 "PAC_CONSTRAINED_DELEGATION:", -1);
2688         actx->pinfo->private_data=old_private_data;
2689
2690         return offset;
2691 }
2692
2693 static int
2694 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2695 {
2696         proto_item *item=NULL;
2697         proto_tree *tree=NULL;
2698         guint16 dns_offset, dns_len;
2699         guint16 upn_offset, upn_len;
2700         const char *dn;
2701         int dn_len;
2702         guint16 bc;
2703
2704         item=proto_tree_add_item(parent_tree, hf_krb_PAC_UPN_DNS_INFO, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2705         if(parent_tree){
2706                 tree=proto_item_add_subtree(item, ett_krb_PAC_UPN_DNS_INFO);
2707         }
2708
2709         /* upn */
2710         upn_len = tvb_get_letohs(tvb, offset);
2711         proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, TRUE);
2712         offset+=2;
2713         upn_offset = tvb_get_letohs(tvb, offset);
2714         proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, TRUE);
2715         offset+=2;
2716
2717         /* dns */
2718         dns_len = tvb_get_letohs(tvb, offset);
2719         proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, TRUE);
2720         offset+=2;
2721         dns_offset = tvb_get_letohs(tvb, offset);
2722         proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, TRUE);
2723         offset+=2;
2724
2725         /* flags */
2726         proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, TRUE);
2727
2728         /* upn */
2729         offset = upn_offset;
2730         dn_len = upn_len;
2731         bc = tvb_length_remaining(tvb, offset);
2732         dn = get_unicode_or_ascii_string(tvb, &offset,
2733                         TRUE, &dn_len, TRUE, TRUE, &bc);
2734         proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
2735
2736         /* dns */
2737         offset = dns_offset;
2738         dn_len = dns_len;
2739         bc = tvb_length_remaining(tvb, offset);
2740         dn = get_unicode_or_ascii_string(tvb, &offset,
2741                         TRUE, &dn_len, TRUE, TRUE, &bc);
2742         proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
2743
2744         return offset;
2745 }
2746
2747 static int
2748 dissect_krb5_PAC_CREDENTIAL_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2749 {
2750         proto_item *item=NULL;
2751         proto_tree *tree=NULL;
2752
2753         item=proto_tree_add_item(parent_tree, hf_krb_PAC_CREDENTIAL_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2754         if(parent_tree){
2755                 tree=proto_item_add_subtree(item, ett_krb_PAC_CREDENTIAL_TYPE);
2756         }
2757
2758 /*qqq*/
2759         return offset;
2760 }
2761
2762 static int
2763 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2764 {
2765         proto_item *item=NULL;
2766         proto_tree *tree=NULL;
2767
2768         item=proto_tree_add_item(parent_tree, hf_krb_PAC_SERVER_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2769         if(parent_tree){
2770                 tree=proto_item_add_subtree(item, ett_krb_PAC_SERVER_CHECKSUM);
2771         }
2772
2773         /* signature type */
2774         proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, TRUE);
2775         offset+=4;
2776
2777         /* signature data */
2778         proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2779
2780         return offset;
2781 }
2782
2783 static int
2784 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2785 {
2786         proto_item *item=NULL;
2787         proto_tree *tree=NULL;
2788
2789         item=proto_tree_add_item(parent_tree, hf_krb_PAC_PRIVSVR_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2790         if(parent_tree){
2791                 tree=proto_item_add_subtree(item, ett_krb_PAC_PRIVSVR_CHECKSUM);
2792         }
2793
2794         /* signature type */
2795         proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, TRUE);
2796         offset+=4;
2797
2798         /* signature data */
2799         proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2800
2801         return offset;
2802 }
2803
2804 static int
2805 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2806 {
2807         proto_item *item=NULL;
2808         proto_tree *tree=NULL;
2809         guint16 namelen;
2810         char *name;
2811
2812         item=proto_tree_add_item(parent_tree, hf_krb_PAC_CLIENT_INFO_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2813         if(parent_tree){
2814                 tree=proto_item_add_subtree(item, ett_krb_PAC_CLIENT_INFO_TYPE);
2815         }
2816
2817         /* clientid */
2818         offset = dissect_nt_64bit_time(tvb, tree, offset,
2819                         hf_krb_pac_clientid);
2820
2821         /* name length */
2822         namelen=tvb_get_letohs(tvb, offset);
2823         proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
2824         offset+=2;
2825
2826         /* client name */
2827         name=tvb_get_ephemeral_faked_unicode(tvb, offset, namelen/2, TRUE);
2828         proto_tree_add_string(tree, hf_krb_pac_clientname, tvb, offset, namelen, name);
2829         offset+=namelen;
2830
2831         return offset;
2832 }
2833
2834 static int
2835 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2836 {
2837         guint32 pac_type;
2838         guint32 pac_size;
2839         guint32 pac_offset;
2840         proto_item *it=NULL;
2841         proto_tree *tr=NULL;
2842         tvbuff_t *next_tvb;
2843
2844         /* type of pac data */
2845         pac_type=tvb_get_letohl(tvb, offset);
2846         it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
2847         if(it){
2848                 tr=proto_item_add_subtree(it, ett_krb_PAC);
2849         }
2850
2851         offset += 4;
2852
2853         /* size of pac data */
2854         pac_size=tvb_get_letohl(tvb, offset);
2855         proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
2856         offset += 4;
2857
2858         /* offset to pac data */
2859         pac_offset=tvb_get_letohl(tvb, offset);
2860         proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
2861         offset += 8;
2862
2863
2864         next_tvb=tvb_new_subset(tvb, pac_offset, pac_size, pac_size);
2865         switch(pac_type){
2866         case PAC_LOGON_INFO:
2867                 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
2868                 break;
2869         case PAC_CREDENTIAL_TYPE:
2870                 dissect_krb5_PAC_CREDENTIAL_TYPE(tr, next_tvb, 0, actx);
2871                 break;
2872         case PAC_SERVER_CHECKSUM:
2873                 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
2874                 break;
2875         case PAC_PRIVSVR_CHECKSUM:
2876                 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
2877                 break;
2878         case PAC_CLIENT_INFO_TYPE:
2879                 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
2880                 break;
2881         case PAC_CONSTRAINED_DELEGATION:
2882                 dissect_krb5_PAC_CONSTRAINED_DELEGATION(tr, next_tvb, 0, actx);
2883                 break;
2884         case PAC_UPN_DNS_INFO:
2885                 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
2886                 break;
2887
2888         default:;
2889 /*qqq*/
2890         }
2891         return offset;
2892 }
2893
2894 static int
2895 dissect_krb5_AD_WIN2K_PAC(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2896 {
2897         guint32 entries;
2898         guint32 version;
2899         guint32 i;
2900
2901         /* first in the PAC structure comes the number of entries */
2902         entries=tvb_get_letohl(tvb, offset);
2903         proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
2904         offset += 4;
2905
2906         /* second comes the version */
2907         version=tvb_get_letohl(tvb, offset);
2908         proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
2909         offset += 4;
2910
2911         for(i=0;i<entries;i++){
2912                 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
2913         }
2914
2915         return offset;
2916 }
2917
2918
2919 int dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx);
2920
2921 static ber_old_sequence_t AD_SIGNTICKET_sequence[] = {
2922         { BER_CLASS_CON, 0, 0,
2923                 dissect_krb5_etype },
2924         { BER_CLASS_CON, 1, 0,
2925                 dissect_krb5_Checksum },
2926         { 0, 0, 0, NULL }
2927 };
2928
2929 /* first seen in traces from vista */
2930 static int
2931 dissect_krb5_AD_SIGNTICKET(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2932 {
2933         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, AD_SIGNTICKET_sequence, -1, -1);
2934
2935         return offset;
2936 }
2937
2938 static guint32 IF_RELEVANT_type;
2939 static int
2940 dissect_krb5_IF_RELEVANT_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2941 {
2942         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_IF_RELEVANT_type, &IF_RELEVANT_type);
2943         if(tree){
2944                 proto_item_append_text(tree, " %s",
2945                         val_to_str(IF_RELEVANT_type, krb5_ad_types,
2946                         "%#x"));
2947         }
2948         return offset;
2949 }
2950 static int
2951 dissect_krb5_IF_RELEVANT_value(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2952 {
2953         switch(IF_RELEVANT_type){
2954         case KRB5_AD_WIN2K_PAC:
2955                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_advalue, dissect_krb5_AD_WIN2K_PAC);
2956                 break;
2957         case KRB5_AD_SIGNTICKET:
2958                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_advalue, dissect_krb5_AD_SIGNTICKET);
2959                 break;
2960         default:
2961                 offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_IF_RELEVANT_value, NULL);
2962         }
2963         return offset;
2964 }
2965 static ber_old_sequence_t IF_RELEVANT_item_sequence[] = {
2966         { BER_CLASS_CON, 0, 0,
2967                 dissect_krb5_IF_RELEVANT_type },
2968         { BER_CLASS_CON, 1, 0,
2969                 dissect_krb5_IF_RELEVANT_value },
2970         { 0, 0, 0, NULL }
2971 };
2972 static int
2973 dissect_krb5_IF_RELEVANT_item(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2974 {
2975         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, IF_RELEVANT_item_sequence, hf_krb_IF_RELEVANT, ett_krb_IF_RELEVANT);
2976
2977         return offset;
2978 }
2979
2980 static ber_old_sequence_t IF_RELEVANT_sequence_of[1] = {
2981   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_IF_RELEVANT_item },
2982 };
2983
2984 static int
2985 dissect_krb5_IF_RELEVANT(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2986 {
2987         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, IF_RELEVANT_sequence_of, -1, -1);
2988
2989         return offset;
2990 }
2991
2992 static guint32 adtype;
2993 static int
2994 dissect_krb5_adtype(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2995 {
2996         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_adtype, &adtype);
2997         if(tree){
2998                 proto_item_append_text(tree, " %s",
2999                         val_to_str(adtype, krb5_ad_types,
3000                         "%#x"));
3001         }
3002         return offset;
3003 }
3004 static int
3005 dissect_krb5_advalue(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3006 {
3007         switch(adtype){
3008         case KRB5_AD_IF_RELEVANT:
3009                 offset=dissect_ber_old_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_krb_advalue, dissect_krb5_IF_RELEVANT);
3010                 break;
3011         default:
3012                 offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_advalue, NULL);
3013         }
3014         return offset;
3015 }
3016 /*
3017  * AuthorizationData ::=        SEQUENCE {
3018  *     ad-type  [0] int32
3019  *     ad-data  [1] octet string
3020  */
3021 static ber_old_sequence_t AuthorizationData_item_sequence[] = {
3022         { BER_CLASS_CON, 0, 0,
3023                 dissect_krb5_adtype },
3024         { BER_CLASS_CON, 1, 0,
3025                 dissect_krb5_advalue },
3026         { 0, 0, 0, NULL }
3027 };
3028 static int
3029 dissect_krb5_AuthorizationData_item(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3030 {
3031         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, AuthorizationData_item_sequence, hf_krb_AuthorizationData, ett_krb_AuthorizationData);
3032
3033         return offset;
3034 }
3035
3036 static ber_old_sequence_t AuthorizationData_sequence_of[1] = {
3037   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_AuthorizationData_item },
3038 };
3039 static int
3040 dissect_krb5_AuthorizationData(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3041 {
3042         offset=dissect_ber_old_sequence_of(FALSE, actx, tree, tvb, offset, AuthorizationData_sequence_of, -1, -1);
3043
3044         return offset;
3045 }
3046
3047
3048 static int
3049 dissect_krb5_transited_type(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3050 {
3051         guint32 trtype;
3052
3053         offset=dissect_ber_integer(FALSE, actx, tree, tvb, offset, hf_krb_transitedtype, &trtype);
3054         if(tree){
3055                 proto_item_append_text(tree, " %s",
3056                         val_to_str(trtype, krb5_transited_types,
3057                         "%#x"));
3058         }
3059         return offset;
3060 }
3061
3062 static int
3063 dissect_krb5_transited_contents(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3064 {
3065         offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_krb_transitedcontents, NULL);
3066         return offset;
3067 }
3068
3069 /*
3070  * TransitedEncoding ::=        SEQUENCE {
3071  *     tr-type  [0] int32
3072  *     contents [1] octet string
3073  */
3074 static ber_old_sequence_t TransitedEncoding_sequence[] = {
3075         { BER_CLASS_CON, 0, 0,
3076                 dissect_krb5_transited_type },
3077         { BER_CLASS_CON, 1, 0,
3078                 dissect_krb5_transited_contents },
3079         { 0, 0, 0, NULL }
3080 };
3081 static int
3082 dissect_krb5_transited(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3083 {
3084         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, TransitedEncoding_sequence, hf_krb_TransitedEncoding, ett_krb_TransitedEncoding);
3085
3086         return offset;
3087 }
3088
3089
3090 static int
3091 dissect_krb5_authtime(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_authtime);
3094         return offset;
3095 }
3096 static int
3097 dissect_krb5_starttime(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_starttime);
3100         return offset;
3101 }
3102 static int
3103 dissect_krb5_endtime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3104 {
3105         offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_endtime);
3106         return offset;
3107 }
3108 static int
3109 dissect_krb5_renew_till(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3110 {
3111         offset=dissect_ber_GeneralizedTime(FALSE, actx, tree, tvb, offset, hf_krb_renew_till);
3112         return offset;
3113 }
3114
3115 /*
3116  * EncTicketPart ::=        SEQUENCE {
3117  *      flags                   [0] TicketFlags,
3118  *      key                     [1] EncryptionKey,
3119  *      crealm                  [2] Realm,
3120  *      cname                   [3] PrincipalName,
3121  *      transited               [4] TransitedEncoding,
3122  *      authtime                [5] KerberosTime,
3123  *      starttime               [6] KerberosTime OPTIONAL,
3124  *      endtime                 [7] KerberosTime,
3125  *      renew-till              [8] KerberosTime OPTIONAL,
3126  *      caddr                   [9] HostAddresses OPTIONAL,
3127  *      authorization-data      [10] AuthorizationData OPTIONAL
3128  * }
3129  */
3130 static ber_old_sequence_t EncTicketPart_sequence[] = {
3131         { BER_CLASS_CON, 0, 0,
3132                 dissect_krb5_TicketFlags },
3133         { BER_CLASS_CON, 1, 0,
3134                 dissect_krb5_key },
3135         { BER_CLASS_CON, 2, 0,
3136                 dissect_krb5_crealm },
3137         { BER_CLASS_CON, 3, 0,
3138                 dissect_krb5_cname },
3139         { BER_CLASS_CON, 4, 0,
3140                 dissect_krb5_transited },
3141         { BER_CLASS_CON, 5, 0,
3142                 dissect_krb5_authtime },
3143         { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
3144                 dissect_krb5_starttime },
3145         { BER_CLASS_CON, 7, 0,
3146                 dissect_krb5_endtime },
3147         { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
3148                 dissect_krb5_renew_till },
3149         { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
3150                 dissect_krb5_HostAddresses },
3151         { BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL,
3152                 dissect_krb5_AuthorizationData },
3153         { 0, 0, 0, NULL }
3154 };
3155 static int
3156 dissect_krb5_EncTicketPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3157 {
3158         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncTicketPart_sequence, hf_krb_EncTicketPart, ett_krb_EncTicketPart);
3159
3160         return offset;
3161 }
3162
3163
3164
3165
3166
3167
3168 /*
3169  * EncAPRepPart ::=        SEQUENCE {
3170  *     ctime                    [0] KerberosTime
3171  *     cusec                    [1] Microseconds
3172  *     subkey                   [2] encryptionKey OPTIONAL
3173  *     seq-number               [3] uint32 OPTIONAL
3174  * }
3175  */
3176 static ber_old_sequence_t EncAPRepPart_sequence[] = {
3177         { BER_CLASS_CON, 0, 0,
3178                 dissect_krb5_ctime },
3179         { BER_CLASS_CON, 1, 0,
3180                 dissect_krb5_cusec },
3181         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
3182                 dissect_krb5_subkey },
3183         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3184                 dissect_krb5_seq_number },
3185         { 0, 0, 0, NULL }
3186 };
3187 static int
3188 dissect_krb5_EncAPRepPart(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
3189 {
3190         offset=dissect_ber_old_sequence(FALSE, actx, tree, tvb, offset, EncAPRepPart_sequence, hf_krb_EncAPRepPart, ett_krb_EncAPRepPart);
3191
3192         return offset;
3193 }
3194
3195
3196
3197 static guint32 lr_type;
3198 static const value_string krb5_lr_types[] = {
3199     { 0              , "No information available" },
3200     { 1              , "Time of last initial TGT request" },
3201     { 2              , "Time of last initial request" },