MSWSP: use GuidPropertySet_find_guid() in parse_CFullPropSpec()
[wireshark-wip.git] / asn1 / kerberos / packet-kerberos-template.c
blob87ed2246b2a84cb7a700c9dc0102a737f28f490c
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
8 * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API.
9 * decryption of kerberos blobs if keytab is provided
11 * See RFC 1510, and various I-Ds and other documents showing additions,
12 * e.g. ones listed under
14 * http://www.isi.edu/people/bcn/krb-revisions/
16 * and
18 * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-07.txt
20 * and
22 * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-referrals-05.txt
24 * Some structures from RFC2630
26 * $Id$
28 * Wireshark - Network traffic analyzer
29 * By Gerald Combs <gerald@wireshark.org>
30 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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.
57 #include "config.h"
59 #include <stdio.h>
60 #include <string.h>
61 #include <glib.h>
63 #ifdef HAVE_LIBNETTLE
64 #define HAVE_KERBEROS
65 #ifdef _WIN32
66 #include <des.h>
67 #include <cbc.h>
68 #else
69 #include <nettle/des.h>
70 #include <nettle/cbc.h>
71 #endif
72 #include <wsutil/md5.h>
73 #include <sys/stat.h> /* For keyfile manipulation */
74 #endif
76 #include <wsutil/file_util.h>
77 #include <epan/packet.h>
78 #include <epan/strutil.h>
80 #include <epan/conversation.h>
81 #include <epan/asn1.h>
82 #include <epan/expert.h>
83 #include <epan/prefs.h>
84 #include <epan/dissectors/packet-kerberos.h>
85 #include <epan/dissectors/packet-netbios.h>
86 #include <epan/dissectors/packet-tcp.h>
87 #include <epan/dissectors/packet-ber.h>
88 #include <epan/dissectors/packet-pkinit.h>
89 #include <epan/dissectors/packet-cms.h>
90 #include <epan/dissectors/packet-windows-common.h>
92 #include <epan/dissectors/packet-dcerpc-netlogon.h>
93 #include <epan/dissectors/packet-dcerpc.h>
95 #include <epan/dissectors/packet-gssapi.h>
96 #include <epan/dissectors/packet-smb-common.h>
98 #define UDP_PORT_KERBEROS 88
99 #define TCP_PORT_KERBEROS 88
101 #define ADDRESS_STR_BUFSIZ 256
103 typedef struct kerberos_key {
104 guint32 keytype;
105 int keylength;
106 const guint8 *keyvalue;
107 } kerberos_key_t;
109 static dissector_handle_t kerberos_handle_udp;
111 /* Forward declarations */
112 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_);
113 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_);
114 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_);
115 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_);
116 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_);
117 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_);
118 static int dissect_kerberos_AD_IF_RELEVANT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
121 /* Desegment Kerberos over TCP messages */
122 static gboolean krb_desegment = TRUE;
124 static gint proto_kerberos = -1;
126 static struct { const char *set; const char *unset; } bitval = { "Set", "Not set" };
128 static gint hf_krb_rm_reserved = -1;
129 static gint hf_krb_rm_reclen = -1;
130 static gint hf_krb_provsrv_location = -1;
131 static gint hf_krb_smb_nt_status = -1;
132 static gint hf_krb_smb_unknown = -1;
133 static gint hf_krb_address_ip = -1;
134 static gint hf_krb_address_netbios = -1;
135 static gint hf_krb_address_ipv6 = -1;
136 static gint hf_krb_gssapi_len = -1;
137 static gint hf_krb_gssapi_bnd = -1;
138 static gint hf_krb_gssapi_dlgopt = -1;
139 static gint hf_krb_gssapi_dlglen = -1;
140 static gint hf_krb_gssapi_c_flag_deleg = -1;
141 static gint hf_krb_gssapi_c_flag_mutual = -1;
142 static gint hf_krb_gssapi_c_flag_replay = -1;
143 static gint hf_krb_gssapi_c_flag_sequence = -1;
144 static gint hf_krb_gssapi_c_flag_conf = -1;
145 static gint hf_krb_gssapi_c_flag_integ = -1;
146 static gint hf_krb_gssapi_c_flag_dce_style = -1;
147 #include "packet-kerberos-hf.c"
149 /* Initialize the subtree pointers */
150 static gint ett_kerberos = -1;
151 static gint ett_krb_recordmark = -1;
153 #include "packet-kerberos-ett.c"
155 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
157 static dissector_handle_t krb4_handle=NULL;
159 /* Global variables */
160 static guint32 krb5_errorcode;
161 static guint32 gbl_keytype;
162 static gboolean gbl_do_col_info;
164 static void
165 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
167 if(!cb){
168 return;
171 while(cb->tag){
172 if(cb->tag==tag){
173 cb->callback(pinfo, tvb, tree);
174 return;
176 cb++;
178 return;
183 #ifdef HAVE_KERBEROS
185 /* Decrypt Kerberos blobs */
186 gboolean krb_decrypt = FALSE;
188 /* keytab filename */
189 static const char *keytab_filename = "";
191 WS_DLL_PUBLIC
192 void read_keytab_file(const char *);
194 void
195 read_keytab_file_from_preferences(void)
197 static char *last_keytab = NULL;
199 if (!krb_decrypt) {
200 return;
203 if (keytab_filename == NULL) {
204 return;
207 if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
208 return;
211 if (last_keytab != NULL) {
212 g_free(last_keytab);
213 last_keytab = NULL;
215 last_keytab = g_strdup(keytab_filename);
217 read_keytab_file(last_keytab);
220 #elif defined(_WIN32)
223 * Dummy version to allow us to export this function -- even
224 * on systems without KERBEROS.
226 void
227 read_keytab_file_from_preferences(void)
231 #endif
233 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
234 #ifdef _WIN32
235 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
236 #undef HAVE_STDARG_H
237 #undef HAVE_SYS_TYPES_H
238 #endif
239 #include <krb5.h>
240 enc_key_t *enc_key_list=NULL;
242 static void
243 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
245 enc_key_t *new_key;
247 if(pinfo->fd->flags.visited){
248 return;
250 printf("added key in %u keytype:%d len:%d\n",pinfo->fd->num, keytype, keylength);
252 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
253 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->fd->num);
254 new_key->next=enc_key_list;
255 enc_key_list=new_key;
256 new_key->keytype=keytype;
257 new_key->keylength=keylength;
258 /*XXX this needs to be freed later */
259 new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
261 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
263 #if defined(_WIN32) && !defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_MIT_KERBEROS) && !defined(HAVE_LIBNETTLE)
264 void
265 read_keytab_file(const char *filename _U_)
268 #endif
270 #ifdef HAVE_MIT_KERBEROS
272 static krb5_context krb5_ctx;
274 void
275 read_keytab_file(const char *filename)
277 krb5_keytab keytab;
278 krb5_error_code ret;
279 krb5_keytab_entry key;
280 krb5_kt_cursor cursor;
281 enc_key_t *new_key;
282 static gboolean first_time=TRUE;
284 printf("read keytab file %s\n", filename);
285 if(first_time){
286 first_time=FALSE;
287 ret = krb5_init_context(&krb5_ctx);
288 if(ret && ret != KRB5_CONFIG_CANTOPEN){
289 return;
293 /* should use a file in the wireshark users dir */
294 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
295 if(ret){
296 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
298 return;
301 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
302 if(ret){
303 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
304 return;
308 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
309 new_key->next=enc_key_list;
310 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
311 if(ret==0){
312 int i;
313 char *pos;
315 /* generate origin string, describing where this key came from */
316 pos=new_key->key_origin;
317 pos+=MIN(KRB_MAX_ORIG_LEN,
318 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
319 for(i=0;i<key.principal->length;i++){
320 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
321 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),(key.principal->data[i]).data));
323 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
324 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm.data));
325 *pos=0;
326 /*printf("added key for principal :%s\n", new_key->key_origin);*/
327 new_key->keytype=key.key.enctype;
328 new_key->keylength=key.key.length;
329 new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
330 enc_key_list=new_key;
332 }while(ret==0);
334 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
335 if(ret){
336 krb5_kt_close(krb5_ctx, keytab);
342 guint8 *
343 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
344 int usage,
345 tvbuff_t *cryptotvb,
346 int keytype,
347 int *datalen)
349 krb5_error_code ret;
350 enc_key_t *ek;
351 krb5_data data = {0,0,NULL};
352 krb5_keytab_entry key;
353 int length = tvb_length(cryptotvb);
354 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
356 /* don't do anything if we are not attempting to decrypt data */
357 if(!krb_decrypt || length < 1){
358 return NULL;
361 /* make sure we have all the data we need */
362 if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
363 return NULL;
366 read_keytab_file_from_preferences();
367 data.data = (char *)g_malloc(length);
368 data.length = length;
370 for(ek=enc_key_list;ek;ek=ek->next){
371 krb5_enc_data input;
373 /* shortcircuit and bail out if enctypes are not matching */
374 if((keytype != -1) && (ek->keytype != keytype)) {
375 continue;
378 input.enctype = ek->keytype;
379 input.ciphertext.length = length;
380 input.ciphertext.data = (guint8 *)cryptotext;
382 key.key.enctype=ek->keytype;
383 key.key.length=ek->keylength;
384 key.key.contents=ek->keyvalue;
385 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
386 if(ret == 0){
387 char *user_data;
389 expert_add_info_format(pinfo, NULL, &ei_kerberos_decrypted_keytype,
390 "Decrypted keytype %d in frame %u using %s",
391 ek->keytype, pinfo->fd->num, ek->key_origin);
393 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
394 /* return a private g_malloced blob to the caller */
395 user_data=data.data;
396 if (datalen) {
397 *datalen = data.length;
399 return user_data;
402 g_free(data.data);
404 return NULL;
407 #elif defined(HAVE_HEIMDAL_KERBEROS)
408 static krb5_context krb5_ctx;
410 void
411 read_keytab_file(const char *filename)
413 krb5_keytab keytab;
414 krb5_error_code ret;
415 krb5_keytab_entry key;
416 krb5_kt_cursor cursor;
417 enc_key_t *new_key;
418 static gboolean first_time=TRUE;
420 if(first_time){
421 first_time=FALSE;
422 ret = krb5_init_context(&krb5_ctx);
423 if(ret){
424 return;
428 /* should use a file in the wireshark users dir */
429 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
430 if(ret){
431 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
433 return;
436 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
437 if(ret){
438 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
439 return;
443 new_key=g_malloc(sizeof(enc_key_t));
444 new_key->next=enc_key_list;
445 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
446 if(ret==0){
447 unsigned int i;
448 char *pos;
450 /* generate origin string, describing where this key came from */
451 pos=new_key->key_origin;
452 pos+=MIN(KRB_MAX_ORIG_LEN,
453 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
454 for(i=0;i<key.principal->name.name_string.len;i++){
455 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
456 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
458 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
459 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
460 *pos=0;
461 new_key->keytype=key.keyblock.keytype;
462 new_key->keylength=key.keyblock.keyvalue.length;
463 new_key->keyvalue=g_memdup(key.keyblock.keyvalue.data, key.keyblock.keyvalue.length);
464 enc_key_list=new_key;
466 }while(ret==0);
468 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
469 if(ret){
470 krb5_kt_close(krb5_ctx, keytab);
476 guint8 *
477 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
478 int usage,
479 tvbuff_t *cryptotvb,
480 int keytype,
481 int *datalen)
483 krb5_error_code ret;
484 krb5_data data;
485 enc_key_t *ek;
486 int length = tvb_length(cryptotvb);
487 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
489 /* don't do anything if we are not attempting to decrypt data */
490 if(!krb_decrypt){
491 return NULL;
494 /* make sure we have all the data we need */
495 if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
496 return NULL;
499 read_keytab_file_from_preferences();
501 for(ek=enc_key_list;ek;ek=ek->next){
502 krb5_keytab_entry key;
503 krb5_crypto crypto;
504 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
506 /* shortcircuit and bail out if enctypes are not matching */
507 if((keytype != -1) && (ek->keytype != keytype)) {
508 continue;
511 key.keyblock.keytype=ek->keytype;
512 key.keyblock.keyvalue.length=ek->keylength;
513 key.keyblock.keyvalue.data=ek->keyvalue;
514 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), 0, &crypto);
515 if(ret){
516 return NULL;
519 /* pre-0.6.1 versions of Heimdal would sometimes change
520 the cryptotext data even when the decryption failed.
521 This would obviously not work since we iterate over the
522 keys. So just give it a copy of the crypto data instead.
523 This has been seen for RC4-HMAC blobs.
525 cryptocopy=g_memdup(cryptotext, length);
526 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
527 cryptocopy, length,
528 &data,
529 NULL);
530 g_free(cryptocopy);
531 if((ret == 0) && (length>0)){
532 char *user_data;
534 printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
535 proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
536 krb5_crypto_destroy(krb5_ctx, crypto);
537 /* return a private g_malloced blob to the caller */
538 user_data=g_memdup(data.data, data.length);
539 if (datalen) {
540 *datalen = data.length;
542 return user_data;
544 krb5_crypto_destroy(krb5_ctx, crypto);
546 return NULL;
549 #elif defined (HAVE_LIBNETTLE)
551 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
552 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
554 typedef struct _service_key_t {
555 guint16 kvno;
556 int keytype;
557 int length;
558 guint8 *contents;
559 char origin[KRB_MAX_ORIG_LEN+1];
560 } service_key_t;
561 GSList *service_key_list = NULL;
564 static void
565 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
567 service_key_t *new_key;
569 if(pinfo->fd->flags.visited){
570 return;
572 printf("added key in %u\n",pinfo->fd->num);
574 new_key = g_malloc(sizeof(service_key_t));
575 new_key->kvno = 0;
576 new_key->keytype = keytype;
577 new_key->length = keylength;
578 new_key->contents = g_memdup(keyvalue, keylength);
579 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->fd->num);
580 service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
583 static void
584 clear_keytab(void) {
585 GSList *ske;
586 service_key_t *sk;
588 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
589 sk = (service_key_t *) ske->data;
590 if (sk) {
591 g_free(sk->contents);
592 g_free(sk);
595 g_slist_free(service_key_list);
596 service_key_list = NULL;
599 static void
600 read_keytab_file(const char *service_key_file)
602 FILE *skf;
603 ws_statb64 st;
604 service_key_t *sk;
605 unsigned char buf[SERVICE_KEY_SIZE];
606 int newline_skip = 0, count = 0;
608 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
610 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
611 * There can be zero, one (\n), or two (\r\n) characters between
612 * keys. Trailing characters are ignored.
615 /* XXX We should support the standard keytab format instead */
616 if (st.st_size > SERVICE_KEY_SIZE) {
617 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
618 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
619 newline_skip = 1;
620 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
621 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
622 newline_skip = 2;
626 skf = ws_fopen(service_key_file, "rb");
627 if (! skf) return;
629 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
630 sk = g_malloc(sizeof(service_key_t));
631 sk->kvno = buf[0] << 8 | buf[1];
632 sk->keytype = KEYTYPE_DES3_CBC_MD5;
633 sk->length = DES3_KEY_SIZE;
634 sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
635 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
636 service_key_list = g_slist_append(service_key_list, (gpointer) sk);
637 fseek(skf, newline_skip, SEEK_CUR);
638 count++;
639 g_warning("added key: %s", sk->origin);
641 fclose(skf);
645 #define CONFOUNDER_PLUS_CHECKSUM 24
647 guint8 *
648 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
649 int _U_ usage,
650 tvbuff_t *cryptotvb,
651 int keytype,
652 int *datalen)
654 tvbuff_t *encr_tvb;
655 guint8 *decrypted_data = NULL, *plaintext = NULL;
656 guint8 cls;
657 gboolean pc;
658 guint32 tag, item_len, data_len;
659 int id_offset, offset;
660 guint8 key[DES3_KEY_SIZE];
661 guint8 initial_vector[DES_BLOCK_SIZE];
662 md5_state_t md5s;
663 md5_byte_t digest[16];
664 md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
665 md5_byte_t confounder[8];
666 gboolean ind;
667 GSList *ske;
668 service_key_t *sk;
669 struct des3_ctx ctx;
670 int length = tvb_length(cryptotvb);
671 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
674 /* don't do anything if we are not attempting to decrypt data */
675 if(!krb_decrypt){
676 return NULL;
679 /* make sure we have all the data we need */
680 if (tvb_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
681 return NULL;
684 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
685 return NULL;
688 decrypted_data = g_malloc(length);
689 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
690 gboolean do_continue = FALSE;
691 sk = (service_key_t *) ske->data;
693 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
695 md5_init(&md5s);
696 memset(initial_vector, 0, DES_BLOCK_SIZE);
697 des3_set_key(&ctx, key);
698 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
699 length, decrypted_data, cryptotext);
700 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
702 tvb_memcpy(encr_tvb, confounder, 0, 8);
704 /* We have to pull the decrypted data length from the decrypted
705 * content. If the key doesn't match or we otherwise get garbage,
706 * an exception may get thrown while decoding the ASN.1 header.
707 * Catch it, just in case.
709 TRY {
710 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
711 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
713 CATCH_BOUNDS_ERRORS {
714 tvb_free(encr_tvb);
715 do_continue = TRUE;
717 ENDTRY;
719 if (do_continue) continue;
721 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
722 if ((int) item_len + offset > length) {
723 tvb_free(encr_tvb);
724 continue;
727 md5_append(&md5s, confounder, 8);
728 md5_append(&md5s, zero_fill, 16);
729 md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
730 md5_finish(&md5s, digest);
732 if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) {
733 g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
734 plaintext = g_malloc(data_len);
735 tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
736 tvb_free(encr_tvb);
738 if (datalen) {
739 *datalen = data_len;
741 g_free(decrypted_data);
742 return(plaintext);
744 tvb_free(encr_tvb);
747 g_free(decrypted_data);
748 return NULL;
751 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
753 #define INET6_ADDRLEN 16
755 /* TCP Record Mark */
756 #define KRB_RM_RESERVED 0x80000000U
757 #define KRB_RM_RECLEN 0x7fffffffU
759 #define KRB5_MSG_TICKET 1 /* Ticket */
760 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
761 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
762 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
763 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
764 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
765 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
766 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
767 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
769 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
770 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
771 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
772 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
773 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
774 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
775 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
776 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
777 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
779 /* address type constants */
780 #define KRB5_ADDR_IPv4 0x02
781 #define KRB5_ADDR_CHAOS 0x05
782 #define KRB5_ADDR_XEROX 0x06
783 #define KRB5_ADDR_ISO 0x07
784 #define KRB5_ADDR_DECNET 0x0c
785 #define KRB5_ADDR_APPLETALK 0x10
786 #define KRB5_ADDR_NETBIOS 0x14
787 #define KRB5_ADDR_IPv6 0x18
789 /* encryption type constants */
790 #define KRB5_ENCTYPE_NULL 0
791 #define KRB5_ENCTYPE_DES_CBC_CRC 1
792 #define KRB5_ENCTYPE_DES_CBC_MD4 2
793 #define KRB5_ENCTYPE_DES_CBC_MD5 3
794 #define KRB5_ENCTYPE_DES_CBC_RAW 4
795 #define KRB5_ENCTYPE_DES3_CBC_SHA 5
796 #define KRB5_ENCTYPE_DES3_CBC_RAW 6
797 #define KRB5_ENCTYPE_DES_HMAC_SHA1 8
798 #define KRB5_ENCTYPE_DSA_SHA1_CMS 9
799 #define KRB5_ENCTYPE_RSA_MD5_CMS 10
800 #define KRB5_ENCTYPE_RSA_SHA1_CMS 11
801 #define KRB5_ENCTYPE_RC2_CBC_ENV 12
802 #define KRB5_ENCTYPE_RSA_ENV 13
803 #define KRB5_ENCTYPE_RSA_ES_OEAP_ENV 14
804 #define KRB5_ENCTYPE_DES_EDE3_CBC_ENV 15
805 #define KRB5_ENCTYPE_DES3_CBC_SHA1 16
806 #define KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96 17
807 #define KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96 18
808 #define KRB5_ENCTYPE_DES_CBC_MD5_NT 20
809 #define KERB_ENCTYPE_RC4_HMAC 23
810 #define KERB_ENCTYPE_RC4_HMAC_EXP 24
811 #define KRB5_ENCTYPE_UNKNOWN 0x1ff
812 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007
813 #define KRB5_ENCTYPE_RC4_PLAIN_EXP 0xffffff73
814 #define KRB5_ENCTYPE_RC4_PLAIN 0xffffff74
815 #define KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP 0xffffff78
816 #define KRB5_ENCTYPE_RC4_HMAC_OLD_EXP 0xffffff79
817 #define KRB5_ENCTYPE_RC4_PLAIN_OLD 0xffffff7a
818 #define KRB5_ENCTYPE_RC4_HMAC_OLD 0xffffff7b
819 #define KRB5_ENCTYPE_DES_PLAIN 0xffffff7c
820 #define KRB5_ENCTYPE_RC4_SHA 0xffffff7d
821 #define KRB5_ENCTYPE_RC4_LM 0xffffff7e
822 #define KRB5_ENCTYPE_RC4_PLAIN2 0xffffff7f
823 #define KRB5_ENCTYPE_RC4_MD4 0xffffff80
825 /* checksum types */
826 #define KRB5_CHKSUM_NONE 0
827 #define KRB5_CHKSUM_CRC32 1
828 #define KRB5_CHKSUM_MD4 2
829 #define KRB5_CHKSUM_KRB_DES_MAC 4
830 #define KRB5_CHKSUM_KRB_DES_MAC_K 5
831 #define KRB5_CHKSUM_MD5 7
832 #define KRB5_CHKSUM_MD5_DES 8
833 /* the following four come from packetcable */
834 #define KRB5_CHKSUM_MD5_DES3 9
835 #define KRB5_CHKSUM_HMAC_SHA1_DES3_KD 12
836 #define KRB5_CHKSUM_HMAC_SHA1_DES3 13
837 #define KRB5_CHKSUM_SHA1_UNKEYED 14
838 #define KRB5_CHKSUM_HMAC_MD5 0xffffff76
839 #define KRB5_CHKSUM_MD5_HMAC 0xffffff77
840 #define KRB5_CHKSUM_RC4_MD5 0xffffff78
841 #define KRB5_CHKSUM_MD25 0xffffff79
842 #define KRB5_CHKSUM_DES_MAC_MD5 0xffffff7a
843 #define KRB5_CHKSUM_DES_MAC 0xffffff7b
844 #define KRB5_CHKSUM_REAL_CRC32 0xffffff7c
845 #define KRB5_CHKSUM_SHA1 0xffffff7d
846 #define KRB5_CHKSUM_LM 0xffffff7e
847 #define KRB5_CHKSUM_GSSAPI 0x8003
850 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
852 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
854 * unless it's expired.
857 /* pre-authentication type constants */
858 #define KRB5_PA_TGS_REQ 1
859 #define KRB5_PA_ENC_TIMESTAMP 2
860 #define KRB5_PA_PW_SALT 3
861 #define KRB5_PA_ENC_ENCKEY 4
862 #define KRB5_PA_ENC_UNIX_TIME 5
863 #define KRB5_PA_ENC_SANDIA_SECURID 6
864 #define KRB5_PA_SESAME 7
865 #define KRB5_PA_OSF_DCE 8
866 #define KRB5_PA_CYBERSAFE_SECUREID 9
867 #define KRB5_PA_AFS3_SALT 10
868 #define KRB5_PA_ENCTYPE_INFO 11
869 #define KRB5_PA_SAM_CHALLENGE 12
870 #define KRB5_PA_SAM_RESPONSE 13
871 #define KRB5_PA_PK_AS_REQ 14
872 #define KRB5_PA_PK_AS_REP 15
873 #define KRB5_PA_DASS 16
874 #define KRB5_PA_ENCTYPE_INFO2 19
875 #define KRB5_PA_USE_SPECIFIED_KVNO 20
876 #define KRB5_PA_SAM_REDIRECT 21
877 #define KRB5_PA_GET_FROM_TYPED_DATA 22
878 #define KRB5_PA_SAM_ETYPE_INFO 23
879 #define KRB5_PA_ALT_PRINC 24
880 #define KRB5_PA_SAM_CHALLENGE2 30
881 #define KRB5_PA_SAM_RESPONSE2 31
882 #define KRB5_TD_PKINIT_CMS_CERTIFICATES 101
883 #define KRB5_TD_KRB_PRINCIPAL 102
884 #define KRB5_TD_KRB_REALM 103
885 #define KRB5_TD_TRUSTED_CERTIFIERS 104
886 #define KRB5_TD_CERTIFICATE_INDEX 105
887 #define KRB5_TD_APP_DEFINED_ERROR 106
888 #define KRB5_TD_REQ_NONCE 107
889 #define KRB5_TD_REQ_SEQ 108
890 /* preauthentication types >127 (i.e. negative ones) are app specific.
891 however since Microsoft is the dominant(only?) user of types in this range
892 we also treat the type as unsigned.
894 #define KRB5_PA_PAC_REQUEST 128 /* (Microsoft extension) */
895 #define KRB5_PA_FOR_USER 129 /* Impersonation (Microsoft extension) See [MS-SFU]. XXX - replaced by KRB5_PA_S4U2SELF */
896 #define KRB5_PA_S4U2SELF 129
898 #define KRB5_PA_PROV_SRV_LOCATION 0xffffffff /* (gint32)0xFF) packetcable stuff */
899 /* Principal name-type */
900 #define KRB5_NT_UNKNOWN 0
901 #define KRB5_NT_PRINCIPAL 1
902 #define KRB5_NT_SRV_INST 2
903 #define KRB5_NT_SRV_HST 3
904 #define KRB5_NT_SRV_XHST 4
905 #define KRB5_NT_UID 5
906 #define KRB5_NT_X500_PRINCIPAL 6
907 #define KRB5_NT_SMTP_NAME 7
908 #define KRB5_NT_ENTERPRISE 10
911 * MS specific name types, from
913 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
915 #define KRB5_NT_MS_PRINCIPAL -128
916 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
917 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
918 #define KRB5_NT_PRINCIPAL_AND_SID -131
919 #define KRB5_NT_SRV_INST_AND_SID -132
921 /* error table constants */
922 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
923 #define KRB5_ET_KRB5KDC_ERR_NONE 0
924 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
925 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
926 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
927 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
928 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
929 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
930 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
931 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
932 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
933 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
934 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
935 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
936 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
937 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
938 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
939 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
940 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
941 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
942 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
943 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
944 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
945 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
946 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
947 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
948 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
949 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
950 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
951 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
952 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
953 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
954 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
955 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
956 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
957 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
958 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
959 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
960 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
961 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
962 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
963 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
964 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
965 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
966 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
967 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
968 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
969 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
970 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
971 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
972 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
973 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
974 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
975 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
976 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
977 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
978 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
979 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
980 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
981 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
982 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
983 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
984 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
985 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
986 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
987 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
988 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
989 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
990 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
991 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
993 static const value_string krb5_error_codes[] = {
994 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
995 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
996 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
997 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
998 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
999 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
1000 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
1001 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
1002 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
1003 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
1004 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
1005 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
1006 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
1007 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
1008 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
1009 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
1010 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
1011 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
1012 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
1013 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
1014 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
1015 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
1016 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
1017 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
1018 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
1019 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
1020 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1021 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1022 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1023 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1024 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1025 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1026 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1027 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1028 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1029 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1030 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1031 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1032 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1033 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1034 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1035 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1036 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1037 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1038 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1039 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1040 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1041 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1042 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1043 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1044 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1045 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1046 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1047 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1048 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1049 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1050 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1051 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1052 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1053 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1054 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1055 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1056 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1057 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1058 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1059 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1060 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1061 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1062 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1063 { 0, NULL }
1067 #define PAC_LOGON_INFO 1
1068 #define PAC_CREDENTIAL_TYPE 2
1069 #define PAC_SERVER_CHECKSUM 6
1070 #define PAC_PRIVSVR_CHECKSUM 7
1071 #define PAC_CLIENT_INFO_TYPE 10
1072 #define PAC_S4U_DELEGATION_INFO 11
1073 #define PAC_UPN_DNS_INFO 12
1074 static const value_string w2k_pac_types[] = {
1075 { PAC_LOGON_INFO , "Logon Info" },
1076 { PAC_CREDENTIAL_TYPE , "Credential Type" },
1077 { PAC_SERVER_CHECKSUM , "Server Checksum" },
1078 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
1079 { PAC_CLIENT_INFO_TYPE , "Client Info Type" },
1080 { PAC_S4U_DELEGATION_INFO, "S4U Delegation Info" },
1081 { PAC_UPN_DNS_INFO , "UPN DNS Info" },
1082 { 0, NULL },
1087 static const value_string krb5_princ_types[] = {
1088 { KRB5_NT_UNKNOWN , "Unknown" },
1089 { KRB5_NT_PRINCIPAL , "Principal" },
1090 { KRB5_NT_SRV_INST , "Service and Instance" },
1091 { KRB5_NT_SRV_HST , "Service and Host" },
1092 { KRB5_NT_SRV_XHST , "Service and Host Components" },
1093 { KRB5_NT_UID , "Unique ID" },
1094 { KRB5_NT_X500_PRINCIPAL , "Encoded X.509 Distinguished Name" },
1095 { KRB5_NT_SMTP_NAME , "SMTP Name" },
1096 { KRB5_NT_ENTERPRISE , "Enterprise Name" },
1097 { KRB5_NT_MS_PRINCIPAL , "NT 4.0 style name (MS specific)" },
1098 { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
1099 { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
1100 { KRB5_NT_PRINCIPAL_AND_SID , "Principal name and SID (MS specific)"},
1101 { KRB5_NT_SRV_INST_AND_SID , "SPN and SID (MS specific)"},
1102 { 0 , NULL },
1105 static const value_string krb5_preauthentication_types[] = {
1106 { KRB5_PA_TGS_REQ , "PA-TGS-REQ" },
1107 { KRB5_PA_ENC_TIMESTAMP , "PA-ENC-TIMESTAMP" },
1108 { KRB5_PA_PW_SALT , "PA-PW-SALT" },
1109 { KRB5_PA_ENC_ENCKEY , "PA-ENC-ENCKEY" },
1110 { KRB5_PA_ENC_UNIX_TIME , "PA-ENC-UNIX-TIME" },
1111 { KRB5_PA_ENC_SANDIA_SECURID , "PA-PW-SALT" },
1112 { KRB5_PA_SESAME , "PA-SESAME" },
1113 { KRB5_PA_OSF_DCE , "PA-OSF-DCE" },
1114 { KRB5_PA_CYBERSAFE_SECUREID , "PA-CYBERSAFE-SECURID" },
1115 { KRB5_PA_AFS3_SALT , "PA-AFS3-SALT" },
1116 { KRB5_PA_ENCTYPE_INFO , "PA-ENCTYPE-INFO" },
1117 { KRB5_PA_ENCTYPE_INFO2 , "PA-ENCTYPE-INFO2" },
1118 { KRB5_PA_SAM_CHALLENGE , "PA-SAM-CHALLENGE" },
1119 { KRB5_PA_SAM_RESPONSE , "PA-SAM-RESPONSE" },
1120 { KRB5_PA_PK_AS_REQ , "PA-PK-AS-REQ" },
1121 { KRB5_PA_PK_AS_REP , "PA-PK-AS-REP" },
1122 { KRB5_PA_DASS , "PA-DASS" },
1123 { KRB5_PA_USE_SPECIFIED_KVNO , "PA-USE-SPECIFIED-KVNO" },
1124 { KRB5_PA_SAM_REDIRECT , "PA-SAM-REDIRECT" },
1125 { KRB5_PA_GET_FROM_TYPED_DATA , "PA-GET-FROM-TYPED-DATA" },
1126 { KRB5_PA_SAM_ETYPE_INFO , "PA-SAM-ETYPE-INFO" },
1127 { KRB5_PA_ALT_PRINC , "PA-ALT-PRINC" },
1128 { KRB5_PA_SAM_CHALLENGE2 , "PA-SAM-CHALLENGE2" },
1129 { KRB5_PA_SAM_RESPONSE2 , "PA-SAM-RESPONSE2" },
1130 { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
1131 { KRB5_TD_KRB_PRINCIPAL , "TD-KRB-PRINCIPAL" },
1132 { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
1133 { KRB5_TD_TRUSTED_CERTIFIERS , "TD-TRUSTED-CERTIFIERS" },
1134 { KRB5_TD_CERTIFICATE_INDEX , "TD-CERTIFICATE-INDEX" },
1135 { KRB5_TD_APP_DEFINED_ERROR , "TD-APP-DEFINED-ERROR" },
1136 { KRB5_TD_REQ_NONCE , "TD-REQ-NONCE" },
1137 { KRB5_TD_REQ_SEQ , "TD-REQ-SEQ" },
1138 { KRB5_PA_PAC_REQUEST , "PA-PAC-REQUEST" },
1139 { KRB5_PA_FOR_USER , "PA-FOR-USER" },
1140 { KRB5_PA_PROV_SRV_LOCATION , "PA-PROV-SRV-LOCATION" },
1141 { 0 , NULL },
1144 static const value_string krb5_encryption_types[] = {
1145 { KRB5_ENCTYPE_NULL , "NULL" },
1146 { KRB5_ENCTYPE_DES_CBC_CRC , "des-cbc-crc" },
1147 { KRB5_ENCTYPE_DES_CBC_MD4 , "des-cbc-md4" },
1148 { KRB5_ENCTYPE_DES_CBC_MD5 , "des-cbc-md5" },
1149 { KRB5_ENCTYPE_DES_CBC_RAW , "des-cbc-raw" },
1150 { KRB5_ENCTYPE_DES3_CBC_SHA , "des3-cbc-sha" },
1151 { KRB5_ENCTYPE_DES3_CBC_RAW , "des3-cbc-raw" },
1152 { KRB5_ENCTYPE_DES_HMAC_SHA1 , "des-hmac-sha1" },
1153 { KRB5_ENCTYPE_DSA_SHA1_CMS , "dsa-sha1-cms" },
1154 { KRB5_ENCTYPE_RSA_MD5_CMS , "rsa-md5-cms" },
1155 { KRB5_ENCTYPE_RSA_SHA1_CMS , "rsa-sha1-cms" },
1156 { KRB5_ENCTYPE_RC2_CBC_ENV , "rc2-cbc-env" },
1157 { KRB5_ENCTYPE_RSA_ENV , "rsa-env" },
1158 { KRB5_ENCTYPE_RSA_ES_OEAP_ENV, "rsa-es-oeap-env" },
1159 { KRB5_ENCTYPE_DES_EDE3_CBC_ENV, "des-ede3-cbc-env" },
1160 { KRB5_ENCTYPE_DES3_CBC_SHA1 , "des3-cbc-sha1" },
1161 { KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96 , "aes128-cts-hmac-sha1-96" },
1162 { KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96 , "aes256-cts-hmac-sha1-96" },
1163 { KRB5_ENCTYPE_DES_CBC_MD5_NT , "des-cbc-md5-nt" },
1164 { KERB_ENCTYPE_RC4_HMAC , "rc4-hmac" },
1165 { KERB_ENCTYPE_RC4_HMAC_EXP , "rc4-hmac-exp" },
1166 { KRB5_ENCTYPE_UNKNOWN , "unknown" },
1167 { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 , "local-des3-hmac-sha1" },
1168 { KRB5_ENCTYPE_RC4_PLAIN_EXP , "rc4-plain-exp" },
1169 { KRB5_ENCTYPE_RC4_PLAIN , "rc4-plain" },
1170 { KRB5_ENCTYPE_RC4_PLAIN_OLD_EXP, "rc4-plain-old-exp" },
1171 { KRB5_ENCTYPE_RC4_HMAC_OLD_EXP, "rc4-hmac-old-exp" },
1172 { KRB5_ENCTYPE_RC4_PLAIN_OLD , "rc4-plain-old" },
1173 { KRB5_ENCTYPE_RC4_HMAC_OLD , "rc4-hmac-old" },
1174 { KRB5_ENCTYPE_DES_PLAIN , "des-plain" },
1175 { KRB5_ENCTYPE_RC4_SHA , "rc4-sha" },
1176 { KRB5_ENCTYPE_RC4_LM , "rc4-lm" },
1177 { KRB5_ENCTYPE_RC4_PLAIN2 , "rc4-plain2" },
1178 { KRB5_ENCTYPE_RC4_MD4 , "rc4-md4" },
1179 { 0 , NULL },
1182 static const value_string krb5_checksum_types[] = {
1183 { KRB5_CHKSUM_NONE , "none" },
1184 { KRB5_CHKSUM_CRC32 , "crc32" },
1185 { KRB5_CHKSUM_MD4 , "md4" },
1186 { KRB5_CHKSUM_KRB_DES_MAC , "krb-des-mac" },
1187 { KRB5_CHKSUM_KRB_DES_MAC_K , "krb-des-mac-k" },
1188 { KRB5_CHKSUM_MD5 , "md5" },
1189 { KRB5_CHKSUM_MD5_DES , "md5-des" },
1190 { KRB5_CHKSUM_MD5_DES3 , "md5-des3" },
1191 { KRB5_CHKSUM_HMAC_SHA1_DES3_KD, "hmac-sha1-des3-kd" },
1192 { KRB5_CHKSUM_HMAC_SHA1_DES3 , "hmac-sha1-des3" },
1193 { KRB5_CHKSUM_SHA1_UNKEYED , "sha1 (unkeyed)" },
1194 { KRB5_CHKSUM_HMAC_MD5 , "hmac-md5" },
1195 { KRB5_CHKSUM_MD5_HMAC , "md5-hmac" },
1196 { KRB5_CHKSUM_RC4_MD5 , "rc5-md5" },
1197 { KRB5_CHKSUM_MD25 , "md25" },
1198 { KRB5_CHKSUM_DES_MAC_MD5 , "des-mac-md5" },
1199 { KRB5_CHKSUM_DES_MAC , "des-mac" },
1200 { KRB5_CHKSUM_REAL_CRC32 , "real-crc32" },
1201 { KRB5_CHKSUM_SHA1 , "sha1" },
1202 { KRB5_CHKSUM_LM , "lm" },
1203 { KRB5_CHKSUM_GSSAPI , "gssapi-8003" },
1204 { 0 , NULL },
1207 #define KRB5_AD_IF_RELEVANT 1
1208 #define KRB5_AD_INTENDED_FOR_SERVER 2
1209 #define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS 3
1210 #define KRB5_AD_KDC_ISSUED 4
1211 #define KRB5_AD_OR 5
1212 #define KRB5_AD_MANDATORY_TICKET_EXTENSIONS 6
1213 #define KRB5_AD_IN_TICKET_EXTENSIONS 7
1214 #define KRB5_AD_MANDATORY_FOR_KDC 8
1215 #define KRB5_AD_OSF_DCE 64
1216 #define KRB5_AD_SESAME 65
1217 #define KRB5_AD_OSF_DCE_PKI_CERTID 66
1218 #define KRB5_AD_WIN2K_PAC 128
1219 #define KRB5_AD_SIGNTICKET 0xffffffef
1220 static const value_string krb5_ad_types[] = {
1221 { KRB5_AD_IF_RELEVANT , "AD-IF-RELEVANT" },
1222 { KRB5_AD_INTENDED_FOR_SERVER , "AD-Intended-For-Server" },
1223 { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS , "AD-Intended-For-Application-Class" },
1224 { KRB5_AD_KDC_ISSUED , "AD-KDCIssued" },
1225 { KRB5_AD_OR , "AD-AND-OR" },
1226 { KRB5_AD_MANDATORY_TICKET_EXTENSIONS , "AD-Mandatory-Ticket-Extensions" },
1227 { KRB5_AD_IN_TICKET_EXTENSIONS , "AD-IN-Ticket-Extensions" },
1228 { KRB5_AD_MANDATORY_FOR_KDC , "AD-MANDATORY-FOR-KDC" },
1229 { KRB5_AD_OSF_DCE , "AD-OSF-DCE" },
1230 { KRB5_AD_SESAME , "AD-SESAME" },
1231 { KRB5_AD_OSF_DCE_PKI_CERTID , "AD-OSF-DCE-PKI-CertID" },
1232 { KRB5_AD_WIN2K_PAC , "AD-Win2k-PAC" },
1233 { KRB5_AD_SIGNTICKET , "AD-SignTicket" },
1234 { 0 , NULL },
1237 static const value_string krb5_transited_types[] = {
1238 { 1 , "DOMAIN-X500-COMPRESS" },
1239 { 0 , NULL }
1242 static const value_string krb5_address_types[] = {
1243 { KRB5_ADDR_IPv4, "IPv4"},
1244 { KRB5_ADDR_CHAOS, "CHAOS"},
1245 { KRB5_ADDR_XEROX, "XEROX"},
1246 { KRB5_ADDR_ISO, "ISO"},
1247 { KRB5_ADDR_DECNET, "DECNET"},
1248 { KRB5_ADDR_APPLETALK, "APPLETALK"},
1249 { KRB5_ADDR_NETBIOS, "NETBIOS"},
1250 { KRB5_ADDR_IPv6, "IPv6"},
1251 { 0, NULL },
1254 static const value_string krb5_msg_types[] = {
1255 { KRB5_MSG_TICKET, "Ticket" },
1256 { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
1257 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
1258 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
1259 { KRB5_MSG_TGS_REP, "TGS-REP" },
1260 { KRB5_MSG_AS_REQ, "AS-REQ" },
1261 { KRB5_MSG_AS_REP, "AS-REP" },
1262 { KRB5_MSG_AP_REQ, "AP-REQ" },
1263 { KRB5_MSG_AP_REP, "AP-REP" },
1264 { KRB5_MSG_SAFE, "KRB-SAFE" },
1265 { KRB5_MSG_PRIV, "KRB-PRIV" },
1266 { KRB5_MSG_CRED, "KRB-CRED" },
1267 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
1268 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
1269 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
1270 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1271 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1272 { KRB5_MSG_ERROR, "KRB-ERROR" },
1273 { 0, NULL },
1276 #define KRB5_GSS_C_DELEG_FLAG 0x01
1277 #define KRB5_GSS_C_MUTUAL_FLAG 0x02
1278 #define KRB5_GSS_C_REPLAY_FLAG 0x04
1279 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08
1280 #define KRB5_GSS_C_CONF_FLAG 0x10
1281 #define KRB5_GSS_C_INTEG_FLAG 0x20
1282 #define KRB5_GSS_C_DCE_STYLE 0x1000
1284 static const true_false_string tfs_gss_flags_deleg = {
1285 "Delegate credentials to remote peer",
1286 "Do NOT delegate"
1288 static const true_false_string tfs_gss_flags_mutual = {
1289 "Request that remote peer authenticates itself",
1290 "Mutual authentication NOT required"
1292 static const true_false_string tfs_gss_flags_replay = {
1293 "Enable replay protection for signed or sealed messages",
1294 "Do NOT enable replay protection"
1296 static const true_false_string tfs_gss_flags_sequence = {
1297 "Enable Out-of-sequence detection for sign or sealed messages",
1298 "Do NOT enable out-of-sequence detection"
1300 static const true_false_string tfs_gss_flags_conf = {
1301 "Confidentiality (sealing) may be invoked",
1302 "Do NOT use Confidentiality (sealing)"
1304 static const true_false_string tfs_gss_flags_integ = {
1305 "Integrity protection (signing) may be invoked",
1306 "Do NOT use integrity protection"
1309 static const true_false_string tfs_gss_flags_dce_style = {
1310 "DCE-STYLE",
1311 "Not using DCE-STYLE"
1314 #ifdef HAVE_KERBEROS
1315 static int
1316 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1317 proto_tree *tree, int hf_index _U_)
1319 guint8 *plaintext;
1320 int length;
1321 guint32 etype = 0;
1322 tvbuff_t *next_tvb;
1324 next_tvb=tvb_new_subset_remaining(tvb, offset);
1325 length=tvb_length_remaining(tvb, offset);
1327 if (actx->value_ptr) {
1328 etype = *((guint32*)actx->value_ptr);
1331 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1332 * 7.5.1
1333 * All Ticket encrypted parts use usage == 2
1335 plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, etype, NULL);
1337 if(plaintext){
1338 tvbuff_t *child_tvb;
1339 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1340 tvb_set_free_cb(child_tvb, g_free);
1342 /* Add the decrypted data to the data source list. */
1343 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1345 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1347 return offset;
1350 static int
1351 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1352 proto_tree *tree, int hf_index _U_)
1354 guint8 *plaintext;
1355 int length;
1356 guint32 etype = 0;
1357 tvbuff_t *next_tvb;
1359 next_tvb=tvb_new_subset_remaining(tvb, offset);
1360 length=tvb_length_remaining(tvb, offset);
1362 if (actx->value_ptr) {
1363 etype = *((guint32*)actx->value_ptr);
1366 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1367 * 7.5.1
1368 * Authenticators are encrypted with usage
1369 * == 7 or
1370 * == 11
1372 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, etype, NULL);
1374 if(!plaintext){
1375 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, etype, NULL);
1378 if(plaintext){
1379 tvbuff_t *child_tvb;
1380 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1381 tvb_set_free_cb(child_tvb, g_free);
1383 /* Add the decrypted data to the data source list. */
1384 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1386 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1388 return offset;
1391 static int
1392 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1393 proto_tree *tree, int hf_index _U_)
1395 guint8 *plaintext;
1396 int length;
1397 guint32 etype = 0;
1398 tvbuff_t *next_tvb;
1400 next_tvb=tvb_new_subset_remaining(tvb, offset);
1401 length=tvb_length_remaining(tvb, offset);
1403 if (actx->value_ptr) {
1404 etype = *((guint32*)actx->value_ptr);
1407 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1408 * 7.5.1
1409 * ASREP/TGSREP encryptedparts are encrypted with usage
1410 * == 3 or
1411 * == 8 or
1412 * == 9
1414 plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, etype, NULL);
1416 if(!plaintext){
1417 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, etype, NULL);
1420 if(!plaintext){
1421 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, etype, NULL);
1424 if(plaintext){
1425 tvbuff_t *child_tvb;
1426 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1427 tvb_set_free_cb(child_tvb, g_free);
1429 /* Add the decrypted data to the data source list. */
1430 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1432 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1434 return offset;
1437 static int
1438 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1439 proto_tree *tree, int hf_index _U_)
1441 guint8 *plaintext;
1442 int length;
1443 guint32 etype = 0;
1444 tvbuff_t *next_tvb;
1446 next_tvb=tvb_new_subset_remaining(tvb, offset);
1447 length=tvb_length_remaining(tvb, offset);
1449 if (actx->value_ptr) {
1450 etype = *((guint32*)actx->value_ptr);
1453 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1454 * 7.5.1
1455 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1456 * == 1
1458 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, etype, NULL);
1460 if(plaintext){
1461 tvbuff_t *child_tvb;
1462 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1463 tvb_set_free_cb(child_tvb, g_free);
1465 /* Add the decrypted data to the data source list. */
1466 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1468 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1470 return offset;
1473 static int
1474 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1475 proto_tree *tree, int hf_index _U_)
1477 guint8 *plaintext;
1478 int length;
1479 guint32 etype = 0;
1480 tvbuff_t *next_tvb;
1482 next_tvb=tvb_new_subset_remaining(tvb, offset);
1483 length=tvb_length_remaining(tvb, offset);
1485 if (actx->value_ptr) {
1486 etype = *((guint32*)actx->value_ptr);
1489 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1490 * 7.5.1
1491 * AP-REP are encrypted with usage == 12
1493 plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, etype, NULL);
1495 if(plaintext){
1496 tvbuff_t *child_tvb;
1497 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1498 tvb_set_free_cb(child_tvb, g_free);
1500 /* Add the decrypted data to the data source list. */
1501 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1503 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1505 return offset;
1508 static int
1509 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1510 proto_tree *tree, int hf_index _U_)
1512 guint8 *plaintext;
1513 int length;
1514 guint32 etype = 0;
1515 tvbuff_t *next_tvb;
1517 next_tvb=tvb_new_subset_remaining(tvb, offset);
1518 length=tvb_length_remaining(tvb, offset);
1520 if (actx->value_ptr) {
1521 etype = *((guint32*)actx->value_ptr);
1524 /* RFC4120 :
1525 * EncKrbPrivPart encrypted with usage
1526 * == 13
1528 plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, etype, NULL);
1530 if(plaintext){
1531 tvbuff_t *child_tvb;
1532 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1533 tvb_set_free_cb(child_tvb, g_free);
1535 /* Add the decrypted data to the data source list. */
1536 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1538 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1540 return offset;
1543 static int
1544 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1545 proto_tree *tree, int hf_index _U_)
1547 guint8 *plaintext;
1548 int length;
1549 guint32 etype = 0;
1550 tvbuff_t *next_tvb;
1552 next_tvb=tvb_new_subset_remaining(tvb, offset);
1553 length=tvb_length_remaining(tvb, offset);
1555 if (actx->value_ptr) {
1556 etype = *((guint32*)actx->value_ptr);
1559 /* RFC4120 :
1560 * EncKrbCredPart encrypted with usage
1561 * == 14
1563 plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, etype, NULL);
1565 if(plaintext){
1566 tvbuff_t *child_tvb;
1567 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1568 tvb_set_free_cb(child_tvb, g_free);
1570 /* Add the decrypted data to the data source list. */
1571 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1573 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1575 return offset;
1577 #endif
1579 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1581 static int
1582 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1584 int offset=0;
1585 guint32 len;
1586 guint16 dlglen;
1588 /* Length of Bnd field */
1589 len=tvb_get_letohl(tvb, offset);
1590 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1591 offset += 4;
1593 /* Bnd field */
1594 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1595 offset += len;
1598 /* flags */
1599 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1600 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1601 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1602 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1603 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1604 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1605 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1606 offset += 4;
1608 /* the next fields are optional so we have to check that we have
1609 * more data in our buffers */
1610 if(tvb_length_remaining(tvb, offset)<2){
1611 return offset;
1613 /* dlgopt identifier */
1614 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1615 offset += 2;
1617 if(tvb_length_remaining(tvb, offset)<2){
1618 return offset;
1620 /* dlglen identifier */
1621 dlglen=tvb_get_letohs(tvb, offset);
1622 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1623 offset += 2;
1625 if(dlglen!=tvb_length_remaining(tvb, offset)){
1626 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));
1627 return offset;
1630 /* this should now be a KRB_CRED message */
1631 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1633 return offset;
1636 static int
1637 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_)
1639 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1641 return offset;
1644 static int
1645 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_)
1647 guint32 nt_status;
1649 /* Microsoft stores a special 12 byte blob here
1650 * guint32 NT_status
1651 * guint32 unknown
1652 * guint32 unknown
1653 * decode everything as this blob for now until we see if anyone
1654 * else ever uses it or we learn how to tell whether this
1655 * is such an MS blob or not.
1657 proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
1658 ENC_LITTLE_ENDIAN);
1659 nt_status=tvb_get_letohl(tvb, offset);
1660 if(nt_status) {
1661 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
1662 " NT Status: %s",
1663 val_to_str(nt_status, NT_errors,
1664 "Unknown error code %#x"));
1666 offset += 4;
1668 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1669 ENC_LITTLE_ENDIAN);
1670 offset += 4;
1672 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
1673 ENC_LITTLE_ENDIAN);
1674 offset += 4;
1676 return offset;
1679 #include "packet-kerberos-fn.c"
1681 /* Make wrappers around exported functions for now */
1683 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1685 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
1690 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1692 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
1697 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1699 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
1702 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
1704 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
1708 static gint
1709 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1710 gboolean dci, gboolean do_col_protocol, gboolean have_rm,
1711 kerberos_callbacks *cb)
1713 volatile int offset = 0;
1714 proto_tree *volatile kerberos_tree = NULL;
1715 proto_item *volatile item = NULL;
1716 asn1_ctx_t asn1_ctx;
1718 /* TCP record mark and length */
1719 guint32 krb_rm = 0;
1720 gint krb_reclen = 0;
1722 gbl_do_col_info=dci;
1724 if (have_rm) {
1725 krb_rm = tvb_get_ntohl(tvb, offset);
1726 krb_reclen = kerberos_rm_to_reclen(krb_rm);
1728 * What is a reasonable size limit?
1730 if (krb_reclen > 10 * 1024 * 1024) {
1731 return (-1);
1734 if (do_col_protocol) {
1735 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1738 if (tree) {
1739 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1740 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1743 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1744 offset += 4;
1745 } else {
1746 /* Do some sanity checking here,
1747 * All krb5 packets start with a TAG class that is BER_CLASS_APP
1748 * and a tag value that is either of the values below:
1749 * If it doesnt look like kerberos, return 0 and let someone else have
1750 * a go at it.
1752 gint8 tmp_class;
1753 gboolean tmp_pc;
1754 gint32 tmp_tag;
1756 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
1757 if(tmp_class!=BER_CLASS_APP){
1758 return 0;
1760 switch(tmp_tag){
1761 case KRB5_MSG_TICKET:
1762 case KRB5_MSG_AUTHENTICATOR:
1763 case KRB5_MSG_ENC_TICKET_PART:
1764 case KRB5_MSG_AS_REQ:
1765 case KRB5_MSG_AS_REP:
1766 case KRB5_MSG_TGS_REQ:
1767 case KRB5_MSG_TGS_REP:
1768 case KRB5_MSG_AP_REQ:
1769 case KRB5_MSG_AP_REP:
1770 case KRB5_MSG_ENC_AS_REP_PART:
1771 case KRB5_MSG_ENC_TGS_REP_PART:
1772 case KRB5_MSG_ENC_AP_REP_PART:
1773 case KRB5_MSG_ENC_KRB_PRIV_PART:
1774 case KRB5_MSG_ENC_KRB_CRED_PART:
1775 case KRB5_MSG_SAFE:
1776 case KRB5_MSG_PRIV:
1777 case KRB5_MSG_ERROR:
1778 break;
1779 default:
1780 return 0;
1782 if (do_col_protocol) {
1783 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1785 if (gbl_do_col_info) {
1786 col_clear(pinfo->cinfo, COL_INFO);
1788 if (tree) {
1789 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
1790 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
1793 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1794 asn1_ctx.private_data = cb;
1796 TRY {
1797 offset=dissect_kerberos_Applications(FALSE, tvb, 0, &asn1_ctx , tree, /* hf_index */ -1);
1798 } CATCH_BOUNDS_ERRORS {
1799 RETHROW;
1800 } ENDTRY;
1802 proto_item_set_len(item, offset);
1803 return offset;
1807 * Display the TCP record mark.
1809 void
1810 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
1812 gint rec_len;
1813 proto_item *rm_item;
1814 proto_tree *rm_tree;
1816 if (tree == NULL)
1817 return;
1819 rec_len = kerberos_rm_to_reclen(krb_rm);
1820 rm_item = proto_tree_add_text(tree, tvb, start, 4,
1821 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
1822 rm_tree = proto_item_add_subtree(rm_item, ett_krb_recordmark);
1823 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
1824 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
1827 gint
1828 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
1830 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
1833 guint32
1834 kerberos_output_keytype(void)
1836 return gbl_keytype;
1839 static gint
1840 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1842 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
1843 Since all (except weirdo transarc krb4 stuff) use
1844 an opcode <=16 in the first byte, use this to see if it might
1845 be krb4.
1846 All krb5 commands start with an APPL tag and thus is >=0x60
1847 so if first byte is <=16 just blindly assume it is krb4 then
1849 if(tvb_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
1850 if(krb4_handle){
1851 gboolean res;
1853 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
1854 return res;
1855 }else{
1856 return 0;
1861 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
1864 gint
1865 kerberos_rm_to_reclen(guint krb_rm)
1867 return (krb_rm & KRB_RM_RECLEN);
1870 guint
1871 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1873 guint krb_rm;
1874 gint pdulen;
1876 krb_rm = tvb_get_ntohl(tvb, offset);
1877 pdulen = kerberos_rm_to_reclen(krb_rm);
1878 return (pdulen + 4);
1880 static void
1881 kerberos_prefs_apply_cb(void) {
1882 #ifdef HAVE_LIBNETTLE
1883 clear_keytab();
1884 read_keytab_file(keytab_filename);
1885 #endif
1888 static int
1889 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1891 pinfo->fragmented = TRUE;
1892 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
1894 * The dissector failed to recognize this as a valid
1895 * Kerberos message. Mark it as a continuation packet.
1897 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1900 return tvb_length(tvb);
1903 static int
1904 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1906 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1907 col_clear(pinfo->cinfo, COL_INFO);
1909 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
1910 dissect_kerberos_tcp_pdu, data);
1911 return tvb_length(tvb);
1914 /*--- proto_register_kerberos -------------------------------------------*/
1915 void proto_register_kerberos(void) {
1917 /* List of fields */
1919 static hf_register_info hf[] = {
1920 { &hf_krb_rm_reserved, {
1921 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
1922 &bitval, KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
1923 { &hf_krb_rm_reclen, {
1924 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
1925 NULL, KRB_RM_RECLEN, NULL, HFILL }},
1926 { &hf_krb_provsrv_location, {
1927 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
1928 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
1929 { &hf_krb_smb_nt_status,
1930 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
1931 VALS(NT_errors), 0, "NT Status code", HFILL }},
1932 { &hf_krb_smb_unknown,
1933 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
1934 NULL, 0, NULL, HFILL }},
1935 { &hf_krb_address_ip, {
1936 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
1937 NULL, 0, NULL, HFILL }},
1938 { &hf_krb_address_ipv6, {
1939 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
1940 NULL, 0, NULL, HFILL }},
1941 { &hf_krb_address_netbios, {
1942 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
1943 NULL, 0, "NetBIOS Address and type", HFILL }},
1944 { &hf_krb_gssapi_len, {
1945 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
1946 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
1947 { &hf_krb_gssapi_bnd, {
1948 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
1949 NULL, 0, "GSSAPI Bnd field", HFILL }},
1950 { &hf_krb_gssapi_c_flag_deleg, {
1951 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
1952 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
1953 { &hf_krb_gssapi_c_flag_mutual, {
1954 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
1955 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
1956 { &hf_krb_gssapi_c_flag_replay, {
1957 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
1958 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
1959 { &hf_krb_gssapi_c_flag_sequence, {
1960 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
1961 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
1962 { &hf_krb_gssapi_c_flag_conf, {
1963 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
1964 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
1965 { &hf_krb_gssapi_c_flag_integ, {
1966 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
1967 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
1968 { &hf_krb_gssapi_c_flag_dce_style, {
1969 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
1970 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
1971 { &hf_krb_gssapi_dlgopt, {
1972 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
1973 NULL, 0, "GSSAPI DlgOpt", HFILL }},
1974 { &hf_krb_gssapi_dlglen, {
1975 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
1976 NULL, 0, "GSSAPI DlgLen", HFILL }},
1978 #include "packet-kerberos-hfarr.c"
1981 /* List of subtrees */
1982 static gint *ett[] = {
1983 &ett_kerberos,
1984 &ett_krb_recordmark,
1985 #include "packet-kerberos-ettarr.c"
1988 static ei_register_info ei[] = {
1989 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
1992 expert_module_t* expert_krb;
1993 module_t *krb_module;
1995 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
1996 proto_register_field_array(proto_kerberos, hf, array_length(hf));
1997 proto_register_subtree_array(ett, array_length(ett));
1998 expert_krb = expert_register_protocol(proto_kerberos);
1999 expert_register_field_array(expert_krb, ei, array_length(ei));
2001 /* Register preferences */
2002 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2003 prefs_register_bool_preference(krb_module, "desegment",
2004 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2005 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2006 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2007 &krb_desegment);
2008 #ifdef HAVE_KERBEROS
2009 prefs_register_bool_preference(krb_module, "decrypt",
2010 "Try to decrypt Kerberos blobs",
2011 "Whether the dissector should try to decrypt "
2012 "encrypted Kerberos blobs. This requires that the proper "
2013 "keytab file is installed as well.", &krb_decrypt);
2015 prefs_register_filename_preference(krb_module, "file",
2016 "Kerberos keytab file",
2017 "The keytab file containing all the secrets",
2018 &keytab_filename);
2019 #endif
2022 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2023 proto_tree *tree, guint8 *drep _U_)
2025 tvbuff_t *auth_tvb;
2027 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2029 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2031 return tvb_length_remaining(tvb, offset);
2035 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2036 wrap_dissect_gss_kerb, /* Bind */
2037 wrap_dissect_gss_kerb, /* Bind ACK */
2038 wrap_dissect_gss_kerb, /* AUTH3 */
2039 NULL, /* Request verifier */
2040 NULL, /* Response verifier */
2041 NULL, /* Request data */
2042 NULL /* Response data */
2045 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2046 wrap_dissect_gss_kerb, /* Bind */
2047 wrap_dissect_gss_kerb, /* Bind ACK */
2048 wrap_dissect_gss_kerb, /* AUTH3 */
2049 wrap_dissect_gssapi_verf, /* Request verifier */
2050 wrap_dissect_gssapi_verf, /* Response verifier */
2051 NULL, /* Request data */
2052 NULL /* Response data */
2055 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2056 wrap_dissect_gss_kerb, /* Bind */
2057 wrap_dissect_gss_kerb, /* Bind ACK */
2058 wrap_dissect_gss_kerb, /* AUTH3 */
2059 wrap_dissect_gssapi_verf, /* Request verifier */
2060 wrap_dissect_gssapi_verf, /* Response verifier */
2061 wrap_dissect_gssapi_payload, /* Request data */
2062 wrap_dissect_gssapi_payload /* Response data */
2067 void
2068 proto_reg_handoff_kerberos(void)
2070 dissector_handle_t kerberos_handle_tcp;
2072 krb4_handle = find_dissector("krb4");
2074 kerberos_handle_udp = new_create_dissector_handle(dissect_kerberos_udp,
2075 proto_kerberos);
2077 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
2078 proto_kerberos);
2080 dissector_add_uint("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
2081 dissector_add_uint("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
2083 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2084 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2085 &gss_kerb_auth_connect_fns);
2087 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2088 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2089 &gss_kerb_auth_sign_fns);
2091 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2092 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
2093 &gss_kerb_auth_seal_fns);