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