when kerberos claims a conversation, it only claims it for the source port
[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
99 #define UDP_PORT_KERBEROS               88
100 #define TCP_PORT_KERBEROS               88
101
102 static dissector_handle_t kerberos_handle_udp;
103
104 /* Desegment Kerberos over TCP messages */
105 static gboolean krb_desegment = TRUE;
106
107 static gint proto_kerberos = -1;
108 static gint hf_krb_rm_reserved = -1;
109 static gint hf_krb_rm_reclen = -1;
110
111 static gint hf_krb_pac_signature_type = -1;
112 static gint hf_krb_pac_signature_signature = -1;
113 static gint hf_krb_pac_clientid = -1;
114 static gint hf_krb_pac_namelen = -1;
115 static gint hf_krb_pac_clientname = -1;
116 static gint hf_krb_w2k_pac_entries = -1;
117 static gint hf_krb_w2k_pac_version = -1;
118 static gint hf_krb_w2k_pac_type = -1;
119 static gint hf_krb_w2k_pac_size = -1;
120 static gint hf_krb_w2k_pac_offset = -1;
121 static gint hf_krb_padata = -1;
122 static gint hf_krb_error_code = -1;
123 static gint hf_krb_ticket = -1;
124 static gint hf_krb_AP_REP_enc = -1;
125 static gint hf_krb_KDC_REP_enc = -1;
126 static gint hf_krb_tkt_vno = -1;
127 static gint hf_krb_e_data = -1;
128 static gint hf_krb_TransitedEncoding = -1;
129 static gint hf_krb_PA_PAC_REQUEST_flag = -1;
130 static gint hf_krb_encrypted_authenticator_data = -1;
131 static gint hf_krb_PAC_LOGON_INFO = -1;
132 static gint hf_krb_PAC_CREDENTIAL_TYPE = -1;
133 static gint hf_krb_PAC_SERVER_CHECKSUM = -1;
134 static gint hf_krb_PAC_PRIVSVR_CHECKSUM = -1;
135 static gint hf_krb_PAC_CLIENT_INFO_TYPE = -1;
136 static gint hf_krb_encrypted_PA_ENC_TIMESTAMP = -1;
137 static gint hf_krb_checksum_checksum = -1;
138 static gint hf_krb_encrypted_PRIV = -1;
139 static gint hf_krb_encrypted_Ticket_data = -1;
140 static gint hf_krb_encrypted_AP_REP_data = -1;
141 static gint hf_krb_encrypted_KDC_REP_data = -1;
142 static gint hf_krb_PA_DATA_type = -1;
143 static gint hf_krb_PA_DATA_value = -1;
144 static gint hf_krb_etype_info_salt = -1;
145 static gint hf_krb_SAFE_BODY_user_data = -1;
146 static gint hf_krb_PRIV_BODY_user_data = -1;
147 static gint hf_krb_realm = -1;
148 static gint hf_krb_crealm = -1;
149 static gint hf_krb_sname = -1;
150 static gint hf_krb_cname = -1;
151 static gint hf_krb_name_string = -1;
152 static gint hf_krb_provsrv_location = -1;
153 static gint hf_krb_e_text = -1;
154 static gint hf_krb_name_type = -1;
155 static gint hf_krb_lr_type = -1;
156 static gint hf_krb_from = -1;
157 static gint hf_krb_till = -1;
158 static gint hf_krb_authtime = -1;
159 static gint hf_krb_patimestamp = -1;
160 static gint hf_krb_SAFE_BODY_timestamp = -1;
161 static gint hf_krb_pausec = -1;
162 static gint hf_krb_lr_time = -1;
163 static gint hf_krb_starttime = -1;
164 static gint hf_krb_endtime = -1;
165 static gint hf_krb_key_expire = -1;
166 static gint hf_krb_renew_till = -1;
167 static gint hf_krb_rtime = -1;
168 static gint hf_krb_ctime = -1;
169 static gint hf_krb_cusec = -1;
170 static gint hf_krb_stime = -1;
171 static gint hf_krb_susec = -1;
172 static gint hf_krb_SAFE_BODY_usec = -1;
173 static gint hf_krb_nonce = -1;
174 static gint hf_krb_transitedtype = -1;
175 static gint hf_krb_transitedcontents = -1;
176 static gint hf_krb_keytype = -1;
177 static gint hf_krb_keyvalue = -1;
178 static gint hf_krb_IF_RELEVANT_type = -1;
179 static gint hf_krb_IF_RELEVANT_value = -1;
180 static gint hf_krb_adtype = -1;
181 static gint hf_krb_advalue = -1;
182 static gint hf_krb_etype = -1;
183 static gint hf_krb_etypes = -1;
184 static gint hf_krb_LastReqs = -1;
185 static gint hf_krb_IF_RELEVANT = -1;
186 static gint hf_krb_addr_type = -1;
187 static gint hf_krb_address_ip = -1;
188 static gint hf_krb_address_netbios = -1;
189 static gint hf_krb_msg_type = -1;
190 static gint hf_krb_pvno = -1;
191 static gint hf_krb_kvno = -1;
192 static gint hf_krb_checksum_type = -1;
193 static gint hf_krb_authenticator_vno = -1;
194 static gint hf_krb_AuthorizationData = -1;
195 static gint hf_krb_key = -1;
196 static gint hf_krb_subkey = -1;
197 static gint hf_krb_seq_number = -1;
198 static gint hf_krb_EncTicketPart = -1;
199 static gint hf_krb_EncAPRepPart = -1;
200 static gint hf_krb_EncKrbPrivPart = -1;
201 static gint hf_krb_EncKDCRepPart = -1;
202 static gint hf_krb_LastReq = -1;
203 static gint hf_krb_Authenticator = -1;
204 static gint hf_krb_Checksum = -1;
205 static gint hf_krb_s_address = -1;
206 static gint hf_krb_HostAddress = -1;
207 static gint hf_krb_HostAddresses = -1;
208 static gint hf_krb_APOptions = -1;
209 static gint hf_krb_APOptions_use_session_key = -1;
210 static gint hf_krb_APOptions_mutual_required = -1;
211 static gint hf_krb_TicketFlags = -1;
212 static gint hf_krb_TicketFlags_forwardable = -1;
213 static gint hf_krb_TicketFlags_forwarded = -1;
214 static gint hf_krb_TicketFlags_proxyable = -1;
215 static gint hf_krb_TicketFlags_proxy = -1;
216 static gint hf_krb_TicketFlags_allow_postdate = -1;
217 static gint hf_krb_TicketFlags_postdated = -1;
218 static gint hf_krb_TicketFlags_invalid = -1;
219 static gint hf_krb_TicketFlags_renewable = -1;
220 static gint hf_krb_TicketFlags_initial = -1;
221 static gint hf_krb_TicketFlags_pre_auth = -1;
222 static gint hf_krb_TicketFlags_hw_auth = -1;
223 static gint hf_krb_TicketFlags_transited_policy_checked = -1;
224 static gint hf_krb_TicketFlags_ok_as_delegate = -1;
225 static gint hf_krb_KDCOptions = -1;
226 static gint hf_krb_KDCOptions_forwardable = -1;
227 static gint hf_krb_KDCOptions_forwarded = -1;
228 static gint hf_krb_KDCOptions_proxyable = -1;
229 static gint hf_krb_KDCOptions_proxy = -1;
230 static gint hf_krb_KDCOptions_allow_postdate = -1;
231 static gint hf_krb_KDCOptions_postdated = -1;
232 static gint hf_krb_KDCOptions_renewable = -1;
233 static gint hf_krb_KDCOptions_canonicalize = -1;
234 static gint hf_krb_KDCOptions_opt_hardware_auth = -1;
235 static gint hf_krb_KDCOptions_disable_transited_check = -1;
236 static gint hf_krb_KDCOptions_renewable_ok = -1;
237 static gint hf_krb_KDCOptions_enc_tkt_in_skey = -1;
238 static gint hf_krb_KDCOptions_renew = -1;
239 static gint hf_krb_KDCOptions_validate = -1;
240 static gint hf_krb_KDC_REQ_BODY = -1;
241 static gint hf_krb_PRIV_BODY = -1;
242 static gint hf_krb_ENC_PRIV = -1;
243 static gint hf_krb_authenticator_enc = -1;
244 static gint hf_krb_ticket_enc = -1;
245 static gint hf_krb_e_checksum = -1;
246
247 static gint ett_krb_kerberos = -1;
248 static gint ett_krb_TransitedEncoding = -1;
249 static gint ett_krb_PAC_LOGON_INFO = -1;
250 static gint ett_krb_PAC_CREDENTIAL_TYPE = -1;
251 static gint ett_krb_PAC_SERVER_CHECKSUM = -1;
252 static gint ett_krb_PAC_PRIVSVR_CHECKSUM = -1;
253 static gint ett_krb_PAC_CLIENT_INFO_TYPE = -1;
254 static gint ett_krb_KDC_REP_enc = -1;
255 static gint ett_krb_EncTicketPart = -1;
256 static gint ett_krb_EncAPRepPart = -1;
257 static gint ett_krb_EncKrbPrivPart = -1;
258 static gint ett_krb_EncKDCRepPart = -1;
259 static gint ett_krb_LastReq = -1;
260 static gint ett_krb_Authenticator = -1;
261 static gint ett_krb_Checksum = -1;
262 static gint ett_krb_key = -1;
263 static gint ett_krb_subkey = -1;
264 static gint ett_krb_AuthorizationData = -1;
265 static gint ett_krb_sname = -1;
266 static gint ett_krb_cname = -1;
267 static gint ett_krb_AP_REP_enc = -1;
268 static gint ett_krb_padata = -1;
269 static gint ett_krb_etypes = -1;
270 static gint ett_krb_LastReqs = -1;
271 static gint ett_krb_IF_RELEVANT = -1;
272 static gint ett_krb_PA_DATA_tree = -1;
273 static gint ett_krb_PAC = -1;
274 static gint ett_krb_s_address = -1;
275 static gint ett_krb_HostAddress = -1;
276 static gint ett_krb_HostAddresses = -1;
277 static gint ett_krb_authenticator_enc = -1;
278 static gint ett_krb_AP_Options = -1;
279 static gint ett_krb_KDC_Options = -1;
280 static gint ett_krb_Ticket_Flags = -1;
281 static gint ett_krb_request = -1;
282 static gint ett_krb_recordmark = -1;
283 static gint ett_krb_ticket = -1;
284 static gint ett_krb_ticket_enc = -1;
285 static gint ett_krb_PRIV = -1;
286 static gint ett_krb_PRIV_enc = -1;
287 static gint ett_krb_e_checksum = -1;
288
289 guint32 krb5_errorcode;
290
291
292 dissector_handle_t krb4_handle=NULL;
293
294 static int do_col_info;
295
296
297 static void
298 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag)
299 {
300         kerberos_callbacks *cb=(kerberos_callbacks *)pinfo->private_data;
301
302         if(!cb){
303                 return;
304         }
305
306         while(cb->tag){
307                 if(cb->tag==tag){
308                         cb->callback(pinfo, tvb, tree);
309                         return;
310                 }
311                 cb++;
312         }
313         return;
314 }
315
316
317
318 #ifdef HAVE_KERBEROS
319
320 /* Decrypt Kerberos blobs */
321 static gboolean krb_decrypt = FALSE;
322
323 /* keytab filename */
324 static const char *keytab_filename = "insert filename here";
325
326 #endif
327
328 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
329 #include <krb5.h>
330 enc_key_t *enc_key_list=NULL;
331
332 static void
333 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
334 {
335         enc_key_t *new_key;
336
337         if(pinfo->fd->flags.visited){
338                 return;
339         }
340 printf("added key in %d\n",pinfo->fd->num);
341
342         new_key=g_malloc(sizeof(enc_key_t));
343         sprintf(new_key->key_origin, "%s learnt from frame %d",origin,pinfo->fd->num);
344         new_key->next=enc_key_list;
345         enc_key_list=new_key;
346         new_key->keytype=keytype;
347         new_key->keylength=keylength;
348         /*XXX this needs to be freed later */
349         new_key->keyvalue=g_memdup(keyvalue, keylength);
350 }
351 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
352
353
354 #ifdef HAVE_MIT_KERBEROS
355
356 static void
357 read_keytab_file(const char *filename, krb5_context *context)
358 {
359         krb5_keytab keytab;
360         krb5_keytab_entry key;
361         krb5_error_code ret;
362         krb5_kt_cursor cursor;
363         enc_key_t *new_key;
364
365         /* should use a file in the ethereal users dir */
366         ret = krb5_kt_resolve(*context, filename, &keytab);
367         if(ret){
368                 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
369
370                 return;
371         }
372
373         ret = krb5_kt_start_seq_get(*context, keytab, &cursor);
374         if(ret){
375                 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
376                 return;
377         }
378
379         do{
380                 new_key=g_malloc(sizeof(enc_key_t));
381                 new_key->next=enc_key_list;
382                 ret = krb5_kt_next_entry(*context, keytab, &key, &cursor);
383                 if(ret==0){
384                         int i;
385                         char *pos;
386
387                         /* generate origin string, describing where this key came from */
388                         pos=new_key->key_origin;
389                         pos+=sprintf(pos, "keytab principal ");
390                         for(i=0;i<key.principal->length;i++){
391                                 pos+=sprintf(pos,"%s%s",(i?"/":""),(key.principal->data[i]).data);
392                         }
393                         pos+=sprintf(pos,"@%s",key.principal->realm.data);
394                         *pos=0;
395 /*printf("added key for principal :%s\n", new_key->key_origin);*/
396                         new_key->keytype=key.key.enctype;
397                         new_key->keylength=key.key.length;
398                         new_key->keyvalue=g_memdup(key.key.contents, key.key.length);
399                         enc_key_list=new_key;
400                 }
401         }while(ret==0);
402
403         ret = krb5_kt_end_seq_get(*context, keytab, &cursor);
404         if(ret){
405                 krb5_kt_close(*context, keytab);
406         }
407
408 }
409
410
411 guint8 *
412 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
413                         int usage,
414                         int length,
415                         const guint8 *cryptotext,
416                         int keytype)
417 {
418         static int first_time=1;
419         static krb5_context context;
420         krb5_error_code ret;
421         enc_key_t *ek;
422         static krb5_data data = {0,0,NULL};
423         krb5_keytab_entry key;
424
425         /* dont do anything if we are not attempting to decrypt data */
426         if(!krb_decrypt){
427                 return NULL;
428         }
429
430         /* XXX we should only do this for first time, then store somewhere */
431         /* XXX We also need to re-read the keytab when the preference changes */
432
433         /* should this have a destroy context ?  MIT people would know */
434         if(first_time){
435                 first_time=0;
436                 ret = krb5_init_context(&context);
437                 if(ret){
438                         return NULL;
439                 }
440                 read_keytab_file(keytab_filename, &context);
441         }
442
443         for(ek=enc_key_list;ek;ek=ek->next){
444                 krb5_enc_data input;
445
446                 /* shortcircuit and bail out if enctypes are not matching */
447                 if(ek->keytype!=keytype){
448                         continue;
449                 }
450
451                 input.enctype = ek->keytype;
452                 input.ciphertext.length = length;
453                 input.ciphertext.data = (guint8 *)cryptotext;
454
455                 data.length = length;
456                 if(data.data){
457                         g_free(data.data);
458                 }
459                 data.data = g_malloc(length);
460
461                 key.key.enctype=ek->keytype;
462                 key.key.length=ek->keylength;
463                 key.key.contents=ek->keyvalue;
464                 ret = krb5_c_decrypt(context, &(key.key), usage, 0, &input, &data);
465                 if (ret == 0) {
466 printf("woohoo decrypted keytype:%d in frame:%d\n", keytype, pinfo->fd->num);
467                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
468                         return data.data;
469                 }
470         }
471
472         return NULL;
473 }
474
475 #elif defined(HAVE_HEIMDAL_KERBEROS)
476 static void
477 read_keytab_file(const char *filename, krb5_context *context)
478 {
479         krb5_keytab keytab;
480         krb5_keytab_entry key;
481         krb5_error_code ret;
482         krb5_kt_cursor cursor;
483         enc_key_t *new_key;
484
485         /* should use a file in the ethereal users dir */
486         ret = krb5_kt_resolve(*context, filename, &keytab);
487         if(ret){
488                 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
489
490                 return;
491         }
492
493         ret = krb5_kt_start_seq_get(*context, keytab, &cursor);
494         if(ret){
495                 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
496                 return;
497         }
498
499         do{
500                 new_key=g_malloc(sizeof(enc_key_t));
501                 new_key->next=enc_key_list;
502                 ret = krb5_kt_next_entry(*context, keytab, &key, &cursor);
503                 if(ret==0){
504                         unsigned int i;
505                         char *pos;
506
507                         /* generate origin string, describing where this key came from */
508                         pos=new_key->key_origin;
509                         pos+=sprintf(pos, "keytab principal ");
510                         for(i=0;i<key.principal->name.name_string.len;i++){
511                                 pos+=sprintf(pos,"%s%s",(i?"/":""),key.principal->name.name_string.val[i]);
512                         }
513                         pos+=sprintf(pos,"@%s",key.principal->realm);
514                         *pos=0;
515                         new_key->keytype=key.keyblock.keytype;
516                         new_key->keylength=key.keyblock.keyvalue.length;
517                         new_key->keyvalue=g_memdup(key.keyblock.keyvalue.data, key.keyblock.keyvalue.length);
518                         enc_key_list=new_key;
519                 }
520         }while(ret==0);
521
522         ret = krb5_kt_end_seq_get(*context, keytab, &cursor);
523         if(ret){
524                 krb5_kt_close(*context, keytab);
525         }
526
527 }
528
529
530 guint8 *
531 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
532                         int usage,
533                         int length,
534                         const guint8 *cryptotext,
535                         int keytype)
536 {
537         static int first_time=1;
538         static krb5_context context;
539         krb5_error_code ret;
540         krb5_data data;
541         enc_key_t *ek;
542
543         /* dont do anything if we are not attempting to decrypt data */
544         if(!krb_decrypt){
545                 return NULL;
546         }
547
548         /* XXX we should only do this for first time, then store somewhere */
549         /* XXX We also need to re-read the keytab when the preference changes */
550
551         /* should this have a destroy context ?  Heimdal people would know */
552         if(first_time){
553                 first_time=0;
554                 ret = krb5_init_context(&context);
555                 if(ret){
556                         return NULL;
557                 }
558                 read_keytab_file(keytab_filename, &context);
559         }
560
561         for(ek=enc_key_list;ek;ek=ek->next){
562                 krb5_keytab_entry key;
563                 krb5_crypto crypto;
564                 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
565
566                 /* shortcircuit and bail out if enctypes are not matching */
567                 if(ek->keytype!=keytype){
568                         continue;
569                 }
570
571                 key.keyblock.keytype=ek->keytype;
572                 key.keyblock.keyvalue.length=ek->keylength;
573                 key.keyblock.keyvalue.data=ek->keyvalue;
574                 ret = krb5_crypto_init(context, &(key.keyblock), 0, &crypto);
575                 if(ret){
576                         return NULL;
577                 }
578
579                 /* pre-0.6.1 versions of Heimdal would sometimes change
580                   the cryptotext data even when the decryption failed.
581                   This would obviously not work since we iterate over the
582                   keys. So just give it a copy of the crypto data instead.
583                   This has been seen for RC4-HMAC blobs.
584                 */
585                 cryptocopy=g_malloc(length);
586                 memcpy(cryptocopy, cryptotext, length);
587                 ret = krb5_decrypt_ivec(context, crypto, usage,
588                                 cryptocopy, length,
589                                 &data,
590                                 NULL);
591                 g_free(cryptocopy);
592                 if (ret == 0) {
593 printf("woohoo decrypted keytype:%d in frame:%d\n", keytype, pinfo->fd->num);
594                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
595                         krb5_crypto_destroy(context, crypto);
596                         return data.data;
597                 }
598                 krb5_crypto_destroy(context, crypto);
599         }
600         return NULL;
601 }
602
603 #elif defined (HAVE_LIBNETTLE)
604
605 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
606 #define KEYTYPE_DES3_CBC_MD5 5  /* Currently the only one supported */
607
608 typedef struct _service_key_t {
609     guint16 kvno;
610     int     keytype;
611     int     length;
612     guint8 *contents;
613     char    origin[KRB_MAX_ORIG_LEN+1];
614 } service_key_t;
615 GSList *service_key_list = NULL;
616
617
618 static void
619 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
620 {
621         service_key_t *new_key;
622
623         if(pinfo->fd->flags.visited){
624                 return;
625         }
626 printf("added key in %d\n",pinfo->fd->num);
627
628         new_key = g_malloc(sizeof(service_key_t));
629         new_key->kvno = 0;
630         new_key->keytype = keytype;
631         new_key->length = keylength;
632         new_key->contents = g_malloc(keylength);
633         memcpy(new_key->contents, keyvalue, keylength);
634         sprintf(new_key->origin, "%s learnt from frame %d", origin, pinfo->fd->num);
635         service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
636 }
637
638 static void
639 clear_keytab(void) {
640         GSList *ske;
641         service_key_t *sk;
642
643         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
644                 sk = (service_key_t *) ske->data;
645                 if (sk && sk->contents) g_free(sk->contents);
646                 if (sk) g_free(sk);
647         }
648         g_slist_free(service_key_list);
649         service_key_list = NULL;
650 }
651
652 static void
653 read_keytab_file(const char *service_key_file)
654 {
655         FILE *skf;
656         struct stat st;
657         service_key_t *sk;
658         unsigned char buf[SERVICE_KEY_SIZE];
659         int newline_skip = 0, count = 0;
660
661         if (service_key_file != NULL && stat (service_key_file, &st) == 0) {
662
663                 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
664                  * There can be zero, one (\n), or two (\r\n) characters between
665                  * keys.  Trailing characters are ignored.
666                  */
667
668                 /* XXX We should support the standard keytab format instead */
669                 if (st.st_size > SERVICE_KEY_SIZE) {
670                         if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
671                              (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
672                             newline_skip = 1;
673                         } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
674                              (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
675                             newline_skip = 2;
676                         }
677                 }
678
679                 skf = fopen(service_key_file, "rb");
680                 if (! skf) return;
681
682                 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
683                         sk = g_malloc(sizeof(service_key_t));
684                         sk->kvno = buf[0] << 8 | buf[1];
685                         sk->keytype = KEYTYPE_DES3_CBC_MD5;
686                         sk->length = DES3_KEY_SIZE;
687                         sk->contents = g_malloc(DES3_KEY_SIZE);
688                         memcpy(sk->contents, buf + 2, DES3_KEY_SIZE);
689                         sprintf(sk->origin, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
690                         service_key_list = g_slist_append(service_key_list, (gpointer) sk);
691                         fseek(skf, newline_skip, SEEK_CUR);
692                         count++;
693 g_warning("added key: %s", sk->origin);
694                 }
695                 fclose(skf);
696         }
697 }
698
699 #define CONFOUNDER_PLUS_CHECKSUM 24
700
701 guint8 *
702 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
703                         int _U_ usage,
704                         int length,
705                         const guint8 *cryptotext,
706                         int keytype)
707 {
708         tvbuff_t *encr_tvb;
709         guint8 *decrypted_data = NULL, *plaintext = NULL;
710         int res;
711         guint8 cls;
712         gboolean pc;
713         guint32 tag, item_len, data_len;
714         int id_offset, offset;
715         guint8 key[DES3_KEY_SIZE];
716         guint8 initial_vector[DES_BLOCK_SIZE];
717         md5_state_t md5s;
718         md5_byte_t digest[16];
719         md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
720         md5_byte_t confounder[8];
721         gboolean ind;
722         GSList *ske;
723         service_key_t *sk;
724         struct des3_ctx ctx;
725
726
727         /* dont do anything if we are not attempting to decrypt data */
728         if(!krb_decrypt){
729                 return NULL;
730         }
731
732         if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
733                 return NULL;
734         }
735
736         decrypted_data = g_malloc(length);
737         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
738                 sk = (service_key_t *) ske->data;
739
740                 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
741
742                 md5_init(&md5s);
743                 memset(initial_vector, 0, DES_BLOCK_SIZE);
744                 res = des3_set_key(&ctx, key);
745                 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
746                     length, decrypted_data, cryptotext);
747                 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
748
749                 tvb_memcpy(encr_tvb, confounder, 0, 8);
750
751                 /* We have to pull the decrypted data length from the decrypted
752                  * content.  If the key doesn't match or we otherwise get garbage,
753                  * an exception may get thrown while decoding the ASN.1 header.
754                  * Catch it, just in case.
755                  */
756                 TRY {
757                         id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
758                         offset = get_ber_length(tree, encr_tvb, id_offset, &item_len, &ind);
759                 }
760                 CATCH (BoundsError) {
761                         tvb_free(encr_tvb);
762                         continue;
763                 }
764                 ENDTRY;
765
766                 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
767                 if ((int) item_len + offset > length) {
768                         tvb_free(encr_tvb);
769                         continue;
770                 }
771
772                 md5_append(&md5s, confounder, 8);
773                 md5_append(&md5s, zero_fill, 16);
774                 md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
775                 md5_finish(&md5s, digest);
776
777                 if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) {
778 g_warning("woohoo decrypted keytype:%d in frame:%d\n", keytype, pinfo->fd->num);
779                         plaintext = g_malloc(data_len);
780                         tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
781                         tvb_free(encr_tvb);
782
783                         g_free(decrypted_data);
784                         return(plaintext);
785                 }
786         }
787
788         g_free(decrypted_data);
789         return NULL;
790 }
791
792
793 #endif  /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
794
795
796
797 /* TCP Record Mark */
798 #define KRB_RM_RESERVED 0x80000000L
799 #define KRB_RM_RECLEN   0x7fffffffL
800
801 #define KRB5_MSG_AUTHENTICATOR          2       /* Authenticator */
802 #define KRB5_MSG_ENC_TICKET_PART        3       /* EncTicketPart */
803 #define KRB5_MSG_AS_REQ                 10      /* AS-REQ type */
804 #define KRB5_MSG_AS_REP                 11      /* AS-REP type */
805 #define KRB5_MSG_TGS_REQ                12      /* TGS-REQ type */
806 #define KRB5_MSG_TGS_REP                13      /* TGS-REP type */
807 #define KRB5_MSG_AP_REQ                 14      /* AP-REQ type */
808 #define KRB5_MSG_AP_REP                 15      /* AP-REP type */
809
810 #define KRB5_MSG_SAFE                   20      /* KRB-SAFE type */
811 #define KRB5_MSG_PRIV                   21      /* KRB-PRIV type */
812 #define KRB5_MSG_CRED                   22      /* KRB-CRED type */
813 #define KRB5_MSG_ENC_AS_REP_PART        25      /* EncASRepPart */
814 #define KRB5_MSG_ENC_TGS_REP_PART       26      /* EncTGSRepPart */
815 #define KRB5_MSG_ENC_AP_REP_PART        27      /* EncAPRepPart */
816 #define KRB5_MSG_ENC_KRB_PRIV_PART      28      /* EncAPRepPart */
817 #define KRB5_MSG_ERROR                  30      /* KRB-ERROR type */
818
819 /* address type constants */
820 #define KRB5_ADDR_IPv4       0x02
821 #define KRB5_ADDR_CHAOS      0x05
822 #define KRB5_ADDR_XEROX      0x06
823 #define KRB5_ADDR_ISO        0x07
824 #define KRB5_ADDR_DECNET     0x0c
825 #define KRB5_ADDR_APPLETALK  0x10
826 #define KRB5_ADDR_NETBIOS    0x14
827 #define KRB5_ADDR_IPv6       0x18
828
829 /* encryption type constants */
830 #define KRB5_ENCTYPE_NULL                0
831 #define KRB5_ENCTYPE_DES_CBC_CRC         1
832 #define KRB5_ENCTYPE_DES_CBC_MD4         2
833 #define KRB5_ENCTYPE_DES_CBC_MD5         3
834 #define KRB5_ENCTYPE_DES_CBC_RAW         4
835 #define KRB5_ENCTYPE_DES3_CBC_SHA        5
836 #define KRB5_ENCTYPE_DES3_CBC_RAW        6
837 #define KRB5_ENCTYPE_DES_HMAC_SHA1       8
838 #define KRB5_ENCTYPE_DSA_SHA1_CMS        9
839 #define KRB5_ENCTYPE_RSA_MD5_CMS         10
840 #define KRB5_ENCTYPE_RSA_SHA1_CMS        11
841 #define KRB5_ENCTYPE_RC2_CBC_ENV         12
842 #define KRB5_ENCTYPE_RSA_ENV             13
843 #define KRB5_ENCTYPE_RSA_ES_OEAP_ENV     14
844 #define KRB5_ENCTYPE_DES_EDE3_CBC_ENV    15
845 #define KRB5_ENCTYPE_DES3_CBC_SHA1       16
846 #define KRB5_ENCTYPE_DES_CBC_MD5_NT      20
847 #define KERB_ENCTYPE_RC4_HMAC            23
848 #define KERB_ENCTYPE_RC4_HMAC_EXP        24
849 #define KRB5_ENCTYPE_UNKNOWN                0x1ff
850 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1   0x7007
851 #define KRB5_ENCTYPE_RC4_PLAIN_EXP      0xffffff73
852 #define KRB5_ENCTYPE_RC4_PLAIN          0xffffff74
853 #define KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP  0xffffff78
854 #define KRB5_ENCTYPE_RC4_HMAC_OLD_EXP   0xffffff79
855 #define KRB5_ENCTYPE_RC4_PLAIN_OLD      0xffffff7a
856 #define KRB5_ENCTYPE_RC4_HMAC_OLD       0xffffff7b
857 #define KRB5_ENCTYPE_DES_PLAIN          0xffffff7c
858 #define KRB5_ENCTYPE_RC4_SHA            0xffffff7d
859 #define KRB5_ENCTYPE_RC4_LM             0xffffff7e
860 #define KRB5_ENCTYPE_RC4_PLAIN2         0xffffff7f
861 #define KRB5_ENCTYPE_RC4_MD4            0xffffff80
862
863 /* checksum types */
864 #define KRB5_CHKSUM_NONE                0
865 #define KRB5_CHKSUM_CRC32               1
866 #define KRB5_CHKSUM_MD4                 2
867 #define KRB5_CHKSUM_KRB_DES_MAC         4
868 #define KRB5_CHKSUM_KRB_DES_MAC_K       5
869 #define KRB5_CHKSUM_MD5                 7
870 #define KRB5_CHKSUM_MD5_DES             8
871 /* the following four comes from packetcable */
872 #define KRB5_CHKSUM_MD5_DES3            9
873 #define KRB5_CHKSUM_HMAC_SHA1_DES3_KD   12
874 #define KRB5_CHKSUM_HMAC_SHA1_DES3      13
875 #define KRB5_CHKSUM_SHA1_UNKEYED        14
876 #define KRB5_CHKSUM_HMAC_MD5            0xffffff76
877 #define KRB5_CHKSUM_MD5_HMAC            0xffffff77
878 #define KRB5_CHKSUM_RC4_MD5             0xffffff78
879 #define KRB5_CHKSUM_MD25                0xffffff79
880 #define KRB5_CHKSUM_DES_MAC_MD5         0xffffff7a
881 #define KRB5_CHKSUM_DES_MAC             0xffffff7b
882 #define KRB5_CHKSUM_REAL_CRC32          0xffffff7c
883 #define KRB5_CHKSUM_SHA1                0xffffff7d
884 #define KRB5_CHKSUM_LM                  0xffffff7e
885 #define KRB5_CHKSUM_GSSAPI              0x8003
886
887 /*
888  * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
889  *
890  *      http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
891  *
892  * unless it's expired.
893  */
894
895 /* pre-authentication type constants */
896 #define KRB5_PA_TGS_REQ                1
897 #define KRB5_PA_ENC_TIMESTAMP          2
898 #define KRB5_PA_PW_SALT                3
899 #define KRB5_PA_ENC_ENCKEY             4
900 #define KRB5_PA_ENC_UNIX_TIME          5
901 #define KRB5_PA_ENC_SANDIA_SECURID     6
902 #define KRB5_PA_SESAME                 7
903 #define KRB5_PA_OSF_DCE                8
904 #define KRB5_PA_CYBERSAFE_SECUREID     9
905 #define KRB5_PA_AFS3_SALT              10
906 #define KRB5_PA_ENCTYPE_INFO           11
907 #define KRB5_PA_SAM_CHALLENGE          12
908 #define KRB5_PA_SAM_RESPONSE           13
909 #define KRB5_PA_PK_AS_REQ              14
910 #define KRB5_PA_PK_AS_REP              15
911 #define KRB5_PA_DASS                   16
912 #define KRB5_PA_USE_SPECIFIED_KVNO     20
913 #define KRB5_PA_SAM_REDIRECT           21
914 #define KRB5_PA_GET_FROM_TYPED_DATA    22
915 #define KRB5_PA_SAM_ETYPE_INFO         23
916 #define KRB5_PA_ALT_PRINC              24
917 #define KRB5_PA_SAM_CHALLENGE2         30
918 #define KRB5_PA_SAM_RESPONSE2          31
919 #define KRB5_TD_PKINIT_CMS_CERTIFICATES 101
920 #define KRB5_TD_KRB_PRINCIPAL          102
921 #define KRB5_TD_KRB_REALM              103
922 #define KRB5_TD_TRUSTED_CERTIFIERS     104
923 #define KRB5_TD_CERTIFICATE_INDEX      105
924 #define KRB5_TD_APP_DEFINED_ERROR      106
925 #define KRB5_TD_REQ_NONCE              107
926 #define KRB5_TD_REQ_SEQ                108
927 /* preauthentication types >127 (i.e. negative ones) are app specific.
928    hopefully there will be no collissions here or we will have to
929    come up with something better
930 */
931 #define KRB5_PA_PAC_REQUEST            128      /* MS extension */
932 #define KRB5_PA_PROV_SRV_LOCATION      255      /* packetcable stuff */
933
934 /* Principal name-type */
935 #define KRB5_NT_UNKNOWN        0
936 #define KRB5_NT_PRINCIPAL      1
937 #define KRB5_NT_SRV_INST       2
938 #define KRB5_NT_SRV_HST        3
939 #define KRB5_NT_SRV_XHST       4
940 #define KRB5_NT_UID            5
941 #define KRB5_NT_X500_PRINCIPAL 6
942 #define KRB5_NT_SMTP_NAME      7
943 #define KRB5_NT_ENTERPRISE    10
944
945 /*
946  * MS specific name types, from
947  *
948  *      http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
949  */
950 #define KRB5_NT_MS_PRINCIPAL            -128
951 #define KRB5_NT_MS_PRINCIPAL_AND_SID    -129
952 #define KRB5_NT_ENT_PRINCIPAL_AND_SID   -130
953 #define KRB5_NT_PRINCIPAL_AND_SID       -131
954 #define KRB5_NT_SRV_INST_AND_SID        -132
955
956 /* error table constants */
957 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
958 #define KRB5_ET_KRB5KDC_ERR_NONE                         0
959 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP                     1
960 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP                  2
961 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO                     3
962 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO              4
963 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO              5
964 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN          6
965 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN          7
966 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE         8
967 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY                     9
968 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE              10
969 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID                  11
970 #define KRB5_ET_KRB5KDC_ERR_POLICY                       12
971 #define KRB5_ET_KRB5KDC_ERR_BADOPTION                    13
972 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP                 14
973 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP               15
974 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP           16
975 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP                17
976 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED               18
977 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED              19
978 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED                  20
979 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET                21
980 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET               22
981 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP                      23
982 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED               24
983 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED             25
984 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH               26
985 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER           27
986 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED            28
987 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE              29
988 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY             31
989 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED               32
990 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV                   33
991 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT                    34
992 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US                    35
993 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH                  36
994 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW                      37
995 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR                   38
996 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION                39
997 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE                  40
998 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED                  41
999 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER                  42
1000 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT                43
1001 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER                 44
1002 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY                     45
1003 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL                  46
1004 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION              47
1005 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD                    48
1006 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ                    49
1007 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM               50
1008 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED             51
1009 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG             52
1010 #define KRB5_ET_KRB5KRB_ERR_GENERIC                      60
1011 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG                61
1012 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED             62
1013 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED                63
1014 #define KRB5_ET_KDC_ERROR_INVALID_SIG                    64
1015 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK                     65
1016 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH             66
1017 #define KRB5_ET_KRB_AP_ERR_NO_TGT                        67
1018 #define KRB5_ET_KDC_ERR_WRONG_REALM                      68
1019 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED         69
1020 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE          70
1021 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE              71
1022 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE              72
1023 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN        73
1024 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE    74
1025 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH             75
1026 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH                76
1027
1028 static const value_string krb5_error_codes[] = {
1029         { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
1030         { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
1031         { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
1032         { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
1033         { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
1034         { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
1035         { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
1036         { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
1037         { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
1038         { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
1039         { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
1040         { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
1041         { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
1042         { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
1043         { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
1044         { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
1045         { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
1046         { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
1047         { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
1048         { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
1049         { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
1050         { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
1051         { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
1052         { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
1053         { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
1054         { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
1055         { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1056         { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1057         { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1058         { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1059         { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1060         { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1061         { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1062         { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1063         { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1064         { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1065         { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1066         { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1067         { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1068         { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1069         { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1070         { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1071         { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1072         { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1073         { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1074         { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1075         { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1076         { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1077         { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1078         { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1079         { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1080         { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1081         { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1082         { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1083         { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1084         { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1085         { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1086         { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1087         { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1088         { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1089         { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1090         { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1091         { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1092         { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1093         { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1094         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1095         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1096         { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1097         { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1098         { 0, NULL }
1099 };
1100
1101
1102 #define PAC_LOGON_INFO          1
1103 #define PAC_CREDENTIAL_TYPE     2
1104 #define PAC_SERVER_CHECKSUM     6
1105 #define PAC_PRIVSVR_CHECKSUM    7
1106 #define PAC_CLIENT_INFO_TYPE    10
1107 static const value_string w2k_pac_types[] = {
1108     { PAC_LOGON_INFO            , "Logon Info" },
1109     { PAC_CREDENTIAL_TYPE       , "Credential Type" },
1110     { PAC_SERVER_CHECKSUM       , "Server Checksum" },
1111     { PAC_PRIVSVR_CHECKSUM      , "Privsvr Checksum" },
1112     { PAC_CLIENT_INFO_TYPE      , "Client Info Type" },
1113     { 0, NULL },
1114 };
1115
1116
1117
1118 static const value_string krb5_princ_types[] = {
1119     { KRB5_NT_UNKNOWN              , "Unknown" },
1120     { KRB5_NT_PRINCIPAL            , "Principal" },
1121     { KRB5_NT_SRV_INST             , "Service and Instance" },
1122     { KRB5_NT_SRV_HST              , "Service and Host" },
1123     { KRB5_NT_SRV_XHST             , "Service and Host Components" },
1124     { KRB5_NT_UID                  , "Unique ID" },
1125     { KRB5_NT_X500_PRINCIPAL       , "Encoded X.509 Distinguished Name" },
1126     { KRB5_NT_SMTP_NAME            , "SMTP Name" },
1127     { KRB5_NT_ENTERPRISE           , "Enterprise Name" },
1128     { KRB5_NT_MS_PRINCIPAL         , "NT 4.0 style name (MS specific)" },
1129     { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
1130     { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
1131     { KRB5_NT_PRINCIPAL_AND_SID    , "Principal name and SID (MS specific)"},
1132     { KRB5_NT_SRV_INST_AND_SID     , "SPN and SID (MS specific)"},
1133     { 0                            , NULL },
1134 };
1135
1136 static const value_string krb5_preauthentication_types[] = {
1137     { KRB5_PA_TGS_REQ              , "PA-TGS-REQ" },
1138     { KRB5_PA_ENC_TIMESTAMP        , "PA-ENC-TIMESTAMP" },
1139     { KRB5_PA_PW_SALT              , "PA-PW-SALT" },
1140     { KRB5_PA_ENC_ENCKEY           , "PA-ENC-ENCKEY" },
1141     { KRB5_PA_ENC_UNIX_TIME        , "PA-ENC-UNIX-TIME" },
1142     { KRB5_PA_ENC_SANDIA_SECURID   , "PA-PW-SALT" },
1143     { KRB5_PA_SESAME               , "PA-SESAME" },
1144     { KRB5_PA_OSF_DCE              , "PA-OSF-DCE" },
1145     { KRB5_PA_CYBERSAFE_SECUREID   , "PA-CYBERSAFE-SECURID" },
1146     { KRB5_PA_AFS3_SALT            , "PA-AFS3-SALT" },
1147     { KRB5_PA_ENCTYPE_INFO         , "PA-ENCTYPE-INFO" },
1148     { KRB5_PA_SAM_CHALLENGE        , "PA-SAM-CHALLENGE" },
1149     { KRB5_PA_SAM_RESPONSE         , "PA-SAM-RESPONSE" },
1150     { KRB5_PA_PK_AS_REQ            , "PA-PK-AS-REQ" },
1151     { KRB5_PA_PK_AS_REP            , "PA-PK-AS-REP" },
1152     { KRB5_PA_DASS                 , "PA-DASS" },
1153     { KRB5_PA_USE_SPECIFIED_KVNO   , "PA-USE-SPECIFIED-KVNO" },
1154     { KRB5_PA_SAM_REDIRECT         , "PA-SAM-REDIRECT" },
1155     { KRB5_PA_GET_FROM_TYPED_DATA  , "PA-GET-FROM-TYPED-DATA" },
1156     { KRB5_PA_SAM_ETYPE_INFO       , "PA-SAM-ETYPE-INFO" },
1157     { KRB5_PA_ALT_PRINC            , "PA-ALT-PRINC" },
1158     { KRB5_PA_SAM_CHALLENGE2       , "PA-SAM-CHALLENGE2" },
1159     { KRB5_PA_SAM_RESPONSE2        , "PA-SAM-RESPONSE2" },
1160     { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
1161     { KRB5_TD_KRB_PRINCIPAL        , "TD-KRB-PRINCIPAL" },
1162     { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
1163     { KRB5_TD_TRUSTED_CERTIFIERS   , "TD-TRUSTED-CERTIFIERS" },
1164     { KRB5_TD_CERTIFICATE_INDEX    , "TD-CERTIFICATE-INDEX" },
1165     { KRB5_TD_APP_DEFINED_ERROR    , "TD-APP-DEFINED-ERROR" },
1166     { KRB5_TD_REQ_NONCE            , "TD-REQ-NONCE" },
1167     { KRB5_TD_REQ_SEQ              , "TD-REQ-SEQ" },
1168     { KRB5_PA_PAC_REQUEST          , "PA-PAC-REQUEST" },
1169     { KRB5_PA_PROV_SRV_LOCATION    , "PA-PROV-SRV-LOCATION" },
1170     { 0                            , NULL },
1171 };
1172
1173 static const value_string krb5_encryption_types[] = {
1174     { KRB5_ENCTYPE_NULL           , "NULL" },
1175     { KRB5_ENCTYPE_DES_CBC_CRC    , "des-cbc-crc" },
1176     { KRB5_ENCTYPE_DES_CBC_MD4    , "des-cbc-md4" },
1177     { KRB5_ENCTYPE_DES_CBC_MD5    , "des-cbc-md5" },
1178     { KRB5_ENCTYPE_DES_CBC_RAW    , "des-cbc-raw" },
1179     { KRB5_ENCTYPE_DES3_CBC_SHA   , "des3-cbc-sha" },
1180     { KRB5_ENCTYPE_DES3_CBC_RAW   , "des3-cbc-raw" },
1181     { KRB5_ENCTYPE_DES_HMAC_SHA1  , "des-hmac-sha1" },
1182     { KRB5_ENCTYPE_DSA_SHA1_CMS   , "dsa-sha1-cms" },
1183     { KRB5_ENCTYPE_RSA_MD5_CMS    , "rsa-md5-cms" },
1184     { KRB5_ENCTYPE_RSA_SHA1_CMS   , "rsa-sha1-cms" },
1185     { KRB5_ENCTYPE_RC2_CBC_ENV    , "rc2-cbc-env" },
1186     { KRB5_ENCTYPE_RSA_ENV        , "rsa-env" },
1187     { KRB5_ENCTYPE_RSA_ES_OEAP_ENV, "rsa-es-oeap-env" },
1188     { KRB5_ENCTYPE_DES_EDE3_CBC_ENV, "des-ede3-cbc-env" },
1189     { KRB5_ENCTYPE_DES3_CBC_SHA1  , "des3-cbc-sha1" },
1190     { KRB5_ENCTYPE_DES_CBC_MD5_NT  , "des-cbc-md5-nt" },
1191     { KERB_ENCTYPE_RC4_HMAC       , "rc4-hmac" },
1192     { KERB_ENCTYPE_RC4_HMAC_EXP   , "rc4-hmac-exp" },
1193     { KRB5_ENCTYPE_UNKNOWN        , "unknown" },
1194     { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1    , "local-des3-hmac-sha1" },
1195     { KRB5_ENCTYPE_RC4_PLAIN_EXP  , "rc4-plain-exp" },
1196     { KRB5_ENCTYPE_RC4_PLAIN      , "rc4-plain" },
1197     { KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP, "rc4-plain-old-exp" },
1198     { KRB5_ENCTYPE_RC4_HMAC_OLD_EXP, "rc4-hmac-old-exp" },
1199     { KRB5_ENCTYPE_RC4_PLAIN_OLD  , "rc4-plain-old" },
1200     { KRB5_ENCTYPE_RC4_HMAC_OLD   , "rc4-hmac-old" },
1201     { KRB5_ENCTYPE_DES_PLAIN      , "des-plain" },
1202     { KRB5_ENCTYPE_RC4_SHA        , "rc4-sha" },
1203     { KRB5_ENCTYPE_RC4_LM         , "rc4-lm" },
1204     { KRB5_ENCTYPE_RC4_PLAIN2     , "rc4-plain2" },
1205     { KRB5_ENCTYPE_RC4_MD4        , "rc4-md4" },
1206     { 0                           , NULL },
1207 };
1208
1209 static const value_string krb5_checksum_types[] = {
1210     { KRB5_CHKSUM_NONE            , "none" },
1211     { KRB5_CHKSUM_CRC32           , "crc32" },
1212     { KRB5_CHKSUM_MD4             , "md4" },
1213     { KRB5_CHKSUM_KRB_DES_MAC     , "krb-des-mac" },
1214     { KRB5_CHKSUM_KRB_DES_MAC_K   , "krb-des-mac-k" },
1215     { KRB5_CHKSUM_MD5             , "md5" },
1216     { KRB5_CHKSUM_MD5_DES         , "md5-des" },
1217     { KRB5_CHKSUM_MD5_DES3        , "md5-des3" },
1218     { KRB5_CHKSUM_HMAC_SHA1_DES3_KD, "hmac-sha1-des3-kd" },
1219     { KRB5_CHKSUM_HMAC_SHA1_DES3  , "hmac-sha1-des3" },
1220     { KRB5_CHKSUM_SHA1_UNKEYED    , "sha1 (unkeyed)" },
1221     { KRB5_CHKSUM_HMAC_MD5        , "hmac-md5" },
1222     { KRB5_CHKSUM_MD5_HMAC        , "md5-hmac" },
1223     { KRB5_CHKSUM_RC4_MD5         , "rc5-md5" },
1224     { KRB5_CHKSUM_MD25            , "md25" },
1225     { KRB5_CHKSUM_DES_MAC_MD5     , "des-mac-md5" },
1226     { KRB5_CHKSUM_DES_MAC         , "des-mac" },
1227     { KRB5_CHKSUM_REAL_CRC32      , "real-crc32" },
1228     { KRB5_CHKSUM_SHA1            , "sha1" },
1229     { KRB5_CHKSUM_LM              , "lm" },
1230     { KRB5_CHKSUM_GSSAPI          , "gssapi-8003" },
1231     { 0                           , NULL },
1232 };
1233
1234 #define KRB5_AD_IF_RELEVANT                     1
1235 #define KRB5_AD_INTENDED_FOR_SERVER             2
1236 #define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS  3
1237 #define KRB5_AD_KDC_ISSUED                      4
1238 #define KRB5_AD_OR                              5
1239 #define KRB5_AD_MANDATORY_TICKET_EXTENSIONS     6
1240 #define KRB5_AD_IN_TICKET_EXTENSIONS            7
1241 #define KRB5_AD_MANDATORY_FOR_KDC               8
1242 #define KRB5_AD_OSF_DCE                         64
1243 #define KRB5_AD_SESAME                          65
1244 #define KRB5_AD_OSF_DCE_PKI_CERTID              66
1245 #define KRB5_AD_WIN2K_PAC                               128
1246 static const value_string krb5_ad_types[] = {
1247     { KRB5_AD_IF_RELEVANT                       , "AD-IF-RELEVANT" },
1248     { KRB5_AD_INTENDED_FOR_SERVER               , "AD-Intended-For-Server" },
1249     { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS    , "AD-Intended-For-Application-Class" },
1250     { KRB5_AD_KDC_ISSUED                        , "AD-KDCIssued" },
1251     { KRB5_AD_OR                                , "AD-AND-OR" },
1252     { KRB5_AD_MANDATORY_TICKET_EXTENSIONS       , "AD-Mandatory-Ticket-Extensions" },
1253     { KRB5_AD_IN_TICKET_EXTENSIONS              , "AD-IN-Ticket-Extensions" },
1254     { KRB5_AD_MANDATORY_FOR_KDC                 , "AD-MANDATORY-FOR-KDC" },
1255     { KRB5_AD_OSF_DCE                           , "AD-OSF-DCE" },
1256     { KRB5_AD_SESAME                            , "AD-SESAME" },
1257     { KRB5_AD_OSF_DCE_PKI_CERTID                , "AD-OSF-DCE-PKI-CertID" },
1258     { KRB5_AD_WIN2K_PAC                         , "AD-Win2k-PAC" },
1259     { 0 , NULL },
1260 };
1261
1262 static const value_string krb5_transited_types[] = {
1263     { 1                           , "DOMAIN-X500-COMPRESS" },
1264     { 0                           , NULL }
1265 };
1266
1267 static const value_string krb5_address_types[] = {
1268     { KRB5_ADDR_IPv4,           "IPv4"},
1269     { KRB5_ADDR_CHAOS,          "CHAOS"},
1270     { KRB5_ADDR_XEROX,          "XEROX"},
1271     { KRB5_ADDR_ISO,            "ISO"},
1272     { KRB5_ADDR_DECNET,         "DECNET"},
1273     { KRB5_ADDR_APPLETALK,      "APPLETALK"},
1274     { KRB5_ADDR_NETBIOS,        "NETBIOS"},
1275     { KRB5_ADDR_IPv6,           "IPv6"},
1276     { 0,                        NULL },
1277 };
1278
1279 static const value_string krb5_msg_types[] = {
1280         { KRB5_MSG_AUTHENTICATOR,       "Authenticator" },
1281         { KRB5_MSG_ENC_TICKET_PART,     "EncTicketPart" },
1282         { KRB5_MSG_TGS_REQ,             "TGS-REQ" },
1283         { KRB5_MSG_TGS_REP,             "TGS-REP" },
1284         { KRB5_MSG_AS_REQ,              "AS-REQ" },
1285         { KRB5_MSG_AS_REP,              "AS-REP" },
1286         { KRB5_MSG_AP_REQ,              "AP-REQ" },
1287         { KRB5_MSG_AP_REP,              "AP-REP" },
1288         { KRB5_MSG_SAFE,                "KRB-SAFE" },
1289         { KRB5_MSG_PRIV,                "KRB-PRIV" },
1290         { KRB5_MSG_CRED,                "KRB-CRED" },
1291         { KRB5_MSG_ENC_AS_REP_PART,     "EncASRepPart" },
1292         { KRB5_MSG_ENC_TGS_REP_PART,    "EncTGSRepPart" },
1293         { KRB5_MSG_ENC_AP_REP_PART,     "EncAPRepPart" },
1294         { KRB5_MSG_ENC_KRB_PRIV_PART,   "EncKrbPrivPart" },
1295         { KRB5_MSG_ERROR,               "KRB-ERROR" },
1296         { 0, NULL },
1297 };
1298
1299
1300
1301
1302 static int dissect_krb5_application_choice(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1303 static int dissect_krb5_Authenticator(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1304 static int dissect_krb5_EncTicketPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1305 static int dissect_krb5_EncAPRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1306 static int dissect_krb5_EncKrbPrivPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1307 static int dissect_krb5_EncKDCRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1308 static int dissect_krb5_KDC_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1309 static int dissect_krb5_KDC_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1310 static int dissect_krb5_AP_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1311 static int dissect_krb5_AP_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1312 static int dissect_krb5_SAFE(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1313 static int dissect_krb5_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1314 static int dissect_krb5_ERROR(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
1315
1316 static const ber_choice_t kerberos_applications_choice[] = {
1317         { KRB5_MSG_AUTHENTICATOR,       BER_CLASS_APP,  KRB5_MSG_AUTHENTICATOR, 0, dissect_krb5_Authenticator },
1318         { KRB5_MSG_ENC_TICKET_PART, BER_CLASS_APP,      KRB5_MSG_ENC_TICKET_PART, 0, dissect_krb5_EncTicketPart },
1319         { KRB5_MSG_AS_REQ,      BER_CLASS_APP,  KRB5_MSG_AS_REQ,        0,      dissect_krb5_KDC_REQ },
1320         { KRB5_MSG_AS_REP,      BER_CLASS_APP,  KRB5_MSG_AS_REP,        0,      dissect_krb5_KDC_REP },
1321         { KRB5_MSG_TGS_REQ,     BER_CLASS_APP,  KRB5_MSG_TGS_REQ,       0,      dissect_krb5_KDC_REQ },
1322         { KRB5_MSG_TGS_REP,     BER_CLASS_APP,  KRB5_MSG_TGS_REP,       0,      dissect_krb5_KDC_REP },
1323         { KRB5_MSG_AP_REQ,      BER_CLASS_APP,  KRB5_MSG_AP_REQ,        0,      dissect_krb5_AP_REQ },
1324         { KRB5_MSG_AP_REP,      BER_CLASS_APP,  KRB5_MSG_AP_REP,        0,      dissect_krb5_AP_REP },
1325         { KRB5_MSG_ENC_AS_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_AS_REP_PART, 0, dissect_krb5_EncKDCRepPart },
1326         { KRB5_MSG_ENC_TGS_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_TGS_REP_PART, 0, dissect_krb5_EncKDCRepPart },
1327         { KRB5_MSG_ENC_AP_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_AP_REP_PART, 0, dissect_krb5_EncAPRepPart },
1328         { KRB5_MSG_ENC_KRB_PRIV_PART, BER_CLASS_APP, KRB5_MSG_ENC_KRB_PRIV_PART, 0, dissect_krb5_EncKrbPrivPart },
1329         { KRB5_MSG_SAFE,        BER_CLASS_APP,  KRB5_MSG_SAFE,          0,      dissect_krb5_SAFE },
1330         { KRB5_MSG_PRIV,        BER_CLASS_APP,  KRB5_MSG_PRIV,          0,      dissect_krb5_PRIV },
1331         { KRB5_MSG_ERROR,       BER_CLASS_APP,  KRB5_MSG_ERROR,         0,      dissect_krb5_ERROR },
1332         { 0, 0, 0, 0, NULL }
1333 };
1334
1335
1336 static int
1337 dissect_krb5_application_choice(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1338 {
1339         offset=dissect_ber_choice(pinfo, tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
1340         return offset;
1341 }
1342
1343
1344 static const true_false_string krb5_apoptions_use_session_key = {
1345         "USE SESSION KEY to encrypt the ticket",
1346         "Do NOT use the session key to encrypt the ticket"
1347 };
1348 static const true_false_string krb5_apoptions_mutual_required = {
1349         "MUTUAL authentication is REQUIRED",
1350         "Mutual authentication is NOT required"
1351 };
1352
1353 static int *APOptions_bits[] = {
1354   &hf_krb_APOptions_use_session_key,
1355   &hf_krb_APOptions_mutual_required,
1356   NULL
1357 };
1358 static int
1359 dissect_krb5_APOptions(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1360 {
1361         offset=dissect_ber_bitstring32(FALSE, pinfo, tree, tvb, offset, APOptions_bits, hf_krb_APOptions, ett_krb_AP_Options, NULL);
1362         return offset;
1363 }
1364
1365
1366
1367 static const true_false_string krb5_kdcoptions_forwardable = {
1368         "FORWARDABLE tickets are allowed/requested",
1369         "Do NOT use forwardable tickets"
1370 };
1371 static const true_false_string krb5_kdcoptions_forwarded = {
1372         "This ticket has been FORWARDED",
1373         "This is NOT a forwarded ticket"
1374 };
1375 static const true_false_string krb5_kdcoptions_proxyable = {
1376         "PROXIABLE tickets are allowed/requested",
1377         "Do NOT use proxiable tickets"
1378 };
1379 static const true_false_string krb5_kdcoptions_proxy = {
1380         "This is a PROXY ticket",
1381         "This ticket has NOT been proxied"
1382 };
1383 static const true_false_string krb5_kdcoptions_allow_postdate = {
1384         "We allow the ticket to be POSTDATED",
1385         "We do NOT allow the ticket to be postdated"
1386 };
1387 static const true_false_string krb5_kdcoptions_postdated = {
1388         "This ticket is POSTDATED",
1389         "This ticket is NOT postdated"
1390 };
1391 static const true_false_string krb5_kdcoptions_renewable = {
1392         "This ticket is RENEWABLE",
1393         "This ticket is NOT renewable"
1394 };
1395 static const true_false_string krb5_kdcoptions_canonicalize = {
1396         "This is a request for a CANONICALIZED ticket",
1397         "This is NOT a canonicalized ticket request"
1398 };
1399 static const true_false_string krb5_kdcoptions_disable_transited_check = {
1400         "Transited checking is DISABLED",
1401         "Transited checking is NOT disabled"
1402 };
1403 static const true_false_string krb5_kdcoptions_renewable_ok = {
1404         "We accept RENEWED tickets",
1405         "We do NOT accept renewed tickets"
1406 };
1407 static const true_false_string krb5_kdcoptions_enc_tkt_in_skey = {
1408         "ENCrypt TKT in SKEY",
1409         "Do NOT encrypt the tkt inside the skey"
1410 };
1411 static const true_false_string krb5_kdcoptions_renew = {
1412         "This is a request to RENEW a ticket",
1413         "This is NOT a request to renew a ticket"
1414 };
1415 static const true_false_string krb5_kdcoptions_validate = {
1416         "This is a request to VALIDATE a postdated ticket",
1417         "This is NOT a request to validate a postdated ticket"
1418 };
1419
1420 static int* KDCOptions_bits[] = {
1421   &hf_krb_KDCOptions_forwardable,
1422   &hf_krb_KDCOptions_forwarded,
1423   &hf_krb_KDCOptions_proxyable,
1424   &hf_krb_KDCOptions_proxy,
1425   &hf_krb_KDCOptions_allow_postdate,
1426   &hf_krb_KDCOptions_postdated,
1427   &hf_krb_KDCOptions_renewable,
1428   &hf_krb_KDCOptions_opt_hardware_auth,
1429   &hf_krb_KDCOptions_canonicalize,
1430   &hf_krb_KDCOptions_disable_transited_check,
1431   &hf_krb_KDCOptions_renewable_ok,
1432   &hf_krb_KDCOptions_enc_tkt_in_skey,
1433   &hf_krb_KDCOptions_renew,
1434   &hf_krb_KDCOptions_validate,
1435   NULL
1436 };
1437
1438 static int
1439 dissect_krb5_KDCOptions(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1440 {
1441         offset=dissect_ber_bitstring32(FALSE, pinfo, tree, tvb, offset, KDCOptions_bits, hf_krb_KDCOptions, ett_krb_KDC_Options, NULL);
1442         return offset;
1443 }
1444
1445 static int
1446 dissect_krb5_rtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1447 {
1448         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_rtime);
1449         return offset;
1450 }
1451
1452 int
1453 dissect_krb5_ctime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1454 {
1455         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_ctime);
1456         return offset;
1457 }
1458 static int
1459 dissect_krb5_cusec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1460 {
1461         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_cusec, NULL);
1462         return offset;
1463 }
1464
1465 static int
1466 dissect_krb5_stime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1467 {
1468         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_stime);
1469         return offset;
1470 }
1471 static int
1472 dissect_krb5_susec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1473 {
1474         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_susec, NULL);
1475         return offset;
1476 }
1477
1478
1479 static int
1480 dissect_krb5_error_code(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1481 {
1482         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_error_code, &krb5_errorcode);
1483         if(krb5_errorcode && check_col(pinfo->cinfo, COL_INFO)) {
1484                 col_add_fstr(pinfo->cinfo, COL_INFO,
1485                         "KRB Error: %s",
1486                         val_to_str(krb5_errorcode, krb5_error_codes,
1487                         "Unknown error code %#x"));
1488         }
1489
1490         return offset;
1491 }
1492
1493
1494 static int
1495 dissect_krb5_till(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1496 {
1497         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_till);
1498         return offset;
1499 }
1500 static int
1501 dissect_krb5_from(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1502 {
1503         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_from);
1504         return offset;
1505 }
1506
1507
1508
1509 static int
1510 dissect_krb5_nonce(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1511 {
1512         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_nonce, NULL);
1513         return offset;
1514 }
1515
1516
1517 /*
1518  *          etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
1519  */
1520 static int
1521 dissect_krb5_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1522 {
1523         guint32 etype;
1524
1525         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_etype, &etype);
1526         if(tree){
1527                 proto_item_append_text(tree, " %s",
1528                         val_to_str(etype, krb5_encryption_types,
1529                         "%d"));
1530         }
1531         return offset;
1532 }
1533 static ber_sequence_t etype_sequence_of[1] = {
1534   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_krb5_etype },
1535 };
1536 static int
1537 dissect_krb5_etype_sequence_of(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1538 {
1539         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, etype_sequence_of, hf_krb_etypes, ett_krb_etypes);
1540
1541         return offset;
1542 }
1543 static guint32 authenticator_etype;
1544 static int
1545 dissect_krb5_authenticator_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1546 {
1547         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_etype, &authenticator_etype);
1548         if(tree){
1549                 proto_item_append_text(tree, " %s",
1550                         val_to_str(authenticator_etype, krb5_encryption_types,
1551                         "%#x"));
1552         }
1553         return offset;
1554 }
1555 static guint32 Ticket_etype;
1556 static int
1557 dissect_krb5_Ticket_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1558 {
1559         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_etype, &Ticket_etype);
1560         if(tree){
1561                 proto_item_append_text(tree, " %s",
1562                         val_to_str(Ticket_etype, krb5_encryption_types,
1563                         "%#x"));
1564         }
1565         return offset;
1566 }
1567 static guint32 AP_REP_etype;
1568 static int
1569 dissect_krb5_AP_REP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1570 {
1571         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_etype, &AP_REP_etype);
1572         if(tree){
1573                 proto_item_append_text(tree, " %s",
1574                         val_to_str(AP_REP_etype, krb5_encryption_types,
1575                         "%#x"));
1576         }
1577         return offset;
1578 }
1579 static guint32 PA_ENC_TIMESTAMP_etype;
1580 static int
1581 dissect_krb5_PA_ENC_TIMESTAMP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1582 {
1583         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_etype, &PA_ENC_TIMESTAMP_etype);
1584         if(tree){
1585                 proto_item_append_text(tree, " %s",
1586                         val_to_str(PA_ENC_TIMESTAMP_etype, krb5_encryption_types,
1587                         "%#x"));
1588         }
1589         return offset;
1590 }
1591
1592
1593 /*
1594  *  HostAddress ::=    SEQUENCE  {
1595  *                     addr-type[0]             INTEGER,
1596  *                     address[1]               OCTET STRING
1597  *  }
1598  */
1599 static guint32 addr_type;
1600 static int dissect_krb5_addr_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1601 {
1602         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_addr_type, &addr_type);
1603         return offset;
1604 }
1605 static int dissect_krb5_address(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1606 {
1607         gint8 class;
1608         gboolean pc;
1609         gint32 tag;
1610         guint32 len;
1611         char address_str[256];
1612         proto_item *it=NULL;
1613
1614         /* read header and len for the octet string */
1615         offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
1616         offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
1617
1618
1619         address_str[0]=0;
1620         address_str[255]=0;
1621         switch(addr_type){
1622         case KRB5_ADDR_IPv4:
1623                 it=proto_tree_add_item(tree, hf_krb_address_ip, tvb, offset, 4, FALSE);
1624                 sprintf(address_str,"%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));
1625                 break;
1626         case KRB5_ADDR_NETBIOS:
1627                 {
1628                 char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1629                 int netbios_name_type;
1630
1631                 netbios_name_type = process_netbios_name(tvb_get_ptr(tvb, offset, 16), netbios_name);
1632                 g_snprintf(address_str, 255, "%s<%02x>", netbios_name, netbios_name_type);
1633                 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));
1634                 }
1635                 break;
1636         default:
1637                 proto_tree_add_text(tree, tvb, offset, len, "KRB Address: I dont know how to parse this type of address yet");
1638
1639         }
1640
1641         /* push it up two levels in the decode pane */
1642         if(it){
1643                 proto_item_append_text(proto_item_get_parent(it), " %s",address_str);
1644                 proto_item_append_text(proto_item_get_parent_nth(it, 2), " %s",address_str);
1645         }
1646
1647         offset+=len;
1648         return offset;
1649 }
1650 static ber_sequence_t HostAddress_sequence[] = {
1651         { BER_CLASS_CON, 0, 0, dissect_krb5_addr_type },
1652         { BER_CLASS_CON, 1, 0, dissect_krb5_address },
1653         { 0, 0, 0, NULL }
1654 };
1655 static int
1656 dissect_krb5_HostAddress(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1657 {
1658
1659         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, HostAddress_sequence, hf_krb_HostAddress, ett_krb_HostAddress);
1660
1661         return offset;
1662 }
1663 static int
1664 dissect_krb5_s_address(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1665 {
1666
1667         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, HostAddress_sequence, hf_krb_s_address, ett_krb_s_address);
1668
1669         return offset;
1670 }
1671
1672 /*
1673  *  HostAddresses ::=   SEQUENCE OF SEQUENCE {
1674  *                      addr-type[0]             INTEGER,
1675  *                      address[1]               OCTET STRING
1676  *  }
1677  *
1678  */
1679 static ber_sequence_t HostAddresses_sequence_of[1] = {
1680   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_HostAddress },
1681 };
1682 static int
1683 dissect_krb5_HostAddresses(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1684 {
1685         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, HostAddresses_sequence_of, hf_krb_HostAddresses, ett_krb_HostAddresses);
1686
1687         return offset;
1688 }
1689
1690
1691
1692 static int
1693 dissect_krb5_msg_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1694 {
1695         guint32 msgtype;
1696
1697         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_msg_type, &msgtype);
1698
1699         if (do_col_info & check_col(pinfo->cinfo, COL_INFO)) {
1700                 col_add_str(pinfo->cinfo, COL_INFO,
1701                         val_to_str(msgtype, krb5_msg_types,
1702                         "Unknown msg type %#x"));
1703         }
1704         do_col_info=FALSE;
1705
1706         /* append the application type to the subtree */
1707         proto_item_append_text(tree, " %s", val_to_str(msgtype, krb5_msg_types, "Unknown:0x%x"));
1708
1709         return offset;
1710 }
1711
1712
1713
1714 static int
1715 dissect_krb5_pvno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1716 {
1717         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_pvno, NULL);
1718
1719         return offset;
1720 }
1721
1722
1723 /*
1724  * PrincipalName ::=   SEQUENCE {
1725  *                     name-type[0]     INTEGER,
1726  *                     name-string[1]   SEQUENCE OF GeneralString
1727  * }
1728  */
1729 guint32 name_type;
1730 static int
1731 dissect_krb5_name_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1732 {
1733
1734         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_name_type, &name_type);
1735         if(tree){
1736                 proto_item_append_text(tree, " (%s):",
1737                         val_to_str(name_type, krb5_princ_types,
1738                         "Unknown:%d"));
1739         }
1740         return offset;
1741 }
1742 static char name_string_separator;
1743 static int
1744 dissect_krb5_name_string(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1745 {
1746         char name_string[256];
1747
1748         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_name_string, name_string, 255);
1749         if(tree){
1750                 proto_item_append_text(tree, "%c%s", name_string_separator, name_string);
1751                 name_string_separator='/';
1752         }
1753
1754         return offset;
1755 }
1756 static ber_sequence_t name_stringe_sequence_of[1] = {
1757   { BER_CLASS_UNI, BER_UNI_TAG_GeneralString, BER_FLAGS_NOOWNTAG, dissect_krb5_name_string },
1758 };
1759 static int
1760 dissect_krb5_name_strings(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1761 {
1762         name_string_separator=' ';
1763         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, name_stringe_sequence_of, -1, -1);
1764
1765         return offset;
1766 }
1767 static ber_sequence_t PrincipalName_sequence[] = {
1768         { BER_CLASS_CON, 0, 0, dissect_krb5_name_type },
1769         { BER_CLASS_CON, 1, 0, dissect_krb5_name_strings },
1770         { 0, 0, 0, NULL }
1771 };
1772 static int
1773 dissect_krb5_sname(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1774 {
1775
1776         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PrincipalName_sequence, hf_krb_sname, ett_krb_sname);
1777
1778         return offset;
1779 }
1780 int
1781 dissect_krb5_cname(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1782 {
1783
1784         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PrincipalName_sequence, hf_krb_cname, ett_krb_cname);
1785
1786         return offset;
1787 }
1788
1789
1790 int
1791 dissect_krb5_realm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1792 {
1793         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_realm, NULL, 0);
1794         return offset;
1795 }
1796
1797 static int
1798 dissect_krb5_crealm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1799 {
1800         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_crealm, NULL, 0);
1801         return offset;
1802 }
1803
1804
1805
1806 static int
1807 dissect_krb5_PA_PAC_REQUEST_flag(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1808 {
1809         offset=dissect_ber_boolean(FALSE, pinfo, tree, tvb, offset, hf_krb_PA_PAC_REQUEST_flag);
1810         return offset;
1811 }
1812
1813
1814 static ber_sequence_t PA_PAC_REQUEST_sequence[] = {
1815         { BER_CLASS_CON, 0, 0, dissect_krb5_PA_PAC_REQUEST_flag },
1816         { 0, 0, 0, NULL }
1817 };
1818 static int
1819 dissect_krb5_PA_PAC_REQUEST(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1820 {
1821
1822         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_PAC_REQUEST_sequence, -1, -1);
1823
1824         return offset;
1825 }
1826
1827
1828
1829
1830 static int
1831 dissect_krb5_PA_PROV_SRV_LOCATION(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1832 {
1833         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1834
1835         return offset;
1836 }
1837
1838
1839
1840 static int
1841 dissect_krb5_kvno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1842 {
1843         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_kvno, NULL);
1844
1845         return offset;
1846 }
1847
1848
1849
1850 static int
1851 dissect_krb5_seq_number(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1852 {
1853         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_seq_number, NULL);
1854
1855         return offset;
1856 }
1857
1858
1859
1860 static int
1861 dissect_krb5_patimestamp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1862 {
1863         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_patimestamp);
1864         return offset;
1865 }
1866 #ifdef HAVE_KERBEROS
1867 static int
1868 dissect_krb5_pausec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1869 {
1870         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_pausec, NULL);
1871         return offset;
1872 }
1873 static const ber_sequence_t PA_ENC_TS_ENC_sequence[] = {
1874         { BER_CLASS_CON, 0, 0, dissect_krb5_patimestamp },
1875         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_pausec },
1876         { 0, 0, 0, NULL }
1877 };
1878 static int
1879 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1880 {
1881         guint8 *plaintext=NULL;
1882         int length;
1883
1884         length=tvb_length_remaining(tvb, offset);
1885
1886         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1887          * 7.5.1
1888          * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1889          * == 1
1890          */
1891         if(!plaintext){
1892                 plaintext=decrypt_krb5_data(tree, pinfo, 1, length, tvb_get_ptr(tvb, offset, length), PA_ENC_TIMESTAMP_etype);
1893         }
1894
1895         if(plaintext){
1896                 tvbuff_t *next_tvb;
1897                 next_tvb = tvb_new_real_data (plaintext,
1898                                           length,
1899                                           length);
1900                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1901
1902                 /* Add the decrypted data to the data source list. */
1903                 add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
1904
1905
1906                 offset=dissect_ber_sequence(FALSE, pinfo, tree, next_tvb, 0, PA_ENC_TS_ENC_sequence, -1, -1);
1907
1908         }
1909         return offset;
1910 }
1911 #endif
1912
1913
1914 static int
1915 dissect_krb5_encrypted_PA_ENC_TIMESTAMP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1916 {
1917 #ifdef HAVE_KERBEROS
1918         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, dissect_krb5_decrypt_PA_ENC_TIMESTAMP);
1919 #else
1920         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, NULL);
1921 #endif
1922         return offset;
1923 }
1924 static ber_sequence_t PA_ENC_TIMESTAMP_sequence[] = {
1925         { BER_CLASS_CON, 0, 0,
1926                 dissect_krb5_PA_ENC_TIMESTAMP_etype },
1927         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1928                 dissect_krb5_kvno },
1929         { BER_CLASS_CON, 2, 0,
1930                 dissect_krb5_encrypted_PA_ENC_TIMESTAMP },
1931         { 0, 0, 0, NULL }
1932 };
1933 static int
1934 dissect_krb5_PA_ENC_TIMESTAMP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1935 {
1936         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_ENC_TIMESTAMP_sequence, -1, -1);
1937
1938         return offset;
1939 }
1940
1941
1942
1943 static int
1944 dissect_krb5_etype_info_salt(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1945 {
1946         offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_etype_info_salt, NULL);
1947         return offset;
1948 }
1949
1950 static ber_sequence_t PA_ENCTYPE_INFO_ENTRY_sequence[] = {
1951         { BER_CLASS_CON, 0, 0,
1952                 dissect_krb5_etype },
1953         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1954                 dissect_krb5_etype_info_salt },
1955         { 0, 0, 0, NULL }
1956 };
1957 static int
1958 dissect_krb5_PA_ENCTYPE_INFO_ENTRY(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1959 {
1960         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_ENCTYPE_INFO_ENTRY_sequence, -1, -1);
1961
1962         return offset;
1963 }
1964
1965 static ber_sequence_t PA_ENCTYPE_INFO_sequence_of[1] = {
1966   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO_ENTRY },
1967 };
1968 static int
1969 dissect_krb5_PA_ENCTYPE_INFO(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1970 {
1971         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, PA_ENCTYPE_INFO_sequence_of, -1, -1);
1972
1973         return offset;
1974 }
1975
1976 /*
1977  * PA-DATA ::=        SEQUENCE {
1978  *          padata-type[1]        INTEGER,
1979  *          padata-value[2]       OCTET STRING,
1980  *                        -- might be encoded AP-REQ
1981  * }
1982  */
1983 guint32 krb_PA_DATA_type;
1984 static int
1985 dissect_krb5_PA_DATA_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1986 {
1987         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_PA_DATA_type, &krb_PA_DATA_type);
1988         krb_PA_DATA_type&=0xff; /*this is really just one single byte */
1989
1990         if(tree){
1991                 proto_item_append_text(tree, " %s",
1992                         val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
1993                         "Unknown:%d"));
1994         }
1995         return offset;
1996 }
1997 static int
1998 dissect_krb5_PA_DATA_value(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1999 {
2000         proto_tree *tree=parent_tree;
2001
2002         if(ber_last_created_item){
2003                 tree=proto_item_add_subtree(ber_last_created_item, ett_krb_PA_DATA_tree);
2004         }
2005
2006
2007         switch(krb_PA_DATA_type){
2008         case KRB5_PA_TGS_REQ:
2009                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_application_choice);
2010                 break;
2011         case KRB5_PA_PK_AS_REQ:
2012                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REQ);
2013                 break;
2014         case KRB5_PA_PK_AS_REP:
2015                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_pkinit_PA_PK_AS_REP);
2016                 break;
2017         case KRB5_PA_PAC_REQUEST:
2018                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PAC_REQUEST);
2019                 break;
2020         case KRB5_PA_PROV_SRV_LOCATION:
2021                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PROV_SRV_LOCATION);
2022                 break;
2023         case KRB5_PA_ENC_TIMESTAMP:
2024                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENC_TIMESTAMP);
2025                 break;
2026         case KRB5_PA_ENCTYPE_INFO:
2027                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO);
2028                 break;
2029         default:
2030                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, NULL);
2031         }
2032         return offset;
2033 /*qqq*/
2034 }
2035
2036 static ber_sequence_t PA_DATA_sequence[] = {
2037         { BER_CLASS_CON, 1, 0, dissect_krb5_PA_DATA_type },
2038         { BER_CLASS_CON, 2, 0, dissect_krb5_PA_DATA_value },
2039         { 0, 0, 0, NULL }
2040 };
2041 static int
2042 dissect_krb5_PA_DATA(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2043 {
2044         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_DATA_sequence, -1, -1);
2045
2046         return offset;
2047 }
2048
2049
2050
2051
2052 /*
2053  * padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
2054  *
2055  */
2056 static ber_sequence_t PA_DATA_sequence_of[1] = {
2057   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_DATA },
2058 };
2059 static int
2060 dissect_krb5_padata(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2061 {
2062         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, PA_DATA_sequence_of, hf_krb_padata, ett_krb_padata);
2063
2064         return offset;
2065 }
2066
2067
2068
2069
2070 static const true_false_string krb5_ticketflags_forwardable = {
2071         "FORWARDABLE tickets are allowed/requested",
2072         "Do NOT use forwardable tickets"
2073 };
2074 static const true_false_string krb5_ticketflags_forwarded = {
2075         "This ticket has been FORWARDED",
2076         "This is NOT a forwarded ticket"
2077 };
2078 static const true_false_string krb5_ticketflags_proxyable = {
2079         "PROXIABLE tickets are allowed/requested",
2080         "Do NOT use proxiable tickets"
2081 };
2082 static const true_false_string krb5_ticketflags_proxy = {
2083         "This is a PROXY ticket",
2084         "This ticket has NOT been proxied"
2085 };
2086 static const true_false_string krb5_ticketflags_allow_postdate = {
2087         "We allow the ticket to be POSTDATED",
2088         "We do NOT allow the ticket to be postdated"
2089 };
2090 static const true_false_string krb5_ticketflags_postdated = {
2091         "This ticket is POSTDATED",
2092         "This ticket is NOT postdated"
2093 };
2094 static const true_false_string krb5_ticketflags_invalid = {
2095         "This ticket is INVALID",
2096         "This ticket is NOT invalid"
2097 };
2098 static const true_false_string krb5_ticketflags_renewable = {
2099         "This ticket is RENEWABLE",
2100         "This ticket is NOT renewable"
2101 };
2102 static const true_false_string krb5_ticketflags_initial = {
2103         "This ticket was granted by AS and not TGT protocol",
2104         "This ticket was granted by TGT and not as protocol"
2105 };
2106 static const true_false_string krb5_ticketflags_pre_auth = {
2107         "The client was PRE-AUTHenticated",
2108         "The client was NOT pre-authenticated"
2109 };
2110 static const true_false_string krb5_ticketflags_hw_auth = {
2111         "The client was authenticated by HardWare",
2112         "The client was NOT authenticated using hardware"
2113 };
2114 static const true_false_string krb5_ticketflags_transited_policy_checked = {
2115         "Kdc has performed TRANSITED POLICY CHECKING",
2116         "Kdc has NOT performed transited policy checking"
2117 };
2118 static const true_false_string krb5_ticketflags_ok_as_delegate = {
2119         "This ticket is OK AS a DELEGATED ticket",
2120         "This ticket is NOT ok as a delegated ticket"
2121 };
2122
2123 static int* TicketFlags_bits[] = {
2124   &hf_krb_TicketFlags_forwardable,
2125   &hf_krb_TicketFlags_forwarded,
2126   &hf_krb_TicketFlags_proxyable,
2127   &hf_krb_TicketFlags_proxy,
2128   &hf_krb_TicketFlags_allow_postdate,
2129   &hf_krb_TicketFlags_postdated,
2130   &hf_krb_TicketFlags_invalid,
2131   &hf_krb_TicketFlags_renewable,
2132   &hf_krb_TicketFlags_initial,
2133   &hf_krb_TicketFlags_pre_auth,
2134   &hf_krb_TicketFlags_hw_auth,
2135   &hf_krb_TicketFlags_transited_policy_checked,
2136   &hf_krb_TicketFlags_ok_as_delegate,
2137   NULL
2138 };
2139
2140 static int
2141 dissect_krb5_TicketFlags(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2142 {
2143         offset=dissect_ber_bitstring32(FALSE, pinfo, tree, tvb, offset, TicketFlags_bits, hf_krb_TicketFlags, ett_krb_Ticket_Flags, NULL);
2144         return offset;
2145 }
2146
2147
2148 static guint32 keytype;
2149 static int
2150 dissect_krb5_keytype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2151 {
2152         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_keytype, &keytype);
2153         if(tree){
2154                 proto_item_append_text(tree, " %s",
2155                         val_to_str(keytype, krb5_encryption_types,
2156                         "%#x"));
2157         }
2158         return offset;
2159 }
2160 static int keylength;
2161 static const guint8 *keyvalue;
2162 static int
2163 store_keyvalue(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb, int offset)
2164 {
2165         keylength=tvb_length_remaining(tvb, offset);
2166         keyvalue=tvb_get_ptr(tvb, offset, keylength);
2167         return 0;
2168 }
2169 static int
2170 dissect_krb5_keyvalue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2171 {
2172         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_keyvalue, store_keyvalue);
2173         return offset;
2174 }
2175
2176
2177 /*
2178  * EncryptionKey ::=        SEQUENCE {
2179  *     keytype  [0] int32
2180  *     keyvalue [1] octet string
2181  */
2182 static ber_sequence_t EncryptionKey_sequence[] = {
2183         { BER_CLASS_CON, 0, 0,
2184                 dissect_krb5_keytype },
2185         { BER_CLASS_CON, 1, 0,
2186                 dissect_krb5_keyvalue },
2187         { 0, 0, 0, NULL }
2188 };
2189 static int
2190 dissect_krb5_key(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2191 {
2192         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncryptionKey_sequence, hf_krb_key, ett_krb_key);
2193
2194 #ifdef HAVE_KERBEROS
2195         add_encryption_key(pinfo, keytype, keylength, keyvalue, "key");
2196 #endif
2197         return offset;
2198 }
2199 static int
2200 dissect_krb5_subkey(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2201 {
2202         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncryptionKey_sequence, hf_krb_subkey, ett_krb_subkey);
2203 #ifdef HAVE_KERBEROS
2204         add_encryption_key(pinfo, keytype, keylength, keyvalue, "subkey");
2205 #endif
2206         return offset;
2207 }
2208
2209
2210
2211 static int
2212 dissect_krb5_PAC_LOGON_INFO(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2213 {
2214         proto_item *item=NULL;
2215         proto_tree *tree=NULL;
2216         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2217         dcerpc_info di; /* fake dcerpc_info struct */
2218         void *old_private_data;
2219
2220         item=proto_tree_add_item(parent_tree, hf_krb_PAC_LOGON_INFO, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2221         if(parent_tree){
2222                 tree=proto_item_add_subtree(item, ett_krb_PAC_LOGON_INFO);
2223         }
2224
2225         /* skip the first 20 bytes, they look like a unique ndr pointer
2226            followed by (where did it come from?) a contect_handle ?*/
2227         proto_tree_add_text(tree, tvb, offset, 20, "unknown: is this an undocumented policy handle?");
2228         offset+=20;
2229
2230
2231         /* the PAC_LOGON_INFO blob */
2232         /* fake whatever state the dcerpc runtime support needs */
2233         di.conformant_run=0;
2234         di.call_data=NULL;
2235         old_private_data=pinfo->private_data;
2236         pinfo->private_data=&di;
2237         init_ndr_pointer_list(pinfo);
2238         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2239                 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_REF,
2240                 "PAC_LOGON_INFO:", -1);
2241         pinfo->private_data=old_private_data;
2242
2243         return offset;
2244 }
2245
2246 static int
2247 dissect_krb5_PAC_CREDENTIAL_TYPE(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2248 {
2249         proto_item *item=NULL;
2250         proto_tree *tree=NULL;
2251
2252         item=proto_tree_add_item(parent_tree, hf_krb_PAC_CREDENTIAL_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2253         if(parent_tree){
2254                 tree=proto_item_add_subtree(item, ett_krb_PAC_CREDENTIAL_TYPE);
2255         }
2256
2257 /*qqq*/
2258         return offset;
2259 }
2260
2261 static int
2262 dissect_krb5_PAC_SERVER_CHECKSUM(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2263 {
2264         proto_item *item=NULL;
2265         proto_tree *tree=NULL;
2266
2267         item=proto_tree_add_item(parent_tree, hf_krb_PAC_SERVER_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2268         if(parent_tree){
2269                 tree=proto_item_add_subtree(item, ett_krb_PAC_SERVER_CHECKSUM);
2270         }
2271
2272         /* signature type */
2273         proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, TRUE);
2274         offset+=4;
2275
2276         /* signature data */
2277         proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2278
2279         return offset;
2280 }
2281
2282 static int
2283 dissect_krb5_PAC_PRIVSVR_CHECKSUM(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2284 {
2285         proto_item *item=NULL;
2286         proto_tree *tree=NULL;
2287
2288         item=proto_tree_add_item(parent_tree, hf_krb_PAC_PRIVSVR_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2289         if(parent_tree){
2290                 tree=proto_item_add_subtree(item, ett_krb_PAC_PRIVSVR_CHECKSUM);
2291         }
2292
2293         /* signature type */
2294         proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, TRUE);
2295         offset+=4;
2296
2297         /* signature data */
2298         proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2299
2300         return offset;
2301 }
2302
2303 static int
2304 dissect_krb5_PAC_CLIENT_INFO_TYPE(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2305 {
2306         proto_item *item=NULL;
2307         proto_tree *tree=NULL;
2308         guint16 namelen;
2309         char *name;
2310
2311         item=proto_tree_add_item(parent_tree, hf_krb_PAC_CLIENT_INFO_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
2312         if(parent_tree){
2313                 tree=proto_item_add_subtree(item, ett_krb_PAC_CLIENT_INFO_TYPE);
2314         }
2315
2316         /* clientid */
2317         offset = dissect_nt_64bit_time(tvb, tree, offset,
2318                         hf_krb_pac_clientid);
2319
2320         /* name length */
2321         namelen=tvb_get_letohs(tvb, offset);
2322         proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
2323         offset+=2;
2324
2325         /* client name */
2326         name=tvb_get_ephemeral_faked_unicode(tvb, offset, namelen/2, TRUE);
2327         proto_tree_add_string(tree, hf_krb_pac_clientname, tvb, offset, namelen, name);
2328         offset+=namelen;
2329
2330         return offset;
2331 }
2332
2333 static int
2334 dissect_krb5_AD_WIN2K_PAC_struct(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2335 {
2336         guint32 pac_type;
2337         guint32 pac_size;
2338         guint32 pac_offset;
2339         proto_item *it=NULL;
2340         proto_tree *tr=NULL;
2341         tvbuff_t *next_tvb;
2342
2343         /* type of pac data */
2344         pac_type=tvb_get_letohl(tvb, offset);
2345         it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
2346         if(it){
2347                 tr=proto_item_add_subtree(it, ett_krb_PAC);
2348         }
2349
2350         offset += 4;
2351
2352         /* size of pac data */
2353         pac_size=tvb_get_letohl(tvb, offset);
2354         proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
2355         offset += 4;
2356
2357         /* offset to pac data */
2358         pac_offset=tvb_get_letohl(tvb, offset);
2359         proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
2360         offset += 8;
2361
2362
2363         next_tvb=tvb_new_subset(tvb, pac_offset, pac_size, pac_size);
2364         switch(pac_type){
2365         case PAC_LOGON_INFO:
2366                 dissect_krb5_PAC_LOGON_INFO(pinfo, tr, next_tvb, 0);
2367                 break;
2368         case PAC_CREDENTIAL_TYPE:
2369                 dissect_krb5_PAC_CREDENTIAL_TYPE(pinfo, tr, next_tvb, 0);
2370                 break;
2371         case PAC_SERVER_CHECKSUM:
2372                 dissect_krb5_PAC_SERVER_CHECKSUM(pinfo, tr, next_tvb, 0);
2373                 break;
2374         case PAC_PRIVSVR_CHECKSUM:
2375                 dissect_krb5_PAC_PRIVSVR_CHECKSUM(pinfo, tr, next_tvb, 0);
2376                 break;
2377         case PAC_CLIENT_INFO_TYPE:
2378                 dissect_krb5_PAC_CLIENT_INFO_TYPE(pinfo, tr, next_tvb, 0);
2379                 break;
2380         default:;
2381 /*qqq*/
2382         }
2383         return offset;
2384 }
2385
2386 static int
2387 dissect_krb5_AD_WIN2K_PAC(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2388 {
2389         guint32 entries;
2390         guint32 version;
2391         guint32 i;
2392
2393         /* first in the PAC structure comes the number of entries */
2394         entries=tvb_get_letohl(tvb, offset);
2395         proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
2396         offset += 4;
2397
2398         /* second comes the version */
2399         version=tvb_get_letohl(tvb, offset);
2400         proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
2401         offset += 4;
2402
2403         for(i=0;i<entries;i++){
2404                 offset=dissect_krb5_AD_WIN2K_PAC_struct(pinfo, tree, tvb, offset);
2405         }
2406
2407         return offset;
2408 }
2409
2410 static guint32 IF_RELEVANT_type;
2411 static int
2412 dissect_krb5_IF_RELEVANT_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2413 {
2414         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_IF_RELEVANT_type, &IF_RELEVANT_type);
2415         if(tree){
2416                 proto_item_append_text(tree, " %s",
2417                         val_to_str(IF_RELEVANT_type, krb5_ad_types,
2418                         "%#x"));
2419         }
2420         return offset;
2421 }
2422 static int
2423 dissect_krb5_IF_RELEVANT_value(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2424 {
2425         switch(IF_RELEVANT_type){
2426         case KRB5_AD_WIN2K_PAC:
2427                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_advalue, dissect_krb5_AD_WIN2K_PAC);
2428                 break;
2429         default:
2430                 offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_IF_RELEVANT_value, NULL);
2431         }
2432         return offset;
2433 }
2434 static ber_sequence_t IF_RELEVANT_item_sequence[] = {
2435         { BER_CLASS_CON, 0, 0,
2436                 dissect_krb5_IF_RELEVANT_type },
2437         { BER_CLASS_CON, 1, 0,
2438                 dissect_krb5_IF_RELEVANT_value },
2439         { 0, 0, 0, NULL }
2440 };
2441 static int
2442 dissect_krb5_IF_RELEVANT_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2443 {
2444         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, IF_RELEVANT_item_sequence, hf_krb_IF_RELEVANT, ett_krb_IF_RELEVANT);
2445
2446         return offset;
2447 }
2448
2449 static ber_sequence_t IF_RELEVANT_sequence_of[1] = {
2450   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_IF_RELEVANT_item },
2451 };
2452
2453 static int
2454 dissect_krb5_IF_RELEVANT(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2455 {
2456         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, IF_RELEVANT_sequence_of, -1, -1);
2457
2458         return offset;
2459 }
2460
2461 static guint32 adtype;
2462 static int
2463 dissect_krb5_adtype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2464 {
2465         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_adtype, &adtype);
2466         if(tree){
2467                 proto_item_append_text(tree, " %s",
2468                         val_to_str(adtype, krb5_ad_types,
2469                         "%#x"));
2470         }
2471         return offset;
2472 }
2473 static int
2474 dissect_krb5_advalue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2475 {
2476         switch(adtype){
2477         case KRB5_AD_IF_RELEVANT:
2478                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_advalue, dissect_krb5_IF_RELEVANT);
2479                 break;
2480         default:
2481                 offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_advalue, NULL);
2482         }
2483         return offset;
2484 }
2485 /*
2486  * AuthorizationData ::=        SEQUENCE {
2487  *     ad-type  [0] int32
2488  *     ad-data  [1] octet string
2489  */
2490 static ber_sequence_t AuthorizationData_item_sequence[] = {
2491         { BER_CLASS_CON, 0, 0,
2492                 dissect_krb5_adtype },
2493         { BER_CLASS_CON, 1, 0,
2494                 dissect_krb5_advalue },
2495         { 0, 0, 0, NULL }
2496 };
2497 static int
2498 dissect_krb5_AuthorizationData_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2499 {
2500         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, AuthorizationData_item_sequence, hf_krb_AuthorizationData, ett_krb_AuthorizationData);
2501
2502         return offset;
2503 }
2504
2505 static ber_sequence_t AuthorizationData_sequence_of[1] = {
2506   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_AuthorizationData_item },
2507 };
2508 static int
2509 dissect_krb5_AuthorizationData(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2510 {
2511         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, AuthorizationData_sequence_of, -1, -1);
2512
2513         return offset;
2514 }
2515
2516
2517 static int
2518 dissect_krb5_transited_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2519 {
2520         guint32 trtype;
2521
2522         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_transitedtype, &trtype);
2523         if(tree){
2524                 proto_item_append_text(tree, " %s",
2525                         val_to_str(trtype, krb5_transited_types,
2526                         "%#x"));
2527         }
2528         return offset;
2529 }
2530
2531 static int
2532 dissect_krb5_transited_contents(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2533 {
2534         offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_transitedcontents, NULL);
2535         return offset;
2536 }
2537
2538 /*
2539  * TransitedEncoding ::=        SEQUENCE {
2540  *     tr-type  [0] int32
2541  *     contents [1] octet string
2542  */
2543 static ber_sequence_t TransitedEncoding_sequence[] = {
2544         { BER_CLASS_CON, 0, 0,
2545                 dissect_krb5_transited_type },
2546         { BER_CLASS_CON, 1, 0,
2547                 dissect_krb5_transited_contents },
2548         { 0, 0, 0, NULL }
2549 };
2550 static int
2551 dissect_krb5_transited(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2552 {
2553         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, TransitedEncoding_sequence, hf_krb_TransitedEncoding, ett_krb_TransitedEncoding);
2554
2555         return offset;
2556 }
2557
2558
2559 static int
2560 dissect_krb5_authtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2561 {
2562         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_authtime);
2563         return offset;
2564 }
2565 static int
2566 dissect_krb5_starttime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2567 {
2568         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_starttime);
2569         return offset;
2570 }
2571 static int
2572 dissect_krb5_endtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2573 {
2574         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_endtime);
2575         return offset;
2576 }
2577 static int
2578 dissect_krb5_renew_till(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2579 {
2580         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_renew_till);
2581         return offset;
2582 }
2583
2584 /*
2585  * EncTicketPart ::=        SEQUENCE {
2586  *      flags                   [0] TicketFlags,
2587  *      key                     [1] EncryptionKey,
2588  *      crealm                  [2] Realm,
2589  *      cname                   [3] PrincipalName,
2590  *      transited               [4] TransitedEncoding,
2591  *      authtime                [5] KerberosTime,
2592  *      starttime               [6] KerberosTime OPTIONAL,
2593  *      endtime                 [7] KerberosTime,
2594  *      renew-till              [8] KerberosTime OPTIONAL,
2595  *      caddr                   [9] HostAddresses OPTIONAL,
2596  *      authorization-data      [10] AuthorizationData OPTIONAL
2597  * }
2598  */
2599 static ber_sequence_t EncTicketPart_sequence[] = {
2600         { BER_CLASS_CON, 0, 0,
2601                 dissect_krb5_TicketFlags },
2602         { BER_CLASS_CON, 1, 0,
2603                 dissect_krb5_key },
2604         { BER_CLASS_CON, 2, 0,
2605                 dissect_krb5_crealm },
2606         { BER_CLASS_CON, 3, 0,
2607                 dissect_krb5_cname },
2608         { BER_CLASS_CON, 4, 0,
2609                 dissect_krb5_transited },
2610         { BER_CLASS_CON, 5, 0,
2611                 dissect_krb5_authtime },
2612         { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
2613                 dissect_krb5_starttime },
2614         { BER_CLASS_CON, 7, 0,
2615                 dissect_krb5_endtime },
2616         { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
2617                 dissect_krb5_renew_till },
2618         { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
2619                 dissect_krb5_HostAddresses },
2620         { BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL,
2621                 dissect_krb5_AuthorizationData },
2622         { 0, 0, 0, NULL }
2623 };
2624 static int
2625 dissect_krb5_EncTicketPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2626 {
2627         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncTicketPart_sequence, hf_krb_EncTicketPart, ett_krb_EncTicketPart);
2628
2629         return offset;
2630 }
2631
2632
2633
2634
2635
2636
2637 /*
2638  * EncAPRepPart ::=        SEQUENCE {
2639  *     ctime                    [0] KerberosTime
2640  *     cusec                    [1] Microseconds
2641  *     subkey                   [2] encryptionKey OPTIONAL
2642  *     seq-number               [3] uint32 OPTIONAL
2643  * }
2644  */
2645 static ber_sequence_t EncAPRepPart_sequence[] = {
2646         { BER_CLASS_CON, 0, 0,
2647                 dissect_krb5_ctime },
2648         { BER_CLASS_CON, 1, 0,
2649                 dissect_krb5_cusec },
2650         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
2651                 dissect_krb5_subkey },
2652         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
2653                 dissect_krb5_seq_number },
2654         { 0, 0, 0, NULL }
2655 };
2656 static int
2657 dissect_krb5_EncAPRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2658 {
2659         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncAPRepPart_sequence, hf_krb_EncAPRepPart, ett_krb_EncAPRepPart);
2660
2661         return offset;
2662 }
2663
2664
2665
2666 static guint32 lr_type;
2667 static const value_string krb5_lr_types[] = {
2668     { 0              , "No information available" },
2669     { 1              , "Time of last initial TGT request" },
2670     { 2              , "Time of last initial request" },
2671     { 3              , "Time of issue of latest TGT ticket" },
2672     { 4              , "Time of last renewal" },
2673     { 5              , "Time of last request" },
2674     { 6              , "Time when password will expire" },
2675     { 7              , "Time when account will expire" },
2676     { 0, NULL }
2677 };
2678 static int
2679 dissect_krb5_lr_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2680 {
2681         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_lr_type, &lr_type);
2682
2683         return offset;
2684 }
2685 static int
2686 dissect_krb5_lr_value(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2687 {
2688         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_lr_time);
2689
2690         return offset;
2691 }
2692
2693 static ber_sequence_t LastReq_sequence[] = {
2694         { BER_CLASS_CON, 0, 0,
2695                 dissect_krb5_lr_type },
2696         { BER_CLASS_CON, 1, 0,
2697                 dissect_krb5_lr_value },
2698         { 0, 0, 0, NULL }
2699 };
2700 static int
2701 dissect_krb5_LastReq(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2702 {
2703         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, LastReq_sequence, hf_krb_LastReq, ett_krb_LastReq);
2704
2705         return offset;
2706 }
2707 static ber_sequence_t LastReq_sequence_of[1] = {
2708   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_LastReq },
2709 };
2710 static int
2711 dissect_krb5_LastReq_sequence_of(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2712 {
2713         offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, LastReq_sequence_of, hf_krb_LastReqs, ett_krb_LastReqs);
2714
2715         return offset;
2716 }
2717
2718 static int
2719 dissect_krb5_key_expiration(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2720 {
2721         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_key_expire);
2722         return offset;
2723 }
2724
2725 static ber_sequence_t EncKDCRepPart_sequence[] = {
2726         { BER_CLASS_CON, 0, 0,
2727                 dissect_krb5_key },
2728         { BER_CLASS_CON, 1, 0,
2729                 dissect_krb5_LastReq_sequence_of },
2730         { BER_CLASS_CON, 2, 0,
2731                 dissect_krb5_nonce },
2732         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
2733                 dissect_krb5_key_expiration },
2734         { BER_CLASS_CON, 4, 0,
2735                 dissect_krb5_TicketFlags },
2736         { BER_CLASS_CON, 5, 0,
2737                 dissect_krb5_authtime },
2738         { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
2739                 dissect_krb5_starttime },
2740         { BER_CLASS_CON, 7, 0,
2741                 dissect_krb5_endtime },
2742         { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
2743                 dissect_krb5_renew_till },
2744         { BER_CLASS_CON, 9, 0,
2745                 dissect_krb5_realm },
2746         { BER_CLASS_CON, 10, 0,
2747                 dissect_krb5_sname },
2748         { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
2749                 dissect_krb5_HostAddresses },
2750         { 0, 0, 0, NULL }
2751 };
2752 static int
2753 dissect_krb5_EncKDCRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2754 {
2755         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncKDCRepPart_sequence, hf_krb_EncKDCRepPart, ett_krb_EncKDCRepPart);
2756
2757         return offset;
2758 }
2759
2760
2761 static int
2762 dissect_krb5_authenticator_vno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2763 {
2764         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_authenticator_vno, NULL);
2765
2766         return offset;
2767 }
2768
2769
2770 static int
2771 dissect_krb5_checksum_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2772 {
2773         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_checksum_type, NULL);
2774
2775         return offset;
2776 }
2777 static int
2778 dissect_krb5_checksum_checksum(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2779 {
2780         offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_checksum_checksum, NULL);
2781         return offset;
2782 }
2783
2784 /*
2785  * Checksum ::=        SEQUENCE {
2786  * }
2787  */
2788 static ber_sequence_t Checksum_sequence[] = {
2789         { BER_CLASS_CON, 0, 0,
2790                 dissect_krb5_checksum_type },
2791         { BER_CLASS_CON, 1, 0,
2792                 dissect_krb5_checksum_checksum },
2793         { 0, 0, 0, NULL }
2794 };
2795 int
2796 dissect_krb5_Checksum(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2797 {
2798         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, Checksum_sequence, hf_krb_Checksum, ett_krb_Checksum);
2799
2800         return offset;
2801 }
2802
2803 /*
2804  * Authenticator ::=        SEQUENCE {
2805  *     authenticator-vno        [0] integer
2806  *     crealm                   [1] Realm
2807  *     cname                    [2] PrincipalName
2808  *     cksum                    [3] Checksum OPTIONAL
2809  *     cusec                    [4] Microseconds
2810  *     ctime                    [5] KerberosTime
2811  *     subkey                   [6] encryptionKey OPTIONAL
2812  *     seq-number               [7] uint32 OPTIONAL
2813  *     authorization-data       [8] AuthorizationData OPTIONAL
2814  * }
2815  */
2816 static ber_sequence_t Authenticator_sequence[] = {
2817         { BER_CLASS_CON, 0, 0,
2818                 dissect_krb5_authenticator_vno },
2819         { BER_CLASS_CON, 1, 0,
2820                 dissect_krb5_crealm },
2821         { BER_CLASS_CON, 2, 0,
2822                 dissect_krb5_cname },
2823         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
2824                 dissect_krb5_Checksum },
2825         { BER_CLASS_CON, 4, 0,
2826                 dissect_krb5_cusec },
2827         { BER_CLASS_CON, 5, 0,
2828                 dissect_krb5_ctime },
2829         { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
2830                 dissect_krb5_subkey },
2831         { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL,
2832                 dissect_krb5_seq_number },
2833         { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
2834                 dissect_krb5_AuthorizationData },
2835         { 0, 0, 0, NULL }
2836 };
2837 static int
2838 dissect_krb5_Authenticator(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2839 {
2840         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, Authenticator_sequence, hf_krb_Authenticator, ett_krb_Authenticator);
2841
2842         return offset;
2843 }
2844
2845
2846 static int
2847 dissect_krb5_PRIV_BODY_user_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2848 {
2849         tvbuff_t *new_tvb;
2850         offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_PRIV_BODY_user_data, &new_tvb);
2851
2852         call_kerberos_callbacks(pinfo, tree, new_tvb, KRB_CBTAG_PRIV_USER_DATA);
2853
2854         return offset;
2855 }
2856
2857 static ber_sequence_t EncKrbPrivPart_sequence[] = {
2858         { BER_CLASS_CON, 0, 0,
2859                 dissect_krb5_PRIV_BODY_user_data },
2860         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2861                 dissect_krb5_patimestamp },
2862         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
2863                 dissect_krb5_cusec },
2864         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
2865                 dissect_krb5_seq_number },
2866         { BER_CLASS_CON, 4, 0,
2867                 dissect_krb5_s_address },
2868         { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
2869                 dissect_krb5_HostAddresses },
2870         { 0, 0, 0, NULL }
2871 };
2872 static int
2873 dissect_krb5_EncKrbPrivPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2874 {
2875         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncKrbPrivPart_sequence, hf_krb_EncKrbPrivPart, ett_krb_EncKrbPrivPart);
2876
2877         return offset;
2878 }
2879
2880 static guint32 PRIV_etype;
2881 static int
2882 dissect_krb5_PRIV_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2883 {
2884         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_etype, &PRIV_etype);
2885         if(tree){
2886                 proto_item_append_text(tree, " %s",
2887                         val_to_str(PRIV_etype, krb5_encryption_types,
2888                         "%#x"));
2889         }
2890         return offset;
2891 }
2892
2893 #ifdef HAVE_KERBEROS
2894 static int
2895 dissect_krb5_decrypt_PRIV (packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2896 {
2897         guint8 *plaintext=NULL;
2898         int length;
2899
2900         length=tvb_length_remaining(tvb, offset);
2901
2902         if(!plaintext){
2903                 plaintext=decrypt_krb5_data(tree, pinfo, 13, length, tvb_get_ptr(tvb, offset, length), PRIV_etype);
2904         }
2905
2906         if(plaintext){
2907                 tvbuff_t *next_tvb;
2908                 next_tvb = tvb_new_real_data (plaintext,
2909                                           length,
2910                                           length);
2911                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
2912
2913                 /* Add the decrypted data to the data source list. */
2914                 add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
2915
2916                 offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
2917
2918         }
2919         return offset;
2920 }
2921 #endif
2922
2923 /*
2924  * PRIV-BODY ::=   SEQUENCE {
2925  *  KRB-PRIV ::=         [APPLICATION 21] SEQUENCE {
2926  *               pvno[0]                   INTEGER,
2927  *               msg-type[1]               INTEGER,
2928  *               enc-part[3]               EncryptedData
2929  *  }
2930  */
2931 static int
2932 dissect_krb5_encrypted_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2933 {
2934 #ifdef HAVE_KERBEROS
2935         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_PRIV, dissect_krb5_decrypt_PRIV);
2936 #else
2937         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_PRIV, NULL);
2938 #endif
2939         return offset;
2940 }
2941 static ber_sequence_t ENC_PRIV_sequence[] = {
2942         { BER_CLASS_CON, 0, 0,
2943                 dissect_krb5_PRIV_etype },
2944         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
2945                 dissect_krb5_kvno },
2946         { BER_CLASS_CON, 2, 0,
2947                 dissect_krb5_encrypted_PRIV },
2948         { 0, 0, 0, NULL }
2949 };
2950 static int
2951 dissect_krb5_ENC_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2952 {
2953         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, ENC_PRIV_sequence, hf_krb_ENC_PRIV, ett_krb_PRIV_enc);
2954         return offset;
2955 }
2956 static ber_sequence_t PRIV_BODY_sequence[] = {
2957         { BER_CLASS_CON, 0, 0,
2958                 dissect_krb5_pvno },
2959         { BER_CLASS_CON, 1, 0,
2960                 dissect_krb5_msg_type },
2961         { BER_CLASS_CON, 3, 0,
2962                 dissect_krb5_ENC_PRIV },
2963         { 0, 0, 0, NULL }
2964 };
2965 static int
2966 dissect_krb5_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2967 {
2968
2969         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PRIV_BODY_sequence, hf_krb_PRIV_BODY, ett_krb_PRIV);
2970
2971         return offset;
2972 }
2973
2974
2975 static int
2976 dissect_krb5_SAFE_BODY_user_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2977 {
2978         tvbuff_t *new_tvb;
2979         offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_user_data, &new_tvb);
2980         call_kerberos_callbacks(pinfo, tree, new_tvb, KRB_CBTAG_SAFE_USER_DATA);
2981         return offset;
2982 }
2983 static int
2984 dissect_krb5_SAFE_BODY_timestamp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2985 {
2986         offset=dissect_ber_GeneralizedTime(FALSE, pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_timestamp);
2987         return offset;
2988 }
2989
2990 static int
2991 dissect_krb5_SAFE_BODY_usec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
2992 {
2993         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_usec, NULL);
2994         return offset;
2995 }
2996
2997 static ber_sequence_t SAFE_BODY_sequence[] = {
2998         { BER_CLASS_CON, 0, 0,
2999                 dissect_krb5_SAFE_BODY_user_data },
3000         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3001                 dissect_krb5_SAFE_BODY_timestamp },
3002         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
3003                 dissect_krb5_SAFE_BODY_usec },
3004         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3005                 dissect_krb5_seq_number },
3006         /*XXX this one is OPTIONAL in packetcable?  but mandatory in kerberos */
3007         { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
3008                 dissect_krb5_s_address },
3009         { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
3010                 dissect_krb5_HostAddresses },
3011         { 0, 0, 0, NULL }
3012 };
3013 static int
3014 dissect_krb5_SAFE_BODY(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3015 {
3016
3017         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, SAFE_BODY_sequence, -1, -1);
3018
3019         return offset;
3020 }
3021
3022
3023
3024 static ber_sequence_t SAFE_sequence[] = {
3025         { BER_CLASS_CON, 0, 0,
3026                 dissect_krb5_pvno },
3027         { BER_CLASS_CON, 1, 0,
3028                 dissect_krb5_msg_type },
3029         { BER_CLASS_CON, 2, 0,
3030                 dissect_krb5_SAFE_BODY },
3031         { BER_CLASS_CON, 3, 0,
3032                 dissect_krb5_Checksum },
3033         { 0, 0, 0, NULL }
3034 };
3035 static int
3036 dissect_krb5_SAFE(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3037 {
3038
3039         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, SAFE_sequence, -1, -1);
3040
3041         return offset;
3042 }
3043
3044
3045 /*
3046  * KDC-REQ-BODY ::=   SEQUENCE {
3047  *           kdc-options[0]       KDCOptions,
3048  *           cname[1]             PrincipalName OPTIONAL,
3049  *                        -- Used only in AS-REQ
3050  *           realm[2]             Realm, -- Server's realm
3051  *                        -- Also client's in AS-REQ
3052  *           sname[3]             PrincipalName OPTIONAL,
3053  *           from[4]              KerberosTime OPTIONAL,
3054  *           till[5]              KerberosTime,
3055  *           rtime[6]             KerberosTime OPTIONAL,
3056  *           nonce[7]             INTEGER,
3057  *           etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
3058  *                        -- in preference order
3059  *           addresses[9]         HostAddresses OPTIONAL,
3060  *           enc-authorization-data[10]   EncryptedData OPTIONAL,
3061  *                        -- Encrypted AuthorizationData encoding
3062  *           additional-tickets[11]       SEQUENCE OF Ticket OPTIONAL
3063  * }
3064  *
3065  */
3066 static ber_sequence_t KDC_REQ_BODY_sequence[] = {
3067         { BER_CLASS_CON, 0, 0,
3068                 dissect_krb5_KDCOptions },
3069         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3070                 dissect_krb5_cname },
3071         { BER_CLASS_CON, 2, 0,
3072                 dissect_krb5_realm},
3073         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3074                 dissect_krb5_sname },
3075         { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
3076                 dissect_krb5_from },
3077                 /* this field is not optional in the kerberos spec,
3078                  * however, in the packetcable spec it is optional.
3079                  * make it optional here since normal kerberos will
3080                  * still decode the pdu correctly.
3081                  */
3082         { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
3083                 dissect_krb5_till },
3084         { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
3085                 dissect_krb5_rtime },
3086         { BER_CLASS_CON, 7, 0,
3087                 dissect_krb5_nonce },
3088         { BER_CLASS_CON, 8, 0,
3089                 dissect_krb5_etype_sequence_of },
3090         { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
3091                 dissect_krb5_HostAddresses },
3092 /* XXX [10] and [11] enc-authorization-data and additional-tickets should be added */
3093         { 0, 0, 0, NULL }
3094 };
3095 static int
3096 dissect_krb5_KDC_REQ_BODY(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3097 {
3098         conversation_t *conversation;
3099
3100         /*
3101          * UDP replies to KDC_REQs are sent from the server back to the client's
3102          * source port, similar to the way TFTP works.  Set up a conversation
3103          * accordingly.
3104          *
3105          * Ref: Section 7.2.1 of
3106          * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-07.txt
3107          */
3108         if (pinfo->destport == UDP_PORT_KERBEROS && pinfo->ptype == PT_UDP) {
3109                 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_UDP,
3110                         pinfo->srcport, 0, NO_PORT_B);
3111                 if (conversation == NULL) {
3112                         conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_UDP,
3113                                 pinfo->srcport, 0, NO_PORT2);
3114                         conversation_set_dissector(conversation, kerberos_handle_udp);
3115                 }
3116         }
3117
3118         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, KDC_REQ_BODY_sequence, hf_krb_KDC_REQ_BODY, ett_krb_request);
3119
3120         return offset;
3121 }
3122
3123
3124
3125 /*
3126  * KDC-REQ ::=        SEQUENCE {
3127  *          pvno[1]               INTEGER,
3128  *          msg-type[2]           INTEGER,
3129  *          padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
3130  *          req-body[4]           KDC-REQ-BODY
3131  * }
3132  */
3133 static ber_sequence_t KDC_REQ_sequence[] = {
3134         { BER_CLASS_CON, 1, 0,
3135                 dissect_krb5_pvno },
3136         { BER_CLASS_CON, 2, 0,
3137                 dissect_krb5_msg_type },
3138         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3139                 dissect_krb5_padata },
3140         { BER_CLASS_CON, 4, 0,
3141                 dissect_krb5_KDC_REQ_BODY },
3142         { 0, 0, 0, NULL }
3143 };
3144 static int
3145 dissect_krb5_KDC_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3146 {
3147         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, KDC_REQ_sequence, -1, -1);
3148
3149         return offset;
3150 }
3151
3152
3153 #ifdef HAVE_KERBEROS
3154 static int
3155 dissect_krb5_decrypt_authenticator_data (packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3156 {
3157         guint8 *plaintext=NULL;
3158         int length;
3159
3160         length=tvb_length_remaining(tvb, offset);
3161
3162         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3163          * 7.5.1
3164          * Authenticators are encrypted with usage
3165          * == 7 or
3166          * == 11
3167          */
3168         if(!plaintext){
3169                 plaintext=decrypt_krb5_data(tree, pinfo, 7, length, tvb_get_ptr(tvb, offset, length), authenticator_etype);
3170         }
3171         if(!plaintext){
3172                 plaintext=decrypt_krb5_data(tree, pinfo, 11, length, tvb_get_ptr(tvb, offset, length), authenticator_etype);
3173         }
3174
3175         if(plaintext){
3176                 tvbuff_t *next_tvb;
3177                 next_tvb = tvb_new_real_data (plaintext,
3178                                           length,
3179                                           length);
3180                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
3181
3182                 /* Add the decrypted data to the data source list. */
3183                 add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
3184
3185
3186                 offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
3187
3188         }
3189         return offset;
3190 }
3191 #endif
3192
3193
3194 /*
3195  *  EncryptedData ::=   SEQUENCE {
3196  *                      etype[0]     INTEGER, -- EncryptionType
3197  *                      kvno[1]      INTEGER OPTIONAL,
3198  *                      cipher[2]    OCTET STRING -- ciphertext
3199  *  }
3200  */
3201 static int
3202 dissect_krb5_encrypted_authenticator_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3203 {
3204 #ifdef HAVE_KERBEROS
3205         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_authenticator_data, dissect_krb5_decrypt_authenticator_data);
3206 #else
3207         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_authenticator_data, NULL);
3208 #endif
3209         return offset;
3210 }
3211 static ber_sequence_t encrypted_authenticator_sequence[] = {
3212         { BER_CLASS_CON, 0, 0,
3213                 dissect_krb5_authenticator_etype },
3214         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3215                 dissect_krb5_kvno },
3216         { BER_CLASS_CON, 2, 0,
3217                 dissect_krb5_encrypted_authenticator_data },
3218         { 0, 0, 0, NULL }
3219 };
3220 static int
3221 dissect_krb5_encrypted_authenticator(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3222 {
3223         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, encrypted_authenticator_sequence, hf_krb_authenticator_enc, ett_krb_authenticator_enc);
3224
3225         return offset;
3226 }
3227
3228
3229
3230
3231 static int
3232 dissect_krb5_tkt_vno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3233 {
3234         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_tkt_vno, NULL);
3235         return offset;
3236 }
3237
3238
3239 #ifdef HAVE_KERBEROS
3240 static int
3241 dissect_krb5_decrypt_Ticket_data (packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3242 {
3243         guint8 *plaintext;
3244         int length;
3245
3246         length=tvb_length_remaining(tvb, offset);
3247
3248         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3249          * 7.5.1
3250          * All Ticket encrypted parts use usage == 2
3251          */
3252         if( (plaintext=decrypt_krb5_data(tree, pinfo, 2, length, tvb_get_ptr(tvb, offset, length), Ticket_etype)) ){
3253                 tvbuff_t *next_tvb;
3254                 next_tvb = tvb_new_real_data (plaintext,
3255                                           length,
3256                                           length);
3257                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
3258
3259                 /* Add the decrypted data to the data source list. */
3260                 add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
3261
3262
3263                 offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
3264
3265         }
3266         return offset;
3267 }
3268 #endif
3269
3270 static int
3271 dissect_krb5_encrypted_Ticket_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3272 {
3273 #ifdef HAVE_KERBEROS
3274         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_Ticket_data, dissect_krb5_decrypt_Ticket_data);
3275 #else
3276         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_Ticket_data, NULL);
3277 #endif
3278         return offset;
3279 }
3280 static ber_sequence_t encrypted_Ticket_sequence[] = {
3281         { BER_CLASS_CON, 0, 0,
3282                 dissect_krb5_Ticket_etype },
3283         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3284                 dissect_krb5_kvno },
3285         { BER_CLASS_CON, 2, 0,
3286                 dissect_krb5_encrypted_Ticket_data },
3287         { 0, 0, 0, NULL }
3288 };
3289 static int
3290 dissect_krb5_Ticket_encrypted(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3291 {
3292         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, encrypted_Ticket_sequence, hf_krb_ticket_enc, ett_krb_ticket_enc);
3293
3294         return offset;
3295 }
3296
3297 static ber_sequence_t Application_1_sequence[] = {
3298         { BER_CLASS_CON, 0, 0,
3299                 dissect_krb5_tkt_vno },
3300         { BER_CLASS_CON, 1, 0,
3301                 dissect_krb5_realm },
3302         { BER_CLASS_CON, 2, 0,
3303                 dissect_krb5_sname },
3304         { BER_CLASS_CON, 3, 0,
3305                 dissect_krb5_Ticket_encrypted },
3306         { 0, 0, 0, NULL }
3307 };
3308 static int
3309 dissect_krb5_Application_1(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3310 {
3311         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, Application_1_sequence, hf_krb_ticket, ett_krb_ticket);
3312
3313         return offset;
3314 }
3315
3316
3317
3318 static const ber_choice_t Ticket_choice[] = {
3319         { 1, BER_CLASS_APP, 1,  0,
3320                 dissect_krb5_Application_1 },
3321         { 0, 0, 0, 0, NULL }
3322 };
3323 static int
3324 dissect_krb5_Ticket(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3325 {
3326         offset=dissect_ber_choice(pinfo, tree, tvb, offset, Ticket_choice, -1, -1, NULL);
3327
3328         return offset;
3329 }
3330
3331
3332
3333
3334 /*
3335  *  AP-REQ ::=      [APPLICATION 14] SEQUENCE {
3336  *                  pvno[0]                       INTEGER,
3337  *                  msg-type[1]                   INTEGER,
3338  *                  ap-options[2]                 APOptions,
3339  *                  ticket[3]                     Ticket,
3340  *                  authenticator[4]              EncryptedData
3341  *  }
3342  */
3343 static ber_sequence_t AP_REQ_sequence[] = {
3344         { BER_CLASS_CON, 0, 0,
3345                 dissect_krb5_pvno },
3346         { BER_CLASS_CON, 1, 0,
3347                 dissect_krb5_msg_type },
3348         { BER_CLASS_CON, 2, 0,
3349                 dissect_krb5_APOptions },
3350         { BER_CLASS_CON, 3, 0,
3351                 dissect_krb5_Ticket },
3352         { BER_CLASS_CON, 4, 0,
3353                 dissect_krb5_encrypted_authenticator },
3354         { 0, 0, 0, NULL }
3355 };
3356 static int
3357 dissect_krb5_AP_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3358 {
3359         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, AP_REQ_sequence, -1, -1);
3360
3361         return offset;
3362 }
3363
3364
3365
3366
3367 #ifdef HAVE_KERBEROS
3368 static int
3369 dissect_krb5_decrypt_AP_REP_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3370 {
3371         guint8 *plaintext=NULL;
3372         int length;
3373
3374         length=tvb_length_remaining(tvb, offset);
3375
3376         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3377          * 7.5.1
3378          * Authenticators are encrypted with usage
3379          * == 7 or
3380          * == 11
3381          */
3382         if(!plaintext){
3383                 plaintext=decrypt_krb5_data(tree, pinfo, 12, length, tvb_get_ptr(tvb, offset, length), AP_REP_etype);
3384         }
3385
3386         if(plaintext){
3387                 tvbuff_t *next_tvb;
3388                 next_tvb = tvb_new_real_data (plaintext,
3389                                           length,
3390                                           length);
3391                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
3392
3393                 /* Add the decrypted data to the data source list. */
3394                 add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
3395
3396
3397                 offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
3398
3399         }
3400         return offset;
3401 }
3402 #endif
3403
3404
3405 static int
3406 dissect_krb5_encrypted_AP_REP_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3407 {
3408 #ifdef HAVE_KERBEROS
3409         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_AP_REP_data, dissect_krb5_decrypt_AP_REP_data);
3410 #else
3411         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_AP_REP_data, NULL);
3412 #endif
3413         return offset;
3414 }
3415 static ber_sequence_t encrypted_AP_REP_sequence[] = {
3416         { BER_CLASS_CON, 0, 0,
3417                 dissect_krb5_AP_REP_etype },
3418         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3419                 dissect_krb5_kvno },
3420         { BER_CLASS_CON, 2, 0,
3421                 dissect_krb5_encrypted_AP_REP_data },
3422         { 0, 0, 0, NULL }
3423 };
3424 static int
3425 dissect_krb5_encrypted_AP_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3426 {
3427         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, encrypted_AP_REP_sequence, hf_krb_AP_REP_enc, ett_krb_AP_REP_enc);
3428
3429         return offset;
3430 }
3431
3432 /*
3433  *  AP-REP ::=         [APPLICATION 15] SEQUENCE {
3434  *             pvno[0]                   INTEGER,
3435  *             msg-type[1]               INTEGER,
3436  *             enc-part[2]               EncryptedData
3437  *  }
3438  */
3439 static ber_sequence_t AP_REP_sequence[] = {
3440         { BER_CLASS_CON, 0, 0,
3441                 dissect_krb5_pvno },
3442         { BER_CLASS_CON, 1, 0,
3443                 dissect_krb5_msg_type },
3444         { BER_CLASS_CON, 2, 0,
3445                 dissect_krb5_encrypted_AP_REP },
3446         { 0, 0, 0, NULL }
3447 };
3448 static int
3449 dissect_krb5_AP_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3450 {
3451         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, AP_REP_sequence, -1, -1);
3452
3453         return offset;
3454 }
3455
3456
3457
3458
3459
3460 static guint32 KDC_REP_etype;
3461 static int
3462 dissect_krb5_KDC_REP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3463 {
3464         offset=dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_krb_etype, &KDC_REP_etype);
3465         if(tree){
3466                 proto_item_append_text(tree, " %s",
3467                         val_to_str(KDC_REP_etype, krb5_encryption_types,
3468                         "%#x"));
3469         }
3470         return offset;
3471 }
3472
3473 #ifdef HAVE_KERBEROS
3474 static int
3475 dissect_krb5_decrypt_KDC_REP_data (packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3476 {
3477         guint8 *plaintext=NULL;
3478         int length;
3479
3480         length=tvb_length_remaining(tvb, offset);
3481
3482         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3483          * 7.5.1
3484          * ASREP/TGSREP encryptedparts are encrypted with usage
3485          * == 3 or
3486          * == 8 or
3487          * == 9
3488          */
3489         if(!plaintext){
3490                 plaintext=decrypt_krb5_data(tree, pinfo, 3, length, tvb_get_ptr(tvb, offset, length), KDC_REP_etype);
3491         }
3492         if(!plaintext){
3493                 plaintext=decrypt_krb5_data(tree, pinfo, 8, length, tvb_get_ptr(tvb, offset, length), KDC_REP_etype);
3494         }
3495         if(!plaintext){
3496                 plaintext=decrypt_krb5_data(tree, pinfo, 9, length, tvb_get_ptr(tvb, offset, length), KDC_REP_etype);
3497         }
3498
3499         if(plaintext){
3500                 tvbuff_t *next_tvb;
3501                 next_tvb = tvb_new_real_data (plaintext,
3502                                           length,
3503                                           length);
3504                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
3505
3506                 /* Add the decrypted data to the data source list. */
3507                 add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
3508
3509
3510                 offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1, NULL);
3511
3512         }
3513         return offset;
3514 }
3515 #endif
3516
3517
3518 static int
3519 dissect_krb5_encrypted_KDC_REP_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3520 {
3521 #ifdef HAVE_KERBEROS
3522         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_KDC_REP_data, dissect_krb5_decrypt_KDC_REP_data);
3523 #else
3524         offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_KDC_REP_data, NULL);
3525 #endif
3526         return offset;
3527 }
3528 static ber_sequence_t encrypted_KDC_REP_sequence[] = {
3529         { BER_CLASS_CON, 0, 0,
3530                 dissect_krb5_KDC_REP_etype },
3531         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
3532                 dissect_krb5_kvno },
3533         { BER_CLASS_CON, 2, 0,
3534                 dissect_krb5_encrypted_KDC_REP_data },
3535         { 0, 0, 0, NULL }
3536 };
3537 static int
3538 dissect_krb5_encrypted_KDC_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3539 {
3540         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, encrypted_KDC_REP_sequence, hf_krb_KDC_REP_enc, ett_krb_KDC_REP_enc);
3541
3542         return offset;
3543 }
3544
3545 /*
3546  *  KDC-REP ::=   SEQUENCE {
3547  *                pvno[0]                    INTEGER,
3548  *                msg-type[1]                INTEGER,
3549  *                padata[2]                  SEQUENCE OF PA-DATA OPTIONAL,
3550  *                crealm[3]                  Realm,
3551  *                cname[4]                   PrincipalName,
3552  *                ticket[5]                  Ticket,
3553  *                enc-part[6]                EncryptedData
3554  *  }
3555  */
3556 static ber_sequence_t KDC_REP_sequence[] = {
3557         { BER_CLASS_CON, 0, 0,
3558                 dissect_krb5_pvno },
3559         { BER_CLASS_CON, 1, 0,
3560                 dissect_krb5_msg_type },
3561         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
3562                 dissect_krb5_padata },
3563         { BER_CLASS_CON, 3, 0,
3564                 dissect_krb5_crealm },
3565         { BER_CLASS_CON, 4, 0,
3566                 dissect_krb5_cname },
3567         { BER_CLASS_CON, 5, 0,
3568                 dissect_krb5_Ticket },
3569         { BER_CLASS_CON, 6, 0,
3570                 dissect_krb5_encrypted_KDC_REP },
3571         { 0, 0, 0, NULL }
3572 };
3573 static int
3574 dissect_krb5_KDC_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3575 {
3576         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, KDC_REP_sequence, -1, -1);
3577
3578         return offset;
3579 }
3580
3581
3582
3583
3584 static int
3585 dissect_krb5_e_text(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3586 {
3587         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_e_text, NULL, 0);
3588         return offset;
3589 }
3590
3591 static int
3592 dissect_krb5_e_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3593 {
3594         switch(krb5_errorcode){
3595         case KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED:
3596                 offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_e_data, dissect_krb5_padata);
3597
3598                 break;
3599         default:
3600                 offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_e_data, NULL);
3601         }
3602         return offset;
3603 }
3604
3605
3606 /* This optional field in KRB_ERR is used by the early drafts which
3607  * PacketCable still use.
3608  */
3609 static int
3610 dissect_krb5_e_checksum(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3611 {
3612         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, Checksum_sequence, hf_krb_e_checksum, ett_krb_e_checksum);
3613
3614         return offset;
3615 }
3616
3617
3618 /*
3619  *  KRB-ERROR ::=   [APPLICATION 30] SEQUENCE {
3620  *                  pvno[0]               INTEGER,
3621  *                  msg-type[1]           INTEGER,
3622  *                  ctime[2]              KerberosTime OPTIONAL,
3623  *                  cusec[3]              INTEGER OPTIONAL,
3624  *                  stime[4]              KerberosTime,
3625  *                  susec[5]              INTEGER,
3626  *                  error-code[6]         INTEGER,
3627  *                  crealm[7]             Realm OPTIONAL,
3628  *                  cname[8]              PrincipalName OPTIONAL,
3629  *                  realm[9]              Realm, -- Correct realm
3630  *                  sname[10]             PrincipalName, -- Correct name
3631  *                  e-text[11]            GeneralString OPTIONAL,
3632  *                  e-data[12]            OCTET STRING OPTIONAL
3633  *  }
3634  *
3635  *  e-data    This field contains additional data about the error for use
3636  *            by the application to help it recover from or handle the
3637  *            error.  If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then
3638  *            the e-data field will contain an encoding of a sequence of
3639  *            padata fields, each corresponding to an acceptable pre-
3640  *            authentication method and optionally containing data for
3641  *            the method:
3642  */
3643 static ber_sequence_t ERROR_sequence[] = {
3644         { BER_CLASS_CON, 0, 0,
3645                 dissect_krb5_pvno },
3646         { BER_CLASS_CON, 1, 0,
3647                 dissect_krb5_msg_type },
3648         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
3649                 dissect_krb5_ctime },
3650         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
3651                 dissect_krb5_cusec },
3652         { BER_CLASS_CON, 4, 0,
3653                 dissect_krb5_stime },
3654         { BER_CLASS_CON, 5, 0,
3655                 dissect_krb5_susec },
3656         { BER_CLASS_CON, 6, 0,
3657                 dissect_krb5_error_code },
3658         { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL,
3659                 dissect_krb5_crealm },
3660         { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
3661                 dissect_krb5_cname },
3662         { BER_CLASS_CON, 9, 0,
3663                 dissect_krb5_realm },
3664         { BER_CLASS_CON, 10, 0,
3665                 dissect_krb5_sname },
3666         { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
3667                 dissect_krb5_e_text },
3668         { BER_CLASS_CON, 12, BER_FLAGS_OPTIONAL,
3669                 dissect_krb5_e_data },
3670         { BER_CLASS_CON, 13, BER_FLAGS_OPTIONAL,
3671                 dissect_krb5_e_checksum }, /* used by PacketCable */
3672         { 0, 0, 0, NULL }
3673 };
3674 int
3675 dissect_krb5_ERROR(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
3676 {
3677         offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, ERROR_sequence, -1, -1);
3678
3679         return offset;
3680 }
3681
3682
3683
3684 static struct { const char *set; const char *unset; } bitval = { "Set", "Not set" };
3685
3686 static gint dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo,
3687                                  proto_tree *tree);
3688 static void dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo,
3689                                  proto_tree *tree);
3690 static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo,
3691                                         proto_tree *tree, int do_col_info,
3692                                         gboolean have_rm,
3693                                         kerberos_callbacks *cb);
3694 static gint kerberos_rm_to_reclen(guint krb_rm);
3695 static void dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo,
3696                                 proto_tree *tree);
3697 static guint get_krb_pdu_len(tvbuff_t *tvb, int offset);
3698
3699
3700
3701 gint
3702 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
3703 {
3704     return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, cb));
3705 }
3706
3707 guint32 
3708 kerberos_output_keytype(void)
3709 {
3710   return keytype;
3711 }
3712
3713 static gint
3714 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3715 {
3716     /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
3717        Since all (except weirdo transarc krb4 stuff) use 
3718        an opcode <=16 in the first byte, use this to see if it might
3719        be krb4.
3720        All krb5 commands start with an APPL tag and thus is >=0x60
3721        so if first byte is <=16  just blindly assume it is krb4 then
3722     */
3723     if(tvb_bytes_exist(tvb, 0, 1) && tvb_get_guint8(tvb, 0)<=0x10){
3724       if(krb4_handle){ 
3725         return call_dissector(krb4_handle, tvb, pinfo, tree);
3726       }else{
3727         return 0;
3728       }
3729     }
3730
3731
3732     if (check_col(pinfo->cinfo, COL_PROTOCOL))
3733         col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
3734
3735     return dissect_kerberos_common(tvb, pinfo, tree, TRUE, FALSE, NULL);
3736 }
3737
3738 static gint
3739 kerberos_rm_to_reclen(guint krb_rm)
3740 {
3741     return (krb_rm & KRB_RM_RECLEN);
3742 }
3743
3744 static guint
3745 get_krb_pdu_len(tvbuff_t *tvb, int offset)
3746 {
3747     guint krb_rm;
3748     gint pdulen;
3749
3750     krb_rm = tvb_get_ntohl(tvb, offset);
3751     pdulen = kerberos_rm_to_reclen(krb_rm);
3752     return (pdulen + 4);
3753 }
3754
3755 static void
3756 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3757 {
3758     pinfo->fragmented = TRUE;
3759     if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, NULL) < 0) {
3760         /*
3761          * The dissector failed to recognize this as a valid
3762          * Kerberos message.  Mark it as a continuation packet.
3763          */
3764         if (check_col(pinfo->cinfo, COL_INFO)) {
3765                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
3766         }
3767     }
3768 }
3769
3770 static void
3771 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3772 {
3773     if (check_col(pinfo->cinfo, COL_PROTOCOL))
3774         col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
3775
3776     tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
3777         dissect_kerberos_tcp_pdu);
3778 }
3779
3780 /*
3781  * Display the TCP record mark.
3782  */
3783 static void
3784 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
3785 {
3786     gint rec_len;
3787     proto_item *rm_item;
3788     proto_tree *rm_tree;
3789
3790     if (tree == NULL)
3791         return;
3792
3793     rec_len = kerberos_rm_to_reclen(krb_rm);
3794     rm_item = proto_tree_add_text(tree, tvb, start, 4,
3795         "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
3796     rm_tree = proto_item_add_subtree(rm_item, ett_krb_recordmark);
3797     proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
3798     proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
3799 }
3800
3801
3802 static gint
3803 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3804     int dci, gboolean have_rm, kerberos_callbacks *cb)
3805 {
3806     int offset = 0;
3807     proto_tree *kerberos_tree = NULL;
3808     proto_item *item = NULL;
3809     void *saved_private_data;
3810
3811     /* TCP record mark and length */
3812     guint32 krb_rm = 0;
3813     gint krb_reclen = 0;
3814
3815     saved_private_data=pinfo->private_data;
3816     pinfo->private_data=cb;
3817     do_col_info=dci;
3818
3819     if (tree) {
3820         item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, FALSE);
3821         kerberos_tree = proto_item_add_subtree(item, ett_krb_kerberos);
3822     }
3823
3824     if (have_rm) {
3825         krb_rm = tvb_get_ntohl(tvb, offset);
3826         krb_reclen = kerberos_rm_to_reclen(krb_rm);
3827         /*
3828          * What is a reasonable size limit?
3829          */
3830         if (krb_reclen > 10 * 1024 * 1024) {
3831             pinfo->private_data=saved_private_data;
3832             return (-1);
3833         }
3834         show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
3835         offset += 4;
3836     }
3837
3838     /* Do some sanity checking here, 
3839      * All krb5 packets start with a TAG class that is BER_CLASS_APP
3840      * and a tag value that is either of the values below:
3841      * If it doesnt look like kerberos, return 0 and let someone else have
3842      * a go at it.
3843      */
3844     if (!have_rm) {
3845         gint8 tmp_class;
3846         gboolean tmp_pc;
3847         gint32 tmp_tag;
3848
3849         get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
3850         if(tmp_class!=BER_CLASS_APP){
3851             return 0;
3852         }
3853         switch(tmp_tag){
3854             case KRB5_MSG_AUTHENTICATOR:
3855             case KRB5_MSG_ENC_TICKET_PART:
3856             case KRB5_MSG_AS_REQ:
3857             case KRB5_MSG_AS_REP:
3858             case KRB5_MSG_TGS_REQ:
3859             case KRB5_MSG_TGS_REP:
3860             case KRB5_MSG_AP_REQ:
3861             case KRB5_MSG_AP_REP:
3862             case KRB5_MSG_ENC_AS_REP_PART:
3863             case KRB5_MSG_ENC_TGS_REP_PART:
3864             case KRB5_MSG_ENC_AP_REP_PART:
3865             case KRB5_MSG_ENC_KRB_PRIV_PART:
3866             case KRB5_MSG_SAFE:
3867             case KRB5_MSG_PRIV:
3868             case KRB5_MSG_ERROR:
3869                 break;
3870             default:
3871                 return 0;
3872         }
3873     }
3874
3875     TRY {
3876         offset=dissect_ber_choice(pinfo, kerberos_tree, tvb, offset, kerberos_applications_choice, -1, -1, NULL);
3877     } CATCH_ALL {
3878         pinfo->private_data=saved_private_data;
3879         RETHROW;
3880     } ENDTRY;
3881
3882     proto_item_set_len(item, offset);
3883     pinfo->private_data=saved_private_data;
3884     return offset;
3885 }
3886
3887 static void
3888 kerberos_prefs_apply_cb(void) {
3889 #ifdef HAVE_LIBNETTLE
3890         clear_keytab();
3891         read_keytab_file(keytab_filename);
3892 #endif
3893 }
3894
3895 void
3896 proto_register_kerberos(void)
3897 {
3898     static hf_register_info hf[] = {
3899         { &hf_krb_rm_reserved, {
3900             "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
3901             &bitval, KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
3902         { &hf_krb_rm_reclen, {
3903             "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
3904             NULL, KRB_RM_RECLEN, "Record length", HFILL }},
3905         { &hf_krb_transitedtype, {
3906             "Type", "kerberos.transited.type", FT_UINT32, BASE_DEC,
3907             VALS(krb5_transited_types), 0, "Transited Type", HFILL }},
3908         { &hf_krb_transitedcontents, {
3909             "Contents", "kerberos.transited.contents", FT_BYTES, BASE_HEX,
3910             NULL, 0, "Transitent Contents string", HFILL }},
3911         { &hf_krb_keytype, {
3912             "Key type", "kerberos.keytype", FT_UINT32, BASE_DEC,
3913             VALS(krb5_encryption_types), 0, "Key Type", HFILL }},
3914         { &hf_krb_keyvalue, {
3915             "Key value", "kerberos.keyvalue", FT_BYTES, BASE_HEX,
3916             NULL, 0, "Key value (encryption key)", HFILL }},
3917         { &hf_krb_adtype, {
3918             "Type", "kerberos.adtype", FT_UINT32, BASE_DEC,
3919             VALS(krb5_ad_types), 0, "Authorization Data Type", HFILL }},
3920         { &hf_krb_IF_RELEVANT_type, {
3921             "Type", "kerberos.IF_RELEVANT.type", FT_UINT32, BASE_DEC,
3922             VALS(krb5_ad_types), 0, "IF-RELEVANT Data Type", HFILL }},
3923         { &hf_krb_advalue, {
3924             "Data", "kerberos.advalue", FT_BYTES, BASE_HEX,
3925             NULL, 0, "Authentication Data", HFILL }},
3926         { &hf_krb_IF_RELEVANT_value, {
3927             "Data", "kerberos.IF_RELEVANT.value", FT_BYTES, BASE_HEX,
3928             NULL, 0, "IF_RELEVANT Data", HFILL }},
3929         { &hf_krb_etype, {
3930             "Encryption type", "kerberos.etype", FT_INT32, BASE_DEC,
3931             VALS(krb5_encryption_types), 0, "Encryption Type", HFILL }},
3932         { &hf_krb_addr_type, {
3933             "Addr-type", "kerberos.addr_type", FT_UINT32, BASE_DEC,
3934             VALS(krb5_address_types), 0, "Address Type", HFILL }},
3935         { &hf_krb_pac_signature_type, {
3936             "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
3937             NULL, 0, "PAC Signature Type", HFILL }},
3938         { &hf_krb_name_type, {
3939             "Name-type", "kerberos.name_type", FT_INT32, BASE_DEC,
3940             VALS(krb5_princ_types), 0, "Type of principal name", HFILL }},
3941         { &hf_krb_lr_type, {
3942             "Lr-type", "kerberos.lr_type", FT_UINT32, BASE_DEC,
3943             VALS(krb5_lr_types), 0, "Type of lastreq value", HFILL }},
3944         { &hf_krb_address_ip, {
3945             "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
3946             NULL, 0, "IP Address", HFILL }},
3947         { &hf_krb_address_netbios, {
3948             "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
3949             NULL, 0, "NetBIOS Address and type", HFILL }},
3950         { &hf_krb_authtime, {
3951             "Authtime", "kerberos.authtime", FT_STRING, BASE_NONE,
3952             NULL, 0, "Time of initial authentication", HFILL }},
3953         { &hf_krb_SAFE_BODY_timestamp, {
3954             "Timestamp", "kerberos.SAFE_BODY.timestamp", FT_STRING, BASE_NONE,
3955             NULL, 0, "Timestamp of this SAFE_BODY", HFILL }},
3956         { &hf_krb_patimestamp, {
3957             "patimestamp", "kerberos.patimestamp", FT_STRING, BASE_NONE,
3958             NULL, 0, "Time of client", HFILL }},
3959         { &hf_krb_pausec, {
3960             "pausec", "kerberos.pausec", FT_UINT32, BASE_DEC,
3961             NULL, 0, "Microsecond component of client time", HFILL }},
3962         { &hf_krb_lr_time, {
3963             "Lr-time", "kerberos.lr_time", FT_STRING, BASE_NONE,
3964             NULL, 0, "Time of LR-entry", HFILL }},
3965         { &hf_krb_starttime, {
3966             "Start time", "kerberos.starttime", FT_STRING, BASE_NONE,
3967             NULL, 0, "The time after which the ticket is valid", HFILL }},
3968         { &hf_krb_endtime, {
3969             "End time", "kerberos.endtime", FT_STRING, BASE_NONE,
3970             NULL, 0, "The time after which the ticket has expired", HFILL }},
3971         { &hf_krb_key_expire, {
3972             "Key Expiration", "kerberos.key_expiration", FT_STRING, BASE_NONE,
3973             NULL, 0, "The time after which the key will expire", HFILL }},
3974         { &hf_krb_renew_till, {
3975             "Renew-till", "kerberos.renenw_till", FT_STRING, BASE_NONE,
3976             NULL, 0, "The maximum time we can renew the ticket until", HFILL }},
3977         { &hf_krb_rtime, {
3978             "rtime", "kerberos.rtime", FT_STRING, BASE_NONE,
3979             NULL, 0, "Renew Until timestamp", HFILL }},
3980         { &hf_krb_ctime, {
3981             "ctime", "kerberos.ctime", FT_STRING, BASE_NONE,
3982             NULL, 0, "Current Time on the client host", HFILL }},
3983         { &hf_krb_cusec, {
3984             "cusec", "kerberos.cusec", FT_UINT32, BASE_DEC,
3985             NULL, 0, "micro second component of client time", HFILL }},
3986         { &hf_krb_SAFE_BODY_usec, {
3987             "usec", "kerberos.SAFE_BODY.usec", FT_UINT32, BASE_DEC,
3988             NULL, 0, "micro second component of SAFE_BODY time", HFILL }},
3989         { &hf_krb_stime, {
3990             "stime", "kerberos.stime", FT_STRING, BASE_NONE,
3991             NULL, 0, "Current Time on the server host", HFILL }},
3992         { &hf_krb_susec, {
3993             "susec", "kerberos.susec", FT_UINT32, BASE_DEC,
3994             NULL, 0, "micro second component of server time", HFILL }},
3995         { &hf_krb_error_code, {
3996             "error_code", "kerberos.error_code", FT_UINT32, BASE_DEC,
3997             VALS(krb5_error_codes), 0, "Kerberos error code", HFILL }},
3998         { &hf_krb_from, {
3999             "from", "kerberos.from", FT_STRING, BASE_NONE,
4000             NULL, 0, "From when the ticket is to be valid (postdating)", HFILL }},
4001         { &hf_krb_till, {
4002             "till", "kerberos.till", FT_STRING, BASE_NONE,
4003             NULL, 0, "When the ticket will expire", HFILL }},
4004         { &hf_krb_name_string, {
4005             "Name", "kerberos.name_string", FT_STRING, BASE_NONE,
4006             NULL, 0, "String component that is part of a PrincipalName", HFILL }},
4007         { &hf_krb_provsrv_location, {
4008             "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
4009             NULL, 0, "PacketCable PROV SRV Location", HFILL }},
4010         { &hf_krb_e_text, {
4011             "e-text", "kerberos.e_text", FT_STRING, BASE_NONE,
4012             NULL, 0, "Additional (human readable) error description", HFILL }},
4013         { &hf_krb_realm, {
4014             "Realm", "kerberos.realm", FT_STRING, BASE_NONE,
4015             NULL, 0, "Name of the Kerberos Realm", HFILL }},
4016         { &hf_krb_crealm, {
4017             "Client Realm", "kerberos.crealm", FT_STRING, BASE_NONE,
4018             NULL, 0, "Name of the Clients Kerberos Realm", HFILL }},
4019         { &hf_krb_pac_clientname, {
4020             "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
4021             NULL, 0, "Name of the Client in the PAC structure", HFILL }},
4022         { &hf_krb_msg_type, {
4023             "MSG Type", "kerberos.msg.type", FT_UINT32, BASE_DEC,
4024             VALS(krb5_msg_types), 0, "Kerberos Message Type", HFILL }},
4025         { &hf_krb_APOptions, {
4026             "APOptions", "kerberos.apoptions", FT_BYTES, BASE_HEX,
4027             NULL, 0, "Kerberos APOptions bitstring", HFILL }},
4028         { &hf_krb_APOptions_use_session_key, {
4029             "Use Session Key", "kerberos.apoptions.use_session_key", FT_BOOLEAN, 32,
4030             TFS(&krb5_apoptions_use_session_key), 0x40000000, "", HFILL }},
4031         { &hf_krb_APOptions_mutual_required, {
4032             "Mutual required", "kerberos.apoptions.mutual_required", FT_BOOLEAN, 32,
4033             TFS(&krb5_apoptions_mutual_required), 0x20000000, "", HFILL }},
4034         { &hf_krb_KDCOptions, {
4035             "KDCOptions", "kerberos.kdcoptions", FT_BYTES, BASE_HEX,
4036             NULL, 0, "Kerberos KDCOptions bitstring", HFILL }},
4037         { &hf_krb_TicketFlags, {
4038             "Ticket Flags", "kerberos.ticketflags", FT_NONE, BASE_NONE,
4039             NULL, 0, "Kerberos Ticket Flags", HFILL }},
4040         { &hf_krb_TicketFlags_forwardable, {
4041             "Forwardable", "kerberos.ticketflags.forwardable", FT_BOOLEAN, 32,
4042             TFS(&krb5_ticketflags_forwardable), 0x40000000, "Flag controlling whether the tickes are forwardable or not", HFILL }},
4043         { &hf_krb_TicketFlags_forwarded, {
4044             "Forwarded", "kerberos.ticketflags.forwarded", FT_BOOLEAN, 32,
4045             TFS(&krb5_ticketflags_forwarded), 0x20000000, "Has this ticket been forwarded?", HFILL }},
4046         { &hf_krb_TicketFlags_proxyable, {
4047             "Proxyable", "kerberos.ticketflags.proxyable", FT_BOOLEAN, 32,
4048             TFS(&krb5_ticketflags_proxyable), 0x10000000, "Flag controlling whether the tickes are proxyable or not", HFILL }},
4049         { &hf_krb_TicketFlags_proxy, {
4050             "Proxy", "kerberos.ticketflags.proxy", FT_BOOLEAN, 32,
4051             TFS(&krb5_ticketflags_proxy), 0x08000000, "Has this ticket been proxied?", HFILL }},
4052         { &hf_krb_TicketFlags_allow_postdate, {
4053             "Allow Postdate", "kerberos.ticketflags.allow_postdate", FT_BOOLEAN, 32,
4054             TFS(&krb5_ticketflags_allow_postdate), 0x04000000, "Flag controlling whether we allow postdated tickets or not", HFILL }},
4055         { &hf_krb_TicketFlags_postdated, {
4056             "Postdated", "kerberos.ticketflags.postdated", FT_BOOLEAN, 32,
4057             TFS(&krb5_ticketflags_postdated), 0x02000000, "Whether this ticket is postdated or not", HFILL }},
4058         { &hf_krb_TicketFlags_invalid, {
4059             "Invalid", "kerberos.ticketflags.invalid", FT_BOOLEAN, 32,
4060             TFS(&krb5_ticketflags_invalid), 0x01000000, "Whether this ticket is invalid or not", HFILL }},
4061         { &hf_krb_TicketFlags_renewable, {
4062             "Renewable", "kerberos.ticketflags.renewable", FT_BOOLEAN, 32,
4063             TFS(&krb5_ticketflags_renewable), 0x00800000, "Whether this ticket is renewable or not", HFILL }},
4064         { &hf_krb_TicketFlags_initial, {
4065             "Initial", "kerberos.ticketflags.initial", FT_BOOLEAN, 32,
4066             TFS(&krb5_ticketflags_initial), 0x00400000, "Whether this ticket is an initial ticket or not", HFILL }},
4067         { &hf_krb_TicketFlags_pre_auth, {
4068             "Pre-Auth", "kerberos.ticketflags.pre_auth", FT_BOOLEAN, 32,
4069             TFS(&krb5_ticketflags_pre_auth), 0x00200000, "Whether this ticket is pre-authenticated or not", HFILL }},
4070         { &hf_krb_TicketFlags_hw_auth, {
4071             "HW-Auth", "kerberos.ticketflags.hw_auth", FT_BOOLEAN, 32,
4072             TFS(&krb5_ticketflags_hw_auth), 0x00100000, "Whether this ticket is hardware-authenticated or not", HFILL }},
4073         { &hf_krb_TicketFlags_transited_policy_checked, {
4074             "Transited Policy Checked", "kerberos.ticketflags.transited_policy_checked", FT_BOOLEAN, 32,
4075             TFS(&krb5_ticketflags_transited_policy_checked), 0x00080000, "Whether this ticket is transited policy checked or not", HFILL }},
4076         { &hf_krb_TicketFlags_ok_as_delegate, {
4077             "Ok As Delegate", "kerberos.ticketflags.ok_as_delegate", FT_BOOLEAN, 32,
4078             TFS(&krb5_ticketflags_ok_as_delegate), 0x00040000, "Whether this ticket is Ok As Delegate or not", HFILL }},
4079         { &hf_krb_KDC_REQ_BODY, {
4080             "KDC_REQ_BODY", "kerberos.kdc_req_body", FT_NONE, BASE_NONE,
4081             NULL, 0, "Kerberos KDC REQuest BODY", HFILL }},
4082         { &hf_krb_PRIV_BODY, {
4083             "PRIV_BODY", "kerberos.priv_body", FT_NONE, BASE_NONE,
4084             NULL, 0, "Kerberos PRIVate BODY", HFILL }},
4085         { &hf_krb_encrypted_PRIV, {
4086             "Encrypted PRIV", "kerberos.enc_priv", FT_NONE, BASE_NONE,
4087             NULL, 0, "Kerberos Encrypted PRIVate blob data", HFILL }},
4088         { &hf_krb_KDCOptions_forwardable, {
4089             "Forwardable", "kerberos.kdcoptions.forwardable", FT_BOOLEAN, 32,
4090             TFS(&krb5_kdcoptions_forwardable), 0x40000000, "Flag controlling whether the tickes are forwardable or not", HFILL }},
4091         { &hf_krb_KDCOptions_forwarded, {
4092             "Forwarded", "kerberos.kdcoptions.forwarded", FT_BOOLEAN, 32,
4093             TFS(&krb5_kdcoptions_forwarded), 0x20000000, "Has this ticket been forwarded?", HFILL }},
4094         { &hf_krb_KDCOptions_proxyable, {
4095             "Proxyable", "kerberos.kdcoptions.proxyable", FT_BOOLEAN, 32,
4096             TFS(&krb5_kdcoptions_proxyable), 0x10000000, "Flag controlling whether the tickes are proxyable or not", HFILL }},
4097         { &hf_krb_KDCOptions_proxy, {
4098             "Proxy", "kerberos.kdcoptions.proxy", FT_BOOLEAN, 32,
4099             TFS(&krb5_kdcoptions_proxy), 0x08000000, "Has this ticket been proxied?", HFILL }},
4100         { &hf_krb_KDCOptions_allow_postdate, {
4101             "Allow Postdate", "kerberos.kdcoptions.allow_postdate", FT_BOOLEAN, 32,
4102             TFS(&krb5_kdcoptions_allow_postdate), 0x04000000, "Flag controlling whether we allow postdated tickets or not", HFILL }},
4103         { &hf_krb_KDCOptions_postdated, {
4104             "Postdated", "kerberos.kdcoptions.postdated", FT_BOOLEAN, 32,
4105             TFS(&krb5_kdcoptions_postdated), 0x02000000, "Whether this ticket is postdated or not", HFILL }},
4106         { &hf_krb_KDCOptions_renewable, {
4107             "Renewable", "kerberos.kdcoptions.renewable", FT_BOOLEAN, 32,
4108             TFS(&krb5_kdcoptions_renewable), 0x00800000, "Whether this ticket is renewable or not", HFILL }},
4109         { &hf_krb_KDCOptions_canonicalize, {
4110             "Canonicalize", "kerberos.kdcoptions.canonicalize", FT_BOOLEAN, 32,
4111             TFS(&krb5_kdcoptions_canonicalize), 0x00010000, "Do we want the KDC to canonicalize the principal or not", HFILL }},
4112         { &hf_krb_KDCOptions_opt_hardware_auth, {
4113             "Opt HW Auth", "kerberos.kdcoptions.opt_hardware_auth", FT_BOOLEAN, 32,
4114             NULL, 0x00100000, "Opt HW Auth flag", HFILL }},
4115         { &hf_krb_KDCOptions_disable_transited_check, {
4116             "Disable Transited Check", "kerberos.kdcoptions.disable_transited_check", FT_BOOLEAN, 32,
4117             TFS(&krb5_kdcoptions_disable_transited_check), 0x00000020, "Whether we should do transited checking or not", HFILL }},
4118         { &hf_krb_KDCOptions_renewable_ok, {
4119             "Renewable OK", "kerberos.kdcoptions.renewable_ok", FT_BOOLEAN, 32,
4120             TFS(&krb5_kdcoptions_renewable_ok), 0x00000010, "Whether we accept renewed tickets or not", HFILL }},
4121         { &hf_krb_KDCOptions_enc_tkt_in_skey, {
4122             "Enc-Tkt-in-Skey", "kerberos.kdcoptions.enc_tkt_in_skey", FT_BOOLEAN, 32,
4123             TFS(&krb5_kdcoptions_enc_tkt_in_skey), 0x00000008, "Whether the ticket is encrypted in the skey or not", HFILL }},
4124         { &hf_krb_KDCOptions_renew, {
4125             "Renew", "kerberos.kdcoptions.renew", FT_BOOLEAN, 32,
4126             TFS(&krb5_kdcoptions_renew), 0x00000002, "Is this a request to renew a ticket?", HFILL }},
4127         { &hf_krb_KDCOptions_validate, {
4128             "Validate", "kerberos.kdcoptions.validate", FT_BOOLEAN, 32,
4129             TFS(&krb5_kdcoptions_validate), 0x00000001, "Is this a request to validate a postdated ticket?", HFILL }},
4130         { &hf_krb_pvno, {
4131             "Pvno", "kerberos.pvno", FT_UINT32, BASE_DEC,
4132             NULL, 0, "Kerberos Protocol Version Number", HFILL }},
4133         { &hf_krb_kvno, {
4134             "Kvno", "kerberos.kvno", FT_UINT32, BASE_DEC,
4135             NULL, 0, "Version Number for the encryption Key", HFILL }},
4136         { &hf_krb_checksum_type, {
4137             "Type", "kerberos.checksum.type", FT_UINT32, BASE_DEC,
4138             VALS(krb5_checksum_types), 0, "Type of checksum", HFILL }},
4139         { &hf_krb_authenticator_vno, {
4140             "Authenticator vno", "kerberos.authenticator_vno", FT_UINT32, BASE_DEC,
4141             NULL, 0, "Version Number for the Authenticator", HFILL }},
4142         { &hf_krb_encrypted_authenticator_data, {
4143             "Authenticator data", "kerberos.authenticator.data", FT_BYTES, BASE_HEX,
4144             NULL, 0, "Data content of an encrypted authenticator", HFILL }},
4145         { &hf_krb_encrypted_PA_ENC_TIMESTAMP, {
4146             "enc PA_ENC_TIMESTAMP", "kerberos.PA_ENC_TIMESTAMP.encrypted", FT_BYTES, BASE_HEX,
4147             NULL, 0, "Encrypted PA-ENC-TIMESTAMP blob", HFILL }},
4148         { &hf_krb_PAC_LOGON_INFO, {
4149             "PAC_LOGON_INFO", "kerberos.PAC_LOGON_INFO", FT_BYTES, BASE_HEX,
4150             NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
4151         { &hf_krb_PAC_CREDENTIAL_TYPE, {
4152             "PAC_CREDENTIAL_TYPE", "kerberos.PAC_CREDENTIAL_TYPE", FT_BYTES, BASE_HEX,
4153             NULL, 0, "PAC_CREDENTIAL_TYPE structure", HFILL }},
4154         { &hf_krb_PAC_SERVER_CHECKSUM, {
4155             "PAC_SERVER_CHECKSUM", "kerberos.PAC_SERVER_CHECKSUM", FT_BYTES, BASE_HEX,
4156             NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
4157         { &hf_krb_PAC_PRIVSVR_CHECKSUM, {
4158             "PAC_PRIVSVR_CHECKSUM", "kerberos.PAC_PRIVSVR_CHECKSUM", FT_BYTES, BASE_HEX,
4159             NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
4160         { &hf_krb_PAC_CLIENT_INFO_TYPE, {
4161             "PAC_CLIENT_INFO_TYPE", "kerberos.PAC_CLIENT_INFO_TYPE", FT_BYTES, BASE_HEX,
4162             NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
4163         { &hf_krb_checksum_checksum, {
4164             "checksum", "kerberos.checksum.checksum", FT_BYTES, BASE_HEX,
4165             NULL, 0, "Kerberos Checksum", HFILL }},
4166         { &hf_krb_ENC_PRIV, {
4167             "enc PRIV", "kerberos.ENC_PRIV", FT_BYTES, BASE_HEX,
4168             NULL, 0, "Encrypted PRIV blob", HFILL }},
4169         { &hf_krb_encrypted_Ticket_data, {
4170             "enc-part", "kerberos.ticket.data", FT_BYTES, BASE_HEX,
4171             NULL, 0, "The encrypted part of a ticket", HFILL }},
4172         { &hf_krb_encrypted_AP_REP_data, {
4173             "enc-part", "kerberos.aprep.data", FT_BYTES, BASE_HEX,
4174             NULL, 0, "The encrypted part of AP-REP", HFILL }},
4175         { &hf_krb_encrypted_KDC_REP_data, {
4176             "enc-part", "kerberos.kdcrep.data", FT_BYTES, BASE_HEX,
4177             NULL, 0, "The encrypted part of KDC-REP", HFILL }},
4178         { &hf_krb_PA_DATA_value, {
4179             "Value", "kerberos.padata.value", FT_BYTES, BASE_HEX,
4180             NULL, 0, "Content of the PADATA blob", HFILL }},
4181         { &hf_krb_etype_info_salt, {
4182             "Salt", "kerberos.etype_info.salt", FT_BYTES, BASE_HEX,
4183             NULL, 0, "Salt", HFILL }},
4184         { &hf_krb_SAFE_BODY_user_data, {
4185             "User Data", "kerberos.SAFE_BODY.user_data", FT_BYTES, BASE_HEX,
4186             NULL, 0, "SAFE BODY userdata field", HFILL }},
4187         { &hf_krb_PRIV_BODY_user_data, {
4188             "User Data", "kerberos.PRIV_BODY.user_data", FT_BYTES, BASE_HEX,
4189             NULL, 0, "PRIV BODY userdata field", HFILL }},
4190         { &hf_krb_pac_signature_signature, {
4191             "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_HEX,
4192             NULL, 0, "A PAC signature blob", HFILL }},
4193         { &hf_krb_PA_DATA_type, {
4194             "Type", "kerberos.padata.type", FT_UINT32, BASE_DEC,
4195             VALS(krb5_preauthentication_types), 0, "Type of preauthentication data", HFILL }},
4196         { &hf_krb_nonce, {
4197             "Nonce", "kerberos.nonce", FT_UINT32, BASE_DEC,
4198             NULL, 0, "Kerberos Nonce random number", HFILL }},
4199         { &hf_krb_tkt_vno, {
4200             "Tkt-vno", "kerberos.tkt_vno", FT_UINT32, BASE_DEC,
4201             NULL, 0, "Version number for the Ticket format", HFILL }},
4202         { &hf_krb_HostAddress, {
4203             "HostAddress", "kerberos.hostaddress", FT_NONE, BASE_DEC,
4204             NULL, 0, "This is a Kerberos HostAddress sequence", HFILL }},
4205         { &hf_krb_s_address, {
4206             "S-Address", "kerberos.s_address", FT_NONE, BASE_DEC,
4207             NULL, 0, "This is the Senders address", HFILL }},
4208         { &hf_krb_key, {
4209             "key", "kerberos.key", FT_NONE, BASE_DEC,
4210             NULL, 0, "This is a Kerberos EncryptionKey sequence", HFILL }},
4211         { &hf_krb_subkey, {
4212             "Subkey", "kerberos.subkey", FT_NONE, BASE_DEC,
4213             NULL, 0, "This is a Kerberos subkey", HFILL }},
4214         { &hf_krb_seq_number, {
4215             "Seq Number", "kerberos.seq_number", FT_UINT32, BASE_DEC,
4216             NULL, 0, "This is a Kerberos sequence number", HFILL }},
4217         { &hf_krb_AuthorizationData, {
4218             "AuthorizationData", "kerberos.AuthorizationData", FT_NONE, BASE_DEC,
4219             NULL, 0, "This is a Kerberos AuthorizationData sequence", HFILL }},
4220         { &hf_krb_EncTicketPart, {
4221             "EncTicketPart", "kerberos.EncTicketPart", FT_NONE, BASE_DEC,
4222             NULL, 0, "This is a decrypted Kerberos EncTicketPart sequence", HFILL }},
4223         { &hf_krb_EncAPRepPart, {
4224             "EncAPRepPart", "kerberos.EncAPRepPart", FT_NONE, BASE_DEC,
4225             NULL, 0, "This is a decrypted Kerberos EncAPRepPart sequence", HFILL }},
4226         { &hf_krb_EncKrbPrivPart, {
4227             "EncKrbPrivPart", "kerberos.EncKrbPrivPart", FT_NONE, BASE_DEC,
4228             NULL, 0, "This is a decrypted Kerberos EncKrbPrivPart sequence", HFILL }},
4229         { &hf_krb_EncKDCRepPart, {
4230             "EncKDCRepPart", "kerberos.EncKDCRepPart", FT_NONE, BASE_DEC,
4231             NULL, 0, "This is a decrypted Kerberos EncKDCRepPart sequence", HFILL }},
4232         { &hf_krb_LastReq, {
4233             "LastReq", "kerberos.LastReq", FT_NONE, BASE_DEC,
4234             NULL, 0, "This is a LastReq sequence", HFILL }},
4235         { &hf_krb_Authenticator, {
4236             "Authenticator", "kerberos.Authenticator", FT_NONE, BASE_DEC,
4237             NULL, 0, "This is a decrypted Kerberos Authenticator sequence", HFILL }},
4238         { &hf_krb_Checksum, {
4239             "Checksum", "kerberos.Checksum", FT_NONE, BASE_DEC,
4240             NULL, 0, "This is a Kerberos Checksum sequence", HFILL }},
4241         { &hf_krb_HostAddresses, {
4242             "HostAddresses", "kerberos.hostaddresses", FT_NONE, BASE_DEC,
4243             NULL, 0, "This is a list of Kerberos HostAddress sequences", HFILL }},
4244         { &hf_krb_IF_RELEVANT, {
4245             "IF_RELEVANT", "kerberos.if_relevant", FT_NONE, BASE_DEC,
4246             NULL, 0, "This is a list of IF-RELEVANT sequences", HFILL }},
4247         { &hf_krb_etypes, {
4248             "Encryption Types", "kerberos.etypes", FT_NONE, BASE_DEC,
4249             NULL, 0, "This is a list of Kerberos encryption types", HFILL }},
4250         { &hf_krb_LastReqs, {
4251             "LastReqs", "kerberos.LastReqs", FT_NONE, BASE_DEC,
4252             NULL, 0, "This is a list of LastReq structures", HFILL }},
4253         { &hf_krb_sname, {
4254             "Server Name", "kerberos.sname", FT_NONE, BASE_DEC,
4255             NULL, 0, "This is the name part server's identity", HFILL }},
4256         { &hf_krb_cname, {
4257             "Client Name", "kerberos.cname", FT_NONE, BASE_DEC,
4258             NULL, 0, "The name part of the client principal identifier", HFILL }},
4259         { &hf_krb_authenticator_enc, {
4260             "Authenticator", "kerberos.authenticator", FT_NONE, BASE_DEC,
4261             NULL, 0, "Encrypted authenticator blob", HFILL }},
4262         { &hf_krb_ticket_enc, {
4263             "enc-part", "kerberos.ticket.enc_part", FT_NONE, BASE_DEC,
4264             NULL, 0, "The structure holding the encrypted part of a ticket", HFILL }},
4265         { &hf_krb_AP_REP_enc, {
4266             "enc-part", "kerberos.aprep.enc_part", FT_NONE, BASE_DEC,
4267             NULL, 0, "The structure holding the encrypted part of AP-REP", HFILL }},
4268         { &hf_krb_KDC_REP_enc, {
4269             "enc-part", "kerberos.kdcrep.enc_part", FT_NONE, BASE_DEC,
4270             NULL, 0, "The structure holding the encrypted part of KDC-REP", HFILL }},
4271         { &hf_krb_e_data, {
4272             "e-data", "kerberos.e_data", FT_NONE, BASE_DEC,
4273             NULL, 0, "The e-data blob", HFILL }},
4274         { &hf_krb_padata, {
4275             "padata", "kerberos.padata", FT_NONE, BASE_DEC,
4276             NULL, 0, "Sequence of preauthentication data", HFILL }},
4277         { &hf_krb_ticket, {
4278             "Ticket", "kerberos.ticket", FT_NONE, BASE_DEC,
4279             NULL, 0, "This is a Kerberos Ticket", HFILL }},
4280         { &hf_krb_TransitedEncoding, {
4281             "TransitedEncoding", "kerberos.TransitedEncoding", FT_NONE, BASE_DEC,
4282             NULL, 0, "This is a Kerberos TransitedEncoding sequence", HFILL }},
4283         { &hf_krb_PA_PAC_REQUEST_flag, {
4284             "PAC Request", "kerberos.pac_request.flag", FT_UINT32, BASE_DEC,
4285             NULL, 0, "This is a MS PAC Request Flag", HFILL }},
4286         { &hf_krb_w2k_pac_entries, {
4287             "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
4288             NULL, 0, "Number of W2k PAC entries", HFILL }},
4289         { &hf_krb_w2k_pac_version, {
4290             "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
4291             NULL, 0, "Version of PAC structures", HFILL }},
4292         { &hf_krb_w2k_pac_type, {
4293             "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
4294             VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
4295         { &hf_krb_w2k_pac_size, {
4296             "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
4297             NULL, 0, "Size of W2k PAC entry", HFILL }},
4298         { &hf_krb_w2k_pac_offset, {
4299             "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
4300             NULL, 0, "Offset to W2k PAC entry", HFILL }},
4301         { &hf_krb_pac_clientid, {
4302             "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, BASE_NONE,
4303             NULL, 0, "ClientID Timestamp", HFILL }},
4304         { &hf_krb_pac_namelen, {
4305             "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
4306             NULL, 0, "Length of client name", HFILL }},
4307         { &hf_krb_e_checksum, {
4308             "e-checksum", "kerberos.e_checksum", FT_NONE, BASE_DEC,
4309             NULL, 0, "This is a Kerberos e-checksum", HFILL }},
4310     };
4311
4312     static gint *ett[] = {
4313         &ett_krb_kerberos,
4314         &ett_krb_KDC_REP_enc,
4315         &ett_krb_sname,
4316         &ett_krb_cname,
4317         &ett_krb_AP_REP_enc,
4318         &ett_krb_padata,
4319         &ett_krb_etypes,
4320         &ett_krb_LastReqs,
4321         &ett_krb_IF_RELEVANT,
4322         &ett_krb_PA_DATA_tree,
4323         &ett_krb_s_address,
4324         &ett_krb_HostAddress,
4325         &ett_krb_HostAddresses,
4326         &ett_krb_authenticator_enc,
4327         &ett_krb_AP_Options,
4328         &ett_krb_KDC_Options,
4329         &ett_krb_Ticket_Flags,
4330         &ett_krb_request,
4331         &ett_krb_recordmark,
4332         &ett_krb_ticket,
4333         &ett_krb_ticket_enc,
4334         &ett_krb_PRIV,
4335         &ett_krb_PRIV_enc,
4336         &ett_krb_EncTicketPart,
4337         &ett_krb_EncAPRepPart,
4338         &ett_krb_EncKrbPrivPart,
4339         &ett_krb_EncKDCRepPart,
4340         &ett_krb_LastReq,
4341         &ett_krb_Authenticator,
4342         &ett_krb_Checksum,
4343         &ett_krb_key,
4344         &ett_krb_subkey,
4345         &ett_krb_AuthorizationData,
4346         &ett_krb_TransitedEncoding,
4347         &ett_krb_PAC,
4348         &ett_krb_PAC_LOGON_INFO,
4349         &ett_krb_PAC_CREDENTIAL_TYPE,
4350         &ett_krb_PAC_SERVER_CHECKSUM,
4351         &ett_krb_PAC_PRIVSVR_CHECKSUM,
4352         &ett_krb_PAC_CLIENT_INFO_TYPE,
4353         &ett_krb_e_checksum,
4354     };
4355     module_t *krb_module;
4356
4357     proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
4358     proto_register_field_array(proto_kerberos, hf, array_length(hf));
4359     proto_register_subtree_array(ett, array_length(ett));
4360
4361     /* Register preferences */
4362     krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
4363     prefs_register_bool_preference(krb_module, "desegment",
4364         "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
4365         "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
4366         " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
4367     &krb_desegment);
4368 #ifdef HAVE_KERBEROS
4369     prefs_register_bool_preference(krb_module, "decrypt",
4370         "Try to decrypt Kerberos blobs",
4371         "Whether the dissector should try to decrypt "
4372         "encrypted Kerberos blobs. This requires that the proper "
4373         "keytab file is installed as well.", &krb_decrypt);
4374
4375         prefs_register_string_preference(krb_module, "file",
4376                                    "Kerberos keytab file",
4377                                    "The keytab file containing all the secrets",
4378                                    &keytab_filename);
4379 #endif
4380
4381 }
4382
4383 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
4384                                  proto_tree *tree, guint8 *drep _U_)
4385 {
4386         tvbuff_t *auth_tvb;
4387
4388         auth_tvb = tvb_new_subset(
4389                 tvb, offset, tvb_length_remaining(tvb, offset),
4390                 tvb_reported_length_remaining(tvb, offset));
4391
4392         dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
4393
4394         return tvb_length_remaining(tvb, offset);
4395 }
4396
4397
4398 static dcerpc_auth_subdissector_fns gss_kerb_auth_fns = {
4399         wrap_dissect_gss_kerb,                  /* Bind */
4400         wrap_dissect_gss_kerb,                  /* Bind ACK */
4401         NULL,                                   /* AUTH3 */
4402         wrap_dissect_gssapi_verf,               /* Request verifier */
4403         wrap_dissect_gssapi_verf,               /* Response verifier */
4404         wrap_dissect_gssapi_payload,            /* Request data */
4405         wrap_dissect_gssapi_payload             /* Response data */
4406 };
4407
4408
4409 void
4410 proto_reg_handoff_kerberos(void)
4411 {
4412     dissector_handle_t kerberos_handle_tcp;
4413
4414     krb4_handle = find_dissector("krb4");
4415
4416     kerberos_handle_udp = new_create_dissector_handle(dissect_kerberos_udp,
4417         proto_kerberos);
4418     kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
4419         proto_kerberos);
4420     dissector_add("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
4421     dissector_add("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
4422
4423     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
4424                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
4425                                       &gss_kerb_auth_fns);
4426
4427     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
4428                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
4429                                       &gss_kerb_auth_fns);
4430
4431 }
4432
4433 /*
4434
4435   MISC definitions from RFC1510:
4436
4437    Realm ::=           GeneralString
4438
4439    KerberosTime ::=   GeneralizedTime
4440
4441    AuthorizationData ::=   SEQUENCE OF SEQUENCE {
4442                            ad-type[0]               INTEGER,
4443                            ad-data[1]               OCTET STRING
4444    }
4445                    APOptions ::=   BIT STRING {
4446                                    reserved(0),
4447                                    use-session-key(1),
4448                                    mutual-required(2)
4449                    }
4450
4451
4452                    TicketFlags ::=   BIT STRING {
4453                                      reserved(0),
4454                                      forwardable(1),
4455                                      forwarded(2),
4456                                      proxiable(3),
4457                                      proxy(4),
4458                                      may-postdate(5),
4459                                      postdated(6),
4460                                      invalid(7),
4461                                      renewable(8),
4462                                      initial(9),
4463                                      pre-authent(10),
4464                                      hw-authent(11)
4465                    }
4466
4467                   KDCOptions ::=   BIT STRING {
4468                                    reserved(0),
4469                                    forwardable(1),
4470                                    forwarded(2),
4471                                    proxiable(3),
4472                                    proxy(4),
4473                                    allow-postdate(5),
4474                                    postdated(6),
4475                                    unused7(7),
4476                                    renewable(8),
4477                                    unused9(9),
4478                                    unused10(10),
4479                                    unused11(11),
4480                                    renewable-ok(27),
4481                                    enc-tkt-in-skey(28),
4482                                    renew(30),
4483                                    validate(31)
4484                   }
4485
4486
4487             LastReq ::=   SEQUENCE OF SEQUENCE {
4488                           lr-type[0]               INTEGER,
4489                           lr-value[1]              KerberosTime
4490             }
4491
4492    Ticket ::=                    [APPLICATION 1] SEQUENCE {
4493                                  tkt-vno[0]                   INTEGER,
4494                                  realm[1]                     Realm,
4495                                  sname[2]                     PrincipalName,
4496                                  enc-part[3]                  EncryptedData
4497    }
4498
4499   -- Encrypted part of ticket
4500   EncTicketPart ::=     [APPLICATION 3] SEQUENCE {
4501                         flags[0]             TicketFlags,
4502                         key[1]               EncryptionKey,
4503                         crealm[2]            Realm,
4504                         cname[3]             PrincipalName,
4505                         transited[4]         TransitedEncoding,
4506                         authtime[5]          KerberosTime,
4507                         starttime[6]         KerberosTime OPTIONAL,
4508                         endtime[7]           KerberosTime,
4509                         renew-till[8]        KerberosTime OPTIONAL,
4510                         caddr[9]             HostAddresses OPTIONAL,
4511                         authorization-data[10]   AuthorizationData OPTIONAL
4512   }
4513
4514   -- encoded Transited field
4515   TransitedEncoding ::=         SEQUENCE {
4516                                 tr-type[0]  INTEGER, -- must be registered
4517                                 contents[1]          OCTET STRING
4518   }
4519
4520   -- Unencrypted authenticator
4521   Authenticator ::=    [APPLICATION 2] SEQUENCE    {
4522                  authenticator-vno[0]          INTEGER,
4523                  crealm[1]                     Realm,
4524                  cname[2]                      PrincipalName,
4525                  cksum[3]                      Checksum OPTIONAL,
4526                  cusec[4]                      INTEGER,
4527                  ctime[5]                      KerberosTime,
4528                  subkey[6]                     EncryptionKey OPTIONAL,
4529                  seq-number[7]                 INTEGER OPTIONAL,
4530                  authorization-data[8]         AuthorizationData OPTIONAL
4531   }
4532
4533   PA-DATA ::=        SEQUENCE {
4534            padata-type[1]        INTEGER,
4535            padata-value[2]       OCTET STRING,
4536                          -- might be encoded AP-REQ
4537   }
4538
4539    padata-type     ::= PA-ENC-TIMESTAMP
4540    padata-value    ::= EncryptedData -- PA-ENC-TS-ENC
4541
4542    PA-ENC-TS-ENC   ::= SEQUENCE {
4543            patimestamp[0]               KerberosTime, -- client's time
4544            pausec[1]                    INTEGER OPTIONAL
4545    }
4546
4547    EncASRepPart ::=    [APPLICATION 25[25]] EncKDCRepPart
4548    EncTGSRepPart ::=   [APPLICATION 26] EncKDCRepPart
4549
4550    EncKDCRepPart ::=   SEQUENCE {
4551                key[0]                       EncryptionKey,
4552                last-req[1]                  LastReq,
4553                nonce[2]                     INTEGER,
4554                key-expiration[3]            KerberosTime OPTIONAL,
4555                flags[4]                     TicketFlags,
4556                authtime[5]                  KerberosTime,
4557                starttime[6]                 KerberosTime OPTIONAL,
4558                endtime[7]                   KerberosTime,
4559                renew-till[8]                KerberosTime OPTIONAL,
4560                srealm[9]                    Realm,
4561                sname[10]                    PrincipalName,
4562                caddr[11]                    HostAddresses OPTIONAL
4563    }
4564
4565    APOptions ::=   BIT STRING {
4566                    reserved(0),
4567                    use-session-key(1),
4568                    mutual-required(2)
4569    }
4570
4571    EncAPRepPart ::=   [APPLICATION 27]     SEQUENCE {
4572               ctime[0]                  KerberosTime,
4573               cusec[1]                  INTEGER,
4574               subkey[2]                 EncryptionKey OPTIONAL,
4575               seq-number[3]             INTEGER OPTIONAL
4576    }
4577
4578    KRB-SAFE ::=        [APPLICATION 20] SEQUENCE {
4579                pvno[0]               INTEGER,
4580                msg-type[1]           INTEGER,
4581                safe-body[2]          KRB-SAFE-BODY,
4582                cksum[3]              Checksum
4583    }
4584
4585    KRB-SAFE-BODY ::=   SEQUENCE {
4586                user-data[0]          OCTET STRING,
4587                timestamp[1]          KerberosTime OPTIONAL,
4588                usec[2]               INTEGER OPTIONAL,
4589                seq-number[3]         INTEGER OPTIONAL,
4590                s-address[4]          HostAddress,
4591                r-address[5]          HostAddress OPTIONAL
4592    }
4593
4594    KRB-PRIV ::=         [APPLICATION 21] SEQUENCE {
4595                 pvno[0]                   INTEGER,
4596                 msg-type[1]               INTEGER,
4597                 enc-part[3]               EncryptedData
4598    }
4599
4600    EncKrbPrivPart ::=   [APPLICATION 28] SEQUENCE {
4601                 user-data[0]              OCTET STRING,
4602                 timestamp[1]              KerberosTime OPTIONAL,
4603                 usec[2]                   INTEGER OPTIONAL,
4604                 seq-number[3]             INTEGER OPTIONAL,
4605                 s-address[4]              HostAddress, -- sender's addr
4606                 r-address[5]              HostAddress OPTIONAL
4607                                                       -- recip's addr
4608    }
4609
4610    KRB-CRED         ::= [APPLICATION 22]   SEQUENCE {
4611                     pvno[0]                INTEGER,
4612                     msg-type[1]            INTEGER, -- KRB_CRED
4613                     tickets[2]             SEQUENCE OF Ticket,
4614                     enc-part[3]            EncryptedData
4615    }
4616
4617    EncKrbCredPart   ::= [APPLICATION 29]   SEQUENCE {
4618                     ticket-info[0]         SEQUENCE OF KrbCredInfo,
4619                     nonce[1]               INTEGER OPTIONAL,
4620                     timestamp[2]           KerberosTime OPTIONAL,
4621                     usec[3]                INTEGER OPTIONAL,
4622                     s-address[4]           HostAddress OPTIONAL,
4623                     r-address[5]           HostAddress OPTIONAL
4624    }
4625
4626    KrbCredInfo      ::=                    SEQUENCE {
4627                     key[0]                 EncryptionKey,
4628                     prealm[1]              Realm OPTIONAL,
4629                     pname[2]               PrincipalName OPTIONAL,
4630                     flags[3]               TicketFlags OPTIONAL,
4631                     authtime[4]            KerberosTime OPTIONAL,
4632                     starttime[5]           KerberosTime OPTIONAL,
4633                     endtime[6]             KerberosTime OPTIONAL
4634                     renew-till[7]          KerberosTime OPTIONAL,
4635                     srealm[8]              Realm OPTIONAL,
4636                     sname[9]               PrincipalName OPTIONAL,
4637                     caddr[10]              HostAddresses OPTIONAL
4638    }
4639
4640       METHOD-DATA ::=    SEQUENCE of PA-DATA
4641
4642    If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
4643    contain an encoding of the following sequence:
4644
4645       METHOD-DATA ::=    SEQUENCE {
4646                          method-type[0]   INTEGER,
4647                          method-data[1]   OCTET STRING OPTIONAL
4648       }
4649
4650       EncryptionKey ::=   SEQUENCE {
4651                          keytype[0]    INTEGER,
4652                          keyvalue[1]   OCTET STRING
4653       }
4654
4655       Checksum ::=   SEQUENCE {
4656                          cksumtype[0]   INTEGER,
4657                          checksum[1]    OCTET STRING
4658       }
4659
4660 */
4661