summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/asn1/kerberos/packet-kerberos-template.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/asn1/kerberos/packet-kerberos-template.c')
-rw-r--r--epan/dissectors/asn1/kerberos/packet-kerberos-template.c1565
1 files changed, 1140 insertions, 425 deletions
diff --git a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c
index 2b5a906d..97c4c01d 100644
--- a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c
+++ b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c
@@ -15,11 +15,11 @@
*
* and
*
- * https://tools.ietf.org/html/draft-ietf-krb-wg-kerberos-clarifications-07
+ * https://tools.ietf.org/html/rfc4120
*
* and
*
- * https://tools.ietf.org/html/draft-ietf-krb-wg-kerberos-referrals-05
+ * https://tools.ietf.org/html/rfc6806
*
* Some structures from RFC2630
*
@@ -54,16 +54,19 @@
#endif
#include <epan/packet.h>
+#include <epan/proto_data.h>
#include <epan/exceptions.h>
#include <epan/strutil.h>
#include <epan/conversation.h>
#include <epan/asn1.h>
#include <epan/expert.h>
#include <epan/prefs.h>
+#include <epan/srt_table.h>
#include <wsutil/wsgcrypt.h>
#include <wsutil/file_util.h>
#include <wsutil/str_util.h>
#include <wsutil/pint.h>
+#include <wsutil/array.h>
#include "packet-kerberos.h"
#include "packet-netbios.h"
#include "packet-tcp.h"
@@ -96,9 +99,9 @@ void proto_reg_handoff_kerberos(void);
#define ADDRESS_STR_BUFSIZ 256
typedef struct kerberos_key {
- guint32 keytype;
+ uint32_t keytype;
int keylength;
- const guint8 *keyvalue;
+ const uint8_t *keyvalue;
} kerberos_key_t;
typedef void (*kerberos_key_save_fn)(tvbuff_t *tvb _U_, int offset _U_, int length _U_,
@@ -106,38 +109,50 @@ typedef void (*kerberos_key_save_fn)(tvbuff_t *tvb _U_, int offset _U_, int leng
int parent_hf_index _U_,
int hf_index _U_);
+typedef struct kerberos_conv_t {
+ wmem_list_t *frames;
+} kerberos_conv_t;
+
+typedef struct kerberos_frame_t {
+ struct kerberos_frame_t *req;
+ uint32_t frame;
+ nstime_t time;
+ uint32_t msg_type;
+ int srt_idx;
+} kerberos_frame_t;
+
typedef struct {
- guint32 msg_type;
- gboolean is_win2k_pkinit;
- guint32 errorcode;
- gboolean try_nt_status;
- guint32 etype;
- guint32 padata_type;
- guint32 is_enc_padata;
- guint32 enctype;
+ uint32_t msg_type;
+ bool is_win2k_pkinit;
+ uint32_t errorcode;
+ uint32_t etype;
+ uint32_t padata_type;
+ uint32_t is_enc_padata;
+ uint32_t enctype;
kerberos_key_t key;
proto_tree *key_tree;
proto_item *key_hidden_item;
tvbuff_t *key_tvb;
kerberos_callbacks *callbacks;
- guint32 ad_type;
- guint32 addr_type;
- guint32 checksum_type;
+ uint32_t ad_type;
+ uint32_t addr_type;
+ uint32_t checksum_type;
#ifdef HAVE_KERBEROS
enc_key_t *last_decryption_key;
enc_key_t *last_added_key;
+ enc_key_t *current_ticket_key;
tvbuff_t *last_ticket_enc_part_tvb;
#endif
- gint save_encryption_key_parent_hf_index;
+ int save_encryption_key_parent_hf_index;
kerberos_key_save_fn save_encryption_key_fn;
- guint learnt_key_ids;
- guint missing_key_ids;
+ unsigned learnt_key_ids;
+ unsigned missing_key_ids;
wmem_list_t *decryption_keys;
wmem_list_t *learnt_keys;
wmem_list_t *missing_keys;
- guint32 within_PA_TGS_REQ;
+ uint32_t within_PA_TGS_REQ;
struct _kerberos_PA_FX_FAST_REQUEST {
- gboolean defer;
+ bool defer;
tvbuff_t *tvb;
proto_tree *tree;
} PA_FX_FAST_REQUEST;
@@ -145,20 +160,24 @@ typedef struct {
enc_key_t *PA_TGS_REQ_key;
enc_key_t *PA_TGS_REQ_subkey;
#endif
- guint32 fast_type;
- guint32 fast_armor_within_armor_value;
+ uint32_t fast_type;
+ uint32_t fast_armor_within_armor_value;
#ifdef HAVE_KERBEROS
enc_key_t *PA_FAST_ARMOR_AP_key;
enc_key_t *PA_FAST_ARMOR_AP_subkey;
enc_key_t *fast_armor_key;
enc_key_t *fast_strengthen_key;
#endif
+ kerberos_conv_t *krb5_conv;
+ uint32_t frame_req, frame_rep;
+ nstime_t req_time;
} kerberos_private_data_t;
static dissector_handle_t kerberos_handle_tcp;
static dissector_handle_t kerberos_handle_udp;
/* Forward declarations */
+static kerberos_private_data_t *kerberos_get_private_data(asn1_ctx_t *actx);
static int dissect_kerberos_Applications(bool 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_AuthorizationData(bool 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(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
@@ -181,180 +200,195 @@ static int dissect_kerberos_PA_PAC_OPTIONS(bool implicit_tag _U_, tvbuff_t *tvb
static int dissect_kerberos_KERB_AD_RESTRICTION_ENTRY(bool 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_SEQUENCE_OF_ENCTYPE(bool 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_SPAKE(bool 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_DATA(bool 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_T_rEP_SEQUENCE_OF_PA_DATA(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
#ifdef HAVE_KERBEROS
static int dissect_kerberos_KrbFastReq(bool 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_KrbFastResponse(bool 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_FastOptions(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
#endif
+static int dissect_kerberos_KRB5_SRP_PA_ANNOUNCE(bool 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_KRB5_SRP_PA_INIT(bool 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_KRB5_SRP_PA_SERVER_CHALLENGE(bool 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_KRB5_SRP_PA_CLIENT_RESPONSE(bool 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_KRB5_SRP_PA_SERVER_VERIFIER(bool 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 gint hf_krb_rm_reserved = -1;
-static gint hf_krb_rm_reclen = -1;
-static gint hf_krb_provsrv_location = -1;
-static gint hf_krb_pw_salt = -1;
-static gint hf_krb_ext_error_nt_status = -1;
-static gint hf_krb_ext_error_reserved = -1;
-static gint hf_krb_ext_error_flags = -1;
-static gint hf_krb_address_ip = -1;
-static gint hf_krb_address_netbios = -1;
-static gint hf_krb_address_ipv6 = -1;
-static gint hf_krb_gssapi_len = -1;
-static gint hf_krb_gssapi_bnd = -1;
-static gint hf_krb_gssapi_dlgopt = -1;
-static gint hf_krb_gssapi_dlglen = -1;
-static gint hf_krb_gssapi_c_flag_deleg = -1;
-static gint hf_krb_gssapi_c_flag_mutual = -1;
-static gint hf_krb_gssapi_c_flag_replay = -1;
-static gint hf_krb_gssapi_c_flag_sequence = -1;
-static gint hf_krb_gssapi_c_flag_conf = -1;
-static gint hf_krb_gssapi_c_flag_integ = -1;
-static gint hf_krb_gssapi_c_flag_dce_style = -1;
-static gint hf_krb_midl_version = -1;
-static gint hf_krb_midl_hdr_len = -1;
-static gint hf_krb_midl_fill_bytes = -1;
-static gint hf_krb_midl_blob_len = -1;
-static gint hf_krb_pac_signature_type = -1;
-static gint hf_krb_pac_signature_signature = -1;
-static gint hf_krb_w2k_pac_entries = -1;
-static gint hf_krb_w2k_pac_version = -1;
-static gint hf_krb_w2k_pac_type = -1;
-static gint hf_krb_w2k_pac_size = -1;
-static gint hf_krb_w2k_pac_offset = -1;
-static gint hf_krb_pac_clientid = -1;
-static gint hf_krb_pac_namelen = -1;
-static gint hf_krb_pac_clientname = -1;
-static gint hf_krb_pac_logon_info = -1;
-static gint hf_krb_pac_credential_data = -1;
-static gint hf_krb_pac_credential_info = -1;
-static gint hf_krb_pac_credential_info_version = -1;
-static gint hf_krb_pac_credential_info_etype = -1;
-static gint hf_krb_pac_s4u_delegation_info = -1;
-static gint hf_krb_pac_upn_dns_info = -1;
-static gint hf_krb_pac_upn_flags = -1;
-static gint hf_krb_pac_upn_flag_upn_constructed = -1;
-static gint hf_krb_pac_upn_flag_has_sam_name_and_sid = -1;
-static gint hf_krb_pac_upn_upn_offset = -1;
-static gint hf_krb_pac_upn_upn_len = -1;
-static gint hf_krb_pac_upn_upn_name = -1;
-static gint hf_krb_pac_upn_dns_offset = -1;
-static gint hf_krb_pac_upn_dns_len = -1;
-static gint hf_krb_pac_upn_dns_name = -1;
-static gint hf_krb_pac_upn_samaccountname_offset = -1;
-static gint hf_krb_pac_upn_samaccountname_len = -1;
-static gint hf_krb_pac_upn_samaccountname = -1;
-static gint hf_krb_pac_upn_objectsid_offset = -1;
-static gint hf_krb_pac_upn_objectsid_len = -1;
-static gint hf_krb_pac_server_checksum = -1;
-static gint hf_krb_pac_privsvr_checksum = -1;
-static gint hf_krb_pac_client_info_type = -1;
-static gint hf_krb_pac_client_claims_info = -1;
-static gint hf_krb_pac_device_info = -1;
-static gint hf_krb_pac_device_claims_info = -1;
-static gint hf_krb_pac_ticket_checksum = -1;
-static gint hf_krb_pac_attributes_info = -1;
-static gint hf_krb_pac_attributes_info_length = -1;
-static gint hf_krb_pac_attributes_info_flags = -1;
-static gint hf_krb_pac_attributes_info_flags_pac_was_requested = -1;
-static gint hf_krb_pac_attributes_info_flags_pac_was_given_implicitly = -1;
-static gint hf_krb_pac_requester_sid = -1;
-static gint hf_krb_pa_supported_enctypes = -1;
-static gint hf_krb_pa_supported_enctypes_des_cbc_crc = -1;
-static gint hf_krb_pa_supported_enctypes_des_cbc_md5 = -1;
-static gint hf_krb_pa_supported_enctypes_rc4_hmac = -1;
-static gint hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96 = -1;
-static gint hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96 = -1;
-static gint hf_krb_pa_supported_enctypes_fast_supported = -1;
-static gint hf_krb_pa_supported_enctypes_compound_identity_supported = -1;
-static gint hf_krb_pa_supported_enctypes_claims_supported = -1;
-static gint hf_krb_pa_supported_enctypes_resource_sid_compression_disabled = -1;
-static gint hf_krb_ad_ap_options = -1;
-static gint hf_krb_ad_ap_options_cbt = -1;
-static gint hf_krb_ad_target_principal = -1;
-static gint hf_krb_key_hidden_item = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_MessageType = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_Flags = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicket = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET = -1;
-static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED = -1;
+static bool krb_desegment = true;
+
+static int proto_kerberos;
+static int kerberos_tap;
+
+static int hf_krb_response_to;
+static int hf_krb_response_in;
+static int hf_krb_time;
+static int hf_krb_rm_reserved;
+static int hf_krb_rm_reclen;
+static int hf_krb_provsrv_location;
+static int hf_krb_pw_salt;
+static int hf_krb_ext_error_nt_status;
+static int hf_krb_ext_error_reserved;
+static int hf_krb_ext_error_flags;
+static int hf_krb_address_ip;
+static int hf_krb_address_netbios;
+static int hf_krb_address_ipv6;
+static int hf_krb_gssapi_len;
+static int hf_krb_gssapi_bnd;
+static int hf_krb_gssapi_dlgopt;
+static int hf_krb_gssapi_dlglen;
+static int hf_krb_gssapi_c_flag_deleg;
+static int hf_krb_gssapi_c_flag_mutual;
+static int hf_krb_gssapi_c_flag_replay;
+static int hf_krb_gssapi_c_flag_sequence;
+static int hf_krb_gssapi_c_flag_conf;
+static int hf_krb_gssapi_c_flag_integ;
+static int hf_krb_gssapi_c_flag_dce_style;
+static int hf_krb_midl_version;
+static int hf_krb_midl_hdr_len;
+static int hf_krb_midl_fill_bytes;
+static int hf_krb_midl_blob_len;
+static int hf_krb_pac_signature_type;
+static int hf_krb_pac_signature_signature;
+static int hf_krb_w2k_pac_entries;
+static int hf_krb_w2k_pac_version;
+static int hf_krb_w2k_pac_type;
+static int hf_krb_w2k_pac_size;
+static int hf_krb_w2k_pac_offset;
+static int hf_krb_pac_clientid;
+static int hf_krb_pac_namelen;
+static int hf_krb_pac_clientname;
+static int hf_krb_pac_logon_info;
+static int hf_krb_pac_credential_data;
+static int hf_krb_pac_credential_info;
+static int hf_krb_pac_credential_info_version;
+static int hf_krb_pac_credential_info_etype;
+static int hf_krb_pac_s4u_delegation_info;
+static int hf_krb_pac_upn_dns_info;
+static int hf_krb_pac_upn_flags;
+static int hf_krb_pac_upn_flag_upn_constructed;
+static int hf_krb_pac_upn_flag_has_sam_name_and_sid;
+static int hf_krb_pac_upn_upn_offset;
+static int hf_krb_pac_upn_upn_len;
+static int hf_krb_pac_upn_upn_name;
+static int hf_krb_pac_upn_dns_offset;
+static int hf_krb_pac_upn_dns_len;
+static int hf_krb_pac_upn_dns_name;
+static int hf_krb_pac_upn_samaccountname_offset;
+static int hf_krb_pac_upn_samaccountname_len;
+static int hf_krb_pac_upn_samaccountname;
+static int hf_krb_pac_upn_objectsid_offset;
+static int hf_krb_pac_upn_objectsid_len;
+static int hf_krb_pac_server_checksum;
+static int hf_krb_pac_privsvr_checksum;
+static int hf_krb_pac_client_info_type;
+static int hf_krb_pac_client_claims_info;
+static int hf_krb_pac_device_info;
+static int hf_krb_pac_device_claims_info;
+static int hf_krb_pac_ticket_checksum;
+static int hf_krb_pac_attributes_info;
+static int hf_krb_pac_attributes_info_length;
+static int hf_krb_pac_attributes_info_flags;
+static int hf_krb_pac_attributes_info_flags_pac_was_requested;
+static int hf_krb_pac_attributes_info_flags_pac_was_given_implicitly;
+static int hf_krb_pac_requester_sid;
+static int hf_krb_pac_full_checksum;
+static int hf_krb_pa_supported_enctypes;
+static int hf_krb_pa_supported_enctypes_des_cbc_crc;
+static int hf_krb_pa_supported_enctypes_des_cbc_md5;
+static int hf_krb_pa_supported_enctypes_rc4_hmac;
+static int hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96;
+static int hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96;
+static int hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96_sk;
+static int hf_krb_pa_supported_enctypes_fast_supported;
+static int hf_krb_pa_supported_enctypes_compound_identity_supported;
+static int hf_krb_pa_supported_enctypes_claims_supported;
+static int hf_krb_pa_supported_enctypes_resource_sid_compression_disabled;
+static int hf_krb_ad_ap_options;
+static int hf_krb_ad_ap_options_cbt;
+static int hf_krb_ad_ap_options_unverified_target_name;
+static int hf_krb_ad_target_principal;
+static int hf_krb_key_hidden_item;
+static int hf_kerberos_KERB_TICKET_LOGON;
+static int hf_kerberos_KERB_TICKET_LOGON_MessageType;
+static int hf_kerberos_KERB_TICKET_LOGON_Flags;
+static int hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength;
+static int hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength;
+static int hf_kerberos_KERB_TICKET_LOGON_ServiceTicket;
+static int hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket;
+static int hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET;
+static int hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED;
#ifdef HAVE_KERBEROS
-static gint hf_kerberos_KrbFastResponse = -1;
-static gint hf_kerberos_strengthen_key = -1;
-static gint hf_kerberos_finished = -1;
-static gint hf_kerberos_fast_options = -1;
-static gint hf_kerberos_ticket_checksum = -1;
-static gint hf_krb_patimestamp = -1;
-static gint hf_krb_pausec = -1;
-static gint hf_kerberos_FastOptions_reserved = -1;
-static gint hf_kerberos_FastOptions_hide_client_names = -1;
-static gint hf_kerberos_FastOptions_spare_bit2 = -1;
-static gint hf_kerberos_FastOptions_spare_bit3 = -1;
-static gint hf_kerberos_FastOptions_spare_bit4 = -1;
-static gint hf_kerberos_FastOptions_spare_bit5 = -1;
-static gint hf_kerberos_FastOptions_spare_bit6 = -1;
-static gint hf_kerberos_FastOptions_spare_bit7 = -1;
-static gint hf_kerberos_FastOptions_spare_bit8 = -1;
-static gint hf_kerberos_FastOptions_spare_bit9 = -1;
-static gint hf_kerberos_FastOptions_spare_bit10 = -1;
-static gint hf_kerberos_FastOptions_spare_bit11 = -1;
-static gint hf_kerberos_FastOptions_spare_bit12 = -1;
-static gint hf_kerberos_FastOptions_spare_bit13 = -1;
-static gint hf_kerberos_FastOptions_spare_bit14 = -1;
-static gint hf_kerberos_FastOptions_spare_bit15 = -1;
-static gint hf_kerberos_FastOptions_kdc_follow_referrals = -1;
+static int hf_kerberos_KrbFastResponse;
+static int hf_kerberos_strengthen_key;
+static int hf_kerberos_finished;
+static int hf_kerberos_fast_options;
+static int hf_kerberos_ticket_checksum;
+static int hf_krb_patimestamp;
+static int hf_krb_pausec;
+static int hf_kerberos_FastOptions_reserved;
+static int hf_kerberos_FastOptions_hide_client_names;
+static int hf_kerberos_FastOptions_spare_bit2;
+static int hf_kerberos_FastOptions_spare_bit3;
+static int hf_kerberos_FastOptions_spare_bit4;
+static int hf_kerberos_FastOptions_spare_bit5;
+static int hf_kerberos_FastOptions_spare_bit6;
+static int hf_kerberos_FastOptions_spare_bit7;
+static int hf_kerberos_FastOptions_spare_bit8;
+static int hf_kerberos_FastOptions_spare_bit9;
+static int hf_kerberos_FastOptions_spare_bit10;
+static int hf_kerberos_FastOptions_spare_bit11;
+static int hf_kerberos_FastOptions_spare_bit12;
+static int hf_kerberos_FastOptions_spare_bit13;
+static int hf_kerberos_FastOptions_spare_bit14;
+static int hf_kerberos_FastOptions_spare_bit15;
+static int hf_kerberos_FastOptions_kdc_follow_referrals;
#endif
#include "packet-kerberos-hf.c"
/* Initialize the subtree pointers */
-static gint ett_kerberos = -1;
-static gint ett_krb_recordmark = -1;
-static gint ett_krb_pac = -1;
-static gint ett_krb_pac_drep = -1;
-static gint ett_krb_pac_midl_blob = -1;
-static gint ett_krb_pac_logon_info = -1;
-static gint ett_krb_pac_credential_info = -1;
-static gint ett_krb_pac_s4u_delegation_info = -1;
-static gint ett_krb_pac_upn_dns_info = -1;
-static gint ett_krb_pac_upn_dns_info_flags = -1;
-static gint ett_krb_pac_device_info = -1;
-static gint ett_krb_pac_server_checksum = -1;
-static gint ett_krb_pac_privsvr_checksum = -1;
-static gint ett_krb_pac_client_info_type = -1;
-static gint ett_krb_pac_ticket_checksum = -1;
-static gint ett_krb_pac_attributes_info = -1;
-static gint ett_krb_pac_attributes_info_flags = -1;
-static gint ett_krb_pac_requester_sid = -1;
-static gint ett_krb_pa_supported_enctypes = -1;
-static gint ett_krb_ad_ap_options = -1;
-static gint ett_kerberos_KERB_TICKET_LOGON = -1;
+static int ett_kerberos;
+static int ett_krb_recordmark;
+static int ett_krb_pac;
+static int ett_krb_pac_drep;
+static int ett_krb_pac_midl_blob;
+static int ett_krb_pac_logon_info;
+static int ett_krb_pac_credential_info;
+static int ett_krb_pac_s4u_delegation_info;
+static int ett_krb_pac_upn_dns_info;
+static int ett_krb_pac_upn_dns_info_flags;
+static int ett_krb_pac_device_info;
+static int ett_krb_pac_server_checksum;
+static int ett_krb_pac_privsvr_checksum;
+static int ett_krb_pac_client_info_type;
+static int ett_krb_pac_ticket_checksum;
+static int ett_krb_pac_attributes_info;
+static int ett_krb_pac_attributes_info_flags;
+static int ett_krb_pac_requester_sid;
+static int ett_krb_pac_full_checksum;
+static int ett_krb_pa_supported_enctypes;
+static int ett_krb_ad_ap_options;
+static int ett_kerberos_KERB_TICKET_LOGON;
#ifdef HAVE_KERBEROS
-static gint ett_krb_pa_enc_ts_enc = -1;
-static gint ett_kerberos_KrbFastFinished = -1;
-static gint ett_kerberos_KrbFastResponse = -1;
-static gint ett_kerberos_KrbFastReq = -1;
-static gint ett_kerberos_FastOptions = -1;
+static int ett_krb_pa_enc_ts_enc;
+static int ett_kerberos_KrbFastFinished;
+static int ett_kerberos_KrbFastResponse;
+static int ett_kerberos_KrbFastReq;
+static int ett_kerberos_FastOptions;
#endif
#include "packet-kerberos-ett.c"
-static expert_field ei_kerberos_missing_keytype = EI_INIT;
-static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
-static expert_field ei_kerberos_learnt_keytype = EI_INIT;
-static expert_field ei_kerberos_address = EI_INIT;
-static expert_field ei_krb_gssapi_dlglen = EI_INIT;
+static expert_field ei_kerberos_missing_keytype;
+static expert_field ei_kerberos_decrypted_keytype;
+static expert_field ei_kerberos_learnt_keytype;
+static expert_field ei_kerberos_address;
+static expert_field ei_krb_gssapi_dlglen;
-static dissector_handle_t krb4_handle=NULL;
+static dissector_handle_t krb4_handle;
/* Global variables */
-static guint32 gbl_keytype;
-static gboolean gbl_do_col_info;
+static uint32_t gbl_keytype;
+static bool gbl_do_col_info;
#include "packet-kerberos-val.h"
@@ -375,20 +409,228 @@ call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int
return;
}
+static int
+krb5_frame_compare(gconstpointer a, gconstpointer b)
+{
+ kerberos_frame_t *fa = (kerberos_frame_t *)a;
+ kerberos_frame_t *fb = (kerberos_frame_t *)b;
+
+ return fa->frame - fb->frame;
+}
+
+static kerberos_conv_t *krb5_conv_find_or_create(packet_info *pinfo)
+{
+ conversation_t *conversation = NULL;
+ kerberos_conv_t *kconv = NULL;
+
+ conversation = find_or_create_conversation(pinfo);
+ kconv = (kerberos_conv_t *)conversation_get_proto_data(conversation,
+ proto_kerberos);
+ if (kconv == NULL) {
+ kconv = wmem_new0(wmem_file_scope(), kerberos_conv_t);
+ kconv->frames = wmem_list_new(wmem_file_scope());
+
+ conversation_add_proto_data(conversation, proto_kerberos, kconv);
+ }
+
+ return kconv;
+}
+
+static void krb5_conf_add_request(asn1_ctx_t *actx)
+{
+ kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+ packet_info *pinfo = actx->pinfo;
+ kerberos_frame_t _krqf = { .frame = 0, };
+ kerberos_frame_t *krqf = NULL;
+ wmem_list_frame_t *wf = NULL;
+ kerberos_frame_t *krpf = NULL;
+
+ if (private_data->krb5_conv == NULL)
+ return;
+
+ if (!pinfo->fd->visited) {
+ krqf = wmem_new0(wmem_file_scope(), kerberos_frame_t);
+ if (krqf == NULL) {
+ return;
+ }
+ } else {
+ krqf = &_krqf;
+ }
+
+ krqf->frame = pinfo->num;
+ krqf->time = pinfo->abs_ts;
+ krqf->msg_type = private_data->msg_type;
+ krqf->srt_idx = -1;
+
+ if (!pinfo->fd->visited) {
+ wmem_list_insert_sorted(private_data->krb5_conv->frames,
+ krqf, krb5_frame_compare);
+ }
+
+ wf = wmem_list_find_custom(private_data->krb5_conv->frames,
+ krqf, krb5_frame_compare);
+ if (wf != NULL) {
+ /*
+ * replace the pointer with the one allocated on
+ * wmem_file_scope()
+ */
+ krqf = (kerberos_frame_t *)wmem_list_frame_data(wf);
+ /* The next one should be the response */
+ wf = wmem_list_frame_next(wf);
+ }
+ if (wf == NULL) {
+ return;
+ }
+ krpf = (kerberos_frame_t *)wmem_list_frame_data(wf);
+
+ switch (krpf->msg_type) {
+ case KERBEROS_APPLICATIONS_AS_REP:
+ case KERBEROS_APPLICATIONS_TGS_REP:
+ case KERBEROS_APPLICATIONS_KRB_ERROR:
+ break;
+ default:
+ return;
+ }
+
+ private_data->frame_rep = krpf->frame;
+}
+
+static void krb5_conf_add_response(asn1_ctx_t *actx)
+{
+ kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+ packet_info *pinfo = actx->pinfo;
+ kerberos_frame_t _krpf = { .frame = 0, };
+ kerberos_frame_t *krpf = NULL;
+ wmem_list_frame_t *wf = NULL;
+ kerberos_frame_t *krqf = NULL;
+
+ if (private_data->krb5_conv == NULL)
+ return;
+
+ if (!pinfo->fd->visited) {
+ krpf = wmem_new0(wmem_file_scope(), kerberos_frame_t);
+ if (krpf == NULL) {
+ return;
+ }
+ } else {
+ krpf = &_krpf;
+ }
+
+ krpf->frame = pinfo->num;
+ krpf->time = pinfo->abs_ts;
+ krpf->msg_type = private_data->msg_type;
+ krpf->srt_idx = -1;
+
+ if (!pinfo->fd->visited) {
+ wmem_list_insert_sorted(private_data->krb5_conv->frames,
+ krpf, krb5_frame_compare);
+ }
+
+ wf = wmem_list_find_custom(private_data->krb5_conv->frames,
+ krpf, krb5_frame_compare);
+ if (wf != NULL) {
+ /*
+ * replace the pointer with the one allocated on
+ * wmem_file_scope()
+ */
+ krpf = (kerberos_frame_t *)wmem_list_frame_data(wf);
+ /* The previous one should be the request */
+ wf = wmem_list_frame_prev(wf);
+ }
+ if (wf == NULL) {
+ return;
+ }
+ krqf = (kerberos_frame_t *)wmem_list_frame_data(wf);
+ krpf->req = krqf;
+
+ switch (krqf->msg_type) {
+ case KERBEROS_APPLICATIONS_AS_REQ:
+ if (private_data->msg_type == KERBEROS_APPLICATIONS_AS_REP) {
+ krpf->srt_idx = 0;
+ break;
+ }
+ if (private_data->msg_type == KERBEROS_APPLICATIONS_KRB_ERROR) {
+ krpf->srt_idx = 1;
+ break;
+ }
+ return;
+ case KERBEROS_APPLICATIONS_TGS_REQ:
+ if (private_data->msg_type == KERBEROS_APPLICATIONS_TGS_REP) {
+ krpf->srt_idx = 2;
+ break;
+ }
+ if (private_data->msg_type == KERBEROS_APPLICATIONS_KRB_ERROR) {
+ krpf->srt_idx = 3;
+ break;
+ }
+ return;
+ default:
+ return;
+ }
+
+ private_data->frame_req = krqf->frame;
+ private_data->req_time = krqf->time;
+
+ tap_queue_packet(kerberos_tap, pinfo, krpf);
+}
+
+static void
+krb5stat_init(struct register_srt* srt _U_, GArray* srt_array _U_)
+{
+ srt_stat_table *krb5_srt_table = NULL;
+
+ krb5_srt_table = init_srt_table("Kerberos", "krb5", srt_array, 4, NULL, "kerberos.msg_type", NULL);
+ init_srt_table_row(krb5_srt_table, 0, "AS-REP");
+ init_srt_table_row(krb5_srt_table, 1, "AS-ERROR");
+ init_srt_table_row(krb5_srt_table, 2, "TGS-REP");
+ init_srt_table_row(krb5_srt_table, 3, "TGS-ERROR");
+}
+
+static tap_packet_status
+krb5stat_packet(void *pss _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv, tap_flags_t flags _U_)
+{
+ srt_stat_table *krb5_srt_table = NULL;
+ srt_data_t *data = (srt_data_t *)pss;
+ kerberos_frame_t *krpf = (kerberos_frame_t *)prv;
+
+ if (krpf == NULL)
+ return TAP_PACKET_DONT_REDRAW;
+
+ if (krpf->req == NULL)
+ return TAP_PACKET_DONT_REDRAW;
+
+ krb5_srt_table = g_array_index(data->srt_array, srt_stat_table*, 0);
+ add_srt_table_data(krb5_srt_table, krpf->srt_idx, &krpf->req->time, pinfo);
+ return TAP_PACKET_REDRAW;
+}
+
static kerberos_private_data_t*
kerberos_new_private_data(packet_info *pinfo)
{
kerberos_private_data_t *p;
+ void *existing;
p = wmem_new0(pinfo->pool, kerberos_private_data_t);
if (p == NULL) {
return NULL;
}
+ p->frame_req = UINT32_MAX;
+ p->frame_rep = UINT32_MAX;
p->decryption_keys = wmem_list_new(pinfo->pool);
p->learnt_keys = wmem_list_new(pinfo->pool);
p->missing_keys = wmem_list_new(pinfo->pool);
+ existing = p_get_proto_data(pinfo->pool, pinfo, proto_kerberos, 0);
+ if (existing != NULL) {
+ /*
+ * We only remember the first one.
+ */
+ return p;
+ }
+
+ p_add_proto_data(pinfo->pool, pinfo, proto_kerberos, 0, p);
+ p->krb5_conv = krb5_conv_find_or_create(pinfo);
return p;
}
@@ -407,13 +649,13 @@ kerberos_private_is_kdc_req(kerberos_private_data_t *private_data)
switch (private_data->msg_type) {
case KERBEROS_APPLICATIONS_AS_REQ:
case KERBEROS_APPLICATIONS_TGS_REQ:
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-gboolean
+bool
kerberos_is_win2k_pkinit(asn1_ctx_t *actx)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
@@ -427,15 +669,15 @@ static int dissect_kerberos_defer_PA_FX_FAST_REQUEST(bool implicit_tag _U_, tvbu
/*
* dissect_ber_octet_string_wcb() always passes
- * implicit_tag=FALSE, offset=0 and hf_index=-1
+ * implicit_tag=false, offset=0 and hf_index=-1
*
* It means we only need to remember tvb and tree
* in order to replay dissect_kerberos_PA_FX_FAST_REQUEST()
* in dissect_kerberos_T_rEQ_SEQUENCE_OF_PA_DATA()
*/
- ws_assert(implicit_tag == FALSE);
+ ws_assert(implicit_tag == false);
ws_assert(offset == 0);
- ws_assert(hf_index == -1);
+ ws_assert(hf_index <= 0);
if (private_data->PA_FX_FAST_REQUEST.defer) {
/*
@@ -446,7 +688,7 @@ static int dissect_kerberos_defer_PA_FX_FAST_REQUEST(bool implicit_tag _U_, tvbu
/*
* only handle the first PA_FX_FAST_REQUEST...
*/
- private_data->PA_FX_FAST_REQUEST.defer = FALSE;
+ private_data->PA_FX_FAST_REQUEST.defer = false;
return tvb_reported_length_remaining(tvb, offset);
}
@@ -456,7 +698,7 @@ static int dissect_kerberos_defer_PA_FX_FAST_REQUEST(bool implicit_tag _U_, tvbu
#ifdef HAVE_KERBEROS
/* Decrypt Kerberos blobs */
-gboolean krb_decrypt = FALSE;
+bool krb_decrypt;
/* keytab filename */
static const char *keytab_filename = "";
@@ -487,10 +729,10 @@ read_keytab_file_from_preferences(void)
#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
enc_key_t *enc_key_list=NULL;
-static guint kerberos_longterm_ids = 0;
-wmem_map_t *kerberos_longterm_keys = NULL;
-static wmem_map_t *kerberos_all_keys = NULL;
-static wmem_map_t *kerberos_app_session_keys = NULL;
+static unsigned kerberos_longterm_ids;
+wmem_map_t *kerberos_longterm_keys;
+static wmem_map_t *kerberos_all_keys;
+static wmem_map_t *kerberos_app_session_keys;
static bool
enc_key_list_cb(wmem_allocator_t* allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_)
@@ -498,10 +740,10 @@ enc_key_list_cb(wmem_allocator_t* allocator _U_, wmem_cb_event_t event _U_, void
enc_key_list = NULL;
kerberos_longterm_ids = 0;
/* keep the callback registered */
- return TRUE;
+ return true;
}
-static gint enc_key_cmp_id(gconstpointer k1, gconstpointer k2)
+static int enc_key_cmp_id(const void *k1, const void *k2)
{
const enc_key_t *key1 = (const enc_key_t *)k1;
const enc_key_t *key2 = (const enc_key_t *)k2;
@@ -524,39 +766,39 @@ static gint enc_key_cmp_id(gconstpointer k1, gconstpointer k2)
}
static gboolean
-enc_key_content_equal(gconstpointer k1, gconstpointer k2)
+enc_key_content_equal(const void *k1, const void *k2)
{
const enc_key_t *key1 = (const enc_key_t *)k1;
const enc_key_t *key2 = (const enc_key_t *)k2;
int cmp;
if (key1->keytype != key2->keytype) {
- return FALSE;
+ return false;
}
if (key1->keylength != key2->keylength) {
- return FALSE;
+ return false;
}
cmp = memcmp(key1->keyvalue, key2->keyvalue, key1->keylength);
if (cmp != 0) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
-static guint
-enc_key_content_hash(gconstpointer k)
+static unsigned
+enc_key_content_hash(const void *k)
{
const enc_key_t *key = (const enc_key_t *)k;
- guint ret = 0;
+ unsigned ret = 0;
- ret += wmem_strong_hash((const guint8 *)&key->keytype,
+ ret += wmem_strong_hash((const uint8_t *)&key->keytype,
sizeof(key->keytype));
- ret += wmem_strong_hash((const guint8 *)&key->keylength,
+ ret += wmem_strong_hash((const uint8_t *)&key->keylength,
sizeof(key->keylength));
- ret += wmem_strong_hash((const guint8 *)key->keyvalue,
+ ret += wmem_strong_hash((const uint8_t *)key->keyvalue,
key->keylength);
return ret;
@@ -567,7 +809,7 @@ kerberos_key_map_insert(wmem_map_t *key_map, enc_key_t *new_key)
{
enc_key_t *existing = NULL;
enc_key_t *cur = NULL;
- gint cmp;
+ int cmp;
existing = (enc_key_t *)wmem_map_lookup(key_map, new_key);
if (existing == NULL) {
@@ -659,9 +901,9 @@ struct insert_longterm_keys_into_key_map_state {
wmem_map_t *key_map;
};
-static void insert_longterm_keys_into_key_map_cb(gpointer __key _U_,
- gpointer value,
- gpointer user_data)
+static void insert_longterm_keys_into_key_map_cb(void *__key _U_,
+ void *value,
+ void *user_data)
{
struct insert_longterm_keys_into_key_map_state *state =
(struct insert_longterm_keys_into_key_map_state *)user_data;
@@ -870,6 +1112,22 @@ save_EncAPRepPart_subkey(tvbuff_t *tvb, int offset, int length,
return;
}
+ private_data->last_added_key->is_ap_rep_key = true;
+
+ if (private_data->last_decryption_key != NULL &&
+ private_data->last_decryption_key->is_ticket_key)
+ {
+ enc_key_t *ak = private_data->last_added_key;
+ enc_key_t *tk = private_data->last_decryption_key;
+
+ /*
+ * The enc_key_t structures and their strings
+ * in pac_names are all allocated on wmem_epan_scope(),
+ * so we don't need to copy the content.
+ */
+ ak->pac_names = tk->pac_names;
+ }
+
kerberos_key_map_insert(kerberos_app_session_keys, private_data->last_added_key);
}
@@ -888,7 +1146,20 @@ save_EncTicketPart_key(tvbuff_t *tvb, int offset, int length,
int parent_hf_index,
int hf_index)
{
+ kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+
save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index);
+
+ if (actx->pinfo->fd->visited) {
+ return;
+ }
+
+ if (private_data->last_added_key == NULL) {
+ return;
+ }
+
+ private_data->current_ticket_key = private_data->last_added_key;
+ private_data->current_ticket_key->is_ticket_key = true;
}
static void
@@ -917,8 +1188,8 @@ static void used_encryption_key(proto_tree *tree, packet_info *pinfo,
kerberos_private_data_t *private_data,
enc_key_t *ek, int usage, tvbuff_t *cryptotvb,
const char *keymap_name,
- guint keymap_size,
- guint decryption_count)
+ unsigned keymap_size,
+ unsigned decryption_count)
{
proto_item *item = NULL;
enc_key_t *sek = NULL;
@@ -974,8 +1245,8 @@ static void missing_encryption_key(proto_tree *tree, packet_info *pinfo,
kerberos_private_data_t *private_data,
int keytype, int usage, tvbuff_t *cryptotvb,
const char *keymap_name,
- guint keymap_size,
- guint decryption_count)
+ unsigned keymap_size,
+ unsigned decryption_count)
{
proto_item *item = NULL;
enc_key_t *mek = NULL;
@@ -1010,8 +1281,8 @@ static void used_signing_key(proto_tree *tree, packet_info *pinfo,
krb5_cksumtype checksum,
const char *reason,
const char *keymap_name,
- guint keymap_size,
- guint verify_count)
+ unsigned keymap_size,
+ unsigned verify_count)
{
proto_item *item = NULL;
enc_key_t *sek = NULL;
@@ -1050,8 +1321,8 @@ static void missing_signing_key(proto_tree *tree, packet_info *pinfo,
int keytype,
const char *reason,
const char *keymap_name,
- guint keymap_size,
- guint verify_count)
+ unsigned keymap_size,
+ unsigned verify_count)
{
proto_item *item = NULL;
enc_key_t *mek = NULL;
@@ -1111,12 +1382,12 @@ krb5_fast_key(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb,
k1.magic = KV5M_KEYBLOCK;
k1.enctype = ek1->keytype;
k1.length = ek1->keylength;
- k1.contents = (guint8 *)ek1->keyvalue;
+ k1.contents = (uint8_t *)ek1->keyvalue;
k2.magic = KV5M_KEYBLOCK;
k2.enctype = ek2->keytype;
k2.length = ek2->keylength;
- k2.contents = (guint8 *)ek2->keyvalue;
+ k2.contents = (uint8_t *)ek2->keyvalue;
ret = krb5_c_fx_cf2_simple(krb5_ctx, &k1, p1, &k2, p2, &k);
if (ret != 0) {
@@ -1151,14 +1422,14 @@ read_keytab_file(const char *filename)
krb5_error_code ret;
krb5_keytab_entry key;
krb5_kt_cursor cursor;
- static gboolean first_time=TRUE;
+ static bool first_time=true;
if (filename == NULL || filename[0] == 0) {
return;
}
if(first_time){
- first_time=FALSE;
+ first_time=false;
ret = krb5_init_context(&krb5_ctx);
if(ret && ret != KRB5_CONFIG_CANTOPEN){
return;
@@ -1241,12 +1512,12 @@ struct decrypt_krb5_with_cb_state {
int usage,
void *decrypt_cb_data);
void *decrypt_cb_data;
- guint count;
+ unsigned count;
enc_key_t *ek;
};
static void
-decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userdata)
+decrypt_krb5_with_cb_try_key(void *__key _U_, void *value, void *userdata)
{
struct decrypt_krb5_with_cb_state *state =
(struct decrypt_krb5_with_cb_state *)userdata;
@@ -1256,8 +1527,8 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
#ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
enc_key_t *ak = state->private_data->fast_armor_key;
enc_key_t *sk = state->private_data->fast_strengthen_key;
- gboolean try_with_armor_key = FALSE;
- gboolean try_with_strengthen_key = FALSE;
+ bool try_with_armor_key = false;
+ bool try_with_strengthen_key = false;
#endif
if (state->ek != NULL) {
@@ -1274,7 +1545,7 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
case KEY_USAGE_ENC_CHALLENGE_KDC:
if (ek->fd_num == -1) {
/* Challenges are based on a long term key */
- try_with_armor_key = TRUE;
+ try_with_armor_key = true;
}
break;
}
@@ -1285,7 +1556,7 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
* again
*/
if (sk != NULL) {
- try_with_armor_key = FALSE;
+ try_with_armor_key = false;
}
}
@@ -1294,14 +1565,14 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
case 3:
if (ek->fd_num == -1) {
/* AS-REP is based on a long term key */
- try_with_strengthen_key = TRUE;
+ try_with_strengthen_key = true;
}
break;
case 8:
case 9:
if (ek->fd_num != -1) {
/* TGS-REP is not based on a long term key */
- try_with_strengthen_key = TRUE;
+ try_with_strengthen_key = true;
}
break;
}
@@ -1316,12 +1587,12 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
k1.magic = KV5M_KEYBLOCK;
k1.enctype = ak->keytype;
k1.length = ak->keylength;
- k1.contents = (guint8 *)ak->keyvalue;
+ k1.contents = (uint8_t *)ak->keyvalue;
k2.magic = KV5M_KEYBLOCK;
k2.enctype = ek->keytype;
k2.length = ek->keylength;
- k2.contents = (guint8 *)ek->keyvalue;
+ k2.contents = (uint8_t *)ek->keyvalue;
switch (state->usage) {
case KEY_USAGE_ENC_CHALLENGE_CLIENT:
@@ -1388,12 +1659,12 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
k1.magic = KV5M_KEYBLOCK;
k1.enctype = sk->keytype;
k1.length = sk->keylength;
- k1.contents = (guint8 *)sk->keyvalue;
+ k1.contents = (uint8_t *)sk->keyvalue;
k2.magic = KV5M_KEYBLOCK;
k2.enctype = ek->keytype;
k2.length = ek->keylength;
- k2.contents = (guint8 *)ek->keyvalue;
+ k2.contents = (uint8_t *)ek->keyvalue;
ret = krb5_c_fx_cf2_simple(krb5_ctx,
&k1, "strengthenkey",
@@ -1551,7 +1822,7 @@ decrypt_krb5_data_cb(const krb5_keyblock *key,
&state->output);
}
-static guint8 *
+static uint8_t *
decrypt_krb5_data_private(proto_tree *tree _U_, packet_info *pinfo,
kerberos_private_data_t *private_data,
int usage, tvbuff_t *cryptotvb, int keytype,
@@ -1561,7 +1832,7 @@ decrypt_krb5_data_private(proto_tree *tree _U_, packet_info *pinfo,
struct decrypt_krb5_data_state state;
krb5_error_code ret;
int length = tvb_captured_length(cryptotvb);
- const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
+ const uint8_t *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
/* don't do anything if we are not attempting to decrypt data */
if(!krb_decrypt || length < 1){
@@ -1575,7 +1846,7 @@ decrypt_krb5_data_private(proto_tree *tree _U_, packet_info *pinfo,
memset(&state, 0, sizeof(state));
state.input.length = length;
- state.input.data = (guint8 *)cryptotext;
+ state.input.data = (uint8_t *)cryptotext;
state.output.data = (char *)wmem_alloc(pinfo->pool, length);
state.output.length = length;
@@ -1594,10 +1865,10 @@ decrypt_krb5_data_private(proto_tree *tree _U_, packet_info *pinfo,
if (datalen) {
*datalen = state.output.length;
}
- return (guint8 *)state.output.data;
+ return (uint8_t *)state.output.data;
}
-guint8 *
+uint8_t *
decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
int usage,
tvbuff_t *cryptotvb,
@@ -1614,16 +1885,16 @@ USES_APPLE_RST
#ifdef KRB5_CRYPTO_TYPE_SIGN_ONLY
struct decrypt_krb5_krb_cfx_dce_state {
- const guint8 *gssapi_header_ptr;
- guint gssapi_header_len;
+ const uint8_t *gssapi_header_ptr;
+ unsigned gssapi_header_len;
tvbuff_t *gssapi_encrypted_tvb;
- guint8 *gssapi_payload;
- guint gssapi_payload_len;
- const guint8 *gssapi_trailer_ptr;
- guint gssapi_trailer_len;
+ uint8_t *gssapi_payload;
+ unsigned gssapi_payload_len;
+ const uint8_t *gssapi_trailer_ptr;
+ unsigned gssapi_trailer_len;
tvbuff_t *checksum_tvb;
- guint8 *checksum;
- guint checksum_len;
+ uint8_t *checksum;
+ unsigned checksum_len;
};
static krb5_error_code
@@ -1638,11 +1909,11 @@ decrypt_krb5_krb_cfx_dce_cb(const krb5_keyblock *key,
unsigned int k5_trailerlen = 0;
unsigned int k5_trailerofs = 0;
size_t _k5_blocksize = 0;
- guint k5_blocksize;
+ unsigned k5_blocksize;
krb5_crypto_iov iov[6];
krb5_error_code ret;
- guint checksum_remain = state->checksum_len;
- guint checksum_crypt_len;
+ unsigned checksum_remain = state->checksum_len;
+ unsigned checksum_crypt_len;
memset(iov, 0, sizeof(iov));
@@ -1682,10 +1953,10 @@ decrypt_krb5_krb_cfx_dce_cb(const krb5_keyblock *key,
* The cast is required for the Windows build in order
* to avoid the following warning.
*
- * warning C4267: '-=': conversion from 'size_t' to 'guint',
+ * warning C4267: '-=': conversion from 'size_t' to 'unsigned',
* possible loss of data
*/
- k5_blocksize = (guint)_k5_blocksize;
+ k5_blocksize = (unsigned)_k5_blocksize;
if (checksum_remain < k5_blocksize) {
return -1;
}
@@ -1709,7 +1980,7 @@ decrypt_krb5_krb_cfx_dce_cb(const krb5_keyblock *key,
if (state->gssapi_header_ptr != NULL) {
iov[1].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
- iov[1].data.data = (guint8 *)(guintptr)state->gssapi_header_ptr;
+ iov[1].data.data = (uint8_t *)(uintptr_t)state->gssapi_header_ptr;
iov[1].data.length = state->gssapi_header_len;
} else {
iov[1].flags = KRB5_CRYPTO_TYPE_EMPTY;
@@ -1721,7 +1992,7 @@ decrypt_krb5_krb_cfx_dce_cb(const krb5_keyblock *key,
if (state->gssapi_trailer_ptr != NULL) {
iov[3].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
- iov[3].data.data = (guint8 *)(guintptr)state->gssapi_trailer_ptr;
+ iov[3].data.data = (uint8_t *)(uintptr_t)state->gssapi_trailer_ptr;
iov[3].data.length = state->gssapi_trailer_len;
} else {
iov[3].flags = KRB5_CRYPTO_TYPE_EMPTY;
@@ -1782,7 +2053,7 @@ decrypt_krb5_krb_cfx_dce(proto_tree *tree,
}
state.gssapi_encrypted_tvb = gssapi_encrypted_tvb;
state.gssapi_payload_len = tvb_captured_length(gssapi_encrypted_tvb);
- state.gssapi_payload = (guint8 *)wmem_alloc0(pinfo->pool, state.gssapi_payload_len);
+ state.gssapi_payload = (uint8_t *)wmem_alloc0(pinfo->pool, state.gssapi_payload_len);
if (state.gssapi_payload == NULL) {
return NULL;
}
@@ -1801,7 +2072,7 @@ decrypt_krb5_krb_cfx_dce(proto_tree *tree,
}
state.checksum_tvb = checksum_tvb;
state.checksum_len = tvb_captured_length(checksum_tvb);
- state.checksum = (guint8 *)wmem_alloc0(pinfo->pool, state.checksum_len);
+ state.checksum = (uint8_t *)wmem_alloc0(pinfo->pool, state.checksum_len);
if (state.checksum == NULL) {
return NULL;
}
@@ -1857,15 +2128,14 @@ encode_krb5_enc_tkt_part(const krb5_enc_tkt_part *rep, krb5_data **code);
static int
keytype_for_cksumtype(krb5_cksumtype checksum)
{
-#define _ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
static const int keytypes[] = {
18,
17,
23,
};
- guint i;
+ unsigned i;
- for (i = 0; i < _ARRAY_SIZE(keytypes); i++) {
+ for (i = 0; i < array_length(keytypes); i++) {
krb5_cksumtype checksumtype = 0;
krb5_error_code ret;
@@ -1884,19 +2154,25 @@ keytype_for_cksumtype(krb5_cksumtype checksum)
}
struct verify_krb5_pac_state {
+ int pacbuffer_length;
+ const uint8_t *pacbuffer;
krb5_pac pac;
krb5_cksumtype server_checksum;
- guint server_count;
+ unsigned server_count;
enc_key_t *server_ek;
krb5_cksumtype kdc_checksum;
- guint kdc_count;
+ unsigned kdc_count;
enc_key_t *kdc_ek;
krb5_cksumtype ticket_checksum_type;
const krb5_data *ticket_checksum_data;
+ krb5_cksumtype full_checksum_type;
+ const krb5_data *full_checksum_data;
+ unsigned full_count;
+ enc_key_t *full_ek;
};
static void
-verify_krb5_pac_try_server_key(gpointer __key _U_, gpointer value, gpointer userdata)
+verify_krb5_pac_try_server_key(void *__key _U_, void *value, void *userdata)
{
struct verify_krb5_pac_state *state =
(struct verify_krb5_pac_state *)userdata;
@@ -1932,7 +2208,7 @@ verify_krb5_pac_try_server_key(gpointer __key _U_, gpointer value, gpointer user
keyblock.magic = KV5M_KEYBLOCK;
keyblock.enctype = ek->keytype;
keyblock.length = ek->keylength;
- keyblock.contents = (guint8 *)ek->keyvalue;
+ keyblock.contents = (uint8_t *)ek->keyvalue;
if (checksumtype == state->server_checksum) {
state->server_count += 1;
@@ -1945,7 +2221,7 @@ verify_krb5_pac_try_server_key(gpointer __key _U_, gpointer value, gpointer user
}
static void
-verify_krb5_pac_try_kdc_key(gpointer __key _U_, gpointer value, gpointer userdata)
+verify_krb5_pac_try_kdc_key(void *__key _U_, void *value, void *userdata)
{
struct verify_krb5_pac_state *state =
(struct verify_krb5_pac_state *)userdata;
@@ -1981,7 +2257,7 @@ verify_krb5_pac_try_kdc_key(gpointer __key _U_, gpointer value, gpointer userdat
keyblock.magic = KV5M_KEYBLOCK;
keyblock.enctype = ek->keytype;
keyblock.length = ek->keylength;
- keyblock.contents = (guint8 *)ek->keyvalue;
+ keyblock.contents = (uint8_t *)ek->keyvalue;
if (checksumtype == state->kdc_checksum) {
state->kdc_count += 1;
@@ -2004,20 +2280,20 @@ verify_krb5_pac_ticket_checksum(proto_tree *tree _U_,
#ifdef HAVE_DECODE_KRB5_ENC_TKT_PART
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *teptvb = private_data->last_ticket_enc_part_tvb;
- guint teplength = 0;
- const guint8 *tepbuffer = NULL;
+ unsigned teplength = 0;
+ const uint8_t *tepbuffer = NULL;
krb5_data tepdata = { .length = 0, };
krb5_enc_tkt_part *tep = NULL;
krb5_data *tmpdata = NULL;
krb5_error_code ret;
krb5_authdata **recoded_container = NULL;
- gint ad_orig_idx = -1;
+ int ad_orig_idx = -1;
krb5_authdata *ad_orig_ptr = NULL;
- gint l0idx = 0;
+ int l0idx = 0;
krb5_keyblock kdc_key = { .magic = KV5M_KEYBLOCK, };
size_t checksum_length = 0;
krb5_checksum checksum = { .checksum_type = 0, };
- krb5_boolean valid = FALSE;
+ krb5_boolean valid = false;
if (state->kdc_ek == NULL) {
int keytype = keytype_for_cksumtype(state->ticket_checksum_type);
@@ -2049,11 +2325,11 @@ verify_krb5_pac_ticket_checksum(proto_tree *tree _U_,
kdc_key.magic = KV5M_KEYBLOCK;
kdc_key.enctype = state->kdc_ek->keytype;
kdc_key.length = state->kdc_ek->keylength;
- kdc_key.contents = (guint8 *)state->kdc_ek->keyvalue;
+ kdc_key.contents = (uint8_t *)state->kdc_ek->keyvalue;
checksum.checksum_type = state->ticket_checksum_type;
checksum.length = state->ticket_checksum_data->length;
- checksum.contents = (guint8 *)state->ticket_checksum_data->data;
+ checksum.contents = (uint8_t *)state->ticket_checksum_data->data;
if (checksum.length >= 4) {
checksum.length -= 4;
checksum.contents += 4;
@@ -2093,7 +2369,7 @@ verify_krb5_pac_ticket_checksum(proto_tree *tree _U_,
krb5_authdata *adl0 = tep->authorization_data[l0idx];
krb5_authdata **decoded_container = NULL;
krb5_authdata *ad_pac = NULL;
- gint l1idx = 0;
+ int l1idx = 0;
if (adl0->ad_type != KRB5_AUTHDATA_IF_RELEVANT) {
continue;
@@ -2195,7 +2471,7 @@ verify_krb5_pac_ticket_checksum(proto_tree *tree _U_,
return;
}
- if (valid == FALSE) {
+ if (valid == false) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
@@ -2216,6 +2492,216 @@ verify_krb5_pac_ticket_checksum(proto_tree *tree _U_,
#endif /* HAVE_DECODE_KRB5_ENC_TKT_PART */
}
+#define __KRB5_PAC_FULL_CHECKSUM 19
+
+static void
+verify_krb5_pac_full_checksum(proto_tree *tree,
+ asn1_ctx_t *actx,
+ tvbuff_t *orig_pactvb,
+ struct verify_krb5_pac_state *state)
+{
+ kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+ krb5_error_code ret;
+ krb5_keyblock kdc_key = { .magic = KV5M_KEYBLOCK, };
+ size_t checksum_length = 0;
+ krb5_checksum checksum = { .checksum_type = 0, };
+ krb5_data pac_data = { .length = 0, };
+ tvbuff_t *copy_pactvb = NULL;
+ uint32_t cur_offset;
+ uint32_t num_buffers;
+ uint32_t idx;
+ krb5_boolean valid = false;
+
+ if (state->kdc_ek == NULL) {
+ int keytype = keytype_for_cksumtype(state->full_checksum_type);
+ missing_signing_key(tree, actx->pinfo, private_data,
+ orig_pactvb, state->full_checksum_type,
+ keytype,
+ "Missing KDC (for full)",
+ "kdc_checksum_key",
+ 0,
+ 0);
+ return;
+ }
+
+ kdc_key.magic = KV5M_KEYBLOCK;
+ kdc_key.enctype = state->kdc_ek->keytype;
+ kdc_key.length = state->kdc_ek->keylength;
+ kdc_key.contents = (uint8_t *)state->kdc_ek->keyvalue;
+
+ ret = krb5_c_checksum_length(krb5_ctx,
+ state->full_checksum_type,
+ &checksum_length);
+ if (ret != 0) {
+ missing_signing_key(tree, actx->pinfo, private_data,
+ orig_pactvb, state->full_checksum_type,
+ state->kdc_ek->keytype,
+ "krb5_c_checksum_length failed for Full Signature",
+ "kdc_checksum_key",
+ 1,
+ 0);
+ return;
+ }
+
+ /*
+ * The checksum element begins with 4 bytes of type
+ * (state->full_checksum_type) before the crypto checksum
+ */
+ if (state->full_checksum_data->length < (4 + checksum_length)) {
+ missing_signing_key(tree, actx->pinfo, private_data,
+ orig_pactvb, state->full_checksum_type,
+ state->kdc_ek->keytype,
+ "pacbuffer_length too short for Full Signature",
+ "kdc_checksum_key",
+ 1,
+ 0);
+ return;
+ }
+
+ pac_data.data = wmem_memdup(actx->pinfo->pool, state->pacbuffer, state->pacbuffer_length);
+ if (pac_data.data == NULL) {
+ missing_signing_key(tree, actx->pinfo, private_data,
+ orig_pactvb, state->full_checksum_type,
+ state->kdc_ek->keytype,
+ "wmem_memdup(pacbuffer) failed",
+ "kdc_checksum_key",
+ 1,
+ 0);
+ return;
+ }
+ pac_data.length = state->pacbuffer_length;
+
+ copy_pactvb = tvb_new_child_real_data(orig_pactvb,
+ (uint8_t *)pac_data.data,
+ pac_data.length,
+ pac_data.length);
+ if (copy_pactvb == NULL) {
+ missing_signing_key(tree, actx->pinfo, private_data,
+ orig_pactvb, state->full_checksum_type,
+ state->kdc_ek->keytype,
+ "tvb_new_child_real_data(pac_copy) failed",
+ "kdc_checksum_key",
+ 1,
+ 0);
+ return;
+ }
+
+#define __PAC_CHECK_OFFSET_SIZE(__offset, __length, __reason) do { \
+ uint64_t __end = state->pacbuffer_length; \
+ uint64_t __offset64 = __offset; \
+ uint64_t __length64 = __length; \
+ uint64_t __last; \
+ if (__offset64 > INT32_MAX) { \
+ missing_signing_key(tree, actx->pinfo, private_data, \
+ orig_pactvb, state->full_checksum_type, \
+ state->kdc_ek->keytype, \
+ __reason, \
+ "kdc_checksum_key", \
+ 1, \
+ 0); \
+ return; \
+ } \
+ if (__length64 > INT32_MAX) { \
+ missing_signing_key(tree, actx->pinfo, private_data, \
+ orig_pactvb, state->full_checksum_type, \
+ state->kdc_ek->keytype, \
+ __reason, \
+ "kdc_checksum_key", \
+ 1, \
+ 0); \
+ return; \
+ } \
+ __last = __offset64 + __length64; \
+ if (__last > __end) { \
+ missing_signing_key(tree, actx->pinfo, private_data, \
+ orig_pactvb, state->full_checksum_type, \
+ state->kdc_ek->keytype, \
+ __reason, \
+ "kdc_checksum_key", \
+ 1, \
+ 0); \
+ return; \
+ } \
+} while(0)
+
+ cur_offset = 0;
+ __PAC_CHECK_OFFSET_SIZE(cur_offset, 8, "PACTYPE Header");
+ num_buffers = tvb_get_uint32(copy_pactvb, cur_offset, ENC_LITTLE_ENDIAN);
+ cur_offset += 4;
+ /* ignore 4 byte version */
+ cur_offset += 4;
+
+ for (idx = 0; idx < num_buffers; idx++) {
+ uint32_t b_type;
+ uint32_t b_length;
+ uint64_t b_offset;
+
+ __PAC_CHECK_OFFSET_SIZE(cur_offset, 16, "PAC_INFO_BUFFER Header");
+ b_type = tvb_get_uint32(copy_pactvb, cur_offset, ENC_LITTLE_ENDIAN);
+ cur_offset += 4;
+ b_length = tvb_get_uint32(copy_pactvb, cur_offset, ENC_LITTLE_ENDIAN);
+ cur_offset += 4;
+ b_offset = tvb_get_uint64(copy_pactvb, cur_offset, ENC_LITTLE_ENDIAN);
+ cur_offset += 8;
+
+ __PAC_CHECK_OFFSET_SIZE(b_offset, b_length, "PAC_INFO_BUFFER Payload");
+
+ if (b_length <= 4) {
+ continue;
+ }
+
+ /*
+ * Leave PAC_TICKET_CHECKSUM and clear all other checksums
+ * and their possible RODC identifier, but leaving their
+ * checksum type as is.
+ */
+ switch (b_type) {
+ case KRB5_PAC_SERVER_CHECKSUM:
+ case KRB5_PAC_PRIVSVR_CHECKSUM:
+ case __KRB5_PAC_FULL_CHECKSUM:
+ memset(pac_data.data + b_offset+4, 0, b_length-4);
+ break;
+ }
+ }
+
+ checksum.checksum_type = state->full_checksum_type;
+ checksum.contents = (uint8_t *)state->full_checksum_data->data + 4;
+ checksum.length = (unsigned)checksum_length;
+
+ ret = krb5_c_verify_checksum(krb5_ctx, &kdc_key,
+ KRB5_KEYUSAGE_APP_DATA_CKSUM,
+ &pac_data, &checksum, &valid);
+ if (ret != 0) {
+ missing_signing_key(tree, actx->pinfo, private_data,
+ orig_pactvb, state->full_checksum_type,
+ state->kdc_ek->keytype,
+ "krb5_c_verify_checksum failed for Full PAC Signature",
+ "kdc_checksum_key",
+ 1,
+ 1);
+ return;
+ }
+
+ if (valid == false) {
+ missing_signing_key(tree, actx->pinfo, private_data,
+ orig_pactvb, state->full_checksum_type,
+ state->kdc_ek->keytype,
+ "Invalid Full PAC Signature",
+ "kdc_checksum_key",
+ 1,
+ 1);
+ return;
+ }
+
+ used_signing_key(tree, actx->pinfo, private_data,
+ state->kdc_ek, orig_pactvb,
+ state->full_checksum_type,
+ "Verified Full PAC",
+ "kdc_checksum_key",
+ 1,
+ 1);
+}
+
static void
verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
{
@@ -2223,8 +2709,9 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
krb5_error_code ret;
krb5_data checksum_data = {0,0,NULL};
krb5_data ticket_checksum_data = {0,0,NULL};
+ krb5_data full_checksum_data = {0,0,NULL};
int length = tvb_captured_length(pactvb);
- const guint8 *pacbuffer = NULL;
+ const uint8_t *pacbuffer = NULL;
struct verify_krb5_pac_state state = {
.kdc_checksum = 0,
};
@@ -2240,6 +2727,8 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
}
pacbuffer = tvb_get_ptr(pactvb, 0, length);
+ state.pacbuffer_length = length;
+ state.pacbuffer = pacbuffer;
ret = krb5_pac_parse(krb5_ctx, pacbuffer, length, &state.pac);
if (ret != 0) {
@@ -2269,6 +2758,13 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
state.ticket_checksum_data = &ticket_checksum_data;
state.ticket_checksum_type = pletoh32(ticket_checksum_data.data);
};
+ ret = krb5_pac_get_buffer(krb5_ctx, state.pac,
+ __KRB5_PAC_FULL_CHECKSUM,
+ &full_checksum_data);
+ if (ret == 0) {
+ state.full_checksum_data = &full_checksum_data;
+ state.full_checksum_type = pletoh32(full_checksum_data.data);
+ };
read_keytab_file_from_preferences();
@@ -2319,6 +2815,14 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
krb5_free_data_contents(krb5_ctx, &ticket_checksum_data);
}
+ if (state.full_checksum_type != 0) {
+ verify_krb5_pac_full_checksum(tree, actx, pactvb, &state);
+ }
+
+ if (state.full_checksum_data != NULL) {
+ krb5_free_data_contents(krb5_ctx, &full_checksum_data);
+ }
+
krb5_pac_free(krb5_ctx, state.pac);
}
#endif /* HAVE_KRB5_PAC_VERIFY */
@@ -2344,14 +2848,14 @@ read_keytab_file(const char *filename)
krb5_keytab_entry key;
krb5_kt_cursor cursor;
enc_key_t *new_key;
- static gboolean first_time=TRUE;
+ static bool first_time=true;
if (filename == NULL || filename[0] == 0) {
return;
}
if(first_time){
- first_time=FALSE;
+ first_time=false;
ret = krb5_init_context(&krb5_ctx);
if(ret){
return;
@@ -2399,7 +2903,7 @@ read_keytab_file(const char *filename)
new_key->keylength=(int)key.keyblock.keyvalue.length;
memcpy(new_key->keyvalue,
key.keyblock.keyvalue.data,
- MIN((guint)key.keyblock.keyvalue.length, KRB_MAX_KEY_LENGTH));
+ MIN((unsigned)key.keyblock.keyvalue.length, KRB_MAX_KEY_LENGTH));
enc_key_list=new_key;
ret = krb5_kt_free_entry(krb5_ctx, &key);
@@ -2424,7 +2928,7 @@ read_keytab_file(const char *filename)
USES_APPLE_RST
-guint8 *
+uint8_t *
decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
int usage,
tvbuff_t *cryptotvb,
@@ -2436,7 +2940,7 @@ decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
krb5_data data;
enc_key_t *ek;
int length = tvb_captured_length(cryptotvb);
- const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
+ const uint8_t *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
/* don't do anything if we are not attempting to decrypt data */
if(!krb_decrypt){
@@ -2453,7 +2957,7 @@ decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
for(ek=enc_key_list;ek;ek=ek->next){
krb5_keytab_entry key;
krb5_crypto crypto;
- guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
+ uint8_t *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
/* shortcircuit and bail out if enctypes are not matching */
if((keytype != -1) && (ek->keytype != keytype)) {
@@ -2474,7 +2978,7 @@ decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
keys. So just give it a copy of the crypto data instead.
This has been seen for RC4-HMAC blobs.
*/
- cryptocopy = (guint8 *)wmem_memdup(pinfo->pool, cryptotext, length);
+ cryptocopy = (uint8_t *)wmem_memdup(pinfo->pool, cryptotext, length);
ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
cryptocopy, length,
&data,
@@ -2488,7 +2992,7 @@ decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
krb5_crypto_destroy(krb5_ctx, crypto);
/* return a private wmem_alloced blob to the caller */
- user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
+ user_data = (char *)wmem_memdup(pinfo->pool, data.data, (unsigned)data.length);
if (datalen) {
*datalen = (int)data.length;
}
@@ -2507,13 +3011,13 @@ decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
#define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
typedef struct _service_key_t {
- guint16 kvno;
+ uint16_t kvno;
int keytype;
int length;
- guint8 *contents;
+ uint8_t *contents;
char origin[KRB_MAX_ORIG_LEN+1];
} service_key_t;
-GSList *service_key_list = NULL;
+GSList *service_key_list;
static void
@@ -2531,7 +3035,7 @@ add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *k
new_key->length = keylength;
new_key->contents = g_memdup2(keyvalue, keylength);
snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
- service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
+ service_key_list = g_slist_append(service_key_list, (void *) new_key);
}
static void
@@ -2659,7 +3163,7 @@ read_keytab_file(const char *service_key_file)
sk->length = DES3_KEY_SIZE;
sk->contents = g_memdup2(buf + 2, DES3_KEY_SIZE);
snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
- service_key_list = g_slist_append(service_key_list, (gpointer) sk);
+ service_key_list = g_slist_append(service_key_list, (void *) sk);
if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
fprintf(stderr, "unable to seek...\n");
fclose(skf);
@@ -2673,7 +3177,7 @@ read_keytab_file(const char *service_key_file)
#define CONFOUNDER_PLUS_CHECKSUM 24
-guint8 *
+uint8_t *
decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
int _U_ usage,
tvbuff_t *cryptotvb,
@@ -2681,23 +3185,23 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
int *datalen)
{
tvbuff_t *encr_tvb;
- guint8 *decrypted_data = NULL, *plaintext = NULL;
- guint8 cls;
+ uint8_t *decrypted_data = NULL, *plaintext = NULL;
+ uint8_t cls;
bool pc;
- guint32 tag, item_len, data_len;
+ uint32_t tag, item_len, data_len;
int id_offset, offset;
- guint8 key[DES3_KEY_SIZE];
- guint8 initial_vector[DES_BLOCK_SIZE];
+ uint8_t key[DES3_KEY_SIZE];
+ uint8_t initial_vector[DES_BLOCK_SIZE];
gcry_md_hd_t md5_handle;
- guint8 *digest;
- guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- guint8 confounder[8];
+ uint8_t *digest;
+ uint8_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ uint8_t confounder[8];
bool ind;
GSList *ske;
service_key_t *sk;
struct des3_ctx ctx;
int length = tvb_captured_length(cryptotvb);
- const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
+ const uint8_t *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
/* don't do anything if we are not attempting to decrypt data */
@@ -2716,8 +3220,8 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
decrypted_data = wmem_alloc(pinfo->pool, length);
for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
- gboolean do_continue = FALSE;
- gboolean digest_ok;
+ bool do_continue = false;
+ bool digest_ok;
sk = (service_key_t *) ske->data;
des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
@@ -2741,7 +3245,7 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
}
CATCH_BOUNDS_ERRORS {
tvb_free(encr_tvb);
- do_continue = TRUE;
+ do_continue = true;
}
ENDTRY;
@@ -2764,13 +3268,13 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
gcry_md_close(md5_handle);
if (digest_ok) {
- plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
+ plaintext = (uint8_t* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
tvb_free(encr_tvb);
if (datalen) {
*datalen = data_len;
}
- return(plaintext);
+ return plaintext;
}
tvb_free(encr_tvb);
}
@@ -3021,6 +3525,7 @@ static const value_string krb5_error_codes[] = {
#define PAC_TICKET_CHECKSUM 16
#define PAC_ATTRIBUTES_INFO 17
#define PAC_REQUESTER_SID 18
+#define PAC_FULL_CHECKSUM 19
static const value_string w2k_pac_types[] = {
{ PAC_LOGON_INFO , "Logon Info" },
{ PAC_CREDENTIAL_TYPE , "Credential Type" },
@@ -3035,6 +3540,7 @@ static const value_string w2k_pac_types[] = {
{ PAC_TICKET_CHECKSUM , "Ticket Checksum" },
{ PAC_ATTRIBUTES_INFO , "Attributes Info" },
{ PAC_REQUESTER_SID , "Requester Sid" },
+ { PAC_FULL_CHECKSUM , "Full Checksum" },
{ 0, NULL },
};
@@ -3100,8 +3606,66 @@ static const true_false_string tfs_gss_flags_dce_style = {
"Not using DCE-STYLE"
};
+static int dissect_kerberos_KRB5_SRP_PA_APPLICATIONS(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
+{
+ kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+ proto_item *pi1 = proto_item_get_parent(actx->created_item);
+ proto_item *pi2 = proto_item_get_parent(pi1);
+ int8_t ber_class;
+ bool pc;
+ int32_t tag;
+
+ /*
+ * dissect_ber_octet_string_wcb() always passes
+ * implicit_tag=false, offset=0 and hf_index=-1
+ */
+ ws_assert(implicit_tag == false);
+ ws_assert(offset == 0);
+ ws_assert(hf_index <= 0);
+
+ get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
+ if (ber_class != BER_CLASS_APP) {
+ if (kerberos_private_is_kdc_req(private_data)) {
+ goto unknown;
+ }
+ if (private_data->errorcode != KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED) {
+ goto unknown;
+ }
+
+ proto_item_append_text(pi1, " KRB5_SRP_PA_ANNOUNCE");
+ proto_item_append_text(pi2, ": KRB5_SRP_PA_ANNOUNCE");
+ return dissect_kerberos_KRB5_SRP_PA_ANNOUNCE(implicit_tag, tvb, offset, actx, tree, hf_index);
+ }
+
+ switch (tag) {
+ case 0:
+ proto_item_append_text(pi1, " KRB5_SRP_PA_INIT");
+ proto_item_append_text(pi2, ": KRB5_SRP_PA_INIT");
+ return dissect_kerberos_KRB5_SRP_PA_INIT(implicit_tag, tvb, offset, actx, tree, hf_index);
+ case 1:
+ proto_item_append_text(pi1, " KRB5_SRP_PA_SERVER_CHALLENGE");
+ proto_item_append_text(pi2, ": KRB5_SRP_PA_SERVER_CHALLENGE");
+ return dissect_kerberos_KRB5_SRP_PA_SERVER_CHALLENGE(implicit_tag, tvb, offset, actx, tree, hf_index);
+ case 2:
+ proto_item_append_text(pi1, " KRB5_SRP_PA_CLIENT_RESPONSE");
+ proto_item_append_text(pi2, ": KRB5_SRP_PA_CLIENT_RESPONSE");
+ return dissect_kerberos_KRB5_SRP_PA_CLIENT_RESPONSE(implicit_tag, tvb, offset, actx, tree, hf_index);
+ case 3:
+ proto_item_append_text(pi1, " KRB5_SRP_PA_SERVER_VERIFIER");
+ proto_item_append_text(pi2, ": KRB5_SRP_PA_SERVER_VERIFIER");
+ return dissect_kerberos_KRB5_SRP_PA_SERVER_VERIFIER(implicit_tag, tvb, offset, actx, tree, hf_index);
+ default:
+ break;
+ }
+
+unknown:
+ proto_item_append_text(pi1, " KRB5_SRP_PA_UNKNOWN: ber_class:%u ber_pc=%u ber_tag:%"PRIu32"", ber_class, pc, tag);
+ proto_item_append_text(pi2, ": KRB5_SRP_PA_UNKNOWN");
+ return tvb_reported_length_remaining(tvb, offset);
+}
+
#ifdef HAVE_KERBEROS
-static guint8 *
+static uint8_t *
decrypt_krb5_data_asn1(proto_tree *tree, asn1_ctx_t *actx,
int usage, tvbuff_t *cryptotvb, int *datalen)
{
@@ -3122,7 +3686,7 @@ static int
dissect_krb5_decrypt_ticket_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
proto_tree *tree, int hf_index _U_)
{
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
tvbuff_t *next_tvb;
@@ -3138,6 +3702,7 @@ dissect_krb5_decrypt_ticket_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, a
if(plaintext){
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *last_ticket_enc_part_tvb = private_data->last_ticket_enc_part_tvb;
+ enc_key_t *current_ticket_key = private_data->current_ticket_key;
tvbuff_t *child_tvb;
child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
@@ -3145,7 +3710,9 @@ dissect_krb5_decrypt_ticket_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, a
add_new_data_source(actx->pinfo, child_tvb, "Krb5 Ticket");
private_data->last_ticket_enc_part_tvb = child_tvb;
- offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ private_data->current_ticket_key = NULL;
+ offset=dissect_kerberos_Applications(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ private_data->current_ticket_key = current_ticket_key;
private_data->last_ticket_enc_part_tvb = last_ticket_enc_part_tvb;
}
return offset;
@@ -3156,7 +3723,7 @@ dissect_krb5_decrypt_authenticator_data (bool imp_tag _U_, tvbuff_t *tvb, int of
proto_tree *tree, int hf_index _U_)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
tvbuff_t *next_tvb;
@@ -3189,7 +3756,7 @@ dissect_krb5_decrypt_authenticator_data (bool imp_tag _U_, tvbuff_t *tvb, int of
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 Authenticator");
- offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_Applications(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3199,7 +3766,7 @@ dissect_krb5_decrypt_authorization_data(bool imp_tag _U_, tvbuff_t *tvb, int off
proto_tree *tree, int hf_index _U_)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
tvbuff_t *next_tvb;
@@ -3230,7 +3797,7 @@ dissect_krb5_decrypt_authorization_data(bool imp_tag _U_, tvbuff_t *tvb, int off
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 AuthorizationData");
- offset=dissect_kerberos_AuthorizationData(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_AuthorizationData(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3240,7 +3807,7 @@ dissect_krb5_decrypt_KDC_REP_data (bool imp_tag _U_, tvbuff_t *tvb, int offset,
proto_tree *tree, int hf_index _U_)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
- guint8 *plaintext = NULL;
+ uint8_t *plaintext = NULL;
int length;
tvbuff_t *next_tvb;
@@ -3301,7 +3868,7 @@ dissect_krb5_decrypt_KDC_REP_data (bool imp_tag _U_, tvbuff_t *tvb, int offset,
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 KDC-REP");
- offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_Applications(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3310,7 +3877,7 @@ static int
dissect_krb5_decrypt_PA_ENC_TIMESTAMP (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
proto_tree *tree, int hf_index _U_)
{
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
tvbuff_t *next_tvb;
@@ -3331,7 +3898,7 @@ dissect_krb5_decrypt_PA_ENC_TIMESTAMP (bool imp_tag _U_, tvbuff_t *tvb, int offs
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 EncTimestamp");
- offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_PA_ENC_TS_ENC(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3340,7 +3907,7 @@ static int
dissect_krb5_decrypt_AP_REP_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
proto_tree *tree, int hf_index _U_)
{
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
tvbuff_t *next_tvb;
@@ -3360,7 +3927,7 @@ dissect_krb5_decrypt_AP_REP_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, a
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 AP-REP");
- offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_Applications(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3369,7 +3936,7 @@ static int
dissect_krb5_decrypt_PRIV_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
proto_tree *tree, int hf_index _U_)
{
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
tvbuff_t *next_tvb;
@@ -3389,7 +3956,7 @@ dissect_krb5_decrypt_PRIV_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 PRIV");
- offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_Applications(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3399,7 +3966,7 @@ dissect_krb5_decrypt_CRED_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn
proto_tree *tree, int hf_index _U_)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
tvbuff_t *next_tvb;
@@ -3407,7 +3974,7 @@ dissect_krb5_decrypt_CRED_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn
length=tvb_captured_length_remaining(tvb, offset);
if (private_data->etype == 0) {
- offset=dissect_kerberos_Applications(FALSE, next_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_Applications(false, next_tvb, 0, actx , tree, /* hf_index*/ -1);
return offset;
}
@@ -3424,7 +3991,7 @@ dissect_krb5_decrypt_CRED_data (bool imp_tag _U_, tvbuff_t *tvb, int offset, asn
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 CRED");
- offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_Applications(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3433,7 +4000,7 @@ static int
dissect_krb5_decrypt_KrbFastReq(bool imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
proto_tree *tree, int hf_index _U_)
{
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *next_tvb;
@@ -3487,7 +4054,7 @@ dissect_krb5_decrypt_KrbFastReq(bool imp_tag _U_, tvbuff_t *tvb, int offset, asn
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 FastReq");
- offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_KrbFastReq(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3496,7 +4063,7 @@ static int
dissect_krb5_decrypt_KrbFastResponse(bool imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
proto_tree *tree, int hf_index _U_)
{
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *next_tvb;
@@ -3520,7 +4087,7 @@ dissect_krb5_decrypt_KrbFastResponse(bool imp_tag _U_, tvbuff_t *tvb, int offset
add_new_data_source(actx->pinfo, child_tvb, "Krb5 FastRep");
private_data->fast_armor_key = private_data->last_decryption_key;
- offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_KrbFastResponse(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3529,7 +4096,7 @@ static int
dissect_krb5_decrypt_EncryptedChallenge(bool imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
proto_tree *tree, int hf_index _U_)
{
- guint8 *plaintext;
+ uint8_t *plaintext;
int length;
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *next_tvb;
@@ -3559,7 +4126,7 @@ dissect_krb5_decrypt_EncryptedChallenge(bool imp_tag _U_, tvbuff_t *tvb, int off
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, name);
- offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+ offset=dissect_kerberos_PA_ENC_TS_ENC(false, child_tvb, 0, actx , tree, /* hf_index*/ -1);
}
return offset;
}
@@ -3571,6 +4138,7 @@ static int * const hf_krb_pa_supported_enctypes_fields[] = {
&hf_krb_pa_supported_enctypes_rc4_hmac,
&hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
&hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
+ &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96_sk,
&hf_krb_pa_supported_enctypes_fast_supported,
&hf_krb_pa_supported_enctypes_compound_identity_supported,
&hf_krb_pa_supported_enctypes_claims_supported,
@@ -3595,6 +4163,7 @@ dissect_kerberos_PA_SUPPORTED_ENCTYPES(bool implicit_tag _U_, tvbuff_t *tvb _U_,
static int * const hf_krb_ad_ap_options_fields[] = {
&hf_krb_ad_ap_options_cbt,
+ &hf_krb_ad_ap_options_unverified_target_name,
NULL,
};
@@ -3620,7 +4189,7 @@ dissect_kerberos_AD_TARGET_PRINCIPAL(bool implicit_tag _U_, tvbuff_t *tvb _U_,
proto_tree *tree _U_, int hf_index _U_)
{
int tp_offset, tp_len;
- guint16 bc;
+ uint16_t bc;
bc = tvb_reported_length_remaining(tvb, offset);
tp_offset = offset;
@@ -3638,8 +4207,8 @@ static int
dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
{
int offset=0;
- guint32 len;
- guint16 dlglen;
+ uint32_t len;
+ uint16_t dlglen;
/* Length of Bnd field */
len=tvb_get_letohl(tvb, offset);
@@ -3685,7 +4254,7 @@ dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *
}
/* this should now be a KRB_CRED message */
- offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
+ offset=dissect_kerberos_Applications(false, tvb, offset, actx, tree, /* hf_index */ -1);
return offset;
}
@@ -3702,17 +4271,17 @@ static int
dissect_krb5_PW_SALT(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
- gint length;
- guint32 nt_status = 0;
- guint32 reserved = 0;
- guint32 flags = 0;
+ int length;
+ uint32_t nt_status = 0;
+ uint32_t reserved = 0;
+ uint32_t flags = 0;
/*
* Microsoft stores a special 12 byte blob here
* [MS-KILE] 2.2.1 KERB-EXT-ERROR
- * guint32 NT_status
- * guint32 reserved (== 0)
- * guint32 flags (at least 0x00000001 is set)
+ * uint32_t NT_status
+ * uint32_t reserved (== 0)
+ * uint32_t flags (at least 0x00000001 is set)
*/
length = tvb_reported_length_remaining(tvb, offset);
if (length <= 0) {
@@ -3726,15 +4295,11 @@ dissect_krb5_PW_SALT(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, a
goto no_error;
}
- if (!private_data->try_nt_status) {
- goto no_error;
- }
-
nt_status = tvb_get_letohl(tvb, offset);
reserved = tvb_get_letohl(tvb, offset + 4);
flags = tvb_get_letohl(tvb, offset + 8);
- if (nt_status == 0 || reserved != 0 || flags == 0) {
+ if (reserved != 0 || flags != 1 || !try_val_to_str_ext(nt_status, &NT_errors_ext)) {
goto no_error;
}
@@ -3742,7 +4307,7 @@ dissect_krb5_PW_SALT(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, a
ENC_LITTLE_ENDIAN);
col_append_fstr(actx->pinfo->cinfo, COL_INFO,
" NT Status: %s",
- val_to_str(nt_status, NT_errors,
+ val_to_str_ext(nt_status, &NT_errors_ext,
"Unknown error code %#x"));
offset += 4;
@@ -3764,14 +4329,14 @@ dissect_krb5_PW_SALT(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, a
}
static int
-dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
+dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, uint8_t *drep)
{
proto_tree *tree;
- guint8 val;
+ uint8_t val;
tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
- val = tvb_get_guint8(tvb, offset);
+ val = tvb_get_uint8(tvb, offset);
proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
offset++;
@@ -3789,7 +4354,7 @@ dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8
* endianess and similar are not available.
*/
static int
-dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
+dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, uint8_t *drep, asn1_ctx_t *actx _U_)
{
proto_tree *tree;
@@ -3822,9 +4387,10 @@ dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset,
{
proto_item *item;
proto_tree *tree;
- guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
- static dcerpc_info di; /* fake dcerpc_info struct */
- static dcerpc_call_value call_data;
+ uint8_t drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
+ /* fake dcerpc_info struct */
+ dcerpc_call_value call_data = { .flags = 0, };
+ dcerpc_info di = { .ptype = UINT8_MAX, .call_data = &call_data, };
item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
@@ -3835,14 +4401,11 @@ dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset,
offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
/* the PAC_LOGON_INFO blob */
- /* fake whatever state the dcerpc runtime support needs */
- di.conformant_run=0;
- /* we need di->call_data->flags.NDR64 == 0 */
- di.call_data=&call_data;
init_ndr_pointer_list(&di);
offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
"PAC_LOGON_INFO:", -1);
+ free_ndr_pointer_list(&di);
return offset;
}
@@ -3861,12 +4424,12 @@ dissect_krb5_PAC_CREDENTIAL_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int off
{
proto_item *item;
proto_tree *tree;
- guint8 *plaintext = NULL;
+ uint8_t *plaintext = NULL;
int plainlen = 0;
int length = 0;
#define KRB5_KU_OTHER_ENCRYPTED 16
#ifdef HAVE_KERBEROS
- guint32 etype;
+ uint32_t etype;
tvbuff_t *next_tvb;
int usage = KRB5_KU_OTHER_ENCRYPTED;
#endif
@@ -3913,9 +4476,10 @@ dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int
{
proto_item *item;
proto_tree *tree;
- guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
- static dcerpc_info di; /* fake dcerpc_info struct */
- static dcerpc_call_value call_data;
+ uint8_t drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
+ /* fake dcerpc_info struct */
+ dcerpc_call_value call_data = { .flags = 0, };
+ dcerpc_info di = { .ptype = UINT8_MAX, .call_data = &call_data, };
item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
@@ -3925,16 +4489,12 @@ dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int
*/
offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
-
/* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
- /* fake whatever state the dcerpc runtime support needs */
- di.conformant_run=0;
- /* we need di->call_data->flags.NDR64 == 0 */
- di.call_data=&call_data;
init_ndr_pointer_list(&di);
offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
"PAC_S4U_DELEGATION_INFO:", -1);
+ free_ndr_pointer_list(&di);
return offset;
}
@@ -3958,13 +4518,17 @@ static int * const hf_krb_pac_upn_flags_fields[] = {
static int
dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
+#ifdef HAVE_KERBEROS
+ kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+#endif /* HAVE_KERBEROS */
proto_item *item;
proto_tree *tree;
- guint16 dns_offset, dns_len;
- guint16 upn_offset, upn_len;
- guint16 samaccountname_offset = 0, samaccountname_len = 0;
- guint16 objectsid_offset = 0, objectsid_len = 0;
- guint32 flags;
+ uint16_t dns_offset, dns_len;
+ uint16_t upn_offset, upn_len;
+ uint16_t samaccountname_offset = 0, samaccountname_len = 0;
+ uint16_t objectsid_offset = 0, objectsid_len = 0;
+ char *sid_str = NULL;
+ uint32_t flags;
item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
@@ -4024,9 +4588,38 @@ dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset
if (objectsid_offset != 0 && objectsid_len != 0) {
tvbuff_t *sid_tvb;
sid_tvb=tvb_new_subset_length(tvb, objectsid_offset, objectsid_len);
- dissect_nt_sid(sid_tvb, 0, tree, "objectSid", NULL, -1);
+ dissect_nt_sid(sid_tvb, 0, tree, "objectSid", &sid_str, -1);
}
+#ifdef HAVE_KERBEROS
+ if (private_data->current_ticket_key != NULL) {
+ enc_key_t *ek = private_data->current_ticket_key;
+
+ if (samaccountname_offset != 0 && samaccountname_len != 0) {
+ ek->pac_names.account_name = tvb_get_string_enc(wmem_epan_scope(),
+ tvb,
+ samaccountname_offset,
+ samaccountname_len,
+ ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ } else {
+ ek->pac_names.account_name = tvb_get_string_enc(wmem_epan_scope(),
+ tvb,
+ upn_offset,
+ upn_len,
+ ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ }
+ ek->pac_names.account_domain = tvb_get_string_enc(wmem_epan_scope(),
+ tvb,
+ dns_offset,
+ dns_len,
+ ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ if (sid_str != NULL) {
+ ek->pac_names.account_sid = wmem_strdup(wmem_epan_scope(),
+ sid_str);
+ }
+ }
+#endif /* HAVE_KERBEROS */
+
return dns_offset;
}
@@ -4047,11 +4640,22 @@ dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int
static int
dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
+#ifdef HAVE_KERBEROS
+ kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+ const char *device_sid = NULL;
+#endif /* HAVE_KERBEROS */
proto_item *item;
proto_tree *tree;
- guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
- static dcerpc_info di; /* fake dcerpc_info struct */
- static dcerpc_call_value call_data;
+ uint8_t drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
+ /* fake dcerpc_info struct */
+ dcerpc_call_value call_data = { .flags = 0, };
+ dcerpc_info di = { .ptype = UINT8_MAX, .call_data = &call_data, };
+
+#ifdef HAVE_KERBEROS
+ if (private_data->current_ticket_key != NULL) {
+ call_data.private_data = (void*)&device_sid;
+ }
+#endif /* HAVE_KERBEROS */
item = proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_krb_pac_device_info);
@@ -4062,14 +4666,23 @@ dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset,
offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
/* the PAC_DEVICE_INFO blob */
- /* fake whatever state the dcerpc runtime support needs */
- di.conformant_run=0;
- /* we need di->call_data->flags.NDR64 == 0 */
- di.call_data=&call_data;
init_ndr_pointer_list(&di);
offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
netlogon_dissect_PAC_DEVICE_INFO, NDR_POINTER_UNIQUE,
"PAC_DEVICE_INFO:", -1);
+ free_ndr_pointer_list(&di);
+
+#ifdef HAVE_KERBEROS
+ if (private_data->current_ticket_key != NULL) {
+ enc_key_t *ek = private_data->current_ticket_key;
+
+ /*
+ * netlogon_dissect_PAC_DEVICE_INFO allocated on
+ * wmem_epan_scope() for us
+ */
+ ek->pac_names.device_sid = device_sid;
+ }
+#endif /* HAVE_KERBEROS */
return offset;
}
@@ -4131,13 +4744,14 @@ dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int of
{
proto_item *item;
proto_tree *tree;
- guint16 namelen;
+ uint16_t namelen;
item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
/* clientid */
- offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
+ dissect_nttime(tvb, tree, offset, hf_krb_pac_clientid, ENC_LITTLE_ENDIAN);
+ offset+=8;
/* name length */
namelen=tvb_get_letohs(tvb, offset);
@@ -4225,11 +4839,30 @@ dissect_krb5_PAC_REQUESTER_SID(proto_tree *parent_tree, tvbuff_t *tvb, int offse
}
static int
+dissect_krb5_PAC_FULL_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
+{
+ proto_item *item;
+ proto_tree *tree;
+
+ item = proto_tree_add_item(parent_tree, hf_krb_pac_full_checksum, tvb, offset, -1, ENC_NA);
+ tree = proto_item_add_subtree(item, ett_krb_pac_full_checksum);
+
+ /* signature type */
+ proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset+=4;
+
+ /* signature data */
+ proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
+
+ return offset;
+}
+
+static int
dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
{
- guint32 pac_type;
- guint32 pac_size;
- guint32 pac_offset;
+ uint32_t pac_type;
+ uint32_t pac_size;
+ uint32_t pac_offset;
proto_item *it=NULL;
proto_tree *tr=NULL;
tvbuff_t *next_tvb;
@@ -4292,6 +4925,9 @@ dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, as
case PAC_REQUESTER_SID:
dissect_krb5_PAC_REQUESTER_SID(tr, next_tvb, 0, actx);
break;
+ case PAC_FULL_CHECKSUM:
+ dissect_krb5_PAC_FULL_CHECKSUM(tr, next_tvb, 0, actx);
+ break;
default:
break;
@@ -4302,9 +4938,9 @@ dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, as
static int
dissect_krb5_AD_WIN2K_PAC(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
{
- guint32 entries;
- guint32 version;
- guint32 i;
+ uint32_t entries;
+ uint32_t version;
+ uint32_t i;
#if defined(HAVE_MIT_KERBEROS) && defined(HAVE_KRB5_PAC_VERIFY)
verify_krb5_pac(tree, actx, tvb);
@@ -4327,6 +4963,43 @@ dissect_krb5_AD_WIN2K_PAC(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1
return offset;
}
+static int dissect_kerberos_T_e_data_octets(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
+{
+ int8_t ber_class;
+ bool pc;
+ int32_t tag;
+ int len_offset;
+ uint32_t len;
+ bool ind;
+ int next_offset;
+
+ /*
+ * dissect_ber_octet_string_wcb() always passes
+ * implicit_tag=false, offset=0 and hf_index=-1
+ */
+ ws_assert(implicit_tag == false);
+ ws_assert(offset == 0);
+ ws_assert(hf_index <= 0);
+
+ len_offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
+ if (ber_class != BER_CLASS_UNI || !pc || tag != BER_UNI_TAG_SEQUENCE) {
+ goto unknown;
+ }
+ next_offset = get_ber_length(tvb, len_offset, &len, &ind);
+ if (len < 1) {
+ goto unknown;
+ }
+ get_ber_identifier(tvb, next_offset, &ber_class, &pc, &tag);
+ if (ber_class == BER_CLASS_CON && pc && tag == 1) {
+ return dissect_kerberos_PA_DATA(implicit_tag, tvb, offset, actx, tree, hf_index);
+ }
+ if (ber_class == BER_CLASS_UNI && pc && tag == BER_UNI_TAG_SEQUENCE) {
+ return dissect_kerberos_T_rEP_SEQUENCE_OF_PA_DATA(implicit_tag, tvb, offset, actx, tree, hf_index);
+ }
+unknown:
+ return tvb_reported_length_remaining(tvb, offset);
+}
+
#include "packet-kerberos-fn.c"
#ifdef HAVE_KERBEROS
@@ -4346,7 +5019,7 @@ dissect_kerberos_PA_ENC_TS_ENC(bool implicit_tag _U_, tvbuff_t *tvb _U_, int off
static int
dissect_kerberos_T_strengthen_key(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
- gint save_encryption_key_parent_hf_index = private_data->save_encryption_key_parent_hf_index;
+ int save_encryption_key_parent_hf_index = private_data->save_encryption_key_parent_hf_index;
kerberos_key_save_fn saved_encryption_key_fn = private_data->save_encryption_key_fn;
private_data->save_encryption_key_parent_hf_index = hf_kerberos_KrbFastResponse;
#ifdef HAVE_KERBEROS
@@ -4403,7 +5076,7 @@ static int
dissect_kerberos_KrbFastReq(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
struct _kerberos_PA_FX_FAST_REQUEST saved_stack = private_data->PA_FX_FAST_REQUEST;
- private_data->PA_FX_FAST_REQUEST = (struct _kerberos_PA_FX_FAST_REQUEST) { .defer = FALSE, };
+ private_data->PA_FX_FAST_REQUEST = (struct _kerberos_PA_FX_FAST_REQUEST) { .defer = false, };
offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
KrbFastReq_sequence, hf_index, ett_kerberos_KrbFastReq);
private_data->PA_FX_FAST_REQUEST = saved_stack;
@@ -4447,26 +5120,26 @@ dissect_kerberos_FastOptions(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offse
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);
+ 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);
+ 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);
+ 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);
+ return dissect_kerberos_Realm(false, tvb, offset, actx, tree, hf_kerberos_realm);
}
struct kerberos_display_key_state {
@@ -4475,15 +5148,15 @@ struct kerberos_display_key_state {
expert_field *expindex;
const char *name;
tvbuff_t *tvb;
- gint start;
- gint length;
+ int start;
+ int length;
};
static void
#ifdef HAVE_KERBEROS
-kerberos_display_key(gpointer data, gpointer userdata)
+kerberos_display_key(void *data, void *userdata)
#else
-kerberos_display_key(gpointer data _U_, gpointer userdata _U_)
+kerberos_display_key(void *data _U_, void *userdata _U_)
#endif
{
#ifdef HAVE_KERBEROS
@@ -4573,8 +5246,8 @@ dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
{
proto_item *item;
proto_tree *subtree;
- guint32 ServiceTicketLength;
- guint32 TicketGrantingTicketLength;
+ uint32_t ServiceTicketLength;
+ uint32_t TicketGrantingTicketLength;
int orig_offset;
if (tvb_captured_length(tvb) < 32)
@@ -4608,7 +5281,7 @@ dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
return offset;
orig_offset = offset;
- offset = dissect_kerberos_Ticket(FALSE, tvb, offset, actx, subtree,
+ offset = dissect_kerberos_Ticket(false, tvb, offset, actx, subtree,
hf_kerberos_KERB_TICKET_LOGON_ServiceTicket);
if ((unsigned)(offset-orig_offset) != ServiceTicketLength)
@@ -4617,7 +5290,7 @@ dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
if (TicketGrantingTicketLength == 0)
return offset;
- offset = dissect_kerberos_KRB_CRED(FALSE, tvb, offset, actx, subtree,
+ offset = dissect_kerberos_KRB_CRED(false, tvb, offset, actx, subtree,
hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket);
if ((unsigned)(offset-orig_offset) != ServiceTicketLength + TicketGrantingTicketLength)
@@ -4626,7 +5299,7 @@ dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
return offset;
}
-static gint
+static int
dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
bool dci, bool do_col_protocol, bool have_rm,
kerberos_callbacks *cb)
@@ -4638,8 +5311,8 @@ dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
asn1_ctx_t asn1_ctx;
/* TCP record mark and length */
- guint32 krb_rm = 0;
- gint krb_reclen = 0;
+ uint32_t krb_rm = 0;
+ int krb_reclen = 0;
gbl_do_col_info=dci;
@@ -4671,9 +5344,9 @@ dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
* If it doesn't look like kerberos, return 0 and let someone else have
* a go at it.
*/
- gint8 tmp_class;
+ int8_t tmp_class;
bool tmp_pc;
- gint32 tmp_tag;
+ int32_t tmp_tag;
get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
if(tmp_class!=BER_CLASS_APP){
@@ -4712,17 +5385,37 @@ dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
}
}
- asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
+ asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
asn1_ctx.private_data = NULL;
private_data = kerberos_get_private_data(&asn1_ctx);
private_data->callbacks = cb;
TRY {
- offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
+ offset=dissect_kerberos_Applications(false, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
} CATCH_BOUNDS_ERRORS {
RETHROW;
} ENDTRY;
+ if (private_data->frame_rep != UINT32_MAX) {
+ proto_item *tmp_item;
+
+ tmp_item = proto_tree_add_uint(kerberos_tree, hf_krb_response_in, tvb, 0, 0, private_data->frame_rep);
+ proto_item_set_generated(tmp_item);
+ }
+
+ if (private_data->frame_req != UINT32_MAX) {
+ proto_item *tmp_item;
+ nstime_t t, deltat;
+
+ tmp_item = proto_tree_add_uint(kerberos_tree, hf_krb_response_to, tvb, 0, 0, private_data->frame_req);
+ proto_item_set_generated(tmp_item);
+
+ t = pinfo->abs_ts;
+ nstime_delta(&deltat, &t, &private_data->req_time);
+ tmp_item = proto_tree_add_time(kerberos_tree, hf_krb_time, tvb, 0, 0, &deltat);
+ proto_item_set_generated(tmp_item);
+ }
+
if (kerberos_tree != NULL) {
struct kerberos_display_key_state display_state = {
.tree = kerberos_tree,
@@ -4773,9 +5466,9 @@ dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
* Display the TCP record mark.
*/
void
-show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
+show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, int start, uint32_t krb_rm)
{
- gint rec_len;
+ int rec_len;
proto_tree *rm_tree;
if (tree == NULL)
@@ -4788,19 +5481,19 @@ show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 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)
+int
+dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bool do_col_info, kerberos_callbacks *cb)
{
- return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
+ return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, false, false, cb));
}
-guint32
+uint32_t
kerberos_output_keytype(void)
{
return gbl_keytype;
}
-static gint
+static int
dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
/* Some weird kerberos implementation apparently do krb4 on the krb5 port.
@@ -4810,9 +5503,9 @@ dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
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_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
+ if(tvb_captured_length(tvb) >= 1 && tvb_get_uint8(tvb, 0)<=0x10){
if(krb4_handle){
- gboolean res;
+ bool res;
res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
return res;
@@ -4822,20 +5515,20 @@ dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
}
- return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
+ return dissect_kerberos_common(tvb, pinfo, tree, true, true, false, NULL);
}
-gint
-kerberos_rm_to_reclen(guint krb_rm)
+int
+kerberos_rm_to_reclen(unsigned krb_rm)
{
return (krb_rm & KRB_RM_RECLEN);
}
-guint
+unsigned
get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
- guint krb_rm;
- gint pdulen;
+ unsigned krb_rm;
+ int pdulen;
krb_rm = tvb_get_ntohl(tvb, offset);
pdulen = kerberos_rm_to_reclen(krb_rm);
@@ -4852,8 +5545,8 @@ kerberos_prefs_apply_cb(void) {
static int
dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
- pinfo->fragmented = TRUE;
- if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
+ pinfo->fragmented = true;
+ if (dissect_kerberos_common(tvb, pinfo, tree, true, true, true, NULL) < 0) {
/*
* The dissector failed to recognize this as a valid
* Kerberos message. Mark it as a continuation packet.
@@ -4881,6 +5574,15 @@ void proto_register_kerberos(void) {
/* List of fields */
static hf_register_info hf[] = {
+ { &hf_krb_response_to,
+ { "Response to", "kerberos.response_to", FT_FRAMENUM, BASE_NONE,
+ FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0, "This packet is a response to the packet in this frame", HFILL }},
+ { &hf_krb_response_in,
+ { "Response in", "kerberos.response_in", FT_FRAMENUM, BASE_NONE,
+ FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0, "The response to this packet is in this packet", HFILL }},
+ { &hf_krb_time,
+ { "Time from request", "kerberos.time", FT_RELATIVE_TIME, BASE_NONE,
+ NULL, 0, "Time between Request and Response for Kerberos KDC requests", HFILL }},
{ &hf_krb_rm_reserved, {
"Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
@@ -4894,8 +5596,8 @@ void proto_register_kerberos(void) {
{ "pw-salt", "kerberos.pw_salt", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL }},
{ &hf_krb_ext_error_nt_status, /* we keep kerberos.smb.nt_status for compat reasons */
- { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
- VALS(NT_errors), 0, "NT Status code", HFILL }},
+ { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX|BASE_EXT_STRING,
+ &NT_errors_ext, 0, "NT Status code", HFILL }},
{ &hf_krb_ext_error_reserved,
{ "Reserved", "kerberos.ext_error.reserved", FT_UINT32, BASE_HEX,
NULL, 0, NULL, HFILL }},
@@ -5104,6 +5806,9 @@ void proto_register_kerberos(void) {
{ &hf_krb_pac_requester_sid, {
"PAC_REQUESTER_SID", "kerberos.pac_requester_sid", FT_BYTES, BASE_NONE,
NULL, 0, "PAC_REQUESTER_SID structure", HFILL }},
+ { &hf_krb_pac_full_checksum, {
+ "PAC_FULL_CHECKSUM", "kerberos.pac_full_checksum", FT_BYTES, BASE_NONE,
+ NULL, 0, "PAC_FULL_CHECKSUM structure", HFILL }},
{ &hf_krb_pa_supported_enctypes,
{ "SupportedEnctypes", "kerberos.supported_entypes",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
@@ -5122,6 +5827,9 @@ void proto_register_kerberos(void) {
{ &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
{ "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96",
FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000010, NULL, HFILL }},
+ { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96_sk,
+ { "aes256-cts-hmac-sha1-96-sk", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96-sk",
+ FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000020, NULL, HFILL }},
{ &hf_krb_pa_supported_enctypes_fast_supported,
{ "fast-supported", "kerberos.supported_entypes.fast-supported",
FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00010000, NULL, HFILL }},
@@ -5140,6 +5848,9 @@ void proto_register_kerberos(void) {
{ &hf_krb_ad_ap_options_cbt,
{ "ChannelBindings", "kerberos.ad_ap_options.cbt",
FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00004000, NULL, HFILL }},
+ { &hf_krb_ad_ap_options_unverified_target_name,
+ { "UnverifiedTargetName", "kerberos.ad_ap_options.unverified_target_name",
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00008000, NULL, HFILL }},
{ &hf_krb_ad_target_principal,
{ "Target Principal", "kerberos.ad_target_principal",
FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
@@ -5282,7 +5993,7 @@ void proto_register_kerberos(void) {
};
/* List of subtrees */
- static gint *ett[] = {
+ static int *ett[] = {
&ett_kerberos,
&ett_krb_recordmark,
&ett_krb_pac,
@@ -5301,6 +6012,7 @@ void proto_register_kerberos(void) {
&ett_krb_pac_attributes_info,
&ett_krb_pac_attributes_info_flags,
&ett_krb_pac_requester_sid,
+ &ett_krb_pac_full_checksum,
&ett_krb_pa_supported_enctypes,
&ett_krb_ad_ap_options,
&ett_kerberos_KERB_TICKET_LOGON,
@@ -5331,6 +6043,9 @@ void proto_register_kerberos(void) {
expert_krb = expert_register_protocol(proto_kerberos);
expert_register_field_array(expert_krb, ei, array_length(ei));
+ kerberos_tap = register_tap("kerberos");
+ register_srt_table(proto_kerberos, NULL, 1, krb5stat_packet, krb5stat_init, NULL);
+
/* Register dissectors */
kerberos_handle_udp = register_dissector("kerberos.udp", dissect_kerberos_udp, proto_kerberos);
kerberos_handle_tcp = register_dissector("kerberos.tcp", dissect_kerberos_tcp, proto_kerberos);
@@ -5352,7 +6067,7 @@ void proto_register_kerberos(void) {
prefs_register_filename_preference(krb_module, "file",
"Kerberos keytab file",
"The keytab file containing all the secrets",
- &keytab_filename, FALSE);
+ &keytab_filename, false);
#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
wmem_register_callback(wmem_epan_scope(), enc_key_list_cb, NULL);
@@ -5372,13 +6087,13 @@ void proto_register_kerberos(void) {
}
static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
+ proto_tree *tree, dcerpc_info *di _U_,uint8_t *drep _U_)
{
tvbuff_t *auth_tvb;
auth_tvb = tvb_new_subset_remaining(tvb, offset);
- dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
+ dissect_kerberos_main(auth_tvb, pinfo, tree, false, NULL);
return tvb_captured_length_remaining(tvb, offset);
}