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