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