f3b383f29a3684e893134bbc3ed147503fa42fed
[obnox/wireshark/wip.git] / asn1 / kerberos / packet-kerberos-template.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 <wsutil/file_util.h>
80 #include <epan/packet.h>
81 #include <epan/strutil.h>
82
83 #include <epan/conversation.h>
84 #include <epan/emem.h>
85 #include <epan/oids.h>
86 #include <epan/asn1.h>
87 #include <epan/prefs.h>
88 #include <epan/dissectors/packet-kerberos.h>
89 #include <epan/dissectors/packet-netbios.h>
90 #include <epan/dissectors/packet-tcp.h>
91 #include <epan/dissectors/packet-ber.h>
92 #include <epan/dissectors/packet-per.h>
93 #include <epan/dissectors/packet-pkinit.h>
94 #include <epan/dissectors/packet-cms.h>
95 #include <epan/dissectors/packet-windows-common.h>
96
97 #include <epan/dissectors/packet-dcerpc-netlogon.h>
98 #include <epan/dissectors/packet-dcerpc.h>
99
100 #include <epan/dissectors/packet-gssapi.h>
101
102
103 #define PNAME  "Kerberos"
104 #define PSNAME "KRB5"
105 #define PFNAME "kerberos"
106
107 #define UDP_PORT_KERBEROS               88
108 #define TCP_PORT_KERBEROS               88
109
110 static dissector_handle_t kerberos_handle_udp=NULL;
111
112 /* Global variables */
113 static guint32 authenticator_etype;
114 static guint32 keytype;
115 guint32 krb_PA_DATA_type;
116 static guint32 addr_type;
117 guint32 krb5_errorcode;
118
119 static gboolean do_col_info;
120
121 /* Forward declarations */
122 static int dissect_kerberos_Applications(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
123 static int dissect_kerberos_PA_ENC_TIMESTAMP(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
124 static int dissect_kerberos_KERB_PA_PAC_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
125 static int dissect_kerberos_PA_S4U2Self(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
126 static int dissect_kerberos_ETYPE_INFO(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
127 static int dissect_kerberos_ETYPE_INFO2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
128 /* Desegment Kerberos over TCP messages */
129 static gboolean krb_desegment = TRUE;
130
131 static gint proto_kerberos = -1;
132
133 static struct { const char *set; const char *unset; } bitval = { "Set", "Not set" };
134
135 static gint hf_krb_rm_reserved = -1;
136 static gint hf_krb_rm_reclen = -1;
137 static gint hf_krb_provsrv_location = -1;
138 static gint hf_krb_smb_nt_status = -1;
139 static gint hf_krb_smb_unknown = -1;
140 static gint hf_krb_address_ip = -1;
141 static gint hf_krb_address_netbios = -1;
142 static gint hf_krb_address_ipv6 = -1;
143 #include "packet-kerberos-hf.c"
144
145 /* Initialize the subtree pointers */
146 static gint ett_kerberos = -1;
147 static gint ett_krb_recordmark = -1;
148
149 #include "packet-kerberos-ett.c"
150
151 guint32 krb5_errorcode;
152
153
154 static dissector_handle_t krb4_handle=NULL;
155
156 static gboolean do_col_info;
157
158
159 static void
160 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag)
161 {
162         kerberos_callbacks *cb=(kerberos_callbacks *)pinfo->private_data;
163
164         if(!cb){
165                 return;
166         }
167
168         while(cb->tag){
169                 if(cb->tag==tag){
170                         cb->callback(pinfo, tvb, tree);
171                         return;
172                 }
173                 cb++;
174         }
175         return;
176 }
177
178
179
180 #ifdef HAVE_KERBEROS
181
182 /* Decrypt Kerberos blobs */
183 gboolean krb_decrypt = FALSE;
184
185 /* keytab filename */
186 static const char *keytab_filename = "insert filename here";
187
188 #endif
189
190 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
191 #ifdef _WIN32
192 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
193 #undef HAVE_STDARG_H
194 #undef HAVE_SYS_TYPES_H
195 #endif
196 #include <krb5.h>
197 enc_key_t *enc_key_list=NULL;
198
199 static void
200 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
201 {
202         enc_key_t *new_key;
203
204         if(pinfo->fd->flags.visited){
205                 return;
206         }
207 printf("added key in %u    keytype:%d len:%d\n",pinfo->fd->num, keytype, keylength);
208
209         new_key=g_malloc(sizeof(enc_key_t));
210         g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->fd->num);
211         new_key->next=enc_key_list;
212         enc_key_list=new_key;
213         new_key->keytype=keytype;
214         new_key->keylength=keylength;
215         /*XXX this needs to be freed later */
216         new_key->keyvalue=g_memdup(keyvalue, keylength);
217 }
218 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
219
220
221 #ifdef HAVE_MIT_KERBEROS
222
223 static krb5_context krb5_ctx;
224
225 void
226 read_keytab_file(const char *filename)
227 {
228         krb5_keytab keytab;
229         krb5_error_code ret;
230         krb5_keytab_entry key;
231         krb5_kt_cursor cursor;
232         enc_key_t *new_key;
233         static int first_time=1;
234
235 printf("read keytab file %s\n", filename);
236         if(first_time){
237                 first_time=0;
238                 ret = krb5_init_context(&krb5_ctx);
239                 if(ret){
240                         return;
241                 }
242         }
243
244         /* should use a file in the wireshark users dir */
245         ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
246         if(ret){
247                 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
248
249                 return;
250         }
251
252         ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
253         if(ret){
254                 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
255                 return;
256         }
257
258         do{
259                 new_key=g_malloc(sizeof(enc_key_t));
260                 new_key->next=enc_key_list;
261                 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
262                 if(ret==0){
263                         int i;
264                         char *pos;
265
266                         /* generate origin string, describing where this key came from */
267                         pos=new_key->key_origin;
268                         pos+=MIN(KRB_MAX_ORIG_LEN,
269                                  g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
270                         for(i=0;i<key.principal->length;i++){
271                                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
272                                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),(key.principal->data[i]).data));
273                         }
274                         pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
275                                  g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm.data));
276                         *pos=0;
277 /*printf("added key for principal :%s\n", new_key->key_origin);*/
278                         new_key->keytype=key.key.enctype;
279                         new_key->keylength=key.key.length;
280                         new_key->keyvalue=g_memdup(key.key.contents, key.key.length);
281                         enc_key_list=new_key;
282                 }
283         }while(ret==0);
284
285         ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
286         if(ret){
287                 krb5_kt_close(krb5_ctx, keytab);
288         }
289
290 }
291
292
293 guint8 *
294 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
295                         int usage,
296                         int length,
297                         const guint8 *cryptotext,
298                         int keytype,
299                         int *datalen)
300 {
301         static int first_time=1;
302         krb5_error_code ret;
303         enc_key_t *ek;
304         static krb5_data data = {0,0,NULL};
305         krb5_keytab_entry key;
306
307         /* dont do anything if we are not attempting to decrypt data */
308         if(!krb_decrypt){
309                 return NULL;
310         }
311
312         /* XXX we should only do this for first time, then store somewhere */
313         /* XXX We also need to re-read the keytab when the preference changes */
314
315         /* should this have a destroy context ?  MIT people would know */
316         if(first_time){
317                 first_time=0;
318                 read_keytab_file(keytab_filename);
319         }
320
321         for(ek=enc_key_list;ek;ek=ek->next){
322                 krb5_enc_data input;
323
324                 /* shortcircuit and bail out if enctypes are not matching */
325                 if((keytype != -1) && (ek->keytype != keytype)) {
326                         continue;
327                 }
328
329                 input.enctype = ek->keytype;
330                 input.ciphertext.length = length;
331                 input.ciphertext.data = (guint8 *)cryptotext;
332
333                 data.length = length;
334                 g_free(data.data);
335                 data.data = g_malloc(length);
336
337                 key.key.enctype=ek->keytype;
338                 key.key.length=ek->keylength;
339                 key.key.contents=ek->keyvalue;
340                 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
341                 if((ret == 0) && (length>0)){
342                         char *user_data;
343
344 printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
345                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
346                         /* return a private g_malloced blob to the caller */
347                         user_data=g_malloc(data.length);
348                         memcpy(user_data, data.data, data.length);
349                         if (datalen) {
350                                 *datalen = data.length;
351                         }
352                         return user_data;
353                 }
354         }
355
356         return NULL;
357 }
358
359 #elif defined(HAVE_HEIMDAL_KERBEROS)
360 static krb5_context krb5_ctx;
361
362 void
363 read_keytab_file(const char *filename)
364 {
365         krb5_keytab keytab;
366         krb5_error_code ret;
367         krb5_keytab_entry key;
368         krb5_kt_cursor cursor;
369         enc_key_t *new_key;
370         static int first_time=1;
371
372         if(first_time){
373                 first_time=0;
374                 ret = krb5_init_context(&krb5_ctx);
375                 if(ret){
376                         return;
377                 }
378         }
379
380         /* should use a file in the wireshark users dir */
381         ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
382         if(ret){
383                 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
384
385                 return;
386         }
387
388         ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
389         if(ret){
390                 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
391                 return;
392         }
393
394         do{
395                 new_key=g_malloc(sizeof(enc_key_t));
396                 new_key->next=enc_key_list;
397                 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
398                 if(ret==0){
399                         unsigned int i;
400                         char *pos;
401
402                         /* generate origin string, describing where this key came from */
403                         pos=new_key->key_origin;
404                         pos+=MIN(KRB_MAX_ORIG_LEN,
405                                  g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
406                         for(i=0;i<key.principal->name.name_string.len;i++){
407                                 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
408                                          g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
409                         }
410                         pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
411                                  g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
412                         *pos=0;
413                         new_key->keytype=key.keyblock.keytype;
414                         new_key->keylength=key.keyblock.keyvalue.length;
415                         new_key->keyvalue=g_memdup(key.keyblock.keyvalue.data, key.keyblock.keyvalue.length);
416                         enc_key_list=new_key;
417                 }
418         }while(ret==0);
419
420         ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
421         if(ret){
422                 krb5_kt_close(krb5_ctx, keytab);
423         }
424
425 }
426
427
428 guint8 *
429 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
430                         int usage,
431                         int length,
432                         const guint8 *cryptotext,
433                         int keytype,
434                         int *datalen)
435 {
436         static int first_time=1;
437         krb5_error_code ret;
438         krb5_data data;
439         enc_key_t *ek;
440
441         /* dont do anything if we are not attempting to decrypt data */
442         if(!krb_decrypt){
443                 return NULL;
444         }
445
446         /* XXX we should only do this for first time, then store somewhere */
447         /* XXX We also need to re-read the keytab when the preference changes */
448
449         /* should this have a destroy context ?  Heimdal people would know */
450         if(first_time){
451                 first_time=0;
452                 read_keytab_file(keytab_filename);
453         }
454
455         for(ek=enc_key_list;ek;ek=ek->next){
456                 krb5_keytab_entry key;
457                 krb5_crypto crypto;
458                 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
459
460                 /* shortcircuit and bail out if enctypes are not matching */
461                 if((keytype != -1) && (ek->keytype != keytype)) {
462                         continue;
463                 }
464
465                 key.keyblock.keytype=ek->keytype;
466                 key.keyblock.keyvalue.length=ek->keylength;
467                 key.keyblock.keyvalue.data=ek->keyvalue;
468                 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), 0, &crypto);
469                 if(ret){
470                         return NULL;
471                 }
472
473                 /* pre-0.6.1 versions of Heimdal would sometimes change
474                   the cryptotext data even when the decryption failed.
475                   This would obviously not work since we iterate over the
476                   keys. So just give it a copy of the crypto data instead.
477                   This has been seen for RC4-HMAC blobs.
478                 */
479                 cryptocopy=g_malloc(length);
480                 memcpy(cryptocopy, cryptotext, length);
481                 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
482                                 cryptocopy, length,
483                                 &data,
484                                 NULL);
485                 g_free(cryptocopy);
486                 if((ret == 0) && (length>0)){
487                         char *user_data;
488
489 printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
490                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
491                         krb5_crypto_destroy(krb5_ctx, crypto);
492                         /* return a private g_malloced blob to the caller */
493                         user_data=g_malloc(data.length);
494                         memcpy(user_data, data.data, data.length);
495                         if (datalen) {
496                                 *datalen = data.length;
497                         }
498                         return user_data;
499                 }
500                 krb5_crypto_destroy(krb5_ctx, crypto);
501         }
502         return NULL;
503 }
504
505 #elif defined (HAVE_LIBNETTLE)
506
507 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
508 #define KEYTYPE_DES3_CBC_MD5 5  /* Currently the only one supported */
509
510 typedef struct _service_key_t {
511     guint16 kvno;
512     int     keytype;
513     int     length;
514     guint8 *contents;
515     char    origin[KRB_MAX_ORIG_LEN+1];
516 } service_key_t;
517 GSList *service_key_list = NULL;
518
519
520 static void
521 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
522 {
523         service_key_t *new_key;
524
525         if(pinfo->fd->flags.visited){
526                 return;
527         }
528 printf("added key in %u\n",pinfo->fd->num);
529
530         new_key = g_malloc(sizeof(service_key_t));
531         new_key->kvno = 0;
532         new_key->keytype = keytype;
533         new_key->length = keylength;
534         new_key->contents = g_malloc(keylength);
535         memcpy(new_key->contents, keyvalue, keylength);
536         g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->fd->num);
537         service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
538 }
539
540 static void
541 clear_keytab(void) {
542         GSList *ske;
543         service_key_t *sk;
544
545         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
546                 sk = (service_key_t *) ske->data;
547                 if (sk) {
548                     g_free(sk->contents);
549                     g_free(sk);
550                 }
551         }
552         g_slist_free(service_key_list);
553         service_key_list = NULL;
554 }
555
556 static void
557 read_keytab_file(const char *service_key_file)
558 {
559         FILE *skf;
560         ws_statb64 st;
561         service_key_t *sk;
562         unsigned char buf[SERVICE_KEY_SIZE];
563         int newline_skip = 0, count = 0;
564
565         if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
566
567                 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
568                  * There can be zero, one (\n), or two (\r\n) characters between
569                  * keys.  Trailing characters are ignored.
570                  */
571
572                 /* XXX We should support the standard keytab format instead */
573                 if (st.st_size > SERVICE_KEY_SIZE) {
574                         if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
575                              (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
576                             newline_skip = 1;
577                         } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
578                              (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
579                             newline_skip = 2;
580                         }
581                 }
582
583                 skf = ws_fopen(service_key_file, "rb");
584                 if (! skf) return;
585
586                 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
587                         sk = g_malloc(sizeof(service_key_t));
588                         sk->kvno = buf[0] << 8 | buf[1];
589                         sk->keytype = KEYTYPE_DES3_CBC_MD5;
590                         sk->length = DES3_KEY_SIZE;
591                         sk->contents = g_malloc(DES3_KEY_SIZE);
592                         memcpy(sk->contents, buf + 2, DES3_KEY_SIZE);
593                         g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
594                         service_key_list = g_slist_append(service_key_list, (gpointer) sk);
595                         fseek(skf, newline_skip, SEEK_CUR);
596                         count++;
597 g_warning("added key: %s", sk->origin);
598                 }
599                 fclose(skf);
600         }
601 }
602
603 #define CONFOUNDER_PLUS_CHECKSUM 24
604
605 guint8 *
606 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
607                         int _U_ usage,
608                         int length,
609                         const guint8 *cryptotext,
610                         int keytype,
611                         int *datalen)
612 {
613         tvbuff_t *encr_tvb;
614         guint8 *decrypted_data = NULL, *plaintext = NULL;
615         int res;
616         guint8 cls;
617         gboolean pc;
618         guint32 tag, item_len, data_len;
619         int id_offset, offset;
620         guint8 key[DES3_KEY_SIZE];
621         guint8 initial_vector[DES_BLOCK_SIZE];
622         md5_state_t md5s;
623         md5_byte_t digest[16];
624         md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
625         md5_byte_t confounder[8];
626         gboolean ind;
627         GSList *ske;
628         service_key_t *sk;
629         struct des3_ctx ctx;
630
631
632         /* dont do anything if we are not attempting to decrypt data */
633         if(!krb_decrypt){
634                 return NULL;
635         }
636
637         if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
638                 return NULL;
639         }
640
641         decrypted_data = g_malloc(length);
642         for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
643                 gboolean do_continue = FALSE;
644                 sk = (service_key_t *) ske->data;
645
646                 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
647
648                 md5_init(&md5s);
649                 memset(initial_vector, 0, DES_BLOCK_SIZE);
650                 res = des3_set_key(&ctx, key);
651                 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
652                     length, decrypted_data, cryptotext);
653                 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
654
655                 tvb_memcpy(encr_tvb, confounder, 0, 8);
656
657                 /* We have to pull the decrypted data length from the decrypted
658                  * content.  If the key doesn't match or we otherwise get garbage,
659                  * an exception may get thrown while decoding the ASN.1 header.
660                  * Catch it, just in case.
661                  */
662                 TRY {
663                         id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
664                         offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
665                 }
666                 CATCH (BoundsError) {
667                         tvb_free(encr_tvb);
668                         do_continue = TRUE;
669                 }
670                 ENDTRY;
671
672                 if (do_continue) continue;
673
674                 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
675                 if ((int) item_len + offset > length) {
676                         tvb_free(encr_tvb);
677                         continue;
678                 }
679
680                 md5_append(&md5s, confounder, 8);
681                 md5_append(&md5s, zero_fill, 16);
682                 md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
683                 md5_finish(&md5s, digest);
684
685                 if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) {
686 g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
687                         plaintext = g_malloc(data_len);
688                         tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
689                         tvb_free(encr_tvb);
690
691                         if (datalen) {
692                                 *datalen = data_len;
693                         }
694                         g_free(decrypted_data);
695                         return(plaintext);
696                 }
697         }
698
699         g_free(decrypted_data);
700         return NULL;
701 }
702
703
704 #endif  /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
705
706 #define INET6_ADDRLEN   16
707
708 /* TCP Record Mark */
709 #define KRB_RM_RESERVED 0x80000000L
710 #define KRB_RM_RECLEN   0x7fffffffL
711
712 #define KRB5_MSG_TICKET                 1       /* Ticket */
713 #define KRB5_MSG_AUTHENTICATOR          2       /* Authenticator */
714 #define KRB5_MSG_ENC_TICKET_PART        3       /* EncTicketPart */
715 #define KRB5_MSG_AS_REQ                 10      /* AS-REQ type */
716 #define KRB5_MSG_AS_REP                 11      /* AS-REP type */
717 #define KRB5_MSG_TGS_REQ                12      /* TGS-REQ type */
718 #define KRB5_MSG_TGS_REP                13      /* TGS-REP type */
719 #define KRB5_MSG_AP_REQ                 14      /* AP-REQ type */
720 #define KRB5_MSG_AP_REP                 15      /* AP-REP type */
721
722 #define KRB5_MSG_SAFE                   20      /* KRB-SAFE type */
723 #define KRB5_MSG_PRIV                   21      /* KRB-PRIV type */
724 #define KRB5_MSG_CRED                   22      /* KRB-CRED type */
725 #define KRB5_MSG_ENC_AS_REP_PART        25      /* EncASRepPart */
726 #define KRB5_MSG_ENC_TGS_REP_PART       26      /* EncTGSRepPart */
727 #define KRB5_MSG_ENC_AP_REP_PART        27      /* EncAPRepPart */
728 #define KRB5_MSG_ENC_KRB_PRIV_PART      28      /* EncKrbPrivPart */
729 #define KRB5_MSG_ENC_KRB_CRED_PART      29      /* EncKrbCredPart */
730 #define KRB5_MSG_ERROR                  30      /* KRB-ERROR type */
731
732 /* address type constants */
733 #define KRB5_ADDR_IPv4       0x02
734 #define KRB5_ADDR_CHAOS      0x05
735 #define KRB5_ADDR_XEROX      0x06
736 #define KRB5_ADDR_ISO        0x07
737 #define KRB5_ADDR_DECNET     0x0c
738 #define KRB5_ADDR_APPLETALK  0x10
739 #define KRB5_ADDR_NETBIOS    0x14
740 #define KRB5_ADDR_IPv6       0x18
741
742 /* encryption type constants */
743 #define KRB5_ENCTYPE_NULL                0
744 #define KRB5_ENCTYPE_DES_CBC_CRC         1
745 #define KRB5_ENCTYPE_DES_CBC_MD4         2
746 #define KRB5_ENCTYPE_DES_CBC_MD5         3
747 #define KRB5_ENCTYPE_DES_CBC_RAW         4
748 #define KRB5_ENCTYPE_DES3_CBC_SHA        5
749 #define KRB5_ENCTYPE_DES3_CBC_RAW        6
750 #define KRB5_ENCTYPE_DES_HMAC_SHA1       8
751 #define KRB5_ENCTYPE_DSA_SHA1_CMS        9
752 #define KRB5_ENCTYPE_RSA_MD5_CMS         10
753 #define KRB5_ENCTYPE_RSA_SHA1_CMS        11
754 #define KRB5_ENCTYPE_RC2_CBC_ENV         12
755 #define KRB5_ENCTYPE_RSA_ENV             13
756 #define KRB5_ENCTYPE_RSA_ES_OEAP_ENV     14
757 #define KRB5_ENCTYPE_DES_EDE3_CBC_ENV    15
758 #define KRB5_ENCTYPE_DES3_CBC_SHA1       16
759 #define KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96 17
760 #define KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96 18
761 #define KRB5_ENCTYPE_DES_CBC_MD5_NT      20
762 #define KERB_ENCTYPE_RC4_HMAC            23
763 #define KERB_ENCTYPE_RC4_HMAC_EXP        24
764 #define KRB5_ENCTYPE_UNKNOWN                0x1ff
765 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1   0x7007
766 #define KRB5_ENCTYPE_RC4_PLAIN_EXP      0xffffff73
767 #define KRB5_ENCTYPE_RC4_PLAIN          0xffffff74
768 #define KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP  0xffffff78
769 #define KRB5_ENCTYPE_RC4_HMAC_OLD_EXP   0xffffff79
770 #define KRB5_ENCTYPE_RC4_PLAIN_OLD      0xffffff7a
771 #define KRB5_ENCTYPE_RC4_HMAC_OLD       0xffffff7b
772 #define KRB5_ENCTYPE_DES_PLAIN          0xffffff7c
773 #define KRB5_ENCTYPE_RC4_SHA            0xffffff7d
774 #define KRB5_ENCTYPE_RC4_LM             0xffffff7e
775 #define KRB5_ENCTYPE_RC4_PLAIN2         0xffffff7f
776 #define KRB5_ENCTYPE_RC4_MD4            0xffffff80
777
778 /* checksum types */
779 #define KRB5_CHKSUM_NONE                0
780 #define KRB5_CHKSUM_CRC32               1
781 #define KRB5_CHKSUM_MD4                 2
782 #define KRB5_CHKSUM_KRB_DES_MAC         4
783 #define KRB5_CHKSUM_KRB_DES_MAC_K       5
784 #define KRB5_CHKSUM_MD5                 7
785 #define KRB5_CHKSUM_MD5_DES             8
786 /* the following four comes from packetcable */
787 #define KRB5_CHKSUM_MD5_DES3            9
788 #define KRB5_CHKSUM_HMAC_SHA1_DES3_KD   12
789 #define KRB5_CHKSUM_HMAC_SHA1_DES3      13
790 #define KRB5_CHKSUM_SHA1_UNKEYED        14
791 #define KRB5_CHKSUM_HMAC_MD5            0xffffff76
792 #define KRB5_CHKSUM_MD5_HMAC            0xffffff77
793 #define KRB5_CHKSUM_RC4_MD5             0xffffff78
794 #define KRB5_CHKSUM_MD25                0xffffff79
795 #define KRB5_CHKSUM_DES_MAC_MD5         0xffffff7a
796 #define KRB5_CHKSUM_DES_MAC             0xffffff7b
797 #define KRB5_CHKSUM_REAL_CRC32          0xffffff7c
798 #define KRB5_CHKSUM_SHA1                0xffffff7d
799 #define KRB5_CHKSUM_LM                  0xffffff7e
800 #define KRB5_CHKSUM_GSSAPI              0x8003
801
802 /*
803  * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
804  *
805  *      http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
806  *
807  * unless it's expired.
808  */
809
810 /* pre-authentication type constants */
811 #define KRB5_PA_TGS_REQ                1
812 #define KRB5_PA_ENC_TIMESTAMP          2
813 #define KRB5_PA_PW_SALT                3
814 #define KRB5_PA_ENC_ENCKEY             4
815 #define KRB5_PA_ENC_UNIX_TIME          5
816 #define KRB5_PA_ENC_SANDIA_SECURID     6
817 #define KRB5_PA_SESAME                 7
818 #define KRB5_PA_OSF_DCE                8
819 #define KRB5_PA_CYBERSAFE_SECUREID     9
820 #define KRB5_PA_AFS3_SALT              10
821 #define KRB5_PA_ENCTYPE_INFO           11
822 #define KRB5_PA_SAM_CHALLENGE          12
823 #define KRB5_PA_SAM_RESPONSE           13
824 #define KRB5_PA_PK_AS_REQ              14
825 #define KRB5_PA_PK_AS_REP              15
826 #define KRB5_PA_DASS                   16
827 #define KRB5_PA_ENCTYPE_INFO2          19
828 #define KRB5_PA_USE_SPECIFIED_KVNO     20
829 #define KRB5_PA_SAM_REDIRECT           21
830 #define KRB5_PA_GET_FROM_TYPED_DATA    22
831 #define KRB5_PA_SAM_ETYPE_INFO         23
832 #define KRB5_PA_ALT_PRINC              24
833 #define KRB5_PA_SAM_CHALLENGE2         30
834 #define KRB5_PA_SAM_RESPONSE2          31
835 #define KRB5_TD_PKINIT_CMS_CERTIFICATES 101
836 #define KRB5_TD_KRB_PRINCIPAL          102
837 #define KRB5_TD_KRB_REALM              103
838 #define KRB5_TD_TRUSTED_CERTIFIERS     104
839 #define KRB5_TD_CERTIFICATE_INDEX      105
840 #define KRB5_TD_APP_DEFINED_ERROR      106
841 #define KRB5_TD_REQ_NONCE              107
842 #define KRB5_TD_REQ_SEQ                108
843 /* preauthentication types >127 (i.e. negative ones) are app specific.
844    Hopefully there will be no collisions here or we will have to
845    come up with something better.
846    XXX: Although KRB5_PA_PAC_REQUEST is " >127 " and thus presumably
847          would be encoded as a negative number, various captures seen all
848          have this pa-data-type encoded as a positive number (0x0080).
849          We'll assume that KRB5_PA_S4U2SELF is also encoded as a positive number.
850 */
851 #define KRB5_PA_PAC_REQUEST              128    /* (Microsoft extension) */
852 #define KRB5_PA_S4U2SELF                 129    /* Impersonation (Microsoft extension) */
853
854 #define KRB5_PA_PROV_SRV_LOCATION 0xffffffff    /* (gint32)0xFF) packetcable stuff */
855
856 /* Principal name-type */
857 #define KRB5_NT_UNKNOWN        0
858 #define KRB5_NT_PRINCIPAL      1
859 #define KRB5_NT_SRV_INST       2
860 #define KRB5_NT_SRV_HST        3
861 #define KRB5_NT_SRV_XHST       4
862 #define KRB5_NT_UID            5
863 #define KRB5_NT_X500_PRINCIPAL 6
864 #define KRB5_NT_SMTP_NAME      7
865 #define KRB5_NT_ENTERPRISE    10
866
867 /*
868  * MS specific name types, from
869  *
870  *      http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
871  */
872 #define KRB5_NT_MS_PRINCIPAL            -128
873 #define KRB5_NT_MS_PRINCIPAL_AND_SID    -129
874 #define KRB5_NT_ENT_PRINCIPAL_AND_SID   -130
875 #define KRB5_NT_PRINCIPAL_AND_SID       -131
876 #define KRB5_NT_SRV_INST_AND_SID        -132
877
878 /* error table constants */
879 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
880 #define KRB5_ET_KRB5KDC_ERR_NONE                         0
881 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP                     1
882 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP                  2
883 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO                     3
884 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO              4
885 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO              5
886 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN          6
887 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN          7
888 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE         8
889 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY                     9
890 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE              10
891 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID                  11
892 #define KRB5_ET_KRB5KDC_ERR_POLICY                       12
893 #define KRB5_ET_KRB5KDC_ERR_BADOPTION                    13
894 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP                 14
895 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP               15
896 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP           16
897 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP                17
898 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED               18
899 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED              19
900 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED                  20
901 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET                21
902 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET               22
903 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP                      23
904 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED               24
905 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED             25
906 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH               26
907 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER           27
908 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED            28
909 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE              29
910 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY             31
911 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED               32
912 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV                   33
913 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT                    34
914 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US                    35
915 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH                  36
916 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW                      37
917 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR                   38
918 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION                39
919 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE                  40
920 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED                  41
921 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER                  42
922 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT                43
923 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER                 44
924 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY                     45
925 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL                  46
926 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION              47
927 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD                    48
928 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ                    49
929 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM               50
930 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED             51
931 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG             52
932 #define KRB5_ET_KRB5KRB_ERR_GENERIC                      60
933 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG                61
934 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED             62
935 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED                63
936 #define KRB5_ET_KDC_ERROR_INVALID_SIG                    64
937 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK                     65
938 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH             66
939 #define KRB5_ET_KRB_AP_ERR_NO_TGT                        67
940 #define KRB5_ET_KDC_ERR_WRONG_REALM                      68
941 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED         69
942 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE          70
943 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE              71
944 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE              72
945 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN        73
946 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE    74
947 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH             75
948 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH                76
949
950 static const value_string krb5_error_codes[] = {
951         { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
952         { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
953         { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
954         { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
955         { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
956         { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
957         { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
958         { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
959         { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
960         { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
961         { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
962         { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
963         { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
964         { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
965         { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
966         { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
967         { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
968         { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
969         { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
970         { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
971         { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
972         { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
973         { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
974         { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
975         { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
976         { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
977         { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
978         { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
979         { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
980         { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
981         { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
982         { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
983         { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
984         { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
985         { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
986         { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
987         { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
988         { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
989         { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
990         { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
991         { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
992         { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
993         { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
994         { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
995         { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
996         { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
997         { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
998         { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
999         { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1000         { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1001         { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1002         { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1003         { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1004         { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1005         { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1006         { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1007         { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1008         { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1009         { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1010         { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1011         { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1012         { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1013         { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1014         { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1015         { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1016         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1017         { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1018         { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1019         { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1020         { 0, NULL }
1021 };
1022
1023
1024 #define PAC_LOGON_INFO          1
1025 #define PAC_CREDENTIAL_TYPE     2
1026 #define PAC_SERVER_CHECKSUM     6
1027 #define PAC_PRIVSVR_CHECKSUM    7
1028 #define PAC_CLIENT_INFO_TYPE    10
1029 #define PAC_CONSTRAINED_DELEGATION 11
1030 #define PAC_UPN_DNS_INFO        12
1031 static const value_string w2k_pac_types[] = {
1032     { PAC_LOGON_INFO            , "Logon Info" },
1033     { PAC_CREDENTIAL_TYPE       , "Credential Type" },
1034     { PAC_SERVER_CHECKSUM       , "Server Checksum" },
1035     { PAC_PRIVSVR_CHECKSUM      , "Privsvr Checksum" },
1036     { PAC_CLIENT_INFO_TYPE      , "Client Info Type" },
1037     { PAC_CONSTRAINED_DELEGATION, "Constrained Delegation" },
1038     { PAC_UPN_DNS_INFO          , "UPN DNS Info" },
1039     { 0, NULL },
1040 };
1041
1042
1043
1044 static const value_string krb5_princ_types[] = {
1045     { KRB5_NT_UNKNOWN              , "Unknown" },
1046     { KRB5_NT_PRINCIPAL            , "Principal" },
1047     { KRB5_NT_SRV_INST             , "Service and Instance" },
1048     { KRB5_NT_SRV_HST              , "Service and Host" },
1049     { KRB5_NT_SRV_XHST             , "Service and Host Components" },
1050     { KRB5_NT_UID                  , "Unique ID" },
1051     { KRB5_NT_X500_PRINCIPAL       , "Encoded X.509 Distinguished Name" },
1052     { KRB5_NT_SMTP_NAME            , "SMTP Name" },
1053     { KRB5_NT_ENTERPRISE           , "Enterprise Name" },
1054     { KRB5_NT_MS_PRINCIPAL         , "NT 4.0 style name (MS specific)" },
1055     { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
1056     { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
1057     { KRB5_NT_PRINCIPAL_AND_SID    , "Principal name and SID (MS specific)"},
1058     { KRB5_NT_SRV_INST_AND_SID     , "SPN and SID (MS specific)"},
1059     { 0                            , NULL },
1060 };
1061
1062 static const value_string krb5_preauthentication_types[] = {
1063     { KRB5_PA_TGS_REQ              , "PA-TGS-REQ" },
1064     { KRB5_PA_ENC_TIMESTAMP        , "PA-ENC-TIMESTAMP" },
1065     { KRB5_PA_PW_SALT              , "PA-PW-SALT" },
1066     { KRB5_PA_ENC_ENCKEY           , "PA-ENC-ENCKEY" },
1067     { KRB5_PA_ENC_UNIX_TIME        , "PA-ENC-UNIX-TIME" },
1068     { KRB5_PA_ENC_SANDIA_SECURID   , "PA-PW-SALT" },
1069     { KRB5_PA_SESAME               , "PA-SESAME" },
1070     { KRB5_PA_OSF_DCE              , "PA-OSF-DCE" },
1071     { KRB5_PA_CYBERSAFE_SECUREID   , "PA-CYBERSAFE-SECURID" },
1072     { KRB5_PA_AFS3_SALT            , "PA-AFS3-SALT" },
1073     { KRB5_PA_ENCTYPE_INFO         , "PA-ENCTYPE-INFO" },
1074     { KRB5_PA_ENCTYPE_INFO2         , "PA-ENCTYPE-INFO2" },
1075     { KRB5_PA_SAM_CHALLENGE        , "PA-SAM-CHALLENGE" },
1076     { KRB5_PA_SAM_RESPONSE         , "PA-SAM-RESPONSE" },
1077     { KRB5_PA_PK_AS_REQ            , "PA-PK-AS-REQ" },
1078     { KRB5_PA_PK_AS_REP            , "PA-PK-AS-REP" },
1079     { KRB5_PA_DASS                 , "PA-DASS" },
1080     { KRB5_PA_USE_SPECIFIED_KVNO   , "PA-USE-SPECIFIED-KVNO" },
1081     { KRB5_PA_SAM_REDIRECT         , "PA-SAM-REDIRECT" },
1082     { KRB5_PA_GET_FROM_TYPED_DATA  , "PA-GET-FROM-TYPED-DATA" },
1083     { KRB5_PA_SAM_ETYPE_INFO       , "PA-SAM-ETYPE-INFO" },
1084     { KRB5_PA_ALT_PRINC            , "PA-ALT-PRINC" },
1085     { KRB5_PA_SAM_CHALLENGE2       , "PA-SAM-CHALLENGE2" },
1086     { KRB5_PA_SAM_RESPONSE2        , "PA-SAM-RESPONSE2" },
1087     { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
1088     { KRB5_TD_KRB_PRINCIPAL        , "TD-KRB-PRINCIPAL" },
1089     { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
1090     { KRB5_TD_TRUSTED_CERTIFIERS   , "TD-TRUSTED-CERTIFIERS" },
1091     { KRB5_TD_CERTIFICATE_INDEX    , "TD-CERTIFICATE-INDEX" },
1092     { KRB5_TD_APP_DEFINED_ERROR    , "TD-APP-DEFINED-ERROR" },
1093     { KRB5_TD_REQ_NONCE            , "TD-REQ-NONCE" },
1094     { KRB5_TD_REQ_SEQ              , "TD-REQ-SEQ" },
1095     { KRB5_PA_PAC_REQUEST          , "PA-PAC-REQUEST" },
1096     { KRB5_PA_S4U2SELF             , "PA-S4U2SELF" },
1097     { KRB5_PA_PROV_SRV_LOCATION    , "PA-PROV-SRV-LOCATION" },
1098     { 0                            , NULL },
1099 };
1100
1101 static const value_string krb5_encryption_types[] = {
1102     { KRB5_ENCTYPE_NULL           , "NULL" },
1103     { KRB5_ENCTYPE_DES_CBC_CRC    , "des-cbc-crc" },
1104     { KRB5_ENCTYPE_DES_CBC_MD4    , "des-cbc-md4" },
1105     { KRB5_ENCTYPE_DES_CBC_MD5    , "des-cbc-md5" },
1106     { KRB5_ENCTYPE_DES_CBC_RAW    , "des-cbc-raw" },
1107     { KRB5_ENCTYPE_DES3_CBC_SHA   , "des3-cbc-sha" },
1108     { KRB5_ENCTYPE_DES3_CBC_RAW   , "des3-cbc-raw" },
1109     { KRB5_ENCTYPE_DES_HMAC_SHA1  , "des-hmac-sha1" },
1110     { KRB5_ENCTYPE_DSA_SHA1_CMS   , "dsa-sha1-cms" },
1111     { KRB5_ENCTYPE_RSA_MD5_CMS    , "rsa-md5-cms" },
1112     { KRB5_ENCTYPE_RSA_SHA1_CMS   , "rsa-sha1-cms" },
1113     { KRB5_ENCTYPE_RC2_CBC_ENV    , "rc2-cbc-env" },
1114     { KRB5_ENCTYPE_RSA_ENV        , "rsa-env" },
1115     { KRB5_ENCTYPE_RSA_ES_OEAP_ENV, "rsa-es-oeap-env" },
1116     { KRB5_ENCTYPE_DES_EDE3_CBC_ENV, "des-ede3-cbc-env" },
1117     { KRB5_ENCTYPE_DES3_CBC_SHA1  , "des3-cbc-sha1" },
1118     { KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96  , "aes128-cts-hmac-sha1-96" },
1119     { KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96  , "aes256-cts-hmac-sha1-96" },
1120     { KRB5_ENCTYPE_DES_CBC_MD5_NT  , "des-cbc-md5-nt" },
1121     { KERB_ENCTYPE_RC4_HMAC       , "rc4-hmac" },
1122     { KERB_ENCTYPE_RC4_HMAC_EXP   , "rc4-hmac-exp" },
1123     { KRB5_ENCTYPE_UNKNOWN        , "unknown" },
1124     { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1    , "local-des3-hmac-sha1" },
1125     { KRB5_ENCTYPE_RC4_PLAIN_EXP  , "rc4-plain-exp" },
1126     { KRB5_ENCTYPE_RC4_PLAIN      , "rc4-plain" },
1127     { KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP, "rc4-plain-old-exp" },
1128     { KRB5_ENCTYPE_RC4_HMAC_OLD_EXP, "rc4-hmac-old-exp" },
1129     { KRB5_ENCTYPE_RC4_PLAIN_OLD  , "rc4-plain-old" },
1130     { KRB5_ENCTYPE_RC4_HMAC_OLD   , "rc4-hmac-old" },
1131     { KRB5_ENCTYPE_DES_PLAIN      , "des-plain" },
1132     { KRB5_ENCTYPE_RC4_SHA        , "rc4-sha" },
1133     { KRB5_ENCTYPE_RC4_LM         , "rc4-lm" },
1134     { KRB5_ENCTYPE_RC4_PLAIN2     , "rc4-plain2" },
1135     { KRB5_ENCTYPE_RC4_MD4        , "rc4-md4" },
1136     { 0                           , NULL },
1137 };
1138
1139 static const value_string krb5_checksum_types[] = {
1140     { KRB5_CHKSUM_NONE            , "none" },
1141     { KRB5_CHKSUM_CRC32           , "crc32" },
1142     { KRB5_CHKSUM_MD4             , "md4" },
1143     { KRB5_CHKSUM_KRB_DES_MAC     , "krb-des-mac" },
1144     { KRB5_CHKSUM_KRB_DES_MAC_K   , "krb-des-mac-k" },
1145     { KRB5_CHKSUM_MD5             , "md5" },
1146     { KRB5_CHKSUM_MD5_DES         , "md5-des" },
1147     { KRB5_CHKSUM_MD5_DES3        , "md5-des3" },
1148     { KRB5_CHKSUM_HMAC_SHA1_DES3_KD, "hmac-sha1-des3-kd" },
1149     { KRB5_CHKSUM_HMAC_SHA1_DES3  , "hmac-sha1-des3" },
1150     { KRB5_CHKSUM_SHA1_UNKEYED    , "sha1 (unkeyed)" },
1151     { KRB5_CHKSUM_HMAC_MD5        , "hmac-md5" },
1152     { KRB5_CHKSUM_MD5_HMAC        , "md5-hmac" },
1153     { KRB5_CHKSUM_RC4_MD5         , "rc5-md5" },
1154     { KRB5_CHKSUM_MD25            , "md25" },
1155     { KRB5_CHKSUM_DES_MAC_MD5     , "des-mac-md5" },
1156     { KRB5_CHKSUM_DES_MAC         , "des-mac" },
1157     { KRB5_CHKSUM_REAL_CRC32      , "real-crc32" },
1158     { KRB5_CHKSUM_SHA1            , "sha1" },
1159     { KRB5_CHKSUM_LM              , "lm" },
1160     { KRB5_CHKSUM_GSSAPI          , "gssapi-8003" },
1161     { 0                           , NULL },
1162 };
1163
1164 #define KRB5_AD_IF_RELEVANT                     1
1165 #define KRB5_AD_INTENDED_FOR_SERVER             2
1166 #define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS  3
1167 #define KRB5_AD_KDC_ISSUED                      4
1168 #define KRB5_AD_OR                              5
1169 #define KRB5_AD_MANDATORY_TICKET_EXTENSIONS     6
1170 #define KRB5_AD_IN_TICKET_EXTENSIONS            7
1171 #define KRB5_AD_MANDATORY_FOR_KDC               8
1172 #define KRB5_AD_OSF_DCE                         64
1173 #define KRB5_AD_SESAME                          65
1174 #define KRB5_AD_OSF_DCE_PKI_CERTID              66
1175 #define KRB5_AD_WIN2K_PAC                               128
1176 #define KRB5_AD_SIGNTICKET                      0xffffffef
1177 static const value_string krb5_ad_types[] = {
1178     { KRB5_AD_IF_RELEVANT                       , "AD-IF-RELEVANT" },
1179     { KRB5_AD_INTENDED_FOR_SERVER               , "AD-Intended-For-Server" },
1180     { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS    , "AD-Intended-For-Application-Class" },
1181     { KRB5_AD_KDC_ISSUED                        , "AD-KDCIssued" },
1182     { KRB5_AD_OR                                , "AD-AND-OR" },
1183     { KRB5_AD_MANDATORY_TICKET_EXTENSIONS       , "AD-Mandatory-Ticket-Extensions" },
1184     { KRB5_AD_IN_TICKET_EXTENSIONS              , "AD-IN-Ticket-Extensions" },
1185     { KRB5_AD_MANDATORY_FOR_KDC                 , "AD-MANDATORY-FOR-KDC" },
1186     { KRB5_AD_OSF_DCE                           , "AD-OSF-DCE" },
1187     { KRB5_AD_SESAME                            , "AD-SESAME" },
1188     { KRB5_AD_OSF_DCE_PKI_CERTID                , "AD-OSF-DCE-PKI-CertID" },
1189     { KRB5_AD_WIN2K_PAC                         , "AD-Win2k-PAC" },
1190     { KRB5_AD_SIGNTICKET                        , "AD-SignTicket" },
1191     { 0 , NULL },
1192 };
1193
1194 static const value_string krb5_transited_types[] = {
1195     { 1                           , "DOMAIN-X500-COMPRESS" },
1196     { 0                           , NULL }
1197 };
1198
1199 static const value_string krb5_address_types[] = {
1200     { KRB5_ADDR_IPv4,           "IPv4"},
1201     { KRB5_ADDR_CHAOS,          "CHAOS"},
1202     { KRB5_ADDR_XEROX,          "XEROX"},
1203     { KRB5_ADDR_ISO,            "ISO"},
1204     { KRB5_ADDR_DECNET,         "DECNET"},
1205     { KRB5_ADDR_APPLETALK,      "APPLETALK"},
1206     { KRB5_ADDR_NETBIOS,        "NETBIOS"},
1207     { KRB5_ADDR_IPv6,           "IPv6"},
1208     { 0,                        NULL },
1209 };
1210
1211 static const value_string krb5_msg_types[] = {
1212         { KRB5_MSG_TICKET,              "Ticket" },
1213         { KRB5_MSG_AUTHENTICATOR,       "Authenticator" },
1214         { KRB5_MSG_ENC_TICKET_PART,     "EncTicketPart" },
1215         { KRB5_MSG_TGS_REQ,             "TGS-REQ" },
1216         { KRB5_MSG_TGS_REP,             "TGS-REP" },
1217         { KRB5_MSG_AS_REQ,              "AS-REQ" },
1218         { KRB5_MSG_AS_REP,              "AS-REP" },
1219         { KRB5_MSG_AP_REQ,              "AP-REQ" },
1220         { KRB5_MSG_AP_REP,              "AP-REP" },
1221         { KRB5_MSG_SAFE,                "KRB-SAFE" },
1222         { KRB5_MSG_PRIV,                "KRB-PRIV" },
1223         { KRB5_MSG_CRED,                "KRB-CRED" },
1224         { KRB5_MSG_ENC_AS_REP_PART,     "EncASRepPart" },
1225         { KRB5_MSG_ENC_TGS_REP_PART,    "EncTGSRepPart" },
1226         { KRB5_MSG_ENC_AP_REP_PART,     "EncAPRepPart" },
1227         { KRB5_MSG_ENC_KRB_PRIV_PART,   "EncKrbPrivPart" },
1228         { KRB5_MSG_ENC_KRB_CRED_PART,   "EncKrbCredPart" },
1229         { KRB5_MSG_ERROR,               "KRB-ERROR" },
1230         { 0, NULL },
1231 };
1232
1233 #ifdef HAVE_KERBEROS
1234 static int
1235 dissect_krb5_decrypt_authenticator_data (proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1236 {
1237         guint8 *plaintext=NULL;
1238         int length;
1239
1240         length=tvb_length_remaining(tvb, offset);
1241
1242         /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1243          * 7.5.1
1244          * Authenticators are encrypted with usage
1245          * == 7 or
1246          * == 11
1247          */
1248         if(!plaintext){
1249                 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, length, tvb_get_ptr(tvb, offset, length), authenticator_etype, NULL);
1250         }
1251         if(!plaintext){
1252                 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, length, tvb_get_ptr(tvb, offset, length), authenticator_etype, NULL);
1253         }
1254
1255         if(plaintext){
1256                 tvbuff_t *next_tvb;
1257                 next_tvb = tvb_new_real_data (plaintext,
1258                                           length,
1259                                           length);
1260                 tvb_set_free_cb(next_tvb, g_free);
1261                 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1262
1263                 /* Add the decrypted data to the data source list. */
1264                 add_new_data_source(actx->pinfo, next_tvb, "Decrypted Krb5");
1265
1266                 offset=dissect_kerberos_Applications(FALSE, next_tvb, 0, actx , tree, /* hf_index */ -1);
1267
1268         }
1269         return offset;
1270 }
1271 #endif
1272
1273 static int
1274 dissect_krb5_PA_PROV_SRV_LOCATION(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
1275 {
1276         offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1277
1278         return offset;
1279 }
1280
1281 static int
1282 dissect_krb5_PW_SALT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
1283 {
1284         guint32 nt_status;
1285
1286         /* Microsoft stores a special 12 byte blob here
1287          * guint32 NT_status
1288          * guint32 unknown
1289          * guint32 unknown
1290          * decode everything as this blob for now until we see if anyone
1291          * else ever uses it   or we learn how to tell whether this
1292          * is such an MS blob or not.
1293          */
1294         proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
1295                         ENC_LITTLE_ENDIAN);
1296         nt_status=tvb_get_letohl(tvb, offset);
1297         if(nt_status && check_col(actx->pinfo->cinfo, COL_INFO)) {
1298                 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
1299                         " NT Status: %s",
1300                         val_to_str(nt_status, NT_errors,
1301                         "Unknown error code %#x"));
1302         }
1303         offset += 4;
1304
1305         proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1306                         ENC_LITTLE_ENDIAN);
1307         offset += 4;
1308
1309         proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1310                         ENC_LITTLE_ENDIAN);
1311         offset += 4;
1312
1313         return offset;
1314 }
1315
1316 #include "packet-kerberos-fn.c"
1317
1318 /* Make wrappers around exported functions for now */
1319 int
1320 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1321 {       
1322         return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
1323         
1324 }
1325
1326 int
1327 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1328 {
1329         return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
1330 }
1331
1332
1333 int 
1334 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1335 {
1336         return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
1337 }
1338 int 
1339 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1340 {
1341         return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
1342 }
1343
1344
1345 static gint
1346 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1347     gboolean dci, gboolean do_col_protocol, gboolean have_rm,
1348     kerberos_callbacks *cb)
1349 {
1350     volatile int offset = 0;
1351     proto_tree *volatile kerberos_tree = NULL;
1352     proto_item *volatile item = NULL;
1353     void *saved_private_data;
1354         asn1_ctx_t asn1_ctx;
1355
1356     /* TCP record mark and length */
1357     guint32 krb_rm = 0;
1358     gint krb_reclen = 0;
1359
1360     saved_private_data=pinfo->private_data;
1361     pinfo->private_data=cb;
1362     do_col_info=dci;
1363
1364     if (have_rm) {
1365         krb_rm = tvb_get_ntohl(tvb, offset);
1366         krb_reclen = kerberos_rm_to_reclen(krb_rm);
1367         /*
1368          * What is a reasonable size limit?
1369          */
1370         if (krb_reclen > 10 * 1024 * 1024) {
1371             pinfo->private_data=saved_private_data;
1372             return (-1);
1373         }
1374         if (do_col_protocol) {
1375             col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1376         }
1377         if (tree) {
1378             item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, FALSE);
1379             kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1380         }
1381         show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1382         offset += 4;
1383     } else {
1384         /* Do some sanity checking here,
1385          * All krb5 packets start with a TAG class that is BER_CLASS_APP
1386          * and a tag value that is either of the values below:
1387          * If it doesnt look like kerberos, return 0 and let someone else have
1388          * a go at it.
1389          */
1390         gint8 tmp_class;
1391         gboolean tmp_pc;
1392         gint32 tmp_tag;
1393
1394         get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
1395         if(tmp_class!=BER_CLASS_APP){
1396             pinfo->private_data=saved_private_data;
1397             return 0;
1398         }
1399         switch(tmp_tag){
1400             case KRB5_MSG_TICKET:
1401             case KRB5_MSG_AUTHENTICATOR:
1402             case KRB5_MSG_ENC_TICKET_PART:
1403             case KRB5_MSG_AS_REQ:
1404             case KRB5_MSG_AS_REP:
1405             case KRB5_MSG_TGS_REQ:
1406             case KRB5_MSG_TGS_REP:
1407             case KRB5_MSG_AP_REQ:
1408             case KRB5_MSG_AP_REP:
1409             case KRB5_MSG_ENC_AS_REP_PART:
1410             case KRB5_MSG_ENC_TGS_REP_PART:
1411             case KRB5_MSG_ENC_AP_REP_PART:
1412             case KRB5_MSG_ENC_KRB_PRIV_PART:
1413             case KRB5_MSG_ENC_KRB_CRED_PART:
1414             case KRB5_MSG_SAFE:
1415             case KRB5_MSG_PRIV:
1416             case KRB5_MSG_ERROR:
1417                 break;
1418             default:
1419                 pinfo->private_data=saved_private_data;
1420                 return 0;
1421         }
1422         if (do_col_protocol) {
1423             col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1424         }
1425         if (do_col_info) {
1426             col_clear(pinfo->cinfo, COL_INFO);
1427         }
1428         if (tree) {
1429             item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, FALSE);
1430             kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1431         }
1432     }
1433         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1434
1435     TRY {
1436         offset=dissect_kerberos_Applications(FALSE, tvb, 0, &asn1_ctx , tree, /* hf_index */ -1);
1437     } CATCH_ALL {
1438         pinfo->private_data=saved_private_data;
1439         RETHROW;
1440     } ENDTRY;
1441
1442     proto_item_set_len(item, offset);
1443     pinfo->private_data=saved_private_data;
1444     return offset;
1445 }
1446
1447 /*
1448  * Display the TCP record mark.
1449  */
1450 void
1451 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
1452 {
1453     gint rec_len;
1454     proto_item *rm_item;
1455     proto_tree *rm_tree;
1456
1457     if (tree == NULL)
1458         return;
1459
1460     rec_len = kerberos_rm_to_reclen(krb_rm);
1461     rm_item = proto_tree_add_text(tree, tvb, start, 4,
1462         "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
1463     rm_tree = proto_item_add_subtree(rm_item, ett_krb_recordmark);
1464     proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
1465     proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
1466 }
1467
1468 gint
1469 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
1470 {
1471     return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
1472 }
1473
1474 guint32
1475 kerberos_output_keytype(void)
1476 {
1477   return keytype;
1478 }
1479
1480 static gint
1481 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1482 {
1483     /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
1484        Since all (except weirdo transarc krb4 stuff) use
1485        an opcode <=16 in the first byte, use this to see if it might
1486        be krb4.
1487        All krb5 commands start with an APPL tag and thus is >=0x60
1488        so if first byte is <=16  just blindly assume it is krb4 then
1489     */
1490     if(tvb_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
1491       if(krb4_handle){
1492         gboolean res;
1493
1494         res=call_dissector_only(krb4_handle, tvb, pinfo, tree);
1495         return res;
1496       }else{
1497         return 0;
1498       }
1499     }
1500
1501
1502     return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
1503 }
1504
1505 gint
1506 kerberos_rm_to_reclen(guint krb_rm)
1507 {
1508     return (krb_rm & KRB_RM_RECLEN);
1509 }
1510
1511 guint
1512 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1513 {
1514     guint krb_rm;
1515     gint pdulen;
1516
1517     krb_rm = tvb_get_ntohl(tvb, offset);
1518     pdulen = kerberos_rm_to_reclen(krb_rm);
1519     return (pdulen + 4);
1520 }
1521 static void
1522 kerberos_prefs_apply_cb(void) {
1523 #ifdef HAVE_LIBNETTLE
1524         clear_keytab();
1525         read_keytab_file(keytab_filename);
1526 #endif
1527 }
1528
1529 /*--- proto_register_kerberos -------------------------------------------*/
1530 void proto_register_kerberos(void) {
1531
1532   /* List of fields */
1533
1534    static hf_register_info hf[] = {
1535         { &hf_krb_rm_reserved, {
1536             "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
1537             &bitval, KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
1538         { &hf_krb_rm_reclen, {
1539             "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
1540             NULL, KRB_RM_RECLEN, "Record length", HFILL }},
1541         { &hf_krb_provsrv_location, {
1542             "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
1543             NULL, 0, "PacketCable PROV SRV Location", HFILL }},
1544         { &hf_krb_smb_nt_status,
1545                 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
1546                 VALS(NT_errors), 0, "NT Status code", HFILL }},
1547         { &hf_krb_smb_unknown,
1548                 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
1549                 NULL, 0, "unknown", HFILL }},
1550         { &hf_krb_address_ip, {
1551             "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
1552             NULL, 0, "IP Address", HFILL }},
1553         { &hf_krb_address_ipv6, {
1554             "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
1555             NULL, 0, "IPv6 Address", HFILL }},
1556         { &hf_krb_address_netbios, {
1557             "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
1558             NULL, 0, "NetBIOS Address and type", HFILL }},
1559
1560 #include "packet-kerberos-hfarr.c"
1561   };
1562
1563   /* List of subtrees */
1564   static gint *ett[] = {
1565           &ett_kerberos,
1566           &ett_krb_recordmark,
1567 #include "packet-kerberos-ettarr.c"
1568   };
1569
1570   module_t *krb_module;
1571
1572   /* Register protocol */
1573   proto_kerberos = proto_register_protocol(PNAME, PSNAME, PFNAME);
1574   /* Register fields and subtrees */
1575   proto_register_field_array(proto_kerberos, hf, array_length(hf));
1576   proto_register_subtree_array(ett, array_length(ett));
1577
1578     /* Register preferences */
1579     krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
1580     prefs_register_bool_preference(krb_module, "desegment",
1581         "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
1582         "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
1583         " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1584     &krb_desegment);
1585 #ifdef HAVE_KERBEROS
1586     prefs_register_bool_preference(krb_module, "decrypt",
1587         "Try to decrypt Kerberos blobs",
1588         "Whether the dissector should try to decrypt "
1589         "encrypted Kerberos blobs. This requires that the proper "
1590         "keytab file is installed as well.", &krb_decrypt);
1591
1592         prefs_register_string_preference(krb_module, "file",
1593                                    "Kerberos keytab file",
1594                                    "The keytab file containing all the secrets",
1595                                    &keytab_filename);
1596 #endif
1597
1598 }
1599 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
1600                                  proto_tree *tree, guint8 *drep _U_)
1601 {
1602         tvbuff_t *auth_tvb;
1603
1604         auth_tvb = tvb_new_subset(
1605                 tvb, offset, tvb_length_remaining(tvb, offset),
1606                 tvb_reported_length_remaining(tvb, offset));
1607
1608         dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
1609
1610         return tvb_length_remaining(tvb, offset);
1611 }
1612
1613
1614 static dcerpc_auth_subdissector_fns gss_kerb_auth_fns = {
1615         wrap_dissect_gss_kerb,                  /* Bind */
1616         wrap_dissect_gss_kerb,                  /* Bind ACK */
1617         NULL,                                                           /* AUTH3 */
1618         wrap_dissect_gssapi_verf,                       /* Request verifier */
1619         wrap_dissect_gssapi_verf,                       /* Response verifier */
1620         wrap_dissect_gssapi_payload,        /* Request data */
1621         wrap_dissect_gssapi_payload         /* Response data */
1622 };
1623
1624
1625
1626 /*--- proto_reg_handoff_kerberos ---------------------------------------*/
1627 void
1628 proto_reg_handoff_kerberos(void)
1629 {
1630
1631         /*
1632     dissector_handle_t kerberos_handle_tcp;
1633         */
1634     krb4_handle = find_dissector("krb4");
1635
1636     kerberos_handle_udp = new_create_dissector_handle(dissect_kerberos_udp,
1637         proto_kerberos);
1638         /*
1639     kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
1640         proto_kerberos);
1641         */
1642     dissector_add_uint("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
1643         /*
1644     dissector_add_uint("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
1645         */
1646     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1647                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
1648                                       &gss_kerb_auth_fns);
1649
1650     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1651                                       DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
1652                                       &gss_kerb_auth_fns);
1653
1654 }
1655
1656