aboutsummaryrefslogtreecommitdiffstats
path: root/asn1
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2008-10-15 20:08:10 +0000
committerAnders Broman <anders.broman@ericsson.com>2008-10-15 20:08:10 +0000
commit3cbb374385fdb0cb63efb4c5a68011967e1a98e4 (patch)
treeb44816c978eb84168c2a73d65ef01b0d97310930 /asn1
parent0fde67dd54131faf1ee8e6f0d6928f852af4b913 (diff)
Now Kerberos compiles, a lot of work remains to get it into shape.
svn path=/trunk/; revision=26467
Diffstat (limited to 'asn1')
-rw-r--r--asn1/Makefile.nmake10
-rw-r--r--asn1/kerberos/KerberosV5Spec2.asn4
-rw-r--r--asn1/kerberos/Makefile.common2
-rw-r--r--asn1/kerberos/kerberos.cnf92
-rw-r--r--asn1/kerberos/packet-kerberos-template.c397
-rw-r--r--asn1/kerberos/packet-kerberos-template.h67
-rw-r--r--asn1/pkinit/packet-pkinit-template.h2
-rw-r--r--asn1/pkinit/pkinit.cnf2
8 files changed, 503 insertions, 73 deletions
diff --git a/asn1/Makefile.nmake b/asn1/Makefile.nmake
index ee162f0890..0faac377f6 100644
--- a/asn1/Makefile.nmake
+++ b/asn1/Makefile.nmake
@@ -194,6 +194,9 @@ clean:
cd ldap
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
cd ..
+ cd kerberos
+ $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
+ cd ..
cd logotype-cert-extn
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
cd ..
@@ -484,11 +487,16 @@ inap::
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake copy_files
cd ..
+kerberos::
+ cd kerberos
+ $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake copy_files
+ cd ..
+
ldap::
cd ldap
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake copy_files
cd ..
-
+
logotype-cert-extn::
cd logotype-cert-extn
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake copy_files
diff --git a/asn1/kerberos/KerberosV5Spec2.asn b/asn1/kerberos/KerberosV5Spec2.asn
index 0c5e593c84..6256618816 100644
--- a/asn1/kerberos/KerberosV5Spec2.asn
+++ b/asn1/kerberos/KerberosV5Spec2.asn
@@ -12,7 +12,7 @@ KerberosV5Spec2 {
-- This OID also designates the OID arc for KerberosV5-related OIDs.
--
-- NOTE: RFC 1510 had an incorrect value (5) for "dod" in its OID.
--- My stuff
+-- WS construct
Applications ::= CHOICE {
ticket Ticket, -- 1 --
authenticator Authenticator, -- 2 --
@@ -33,7 +33,7 @@ Applications ::= CHOICE {
encKrbCredPart EncKrbCredPart, -- 29 --
krb-error KRB-ERROR -- 30 --
}
--- end my stuff
+-- end WS construct
id-krb5 OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) dod(6) internet(1)
security(5) kerberosV5(2)
diff --git a/asn1/kerberos/Makefile.common b/asn1/kerberos/Makefile.common
index 658df0627b..f5599f972d 100644
--- a/asn1/kerberos/Makefile.common
+++ b/asn1/kerberos/Makefile.common
@@ -46,7 +46,7 @@ SRC_FILES = \
$(EXTRA_DIST) \
$(EXT_ASN_FILE_LIST)
-A2W_FLAGS= -b -X -T -e
+A2W_FLAGS= -b -e
EXTRA_CNF=
diff --git a/asn1/kerberos/kerberos.cnf b/asn1/kerberos/kerberos.cnf
index 1b99705bcc..451bb7cfca 100644
--- a/asn1/kerberos/kerberos.cnf
+++ b/asn1/kerberos/kerberos.cnf
@@ -1,12 +1,98 @@
# kerberos.cnf
# kerberos conformation file
-# Copyright 2007 Anders Broman
+# Copyright 2008 Anders Broman
# $Id$
+#.EXPORTS
+Checksum
+PrincipalName
+KerberosTime
+Realm
#.FIELD_RENAME
+EncryptedData/etype encryptedData_etype
+KDC-REQ-BODY/etype kDC-REQ-BODY_etype
-#.FN_PARS
-Int32 VAL_PTR = etype
+#.FN_BODY KDC-REQ/msg-type VAL_PTR = &msgtype
+guint32 msgtype;
+
+%(DEFAULT_BODY)s
+ if (do_col_info & check_col(actx->pinfo->cinfo, COL_INFO)) {
+ col_add_str(actx->pinfo->cinfo, COL_INFO,
+ val_to_str(msgtype, krb5_msg_types,
+ "Unknown msg type %%#x"));
+ }
+ do_col_info=FALSE;
+
+ /* append the application type to the tree */
+ proto_item_append_text(tree, " %%s", val_to_str(msgtype, krb5_msg_types, "Unknown:0x%%x"));
+
+#.FN_BODY Int32 VAL_PTR = actx->value_ptr
+%(DEFAULT_BODY)s
+
+#.FN_BODY PA-DATA/padata-type
+/* Calling Int32 returns the value in ctx->value_ptr */
+actx->value_ptr = &krb_PA_DATA_type;
+%(DEFAULT_BODY)s
+
+krb_PA_DATA_type&=0xff; /*this is really just one single byte */
+ if(tree){
+ proto_item_append_text(tree, " %%s",
+ val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
+ "Unknown:%%d"));
+ }
+
+#.FN_BODY PA-DATA/padata-value
+proto_tree *sub_tree=tree;
+
+ if(actx->created_item){
+ sub_tree=proto_item_add_subtree(actx->created_item, ett_kerberos_PA_DATA);
+ }
+
+ switch(krb_PA_DATA_type){
+ case KRB5_PA_TGS_REQ:
+ offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_kerberos_Applications);
+ break;
+ case KRB5_PA_PK_AS_REQ:
+ offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_pkinit_PaPkAsReq);
+ break;
+ case KRB5_PA_PK_AS_REP:
+ offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_pkinit_PaPkAsRep);
+ break;
+ /*
+ case KRB5_PA_PAC_REQUEST:
+ offset=dissect_ber_old_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_krb5_PA_PAC_REQUEST);
+ break;
+ case KRB5_PA_S4U2SELF:
+ offset=dissect_ber_old_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_krb5_PA_S4U2SELF);
+ break;
+ case KRB5_PA_PROV_SRV_LOCATION:
+ offset=dissect_ber_old_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_krb5_PA_PROV_SRV_LOCATION);
+ break;
+ */
+ case KRB5_PA_ENC_TIMESTAMP:
+ offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_kerberos_PA_ENC_TIMESTAMP);
+ break;
+ /*
+ case KRB5_PA_ENCTYPE_INFO:
+ offset=dissect_ber_old_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_krb5_PA_ENCTYPE_INFO);
+ break;
+ case KRB5_PA_ENCTYPE_INFO2:
+ offset=dissect_ber_old_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_krb5_PA_ENCTYPE_INFO2);
+ break;
+ case KRB5_PA_PW_SALT:
+ offset=dissect_ber_old_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, dissect_krb5_PW_SALT);
+ break;
+ */
+ default:
+ offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_kerberos_padata_value, NULL);
+ }
+/*qqq*/
+
+
+#.TYPE_ATTR
+KDC-REQ/msg-type TYPE = FT_UINT32 DISPLAY = BASE_DEC STRINGS = VALS(krb5_msg_types)
+# this does not work for some reason :(
+EncryptedData/etype TYPE = FT_UINT32 DISPLAY = BASE_DEC STRINGS = VALS(krb5_encryption_types)
diff --git a/asn1/kerberos/packet-kerberos-template.c b/asn1/kerberos/packet-kerberos-template.c
index bd13cea8e1..529e2379ee 100644
--- a/asn1/kerberos/packet-kerberos-template.c
+++ b/asn1/kerberos/packet-kerberos-template.c
@@ -76,16 +76,18 @@
#include <sys/stat.h> /* For keyfile manipulation */
#endif
+#include <wsutil/file_util.h>
#include <epan/packet.h>
-
#include <epan/strutil.h>
#include <epan/conversation.h>
#include <epan/emem.h>
+#include <epan/oids.h>
+#include <epan/asn1.h>
+#include <epan/prefs.h>
#include <epan/dissectors/packet-kerberos.h>
#include <epan/dissectors/packet-netbios.h>
#include <epan/dissectors/packet-tcp.h>
-#include <epan/prefs.h>
#include <epan/dissectors/packet-ber.h>
#include <epan/dissectors/packet-per.h>
#include <epan/dissectors/packet-pkinit.h>
@@ -97,29 +99,41 @@
#include <epan/dissectors/packet-gssapi.h>
-#include <wiretap/file_util.h>
#define PNAME "Kerberos"
#define PSNAME "KRB5"
#define PFNAME "kerberos"
-static kerberos_packet_info kerberos_pi;
-
#define UDP_PORT_KERBEROS 88
#define TCP_PORT_KERBEROS 88
static dissector_handle_t kerberos_handle_udp=NULL;
+/* Global variables */
+static guint32 authenticator_etype;
+static guint32 keytype;
+guint32 krb_PA_DATA_type;
+static gboolean do_col_info;
+
+/* Forward declarations */
+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_);
+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_);
+
/* Desegment Kerberos over TCP messages */
static gboolean krb_desegment = TRUE;
static gint proto_kerberos = -1;
+static struct { const char *set; const char *unset; } bitval = { "Set", "Not set" };
+static gint hf_krb_rm_reserved = -1;
+static gint hf_krb_rm_reclen = -1;
#include "packet-kerberos-hf.c"
/* Initialize the subtree pointers */
static gint ett_kerberos = -1;
+static gint ett_krb_recordmark = -1;
+
#include "packet-kerberos-ett.c"
guint32 krb5_errorcode;
@@ -154,7 +168,7 @@ call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int
#ifdef HAVE_KERBEROS
/* Decrypt Kerberos blobs */
-static gboolean krb_decrypt = FALSE;
+gboolean krb_decrypt = FALSE;
/* keytab filename */
static const char *keytab_filename = "insert filename here";
@@ -178,7 +192,7 @@ add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *k
if(pinfo->fd->flags.visited){
return;
}
-printf("added key in %u\n",pinfo->fd->num);
+printf("added key in %u keytype:%d len:%d\n",pinfo->fd->num, keytype, keylength);
new_key=g_malloc(sizeof(enc_key_t));
g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->fd->num);
@@ -194,24 +208,36 @@ printf("added key in %u\n",pinfo->fd->num);
#ifdef HAVE_MIT_KERBEROS
-static void
-read_keytab_file(const char *filename, krb5_context *context)
+static krb5_context krb5_ctx;
+
+void
+read_keytab_file(const char *filename)
{
krb5_keytab keytab;
- krb5_keytab_entry key;
krb5_error_code ret;
+ krb5_keytab_entry key;
krb5_kt_cursor cursor;
enc_key_t *new_key;
+ static int first_time=1;
+
+printf("read keytab file %s\n", filename);
+ if(first_time){
+ first_time=0;
+ ret = krb5_init_context(&krb5_ctx);
+ if(ret){
+ return;
+ }
+ }
/* should use a file in the wireshark users dir */
- ret = krb5_kt_resolve(*context, filename, &keytab);
+ ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
if(ret){
fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
return;
}
- ret = krb5_kt_start_seq_get(*context, keytab, &cursor);
+ ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
if(ret){
fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
return;
@@ -220,7 +246,7 @@ read_keytab_file(const char *filename, krb5_context *context)
do{
new_key=g_malloc(sizeof(enc_key_t));
new_key->next=enc_key_list;
- ret = krb5_kt_next_entry(*context, keytab, &key, &cursor);
+ ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
if(ret==0){
int i;
char *pos;
@@ -244,9 +270,9 @@ read_keytab_file(const char *filename, krb5_context *context)
}
}while(ret==0);
- ret = krb5_kt_end_seq_get(*context, keytab, &cursor);
+ ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
if(ret){
- krb5_kt_close(*context, keytab);
+ krb5_kt_close(krb5_ctx, keytab);
}
}
@@ -257,10 +283,10 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
int usage,
int length,
const guint8 *cryptotext,
- int keytype)
+ int keytype,
+ int *datalen)
{
static int first_time=1;
- static krb5_context context;
krb5_error_code ret;
enc_key_t *ek;
static krb5_data data = {0,0,NULL};
@@ -277,18 +303,14 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
/* should this have a destroy context ? MIT people would know */
if(first_time){
first_time=0;
- ret = krb5_init_context(&context);
- if(ret){
- return NULL;
- }
- read_keytab_file(keytab_filename, &context);
+ read_keytab_file(keytab_filename);
}
for(ek=enc_key_list;ek;ek=ek->next){
krb5_enc_data input;
/* shortcircuit and bail out if enctypes are not matching */
- if(ek->keytype!=keytype){
+ if((keytype != -1) && (ek->keytype != keytype)) {
continue;
}
@@ -305,15 +327,18 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
key.key.enctype=ek->keytype;
key.key.length=ek->keylength;
key.key.contents=ek->keyvalue;
- ret = krb5_c_decrypt(context, &(key.key), usage, 0, &input, &data);
+ ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
if((ret == 0) && (length>0)){
char *user_data;
-printf("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
+printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
/* return a private g_malloced blob to the caller */
user_data=g_malloc(data.length);
memcpy(user_data, data.data, data.length);
+ if (datalen) {
+ *datalen = data.length;
+ }
return user_data;
}
}
@@ -322,24 +347,35 @@ printf("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
}
#elif defined(HAVE_HEIMDAL_KERBEROS)
-static void
-read_keytab_file(const char *filename, krb5_context *context)
+static krb5_context krb5_ctx;
+
+void
+read_keytab_file(const char *filename)
{
krb5_keytab keytab;
- krb5_keytab_entry key;
krb5_error_code ret;
+ krb5_keytab_entry key;
krb5_kt_cursor cursor;
enc_key_t *new_key;
+ static int first_time=1;
+
+ if(first_time){
+ first_time=0;
+ ret = krb5_init_context(&krb5_ctx);
+ if(ret){
+ return;
+ }
+ }
/* should use a file in the wireshark users dir */
- ret = krb5_kt_resolve(*context, filename, &keytab);
+ ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
if(ret){
fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
return;
}
- ret = krb5_kt_start_seq_get(*context, keytab, &cursor);
+ ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
if(ret){
fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
return;
@@ -348,7 +384,7 @@ read_keytab_file(const char *filename, krb5_context *context)
do{
new_key=g_malloc(sizeof(enc_key_t));
new_key->next=enc_key_list;
- ret = krb5_kt_next_entry(*context, keytab, &key, &cursor);
+ ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
if(ret==0){
unsigned int i;
char *pos;
@@ -371,9 +407,9 @@ read_keytab_file(const char *filename, krb5_context *context)
}
}while(ret==0);
- ret = krb5_kt_end_seq_get(*context, keytab, &cursor);
+ ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
if(ret){
- krb5_kt_close(*context, keytab);
+ krb5_kt_close(krb5_ctx, keytab);
}
}
@@ -384,10 +420,10 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
int usage,
int length,
const guint8 *cryptotext,
- int keytype)
+ int keytype,
+ int *datalen)
{
static int first_time=1;
- static krb5_context context;
krb5_error_code ret;
krb5_data data;
enc_key_t *ek;
@@ -403,11 +439,7 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
/* should this have a destroy context ? Heimdal people would know */
if(first_time){
first_time=0;
- ret = krb5_init_context(&context);
- if(ret){
- return NULL;
- }
- read_keytab_file(keytab_filename, &context);
+ read_keytab_file(keytab_filename);
}
for(ek=enc_key_list;ek;ek=ek->next){
@@ -416,14 +448,14 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
/* shortcircuit and bail out if enctypes are not matching */
- if(ek->keytype!=keytype){
+ if((keytype != -1) && (ek->keytype != keytype)) {
continue;
}
key.keyblock.keytype=ek->keytype;
key.keyblock.keyvalue.length=ek->keylength;
key.keyblock.keyvalue.data=ek->keyvalue;
- ret = krb5_crypto_init(context, &(key.keyblock), 0, &crypto);
+ ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), 0, &crypto);
if(ret){
return NULL;
}
@@ -436,7 +468,7 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
*/
cryptocopy=g_malloc(length);
memcpy(cryptocopy, cryptotext, length);
- ret = krb5_decrypt_ivec(context, crypto, usage,
+ ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
cryptocopy, length,
&data,
NULL);
@@ -444,15 +476,18 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
if((ret == 0) && (length>0)){
char *user_data;
-printf("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
+printf("woohoo decrypted keytype:%d in frame:%u\n", ek->keytype, pinfo->fd->num);
proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
- krb5_crypto_destroy(context, crypto);
+ krb5_crypto_destroy(krb5_ctx, crypto);
/* return a private g_malloced blob to the caller */
user_data=g_malloc(data.length);
memcpy(user_data, data.data, data.length);
+ if (datalen) {
+ *datalen = data.length;
+ }
return user_data;
}
- krb5_crypto_destroy(context, crypto);
+ krb5_crypto_destroy(krb5_ctx, crypto);
}
return NULL;
}
@@ -515,7 +550,7 @@ read_keytab_file(const char *service_key_file)
unsigned char buf[SERVICE_KEY_SIZE];
int newline_skip = 0, count = 0;
- if (service_key_file != NULL && stat (service_key_file, &st) == 0) {
+ if (service_key_file != NULL && ws_stat (service_key_file, &st) == 0) {
/* The service key file contains raw 192-bit (24 byte) 3DES keys.
* There can be zero, one (\n), or two (\r\n) characters between
@@ -533,7 +568,7 @@ read_keytab_file(const char *service_key_file)
}
}
- skf = eth_fopen(service_key_file, "rb");
+ skf = ws_fopen(service_key_file, "rb");
if (! skf) return;
while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
@@ -560,7 +595,8 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
int _U_ usage,
int length,
const guint8 *cryptotext,
- int keytype)
+ int keytype,
+ int *datalen)
{
tvbuff_t *encr_tvb;
guint8 *decrypted_data = NULL, *plaintext = NULL;
@@ -613,7 +649,7 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
*/
TRY {
id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
- offset = get_ber_length(tree, encr_tvb, id_offset, &item_len, &ind);
+ offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
}
CATCH (BoundsError) {
tvb_free(encr_tvb);
@@ -622,7 +658,7 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
ENDTRY;
if (do_continue) continue;
-
+
data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
if ((int) item_len + offset > length) {
tvb_free(encr_tvb);
@@ -640,6 +676,9 @@ g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
tvb_free(encr_tvb);
+ if (datalen) {
+ *datalen = data_len;
+ }
g_free(decrypted_data);
return(plaintext);
}
@@ -652,7 +691,7 @@ g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
#endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
-
+#define INET6_ADDRLEN 16
/* TCP Record Mark */
#define KRB_RM_RESERVED 0x80000000L
@@ -794,6 +833,7 @@ g_warning("woohoo decrypted keytype:%d in frame:%u\n", keytype, pinfo->fd->num);
come up with something better
*/
#define KRB5_PA_PAC_REQUEST 128 /* MS extension */
+#define KRB5_PA_S4U2SELF 129 /* Impersonation (Microsoft extension) */
#define KRB5_PA_PROV_SRV_LOCATION 255 /* packetcable stuff */
/* Principal name-type */
@@ -970,6 +1010,7 @@ static const value_string krb5_error_codes[] = {
#define PAC_PRIVSVR_CHECKSUM 7
#define PAC_CLIENT_INFO_TYPE 10
#define PAC_CONSTRAINED_DELEGATION 11
+#define PAC_UPN_DNS_INFO 12
static const value_string w2k_pac_types[] = {
{ PAC_LOGON_INFO , "Logon Info" },
{ PAC_CREDENTIAL_TYPE , "Credential Type" },
@@ -977,6 +1018,7 @@ static const value_string w2k_pac_types[] = {
{ PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
{ PAC_CLIENT_INFO_TYPE , "Client Info Type" },
{ PAC_CONSTRAINED_DELEGATION, "Constrained Delegation" },
+ { PAC_UPN_DNS_INFO , "UPN DNS Info" },
{ 0, NULL },
};
@@ -1034,6 +1076,7 @@ static const value_string krb5_preauthentication_types[] = {
{ KRB5_TD_REQ_NONCE , "TD-REQ-NONCE" },
{ KRB5_TD_REQ_SEQ , "TD-REQ-SEQ" },
{ KRB5_PA_PAC_REQUEST , "PA-PAC-REQUEST" },
+ { KRB5_PA_S4U2SELF , "PA-S4U2SELF" },
{ KRB5_PA_PROV_SRV_LOCATION , "PA-PROV-SRV-LOCATION" },
{ 0 , NULL },
};
@@ -1113,6 +1156,7 @@ static const value_string krb5_checksum_types[] = {
#define KRB5_AD_SESAME 65
#define KRB5_AD_OSF_DCE_PKI_CERTID 66
#define KRB5_AD_WIN2K_PAC 128
+#define KRB5_AD_SIGNTICKET 0xffffffef
static const value_string krb5_ad_types[] = {
{ KRB5_AD_IF_RELEVANT , "AD-IF-RELEVANT" },
{ KRB5_AD_INTENDED_FOR_SERVER , "AD-Intended-For-Server" },
@@ -1126,6 +1170,7 @@ static const value_string krb5_ad_types[] = {
{ KRB5_AD_SESAME , "AD-SESAME" },
{ KRB5_AD_OSF_DCE_PKI_CERTID , "AD-OSF-DCE-PKI-CertID" },
{ KRB5_AD_WIN2K_PAC , "AD-Win2k-PAC" },
+ { KRB5_AD_SIGNTICKET , "AD-SignTicket" },
{ 0 , NULL },
};
@@ -1184,10 +1229,10 @@ dissect_krb5_decrypt_authenticator_data (proto_tree *tree, tvbuff_t *tvb, int of
* == 11
*/
if(!plaintext){
- plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, length, tvb_get_ptr(tvb, offset, length), authenticator_etype);
+ plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, length, tvb_get_ptr(tvb, offset, length), authenticator_etype, NULL);
}
if(!plaintext){
- plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, length, tvb_get_ptr(tvb, offset, length), authenticator_etype);
+ plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, length, tvb_get_ptr(tvb, offset, length), authenticator_etype, NULL);
}
if(plaintext){
@@ -1201,22 +1246,242 @@ dissect_krb5_decrypt_authenticator_data (proto_tree *tree, tvbuff_t *tvb, int of
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, next_tvb, "Decrypted Krb5");
- dissect_kerberos_Applications(FALSE, next_tvb, 0, actx, tree, -1)
+ offset=dissect_kerberos_Applications(FALSE, next_tvb, 0, actx , tree, /* hf_index */ -1);
+
}
return offset;
}
#endif
+
#include "packet-kerberos-fn.c"
+/* Make wrappers around exported functions for now */
+int
+dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
+{
+ return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
+
+}
+
+int
+dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
+{
+ return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
+}
+
+
+int
+dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
+{
+ return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
+}
+int
+dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
+{
+ return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
+}
+
+
+static gint
+dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gboolean dci, gboolean do_col_protocol, gboolean have_rm,
+ kerberos_callbacks *cb)
+{
+ volatile int offset = 0;
+ proto_tree *volatile kerberos_tree = NULL;
+ proto_item *volatile item = NULL;
+ void *saved_private_data;
+ asn1_ctx_t asn1_ctx;
+
+ /* TCP record mark and length */
+ guint32 krb_rm = 0;
+ gint krb_reclen = 0;
+
+ saved_private_data=pinfo->private_data;
+ pinfo->private_data=cb;
+ do_col_info=dci;
+
+ if (have_rm) {
+ krb_rm = tvb_get_ntohl(tvb, offset);
+ krb_reclen = kerberos_rm_to_reclen(krb_rm);
+ /*
+ * What is a reasonable size limit?
+ */
+ if (krb_reclen > 10 * 1024 * 1024) {
+ pinfo->private_data=saved_private_data;
+ return (-1);
+ }
+ if (do_col_protocol) {
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
+ }
+ if (tree) {
+ item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, FALSE);
+ kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
+ }
+ show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
+ offset += 4;
+ } else {
+ /* Do some sanity checking here,
+ * All krb5 packets start with a TAG class that is BER_CLASS_APP
+ * and a tag value that is either of the values below:
+ * If it doesnt look like kerberos, return 0 and let someone else have
+ * a go at it.
+ */
+ gint8 tmp_class;
+ gboolean tmp_pc;
+ gint32 tmp_tag;
+
+ get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
+ if(tmp_class!=BER_CLASS_APP){
+ pinfo->private_data=saved_private_data;
+ return 0;
+ }
+ switch(tmp_tag){
+ case KRB5_MSG_TICKET:
+ case KRB5_MSG_AUTHENTICATOR:
+ case KRB5_MSG_ENC_TICKET_PART:
+ case KRB5_MSG_AS_REQ:
+ case KRB5_MSG_AS_REP:
+ case KRB5_MSG_TGS_REQ:
+ case KRB5_MSG_TGS_REP:
+ case KRB5_MSG_AP_REQ:
+ case KRB5_MSG_AP_REP:
+ case KRB5_MSG_ENC_AS_REP_PART:
+ case KRB5_MSG_ENC_TGS_REP_PART:
+ case KRB5_MSG_ENC_AP_REP_PART:
+ case KRB5_MSG_ENC_KRB_PRIV_PART:
+ case KRB5_MSG_ENC_KRB_CRED_PART:
+ case KRB5_MSG_SAFE:
+ case KRB5_MSG_PRIV:
+ case KRB5_MSG_ERROR:
+ break;
+ default:
+ pinfo->private_data=saved_private_data;
+ return 0;
+ }
+ if (do_col_protocol) {
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
+ }
+ if (do_col_info) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+ }
+ if (tree) {
+ item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, FALSE);
+ kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
+ }
+ }
+ asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
+
+ TRY {
+ offset=dissect_kerberos_Applications(FALSE, tvb, 0, &asn1_ctx , tree, /* hf_index */ -1);
+ } CATCH_ALL {
+ pinfo->private_data=saved_private_data;
+ RETHROW;
+ } ENDTRY;
+
+ proto_item_set_len(item, offset);
+ pinfo->private_data=saved_private_data;
+ return offset;
+}
+/*
+ * Display the TCP record mark.
+ */
+void
+show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
+{
+ gint rec_len;
+ proto_item *rm_item;
+ proto_tree *rm_tree;
+
+ if (tree == NULL)
+ return;
+ rec_len = kerberos_rm_to_reclen(krb_rm);
+ rm_item = proto_tree_add_text(tree, tvb, start, 4,
+ "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
+ rm_tree = proto_item_add_subtree(rm_item, ett_krb_recordmark);
+ proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
+ proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
}
+
+gint
+dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
+{
+ return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
+}
+
+guint32
+kerberos_output_keytype(void)
+{
+ return keytype;
+}
+
+static gint
+dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
+ Since all (except weirdo transarc krb4 stuff) use
+ an opcode <=16 in the first byte, use this to see if it might
+ be krb4.
+ All krb5 commands start with an APPL tag and thus is >=0x60
+ so if first byte is <=16 just blindly assume it is krb4 then
+ */
+ if(tvb_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
+ if(krb4_handle){
+ gboolean res;
+
+ res=call_dissector_only(krb4_handle, tvb, pinfo, tree);
+ return res;
+ }else{
+ return 0;
+ }
+ }
+
+
+ return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
+}
+
+gint
+kerberos_rm_to_reclen(guint krb_rm)
+{
+ return (krb_rm & KRB_RM_RECLEN);
+}
+
+guint
+get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
+{
+ guint krb_rm;
+ gint pdulen;
+
+ krb_rm = tvb_get_ntohl(tvb, offset);
+ pdulen = kerberos_rm_to_reclen(krb_rm);
+ return (pdulen + 4);
+}
+static void
+kerberos_prefs_apply_cb(void) {
+#ifdef HAVE_LIBNETTLE
+ clear_keytab();
+ read_keytab_file(keytab_filename);
+#endif
+}
+
/*--- proto_register_kerberos -------------------------------------------*/
void proto_register_kerberos(void) {
/* List of fields */
+ static hf_register_info hf[] = {
+ { &hf_krb_rm_reserved, {
+ "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
+ &bitval, KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
+ { &hf_krb_rm_reclen, {
+ "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
+ NULL, KRB_RM_RECLEN, "Record length", HFILL }},
#include "packet-kerberos-hfarr.c"
};
@@ -1224,9 +1489,11 @@ void proto_register_kerberos(void) {
/* List of subtrees */
static gint *ett[] = {
&ett_kerberos,
+ &ett_krb_recordmark,
#include "packet-kerberos-ettarr.c"
};
+ module_t *krb_module;
/* Register protocol */
proto_kerberos = proto_register_protocol(PNAME, PSNAME, PFNAME);
@@ -1234,8 +1501,6 @@ void proto_register_kerberos(void) {
proto_register_field_array(proto_kerberos, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
-
- register_dissector("kerberos", dissect_kerberos, proto_kerberos);
/* Register preferences */
krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
prefs_register_bool_preference(krb_module, "desegment",
@@ -1275,11 +1540,11 @@ static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
static dcerpc_auth_subdissector_fns gss_kerb_auth_fns = {
wrap_dissect_gss_kerb, /* Bind */
wrap_dissect_gss_kerb, /* Bind ACK */
- NULL, /* AUTH3 */
- wrap_dissect_gssapi_verf, /* Request verifier */
- wrap_dissect_gssapi_verf, /* Response verifier */
- wrap_dissect_gssapi_payload, /* Request data */
- wrap_dissect_gssapi_payload /* Response data */
+ NULL, /* AUTH3 */
+ wrap_dissect_gssapi_verf, /* Request verifier */
+ wrap_dissect_gssapi_verf, /* Response verifier */
+ wrap_dissect_gssapi_payload, /* Request data */
+ wrap_dissect_gssapi_payload /* Response data */
};
@@ -1289,17 +1554,21 @@ void
proto_reg_handoff_kerberos(void)
{
+ /*
dissector_handle_t kerberos_handle_tcp;
-
+ */
krb4_handle = find_dissector("krb4");
kerberos_handle_udp = new_create_dissector_handle(dissect_kerberos_udp,
proto_kerberos);
+ /*
kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
proto_kerberos);
+ */
dissector_add("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
+ /*
dissector_add("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
-
+ */
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
&gss_kerb_auth_fns);
diff --git a/asn1/kerberos/packet-kerberos-template.h b/asn1/kerberos/packet-kerberos-template.h
index d9397696a8..54b5b71cb2 100644
--- a/asn1/kerberos/packet-kerberos-template.h
+++ b/asn1/kerberos/packet-kerberos-template.h
@@ -24,8 +24,73 @@
*/
#ifndef PACKET_KERBEROS_H
-#define PACKET_ROS_H
+#define PACKET_KERBEROS_H
+/* This is a list of callback functions a caller can use to specify that
+ octet strings in kerberos to be passed back to application specific
+ dissectors, outside of kerberos.
+ This is used for dissection of application specific data for PacketCable
+ KRB_SAFE user data and eventually to pass kerberos session keys
+ to future DCERPC decryption and other uses.
+ The list is terminated by {0, NULL }
+*/
+#define KRB_CBTAG_SAFE_USER_DATA 1
+#define KRB_CBTAG_PRIV_USER_DATA 2
+typedef struct _kerberos_callbacks {
+ int tag;
+ int (*callback)(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree);
+} kerberos_callbacks;
+
+/* Function prototypes */
+
+gint
+dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean do_col_info, kerberos_callbacks *cb);
+
+#include "packet-kerberos-exp.h"
+
+int
+dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
+
+int
+dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
+
+int dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
+int dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
+guint32 kerberos_output_keytype(void);
+
+guint get_krb_pdu_len(packet_info *, tvbuff_t *tvb, int offset);
+
+gint kerberos_rm_to_reclen(guint krb_rm);
+
+void
+show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm);
+
+#ifdef HAVE_KERBEROS
+#define KRB_MAX_ORIG_LEN 256
+
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
+typedef struct _enc_key_t {
+ struct _enc_key_t *next;
+ int keytype;
+ int keylength;
+ char *keyvalue;
+ char key_origin[KRB_MAX_ORIG_LEN+1];
+} enc_key_t;
+extern enc_key_t *enc_key_list;
+
+guint8 *
+decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
+ int usage,
+ int length,
+ const guint8 *cryptotext,
+ int keytype,
+ int *datalen);
+
+#endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
+
+extern gboolean krb_decrypt;
+
+#endif /* HAVE_KERBEROS */
#include "packet-kerberos-exp.h"
diff --git a/asn1/pkinit/packet-pkinit-template.h b/asn1/pkinit/packet-pkinit-template.h
index 9d0d82f5ce..8c41d89a5b 100644
--- a/asn1/pkinit/packet-pkinit-template.h
+++ b/asn1/pkinit/packet-pkinit-template.h
@@ -29,7 +29,7 @@
int dissect_pkinit_PA_PK_AS_REQ(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
int dissect_pkinit_PA_PK_AS_REP(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_);
-/*#include "packet-pkinit-exp.h"*/
+#include "packet-pkinit-exp.h"
#endif /* PACKET_PKINIT_H */
diff --git a/asn1/pkinit/pkinit.cnf b/asn1/pkinit/pkinit.cnf
index 3174efef02..63ce6b006e 100644
--- a/asn1/pkinit/pkinit.cnf
+++ b/asn1/pkinit/pkinit.cnf
@@ -10,6 +10,8 @@ PKIX1Explicit88 pkix1explicit
#.IMPORT ../cms/cms-exp.cnf
#.EXPORTS
+PaPkAsReq
+PaPkAsRep
#.REGISTER
AuthPack B "1.3.6.1.5.2.3.1" "id-pkauthdata"