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