1 /* packet-kerberos.c 2 * Routines for Kerberos 3 * Wes Hardaker (c) 2000 4 * wjhardaker@ucdavis.edu 5 * Richard Sharpe (C) 2002, rsharpe@samba.org, modularized a bit more and 6 * added AP-REQ and AP-REP dissection 7 * 8 * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API. 9 * decryption of kerberos blobs if keytab is provided 10 * 11 * See RFC 1510, and various I-Ds and other documents showing additions, 12 * e.g. ones listed under sanitize_length(length, ds)13 * 14 * http://clifford.neuman.name/krb-revisions/ 15 * 16 * and 17 * 18 * https://tools.ietf.org/html/draft-ietf-krb-wg-kerberos-clarifications-07 19 * 20 * and 21 * 22 * https://tools.ietf.org/html/draft-ietf-krb-wg-kerberos-referrals-05 23 * 24 * Some structures from RFC2630 25 * 26 * Wireshark - Network traffic analyzer 27 * By Gerald Combs <gerald@wireshark.org> 28 * Copyright 1998 Gerald Combs 29 * 30 * SPDX-License-Identifier: GPL-2.0-or-later 31 */ 32 33 /* 34 * Some of the development of the Kerberos protocol decoder was sponsored by 35 * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary 36 * CableLabs' specifications. Your license and use of this protocol decoder 37 * does not mean that you are licensed to use the CableLabs' 38 * specifications. If you have questions about this protocol, contact 39 * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional 40 * information. 41 */ 42 43 #include <config.h> 44 45 #include <stdio.h> 46 47 // krb5.h needs to be included before the defines in packet-kerberos.h 48 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) 49 #ifdef _WIN32 50 /* prevent redefinition warnings in krb5's win-mac.h */ 51 #define SSIZE_T_DEFINED 52 #endif /* _WIN32 */ 53 #include <krb5.h> 54 #endif 55 56 #include <epan/packet.h> 57 #include <epan/exceptions.h> 58 #include <epan/strutil.h> 59 #include <epan/conversation.h> 60 #include <epan/asn1.h> 61 #include <epan/expert.h> 62 #include <epan/prefs.h> 63 #include <wsutil/wsgcrypt.h> 64 #include <wsutil/file_util.h> 65 #include <wsutil/str_util.h> 66 #include <wsutil/pint.h> 67 #include "packet-kerberos.h" 68 #include "packet-netbios.h" 69 #include "packet-tcp.h" 70 #include "packet-ber.h" 71 #include "packet-pkinit.h" 72 #include "packet-cms.h" 73 #include "packet-windows-common.h" 74 75 #include "read_keytab_file.h" 76 77 #include "packet-dcerpc-netlogon.h" 78 #include "packet-dcerpc.h" 79 80 #include "packet-gssapi.h" 81 #include "packet-x509af.h" 82 83 #define KEY_USAGE_FAST_REQ_CHKSUM 50 84 #define KEY_USAGE_FAST_ENC 51 85 #define KEY_USAGE_FAST_REP 52 86 #define KEY_USAGE_FAST_FINISHED 53 87 #define KEY_USAGE_ENC_CHALLENGE_CLIENT 54 88 #define KEY_USAGE_ENC_CHALLENGE_KDC 55 89 90 void proto_register_kerberos(void); 91 void proto_reg_handoff_kerberos(void); 92 93 #define UDP_PORT_KERBEROS 88 94 #define TCP_PORT_KERBEROS 88 95 96 #define ADDRESS_STR_BUFSIZ 256 97 98 typedef struct kerberos_key { 99 guint32 keytype; 100 int keylength; 101 const guint8 *keyvalue; 102 } kerberos_key_t; 103 104 typedef void (*kerberos_key_save_fn)(tvbuff_t *tvb _U_, int offset _U_, int length _U_, 105 asn1_ctx_t *actx _U_, proto_tree *tree _U_, 106 int parent_hf_index _U_, 107 int hf_index _U_); 108 109 typedef struct { 110 guint32 msg_type; 111 gboolean is_win2k_pkinit; 112 guint32 errorcode; 113 gboolean try_nt_status; 114 guint32 etype; 115 guint32 padata_type; 116 guint32 is_enc_padata; 117 guint32 enctype; 118 kerberos_key_t key; 119 proto_tree *key_tree; 120 proto_item *key_hidden_item; 121 tvbuff_t *key_tvb; 122 kerberos_callbacks *callbacks; 123 guint32 ad_type; 124 guint32 addr_type; 125 guint32 checksum_type; 126 #ifdef HAVE_KERBEROS 127 enc_key_t *last_decryption_key; 128 enc_key_t *last_added_key; 129 tvbuff_t *last_ticket_enc_part_tvb; 130 #endif 131 gint save_encryption_key_parent_hf_index; 132 kerberos_key_save_fn save_encryption_key_fn; 133 guint learnt_key_ids; 134 guint missing_key_ids; 135 wmem_list_t *decryption_keys; 136 wmem_list_t *learnt_keys; 137 wmem_list_t *missing_keys; 138 guint32 within_PA_TGS_REQ; 139 #ifdef HAVE_KERBEROS 140 enc_key_t *PA_TGS_REQ_key; 141 enc_key_t *PA_TGS_REQ_subkey; 142 #endif 143 guint32 fast_type; 144 guint32 fast_armor_within_armor_value; 145 #ifdef HAVE_KERBEROS 146 enc_key_t *PA_FAST_ARMOR_AP_key; 147 enc_key_t *PA_FAST_ARMOR_AP_subkey; 148 enc_key_t *fast_armor_key; 149 enc_key_t *fast_strengthen_key; 150 #endif 151 } kerberos_private_data_t; 152 153 static dissector_handle_t kerberos_handle_udp; 154 155 /* Forward declarations */ 156 static int dissect_kerberos_Applications(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 157 static int dissect_kerberos_AuthorizationData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 158 static int dissect_kerberos_PA_ENC_TIMESTAMP(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 159 #ifdef HAVE_KERBEROS 160 static int dissect_kerberos_PA_ENC_TS_ENC(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 161 #endif 162 static int dissect_kerberos_PA_PAC_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 163 static int dissect_kerberos_PA_S4U2Self(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 164 static int dissect_kerberos_PA_S4U_X509_USER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 165 static int dissect_kerberos_ETYPE_INFO(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 166 static int dissect_kerberos_ETYPE_INFO2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 167 static int dissect_kerberos_AD_IF_RELEVANT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 168 static int dissect_kerberos_PA_AUTHENTICATION_SET_ELEM(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 169 static int dissect_kerberos_PA_FX_FAST_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 170 static int dissect_kerberos_EncryptedChallenge(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 171 static int dissect_kerberos_PA_KERB_KEY_LIST_REQ(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 172 static int dissect_kerberos_PA_KERB_KEY_LIST_REP(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 173 static int dissect_kerberos_PA_FX_FAST_REPLY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 174 static int dissect_kerberos_PA_PAC_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 175 static int dissect_kerberos_KERB_AD_RESTRICTION_ENTRY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 176 static int dissect_kerberos_SEQUENCE_OF_ENCTYPE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 177 static int dissect_kerberos_PA_SPAKE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 178 #ifdef HAVE_KERBEROS 179 static int dissect_kerberos_KrbFastReq(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 180 static int dissect_kerberos_KrbFastResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 181 static int dissect_kerberos_FastOptions(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); 182 #endif 183 184 /* Desegment Kerberos over TCP messages */ 185 static gboolean krb_desegment = TRUE; 186 187 static gint proto_kerberos = -1; 188 189 static gint hf_krb_rm_reserved = -1; 190 static gint hf_krb_rm_reclen = -1; 191 static gint hf_krb_provsrv_location = -1; 192 static gint hf_krb_pw_salt = -1; 193 static gint hf_krb_ext_error_nt_status = -1; 194 static gint hf_krb_ext_error_reserved = -1; 195 static gint hf_krb_ext_error_flags = -1; 196 static gint hf_krb_address_ip = -1; 197 static gint hf_krb_address_netbios = -1; 198 static gint hf_krb_address_ipv6 = -1; 199 static gint hf_krb_gssapi_len = -1; 200 static gint hf_krb_gssapi_bnd = -1; 201 static gint hf_krb_gssapi_dlgopt = -1; 202 static gint hf_krb_gssapi_dlglen = -1; 203 static gint hf_krb_gssapi_c_flag_deleg = -1; 204 static gint hf_krb_gssapi_c_flag_mutual = -1; 205 static gint hf_krb_gssapi_c_flag_replay = -1; 206 static gint hf_krb_gssapi_c_flag_sequence = -1; 207 static gint hf_krb_gssapi_c_flag_conf = -1; 208 static gint hf_krb_gssapi_c_flag_integ = -1; 209 static gint hf_krb_gssapi_c_flag_dce_style = -1; 210 static gint hf_krb_midl_version = -1; 211 static gint hf_krb_midl_hdr_len = -1; 212 static gint hf_krb_midl_fill_bytes = -1; 213 static gint hf_krb_midl_blob_len = -1; 214 static gint hf_krb_pac_signature_type = -1; 215 static gint hf_krb_pac_signature_signature = -1; 216 static gint hf_krb_w2k_pac_entries = -1; 217 static gint hf_krb_w2k_pac_version = -1; 218 static gint hf_krb_w2k_pac_type = -1; 219 static gint hf_krb_w2k_pac_size = -1; 220 static gint hf_krb_w2k_pac_offset = -1; 221 static gint hf_krb_pac_clientid = -1; 222 static gint hf_krb_pac_namelen = -1; 223 static gint hf_krb_pac_clientname = -1; 224 static gint hf_krb_pac_logon_info = -1; 225 static gint hf_krb_pac_credential_data = -1; 226 static gint hf_krb_pac_credential_info = -1; 227 static gint hf_krb_pac_credential_info_version = -1; 228 static gint hf_krb_pac_credential_info_etype = -1; 229 static gint hf_krb_pac_s4u_delegation_info = -1; 230 static gint hf_krb_pac_upn_dns_info = -1; 231 static gint hf_krb_pac_upn_flags = -1; 232 static gint hf_krb_pac_upn_dns_offset = -1; 233 static gint hf_krb_pac_upn_dns_len = -1; 234 static gint hf_krb_pac_upn_upn_offset = -1; 235 static gint hf_krb_pac_upn_upn_len = -1; 236 static gint hf_krb_pac_upn_upn_name = -1; 237 static gint hf_krb_pac_upn_dns_name = -1; 238 static gint hf_krb_pac_server_checksum = -1; 239 static gint hf_krb_pac_privsvr_checksum = -1; 240 static gint hf_krb_pac_client_info_type = -1; 241 static gint hf_krb_pac_client_claims_info = -1; 242 static gint hf_krb_pac_device_info = -1; 243 static gint hf_krb_pac_device_claims_info = -1; 244 static gint hf_krb_pac_ticket_checksum = -1; 245 static gint hf_krb_pa_supported_enctypes = -1; 246 static gint hf_krb_pa_supported_enctypes_des_cbc_crc = -1; 247 static gint hf_krb_pa_supported_enctypes_des_cbc_md5 = -1; 248 static gint hf_krb_pa_supported_enctypes_rc4_hmac = -1; 249 static gint hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96 = -1; 250 static gint hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96 = -1; 251 static gint hf_krb_pa_supported_enctypes_fast_supported = -1; 252 static gint hf_krb_pa_supported_enctypes_compound_identity_supported = -1; 253 static gint hf_krb_pa_supported_enctypes_claims_supported = -1; 254 static gint hf_krb_pa_supported_enctypes_resource_sid_compression_disabled = -1; 255 static gint hf_krb_ad_ap_options = -1; 256 static gint hf_krb_ad_ap_options_cbt = -1; 257 static gint hf_krb_ad_target_principal = -1; 258 static gint hf_krb_key_hidden_item = -1; 259 static gint hf_kerberos_KERB_TICKET_LOGON = -1; 260 static gint hf_kerberos_KERB_TICKET_LOGON_MessageType = -1; 261 static gint hf_kerberos_KERB_TICKET_LOGON_Flags = -1; 262 static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength = -1; 263 static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength = -1; 264 static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicket = -1; 265 static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket = -1; 266 static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET = -1; 267 static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED = -1; 268 #ifdef HAVE_KERBEROS 269 static gint hf_kerberos_KrbFastResponse = -1; 270 static gint hf_kerberos_strengthen_key = -1; 271 static gint hf_kerberos_finished = -1; 272 static gint hf_kerberos_fast_options = -1; 273 static gint hf_kerberos_ticket_checksum = -1; 274 static gint hf_krb_patimestamp = -1; 275 static gint hf_krb_pausec = -1; 276 static gint hf_kerberos_FastOptions_reserved = -1; 277 static gint hf_kerberos_FastOptions_hide_client_names = -1; 278 static gint hf_kerberos_FastOptions_spare_bit2 = -1; 279 static gint hf_kerberos_FastOptions_spare_bit3 = -1; 280 static gint hf_kerberos_FastOptions_spare_bit4 = -1; 281 static gint hf_kerberos_FastOptions_spare_bit5 = -1; 282 static gint hf_kerberos_FastOptions_spare_bit6 = -1; 283 static gint hf_kerberos_FastOptions_spare_bit7 = -1; 284 static gint hf_kerberos_FastOptions_spare_bit8 = -1; 285 static gint hf_kerberos_FastOptions_spare_bit9 = -1; 286 static gint hf_kerberos_FastOptions_spare_bit10 = -1; 287 static gint hf_kerberos_FastOptions_spare_bit11 = -1; 288 static gint hf_kerberos_FastOptions_spare_bit12 = -1; 289 static gint hf_kerberos_FastOptions_spare_bit13 = -1; 290 static gint hf_kerberos_FastOptions_spare_bit14 = -1; 291 static gint hf_kerberos_FastOptions_spare_bit15 = -1; 292 static gint hf_kerberos_FastOptions_kdc_follow_referrals = -1; 293 294 #endif 295 #include "packet-kerberos-hf.c" 296 297 /* Initialize the subtree pointers */ 298 static gint ett_kerberos = -1; 299 static gint ett_krb_recordmark = -1; 300 static gint ett_krb_pac = -1; 301 static gint ett_krb_pac_drep = -1; 302 static gint ett_krb_pac_midl_blob = -1; 303 static gint ett_krb_pac_logon_info = -1; 304 static gint ett_krb_pac_credential_info = -1; 305 static gint ett_krb_pac_s4u_delegation_info = -1; 306 static gint ett_krb_pac_upn_dns_info = -1; 307 static gint ett_krb_pac_device_info = -1; 308 static gint ett_krb_pac_server_checksum = -1; 309 static gint ett_krb_pac_privsvr_checksum = -1; 310 static gint ett_krb_pac_client_info_type = -1; 311 static gint ett_krb_pac_ticket_checksum = -1; 312 static gint ett_krb_pa_supported_enctypes = -1; 313 static gint ett_krb_ad_ap_options = -1; 314 static gint ett_kerberos_KERB_TICKET_LOGON = -1; 315 #ifdef HAVE_KERBEROS 316 static gint ett_krb_pa_enc_ts_enc = -1; 317 static gint ett_kerberos_KrbFastFinished = -1; 318 static gint ett_kerberos_KrbFastResponse = -1; 319 static gint ett_kerberos_KrbFastReq = -1; 320 static gint ett_kerberos_FastOptions = -1; 321 #endif 322 #include "packet-kerberos-ett.c" 323 324 static expert_field ei_kerberos_missing_keytype = EI_INIT; 325 static expert_field ei_kerberos_decrypted_keytype = EI_INIT; 326 static expert_field ei_kerberos_learnt_keytype = EI_INIT; 327 static expert_field ei_kerberos_address = EI_INIT; 328 static expert_field ei_krb_gssapi_dlglen = EI_INIT; 329 330 static dissector_handle_t krb4_handle=NULL; 331 332 /* Global variables */ 333 static guint32 gbl_keytype; 334 static gboolean gbl_do_col_info; 335 336 #include "packet-kerberos-val.h" 337 338 static void 339 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb) 340 { 341 if(!cb){ 342 return; 343 } 344 345 while(cb->tag){ 346 if(cb->tag==tag){ 347 cb->callback(pinfo, tvb, tree); 348 return; 349 } 350 cb++; 351 } 352 return; 353 } 354 355 static kerberos_private_data_t* 356 kerberos_new_private_data(packet_info *pinfo) 357 { 358 kerberos_private_data_t *p; 359 360 p = wmem_new0(pinfo->pool, kerberos_private_data_t); 361 if (p == NULL) { 362 return NULL; 363 } 364 365 p->decryption_keys = wmem_list_new(pinfo->pool); 366 p->learnt_keys = wmem_list_new(pinfo->pool); 367 p->missing_keys = wmem_list_new(pinfo->pool); 368 369 return p; 370 } 371 372 static kerberos_private_data_t* 373 kerberos_get_private_data(asn1_ctx_t *actx) 374 { 375 if (!actx->private_data) { 376 actx->private_data = kerberos_new_private_data(actx->pinfo); 377 } 378 return (kerberos_private_data_t *)(actx->private_data); 379 } 380 381 static gboolean 382 kerberos_private_is_kdc_req(kerberos_private_data_t *private_data) 383 { 384 switch (private_data->msg_type) { 385 case KERBEROS_APPLICATIONS_AS_REQ: 386 case KERBEROS_APPLICATIONS_TGS_REQ: 387 return TRUE; 388 } 389 390 return FALSE; 391 } 392 393 gboolean 394 kerberos_is_win2k_pkinit(asn1_ctx_t *actx) 395 { 396 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 397 398 return private_data->is_win2k_pkinit; 399 } 400 401 #ifdef HAVE_KERBEROS 402 403 /* Decrypt Kerberos blobs */ 404 gboolean krb_decrypt = FALSE; 405 406 /* keytab filename */ 407 static const char *keytab_filename = ""; 408 409 void 410 read_keytab_file_from_preferences(void) 411 { 412 static char *last_keytab = NULL; 413 414 if (!krb_decrypt) { 415 return; 416 } 417 418 if (keytab_filename == NULL) { 419 return; 420 } 421 422 if (last_keytab && !strcmp(last_keytab, keytab_filename)) { 423 return; 424 } 425 426 g_free(last_keytab); 427 last_keytab = g_strdup(keytab_filename); 428 429 read_keytab_file(last_keytab); 430 } 431 #endif /* HAVE_KERBEROS */ 432 433 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) 434 enc_key_t *enc_key_list=NULL; 435 static guint kerberos_longterm_ids = 0; 436 wmem_map_t *kerberos_longterm_keys = NULL; 437 static wmem_map_t *kerberos_all_keys = NULL; 438 static wmem_map_t *kerberos_app_session_keys = NULL; 439 440 static gboolean 441 enc_key_list_cb(wmem_allocator_t* allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_) 442 { 443 enc_key_list = NULL; 444 kerberos_longterm_ids = 0; 445 /* keep the callback registered */ 446 return TRUE; 447 } 448 449 static gint enc_key_cmp_id(gconstpointer k1, gconstpointer k2) 450 { 451 const enc_key_t *key1 = (const enc_key_t *)k1; 452 const enc_key_t *key2 = (const enc_key_t *)k2; 453 454 if (key1->fd_num < key2->fd_num) { 455 return -1; 456 } 457 if (key1->fd_num > key2->fd_num) { 458 return 1; 459 } 460 461 if (key1->id < key2->id) { 462 return -1; 463 } 464 if (key1->id > key2->id) { 465 return 1; 466 } 467 468 return 0; 469 } 470 471 static gboolean 472 enc_key_content_equal(gconstpointer k1, gconstpointer k2) 473 { 474 const enc_key_t *key1 = (const enc_key_t *)k1; 475 const enc_key_t *key2 = (const enc_key_t *)k2; 476 int cmp; 477 478 if (key1->keytype != key2->keytype) { 479 return FALSE; 480 } 481 482 if (key1->keylength != key2->keylength) { 483 return FALSE; 484 } 485 486 cmp = memcmp(key1->keyvalue, key2->keyvalue, key1->keylength); 487 if (cmp != 0) { 488 return FALSE; 489 } 490 491 return TRUE; 492 } 493 494 static guint 495 enc_key_content_hash(gconstpointer k) 496 { 497 const enc_key_t *key = (const enc_key_t *)k; 498 guint ret = 0; 499 500 ret += wmem_strong_hash((const guint8 *)&key->keytype, 501 sizeof(key->keytype)); 502 ret += wmem_strong_hash((const guint8 *)&key->keylength, 503 sizeof(key->keylength)); 504 ret += wmem_strong_hash((const guint8 *)key->keyvalue, 505 key->keylength); 506 507 return ret; 508 } 509 510 static void 511 kerberos_key_map_insert(wmem_map_t *key_map, enc_key_t *new_key) 512 { 513 enc_key_t *existing = NULL; 514 enc_key_t *cur = NULL; 515 gint cmp; 516 517 existing = (enc_key_t *)wmem_map_lookup(key_map, new_key); 518 if (existing == NULL) { 519 wmem_map_insert(key_map, new_key, new_key); 520 return; 521 } 522 523 if (key_map != kerberos_all_keys) { 524 /* 525 * It should already be linked to the existing key... 526 */ 527 return; 528 } 529 530 if (existing->fd_num == -1 && new_key->fd_num != -1) { 531 /* 532 * We can't reference a learnt key 533 * from a longterm key. As they have 534 * a shorter lifetime. 535 * 536 * So just let the learnt key remember the 537 * match. 538 */ 539 new_key->same_list = existing; 540 new_key->num_same = existing->num_same + 1; 541 return; 542 } 543 544 /* 545 * If a key with the same content (keytype,keylength,keyvalue) 546 * already exists, we want the earliest key to be 547 * in the list. 548 */ 549 cmp = enc_key_cmp_id(new_key, existing); 550 if (cmp == 0) { 551 /* 552 * It's the same, nothing to do... 553 */ 554 return; 555 } 556 if (cmp < 0) { 557 /* The new key has should be added to the list. */ 558 new_key->same_list = existing; 559 new_key->num_same = existing->num_same + 1; 560 wmem_map_insert(key_map, new_key, new_key); 561 return; 562 } 563 564 /* 565 * We want to link the new_key to the existing one. 566 * 567 * But we want keep the list sorted, so we need to forward 568 * to the correct spot. 569 */ 570 for (cur = existing; cur->same_list != NULL; cur = cur->same_list) { 571 cmp = enc_key_cmp_id(new_key, cur->same_list); 572 if (cmp == 0) { 573 /* 574 * It's the same, nothing to do... 575 */ 576 return; 577 } 578 579 if (cmp < 0) { 580 /* 581 * We found the correct spot, 582 * the new_key should added 583 * between existing and existing->same_list 584 */ 585 new_key->same_list = cur->same_list; 586 new_key->num_same = cur->num_same; 587 break; 588 } 589 } 590 591 /* 592 * finally link new_key to existing 593 * and fix up the numbers 594 */ 595 cur->same_list = new_key; 596 for (cur = existing; cur != new_key; cur = cur->same_list) { 597 cur->num_same += 1; 598 } 599 600 return; 601 } 602 603 struct insert_longterm_keys_into_key_map_state { 604 wmem_map_t *key_map; 605 }; 606 607 static void insert_longterm_keys_into_key_map_cb(gpointer __key _U_, 608 gpointer value, 609 gpointer user_data) 610 { 611 struct insert_longterm_keys_into_key_map_state *state = 612 (struct insert_longterm_keys_into_key_map_state *)user_data; 613 enc_key_t *key = (enc_key_t *)value; 614 615 kerberos_key_map_insert(state->key_map, key); 616 } 617 618 static void insert_longterm_keys_into_key_map(wmem_map_t *key_map) 619 { 620 /* 621 * Because the kerberos_longterm_keys are allocated on 622 * wmem_epan_scope() and kerberos_all_keys are allocated 623 * on wmem_file_scope(), we need to plug the longterm keys 624 * back to kerberos_all_keys if a new file was loaded 625 * and wmem_file_scope() got cleared. 626 */ 627 if (wmem_map_size(key_map) < wmem_map_size(kerberos_longterm_keys)) { 628 struct insert_longterm_keys_into_key_map_state state = { 629 .key_map = key_map, 630 }; 631 /* 632 * Reference all longterm keys into kerberos_all_keys 633 */ 634 wmem_map_foreach(kerberos_longterm_keys, 635 insert_longterm_keys_into_key_map_cb, 636 &state); 637 } 638 } 639 640 static void 641 kerberos_key_list_append(wmem_list_t *key_list, enc_key_t *new_key) 642 { 643 enc_key_t *existing = NULL; 644 645 existing = (enc_key_t *)wmem_list_find(key_list, new_key); 646 if (existing != NULL) { 647 return; 648 } 649 650 wmem_list_append(key_list, new_key); 651 } 652 653 static void 654 add_encryption_key(packet_info *pinfo, 655 kerberos_private_data_t *private_data, 656 proto_tree *key_tree, 657 proto_item *key_hidden_item, 658 tvbuff_t *key_tvb, 659 int keytype, int keylength, const char *keyvalue, 660 const char *origin, 661 enc_key_t *src1, enc_key_t *src2) 662 { 663 wmem_allocator_t *key_scope = NULL; 664 enc_key_t *new_key = NULL; 665 const char *methodl = "learnt"; 666 const char *methodu = "Learnt"; 667 proto_item *item = NULL; 668 669 private_data->last_added_key = NULL; 670 671 if (src1 != NULL && src2 != NULL) { 672 methodl = "derived"; 673 methodu = "Derived"; 674 } 675 676 if(pinfo->fd->visited){ 677 /* 678 * We already processed this, 679 * we can use a shortterm scope 680 */ 681 key_scope = pinfo->pool; 682 } else { 683 /* 684 * As long as we have enc_key_list, we need to 685 * use wmem_epan_scope(), when that's gone 686 * we can dynamically select the scope based on 687 * how long we'll need the particular key. 688 */ 689 key_scope = wmem_epan_scope(); 690 } 691 692 new_key = wmem_new0(key_scope, enc_key_t); 693 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s %s in frame %u", 694 methodl, origin, pinfo->num); 695 new_key->fd_num = pinfo->num; 696 new_key->id = ++private_data->learnt_key_ids; 697 g_snprintf(new_key->id_str, KRB_MAX_ID_STR_LEN, "%d.%u", 698 new_key->fd_num, new_key->id); 699 new_key->keytype=keytype; 700 new_key->keylength=keylength; 701 memcpy(new_key->keyvalue, keyvalue, MIN(keylength, KRB_MAX_KEY_LENGTH)); 702 new_key->src1 = src1; 703 new_key->src2 = src2; 704 705 if(!pinfo->fd->visited){ 706 /* 707 * Only keep it if we don't processed it before. 708 */ 709 new_key->next=enc_key_list; 710 enc_key_list=new_key; 711 insert_longterm_keys_into_key_map(kerberos_all_keys); 712 kerberos_key_map_insert(kerberos_all_keys, new_key); 713 } 714 715 item = proto_tree_add_expert_format(key_tree, pinfo, &ei_kerberos_learnt_keytype, 716 key_tvb, 0, keylength, 717 "%s %s keytype %d (id=%d.%u) (%02x%02x%02x%02x...)", 718 methodu, origin, keytype, pinfo->num, new_key->id, 719 keyvalue[0] & 0xFF, keyvalue[1] & 0xFF, 720 keyvalue[2] & 0xFF, keyvalue[3] & 0xFF); 721 if (item != NULL && key_hidden_item != NULL) { 722 proto_tree_move_item(key_tree, key_hidden_item, item); 723 } 724 if (src1 != NULL) { 725 enc_key_t *sek = src1; 726 expert_add_info_format(pinfo, item, &ei_kerberos_learnt_keytype, 727 "SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 728 sek->key_origin, sek->keytype, 729 sek->id_str, sek->num_same, 730 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 731 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 732 } 733 if (src2 != NULL) { 734 enc_key_t *sek = src2; 735 expert_add_info_format(pinfo, item, &ei_kerberos_learnt_keytype, 736 "SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 737 sek->key_origin, sek->keytype, 738 sek->id_str, sek->num_same, 739 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 740 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 741 } 742 743 kerberos_key_list_append(private_data->learnt_keys, new_key); 744 private_data->last_added_key = new_key; 745 } 746 747 static void 748 save_encryption_key(tvbuff_t *tvb _U_, int offset _U_, int length _U_, 749 asn1_ctx_t *actx _U_, proto_tree *tree _U_, 750 int parent_hf_index _U_, 751 int hf_index _U_) 752 { 753 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 754 const char *parent = proto_registrar_get_name(parent_hf_index); 755 const char *element = proto_registrar_get_name(hf_index); 756 char origin[KRB_MAX_ORIG_LEN] = { 0, }; 757 758 g_snprintf(origin, KRB_MAX_ORIG_LEN, "%s_%s", parent, element); 759 760 add_encryption_key(actx->pinfo, 761 private_data, 762 private_data->key_tree, 763 private_data->key_hidden_item, 764 private_data->key_tvb, 765 private_data->key.keytype, 766 private_data->key.keylength, 767 private_data->key.keyvalue, 768 origin, 769 NULL, 770 NULL); 771 } 772 773 static void 774 save_Authenticator_subkey(tvbuff_t *tvb, int offset, int length, 775 asn1_ctx_t *actx, proto_tree *tree, 776 int parent_hf_index, 777 int hf_index) 778 { 779 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 780 781 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 782 783 if (private_data->last_decryption_key == NULL) { 784 return; 785 } 786 if (private_data->last_added_key == NULL) { 787 return; 788 } 789 790 if (private_data->within_PA_TGS_REQ != 0) { 791 private_data->PA_TGS_REQ_key = private_data->last_decryption_key; 792 private_data->PA_TGS_REQ_subkey = private_data->last_added_key; 793 } 794 if (private_data->fast_armor_within_armor_value != 0) { 795 private_data->PA_FAST_ARMOR_AP_key = private_data->last_decryption_key; 796 private_data->PA_FAST_ARMOR_AP_subkey = private_data->last_added_key; 797 } 798 } 799 800 static void 801 save_EncAPRepPart_subkey(tvbuff_t *tvb, int offset, int length, 802 asn1_ctx_t *actx, proto_tree *tree, 803 int parent_hf_index, 804 int hf_index) 805 { 806 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 807 808 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 809 810 if (actx->pinfo->fd->visited) { 811 return; 812 } 813 814 if (private_data->last_added_key == NULL) { 815 return; 816 } 817 818 kerberos_key_map_insert(kerberos_app_session_keys, private_data->last_added_key); 819 } 820 821 static void 822 save_EncKDCRepPart_key(tvbuff_t *tvb, int offset, int length, 823 asn1_ctx_t *actx, proto_tree *tree, 824 int parent_hf_index, 825 int hf_index) 826 { 827 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 828 } 829 830 static void 831 save_EncTicketPart_key(tvbuff_t *tvb, int offset, int length, 832 asn1_ctx_t *actx, proto_tree *tree, 833 int parent_hf_index, 834 int hf_index) 835 { 836 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 837 } 838 839 static void 840 save_KrbCredInfo_key(tvbuff_t *tvb, int offset, int length, 841 asn1_ctx_t *actx, proto_tree *tree, 842 int parent_hf_index, 843 int hf_index) 844 { 845 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 846 } 847 848 static void 849 save_KrbFastResponse_strengthen_key(tvbuff_t *tvb, int offset, int length, 850 asn1_ctx_t *actx, proto_tree *tree, 851 int parent_hf_index, 852 int hf_index) 853 { 854 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 855 856 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 857 858 private_data->fast_strengthen_key = private_data->last_added_key; 859 } 860 861 static void used_encryption_key(proto_tree *tree, packet_info *pinfo, 862 kerberos_private_data_t *private_data, 863 enc_key_t *ek, int usage, tvbuff_t *cryptotvb, 864 const char *keymap_name, 865 guint keymap_size, 866 guint decryption_count) 867 { 868 proto_item *item = NULL; 869 enc_key_t *sek = NULL; 870 871 item = proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype, 872 cryptotvb, 0, 0, 873 "Decrypted keytype %d usage %d " 874 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)", 875 ek->keytype, usage, ek->key_origin, ek->id_str, ek->num_same, 876 ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF, 877 ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF); 878 expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype, 879 "Used keymap=%s num_keys=%u num_tries=%u)", 880 keymap_name, 881 keymap_size, 882 decryption_count); 883 if (ek->src1 != NULL) { 884 sek = ek->src1; 885 expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype, 886 "SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 887 sek->key_origin, sek->keytype, 888 sek->id_str, sek->num_same, 889 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 890 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 891 } 892 if (ek->src2 != NULL) { 893 sek = ek->src2; 894 expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype, 895 "SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 896 sek->key_origin, sek->keytype, 897 sek->id_str, sek->num_same, 898 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 899 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 900 } 901 sek = ek->same_list; 902 while (sek != NULL) { 903 expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype, 904 "Decrypted keytype %d usage %d " 905 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)", 906 sek->keytype, usage, sek->key_origin, sek->id_str, sek->num_same, 907 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 908 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 909 sek = sek->same_list; 910 } 911 kerberos_key_list_append(private_data->decryption_keys, ek); 912 private_data->last_decryption_key = ek; 913 } 914 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */ 915 916 #ifdef HAVE_MIT_KERBEROS 917 918 static void missing_encryption_key(proto_tree *tree, packet_info *pinfo, 919 kerberos_private_data_t *private_data, 920 int keytype, int usage, tvbuff_t *cryptotvb, 921 const char *keymap_name, 922 guint keymap_size, 923 guint decryption_count) 924 { 925 proto_item *item = NULL; 926 enc_key_t *mek = NULL; 927 928 mek = wmem_new0(pinfo->pool, enc_key_t); 929 g_snprintf(mek->key_origin, KRB_MAX_ORIG_LEN, 930 "keytype %d usage %d missing in frame %u", 931 keytype, usage, pinfo->num); 932 mek->fd_num = pinfo->num; 933 mek->id = ++private_data->missing_key_ids; 934 g_snprintf(mek->id_str, KRB_MAX_ID_STR_LEN, "missing.%u", 935 mek->id); 936 mek->keytype=keytype; 937 938 item = proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_missing_keytype, 939 cryptotvb, 0, 0, 940 "Missing keytype %d usage %d (id=%s)", 941 keytype, usage, mek->id_str); 942 expert_add_info_format(pinfo, item, &ei_kerberos_missing_keytype, 943 "Used keymap=%s num_keys=%u num_tries=%u)", 944 keymap_name, 945 keymap_size, 946 decryption_count); 947 948 kerberos_key_list_append(private_data->missing_keys, mek); 949 } 950 951 #ifdef HAVE_KRB5_PAC_VERIFY 952 static void used_signing_key(proto_tree *tree, packet_info *pinfo, 953 kerberos_private_data_t *private_data, 954 enc_key_t *ek, tvbuff_t *tvb, 955 krb5_cksumtype checksum, 956 const char *reason, 957 const char *keymap_name, 958 guint keymap_size, 959 guint verify_count) 960 { 961 proto_item *item = NULL; 962 enc_key_t *sek = NULL; 963 964 item = proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype, 965 tvb, 0, 0, 966 "%s checksum %d keytype %d " 967 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)", 968 reason, checksum, ek->keytype, ek->key_origin, 969 ek->id_str, ek->num_same, 970 ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF, 971 ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF); 972 expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype, 973 "Used keymap=%s num_keys=%u num_tries=%u)", 974 keymap_name, 975 keymap_size, 976 verify_count); 977 sek = ek->same_list; 978 while (sek != NULL) { 979 expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype, 980 "%s checksum %d keytype %d " 981 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)", 982 reason, checksum, sek->keytype, sek->key_origin, 983 sek->id_str, sek->num_same, 984 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 985 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 986 sek = sek->same_list; 987 } 988 kerberos_key_list_append(private_data->decryption_keys, ek); 989 } 990 991 static void missing_signing_key(proto_tree *tree, packet_info *pinfo, 992 kerberos_private_data_t *private_data, 993 tvbuff_t *tvb, 994 krb5_cksumtype checksum, 995 int keytype, 996 const char *reason, 997 const char *keymap_name, 998 guint keymap_size, 999 guint verify_count) 1000 { 1001 proto_item *item = NULL; 1002 enc_key_t *mek = NULL; 1003 1004 mek = wmem_new0(pinfo->pool, enc_key_t); 1005 g_snprintf(mek->key_origin, KRB_MAX_ORIG_LEN, 1006 "checksum %d keytype %d missing in frame %u", 1007 checksum, keytype, pinfo->num); 1008 mek->fd_num = pinfo->num; 1009 mek->id = ++private_data->missing_key_ids; 1010 g_snprintf(mek->id_str, KRB_MAX_ID_STR_LEN, "missing.%u", 1011 mek->id); 1012 mek->keytype=keytype; 1013 1014 item = proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_missing_keytype, 1015 tvb, 0, 0, 1016 "%s checksum %d keytype %d (id=%s)", 1017 reason, checksum, keytype, mek->id_str); 1018 expert_add_info_format(pinfo, item, &ei_kerberos_missing_keytype, 1019 "Used keymap=%s num_keys=%u num_tries=%u)", 1020 keymap_name, 1021 keymap_size, 1022 verify_count); 1023 1024 kerberos_key_list_append(private_data->missing_keys, mek); 1025 } 1026 1027 #endif /* HAVE_KRB5_PAC_VERIFY */ 1028 1029 static krb5_context krb5_ctx; 1030 1031 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE 1032 static void 1033 krb5_fast_key(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, 1034 enc_key_t *ek1 _U_, const char *p1 _U_, 1035 enc_key_t *ek2 _U_, const char *p2 _U_, 1036 const char *origin _U_) 1037 { 1038 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 1039 krb5_error_code ret; 1040 krb5_keyblock k1; 1041 krb5_keyblock k2; 1042 krb5_keyblock *k = NULL; 1043 1044 if (!krb_decrypt) { 1045 return; 1046 } 1047 1048 if (ek1 == NULL) { 1049 return; 1050 } 1051 1052 if (ek2 == NULL) { 1053 return; 1054 } 1055 1056 k1.magic = KV5M_KEYBLOCK; 1057 k1.enctype = ek1->keytype; 1058 k1.length = ek1->keylength; 1059 k1.contents = (guint8 *)ek1->keyvalue; 1060 1061 k2.magic = KV5M_KEYBLOCK; 1062 k2.enctype = ek2->keytype; 1063 k2.length = ek2->keylength; 1064 k2.contents = (guint8 *)ek2->keyvalue; 1065 1066 ret = krb5_c_fx_cf2_simple(krb5_ctx, &k1, p1, &k2, p2, &k); 1067 if (ret != 0) { 1068 return; 1069 } 1070 1071 add_encryption_key(actx->pinfo, 1072 private_data, 1073 tree, NULL, tvb, 1074 k->enctype, k->length, 1075 (const char *)k->contents, 1076 origin, 1077 ek1, ek2); 1078 1079 krb5_free_keyblock(krb5_ctx, k); 1080 } 1081 #else /* HAVE_KRB5_C_FX_CF2_SIMPLE */ 1082 static void 1083 krb5_fast_key(asn1_ctx_t *actx _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, 1084 enc_key_t *ek1 _U_, const char *p1 _U_, 1085 enc_key_t *ek2 _U_, const char *p2 _U_, 1086 const char *origin _U_) 1087 { 1088 } 1089 #endif /* HAVE_KRB5_C_FX_CF2_SIMPLE */ 1090 1091 USES_APPLE_DEPRECATED_API 1092 void 1093 read_keytab_file(const char *filename) 1094 { 1095 krb5_keytab keytab; 1096 krb5_error_code ret; 1097 krb5_keytab_entry key; 1098 krb5_kt_cursor cursor; 1099 static gboolean first_time=TRUE; 1100 1101 if (filename == NULL || filename[0] == 0) { 1102 return; 1103 } 1104 1105 if(first_time){ 1106 first_time=FALSE; 1107 ret = krb5_init_context(&krb5_ctx); 1108 if(ret && ret != KRB5_CONFIG_CANTOPEN){ 1109 return; 1110 } 1111 } 1112 1113 /* should use a file in the wireshark users dir */ 1114 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab); 1115 if(ret){ 1116 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename); 1117 1118 return; 1119 } 1120 1121 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor); 1122 if(ret){ 1123 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename); 1124 return; 1125 } 1126 1127 do{ 1128 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor); 1129 if(ret==0){ 1130 enc_key_t *new_key; 1131 int i; 1132 char *pos; 1133 1134 new_key = wmem_new0(wmem_epan_scope(), enc_key_t); 1135 new_key->fd_num = -1; 1136 new_key->id = ++kerberos_longterm_ids; 1137 g_snprintf(new_key->id_str, KRB_MAX_ID_STR_LEN, "keytab.%u", new_key->id); 1138 new_key->next = enc_key_list; 1139 1140 /* generate origin string, describing where this key came from */ 1141 pos=new_key->key_origin; 1142 pos+=MIN(KRB_MAX_ORIG_LEN, 1143 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal ")); 1144 for(i=0;i<key.principal->length;i++){ 1145 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), 1146 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data)); 1147 } 1148 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), 1149 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "@%s",key.principal->realm.data)); 1150 *pos=0; 1151 new_key->keytype=key.key.enctype; 1152 new_key->keylength=key.key.length; 1153 memcpy(new_key->keyvalue, 1154 key.key.contents, 1155 MIN(key.key.length, KRB_MAX_KEY_LENGTH)); 1156 1157 enc_key_list=new_key; 1158 ret = krb5_free_keytab_entry_contents(krb5_ctx, &key); 1159 if (ret) { 1160 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret); 1161 ret = 0; /* try to continue with the next entry */ 1162 } 1163 kerberos_key_map_insert(kerberos_longterm_keys, new_key); 1164 } 1165 }while(ret==0); 1166 1167 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor); 1168 if(ret){ 1169 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret); 1170 } 1171 ret = krb5_kt_close(krb5_ctx, keytab); 1172 if(ret){ 1173 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret); 1174 } 1175 } 1176 1177 struct decrypt_krb5_with_cb_state { 1178 proto_tree *tree; 1179 packet_info *pinfo; 1180 kerberos_private_data_t *private_data; 1181 int usage; 1182 int keytype; 1183 tvbuff_t *cryptotvb; 1184 krb5_error_code (*decrypt_cb_fn)( 1185 const krb5_keyblock *key, 1186 int usage, 1187 void *decrypt_cb_data); 1188 void *decrypt_cb_data; 1189 guint count; 1190 enc_key_t *ek; 1191 }; 1192 1193 static void 1194 decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userdata) 1195 { 1196 struct decrypt_krb5_with_cb_state *state = 1197 (struct decrypt_krb5_with_cb_state *)userdata; 1198 enc_key_t *ek = (enc_key_t *)value; 1199 krb5_error_code ret; 1200 krb5_keytab_entry key; 1201 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE 1202 enc_key_t *ak = state->private_data->fast_armor_key; 1203 enc_key_t *sk = state->private_data->fast_strengthen_key; 1204 gboolean try_with_armor_key = FALSE; 1205 gboolean try_with_strengthen_key = FALSE; 1206 #endif 1207 1208 if (state->ek != NULL) { 1209 /* 1210 * we're done. 1211 */ 1212 return; 1213 } 1214 1215 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE 1216 if (ak != NULL && ak != ek && ak->keytype == state->keytype && ek->fd_num == -1) { 1217 switch (state->usage) { 1218 case KEY_USAGE_ENC_CHALLENGE_CLIENT: 1219 case KEY_USAGE_ENC_CHALLENGE_KDC: 1220 if (ek->fd_num == -1) { 1221 /* Challenges are based on a long term key */ 1222 try_with_armor_key = TRUE; 1223 } 1224 break; 1225 } 1226 1227 /* 1228 * If we already have a strengthen_key 1229 * we don't need to try with the armor key 1230 * again 1231 */ 1232 if (sk != NULL) { 1233 try_with_armor_key = FALSE; 1234 } 1235 } 1236 1237 if (sk != NULL && sk != ek && sk->keytype == state->keytype && sk->keytype == ek->keytype) { 1238 switch (state->usage) { 1239 case 3: 1240 if (ek->fd_num == -1) { 1241 /* AS-REP is based on a long term key */ 1242 try_with_strengthen_key = TRUE; 1243 } 1244 break; 1245 case 8: 1246 case 9: 1247 if (ek->fd_num != -1) { 1248 /* TGS-REP is not based on a long term key */ 1249 try_with_strengthen_key = TRUE; 1250 } 1251 break; 1252 } 1253 } 1254 1255 if (try_with_armor_key) { 1256 krb5_keyblock k1; 1257 krb5_keyblock k2; 1258 krb5_keyblock *k = NULL; 1259 const char *p1 = NULL; 1260 1261 k1.magic = KV5M_KEYBLOCK; 1262 k1.enctype = ak->keytype; 1263 k1.length = ak->keylength; 1264 k1.contents = (guint8 *)ak->keyvalue; 1265 1266 k2.magic = KV5M_KEYBLOCK; 1267 k2.enctype = ek->keytype; 1268 k2.length = ek->keylength; 1269 k2.contents = (guint8 *)ek->keyvalue; 1270 1271 switch (state->usage) { 1272 case KEY_USAGE_ENC_CHALLENGE_CLIENT: 1273 p1 = "clientchallengearmor"; 1274 break; 1275 case KEY_USAGE_ENC_CHALLENGE_KDC: 1276 p1 = "kdcchallengearmor"; 1277 break; 1278 default: 1279 /* 1280 * Should never be called! 1281 */ 1282 /* 1283 * try the next one... 1284 */ 1285 return; 1286 } 1287 1288 ret = krb5_c_fx_cf2_simple(krb5_ctx, 1289 &k1, p1, 1290 &k2, "challengelongterm", 1291 &k); 1292 if (ret != 0) { 1293 /* 1294 * try the next one... 1295 */ 1296 return; 1297 } 1298 1299 state->count += 1; 1300 ret = state->decrypt_cb_fn(k, 1301 state->usage, 1302 state->decrypt_cb_data); 1303 if (ret == 0) { 1304 add_encryption_key(state->pinfo, 1305 state->private_data, 1306 state->tree, 1307 NULL, 1308 state->cryptotvb, 1309 k->enctype, k->length, 1310 (const char *)k->contents, 1311 p1, 1312 ak, ek); 1313 krb5_free_keyblock(krb5_ctx, k); 1314 /* 1315 * remember the key and stop traversing 1316 */ 1317 state->ek = state->private_data->last_added_key; 1318 return; 1319 } 1320 krb5_free_keyblock(krb5_ctx, k); 1321 /* 1322 * don't stop traversing... 1323 * try the next one... 1324 */ 1325 return; 1326 } 1327 1328 if (try_with_strengthen_key) { 1329 krb5_keyblock k1; 1330 krb5_keyblock k2; 1331 krb5_keyblock *k = NULL; 1332 1333 k1.magic = KV5M_KEYBLOCK; 1334 k1.enctype = sk->keytype; 1335 k1.length = sk->keylength; 1336 k1.contents = (guint8 *)sk->keyvalue; 1337 1338 k2.magic = KV5M_KEYBLOCK; 1339 k2.enctype = ek->keytype; 1340 k2.length = ek->keylength; 1341 k2.contents = (guint8 *)ek->keyvalue; 1342 1343 ret = krb5_c_fx_cf2_simple(krb5_ctx, 1344 &k1, "strengthenkey", 1345 &k2, "replykey", 1346 &k); 1347 if (ret != 0) { 1348 /* 1349 * try the next one... 1350 */ 1351 return; 1352 } 1353 1354 state->count += 1; 1355 ret = state->decrypt_cb_fn(k, 1356 state->usage, 1357 state->decrypt_cb_data); 1358 if (ret == 0) { 1359 add_encryption_key(state->pinfo, 1360 state->private_data, 1361 state->tree, 1362 NULL, 1363 state->cryptotvb, 1364 k->enctype, k->length, 1365 (const char *)k->contents, 1366 "strengthen-reply-key", 1367 sk, ek); 1368 krb5_free_keyblock(krb5_ctx, k); 1369 /* 1370 * remember the key and stop traversing 1371 */ 1372 state->ek = state->private_data->last_added_key; 1373 return; 1374 } 1375 krb5_free_keyblock(krb5_ctx, k); 1376 /* 1377 * don't stop traversing... 1378 * try the next one... 1379 */ 1380 return; 1381 } 1382 #endif /* HAVE_KRB5_C_FX_CF2_SIMPLE */ 1383 1384 /* shortcircuit and bail out if enctypes are not matching */ 1385 if ((state->keytype != -1) && (ek->keytype != state->keytype)) { 1386 /* 1387 * don't stop traversing... 1388 * try the next one... 1389 */ 1390 return; 1391 } 1392 1393 key.key.enctype=ek->keytype; 1394 key.key.length=ek->keylength; 1395 key.key.contents=ek->keyvalue; 1396 state->count += 1; 1397 ret = state->decrypt_cb_fn(&(key.key), 1398 state->usage, 1399 state->decrypt_cb_data); 1400 if (ret != 0) { 1401 /* 1402 * don't stop traversing... 1403 * try the next one... 1404 */ 1405 return; 1406 } 1407 1408 /* 1409 * we're done, remember the key 1410 */ 1411 state->ek = ek; 1412 } 1413 1414 static krb5_error_code 1415 decrypt_krb5_with_cb(proto_tree *tree, 1416 packet_info *pinfo, 1417 kerberos_private_data_t *private_data, 1418 int usage, 1419 int keytype, 1420 tvbuff_t *cryptotvb, 1421 krb5_error_code (*decrypt_cb_fn)( 1422 const krb5_keyblock *key, 1423 int usage, 1424 void *decrypt_cb_data), 1425 void *decrypt_cb_data) 1426 { 1427 const char *key_map_name = NULL; 1428 wmem_map_t *key_map = NULL; 1429 struct decrypt_krb5_with_cb_state state = { 1430 .tree = tree, 1431 .pinfo = pinfo, 1432 .private_data = private_data, 1433 .usage = usage, 1434 .cryptotvb = cryptotvb, 1435 .keytype = keytype, 1436 .decrypt_cb_fn = decrypt_cb_fn, 1437 .decrypt_cb_data = decrypt_cb_data, 1438 }; 1439 1440 read_keytab_file_from_preferences(); 1441 1442 switch (usage) { 1443 case KRB5_KU_USAGE_INITIATOR_SEAL: 1444 case KRB5_KU_USAGE_ACCEPTOR_SEAL: 1445 key_map_name = "app_session_keys"; 1446 key_map = kerberos_app_session_keys; 1447 break; 1448 default: 1449 key_map_name = "all_keys"; 1450 key_map = kerberos_all_keys; 1451 insert_longterm_keys_into_key_map(key_map); 1452 break; 1453 } 1454 1455 wmem_map_foreach(key_map, decrypt_krb5_with_cb_try_key, &state); 1456 if (state.ek != NULL) { 1457 used_encryption_key(tree, pinfo, private_data, 1458 state.ek, usage, cryptotvb, 1459 key_map_name, 1460 wmem_map_size(key_map), 1461 state.count); 1462 return 0; 1463 } 1464 1465 missing_encryption_key(tree, pinfo, private_data, 1466 keytype, usage, cryptotvb, 1467 key_map_name, 1468 wmem_map_size(key_map), 1469 state.count); 1470 return -1; 1471 } 1472 1473 struct decrypt_krb5_data_state { 1474 krb5_data input; 1475 krb5_data output; 1476 }; 1477 1478 static krb5_error_code 1479 decrypt_krb5_data_cb(const krb5_keyblock *key, 1480 int usage, 1481 void *decrypt_cb_data) 1482 { 1483 struct decrypt_krb5_data_state *state = 1484 (struct decrypt_krb5_data_state *)decrypt_cb_data; 1485 krb5_enc_data input; 1486 1487 memset(&input, 0, sizeof(input)); 1488 input.enctype = key->enctype; 1489 input.ciphertext = state->input; 1490 1491 return krb5_c_decrypt(krb5_ctx, 1492 key, 1493 usage, 1494 0, 1495 &input, 1496 &state->output); 1497 } 1498 1499 static guint8 * 1500 decrypt_krb5_data_private(proto_tree *tree _U_, packet_info *pinfo, 1501 kerberos_private_data_t *private_data, 1502 int usage, tvbuff_t *cryptotvb, int keytype, 1503 int *datalen) 1504 { 1505 #define HAVE_DECRYPT_KRB5_DATA_PRIVATE 1 1506 struct decrypt_krb5_data_state state; 1507 krb5_error_code ret; 1508 int length = tvb_captured_length(cryptotvb); 1509 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length); 1510 1511 /* don't do anything if we are not attempting to decrypt data */ 1512 if(!krb_decrypt || length < 1){ 1513 return NULL; 1514 } 1515 1516 /* make sure we have all the data we need */ 1517 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) { 1518 return NULL; 1519 } 1520 1521 memset(&state, 0, sizeof(state)); 1522 state.input.length = length; 1523 state.input.data = (guint8 *)cryptotext; 1524 state.output.data = (char *)wmem_alloc(pinfo->pool, length); 1525 state.output.length = length; 1526 1527 ret = decrypt_krb5_with_cb(tree, 1528 pinfo, 1529 private_data, 1530 usage, 1531 keytype, 1532 cryptotvb, 1533 decrypt_krb5_data_cb, 1534 &state); 1535 if (ret != 0) { 1536 return NULL; 1537 } 1538 1539 if (datalen) { 1540 *datalen = state.output.length; 1541 } 1542 return (guint8 *)state.output.data; 1543 } 1544 1545 guint8 * 1546 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo, 1547 int usage, 1548 tvbuff_t *cryptotvb, 1549 int keytype, 1550 int *datalen) 1551 { 1552 kerberos_private_data_t *zero_private = kerberos_new_private_data(pinfo); 1553 return decrypt_krb5_data_private(tree, pinfo, zero_private, 1554 usage, cryptotvb, keytype, 1555 datalen); 1556 } 1557 1558 USES_APPLE_RST 1559 1560 #ifdef KRB5_CRYPTO_TYPE_SIGN_ONLY 1561 struct decrypt_krb5_krb_cfx_dce_state { 1562 const guint8 *gssapi_header_ptr; 1563 guint gssapi_header_len; 1564 tvbuff_t *gssapi_encrypted_tvb; 1565 guint8 *gssapi_payload; 1566 guint gssapi_payload_len; 1567 const guint8 *gssapi_trailer_ptr; 1568 guint gssapi_trailer_len; 1569 tvbuff_t *checksum_tvb; 1570 guint8 *checksum; 1571 guint checksum_len; 1572 }; 1573 1574 static krb5_error_code 1575 decrypt_krb5_krb_cfx_dce_cb(const krb5_keyblock *key, 1576 int usage, 1577 void *decrypt_cb_data) 1578 { 1579 struct decrypt_krb5_krb_cfx_dce_state *state = 1580 (struct decrypt_krb5_krb_cfx_dce_state *)decrypt_cb_data; 1581 unsigned int k5_headerlen = 0; 1582 unsigned int k5_headerofs = 0; 1583 unsigned int k5_trailerlen = 0; 1584 unsigned int k5_trailerofs = 0; 1585 size_t _k5_blocksize = 0; 1586 guint k5_blocksize; 1587 krb5_crypto_iov iov[6]; 1588 krb5_error_code ret; 1589 guint checksum_remain = state->checksum_len; 1590 guint checksum_crypt_len; 1591 1592 memset(iov, 0, sizeof(iov)); 1593 1594 ret = krb5_c_crypto_length(krb5_ctx, 1595 key->enctype, 1596 KRB5_CRYPTO_TYPE_HEADER, 1597 &k5_headerlen); 1598 if (ret != 0) { 1599 return ret; 1600 } 1601 if (checksum_remain < k5_headerlen) { 1602 return -1; 1603 } 1604 checksum_remain -= k5_headerlen; 1605 k5_headerofs = checksum_remain; 1606 ret = krb5_c_crypto_length(krb5_ctx, 1607 key->enctype, 1608 KRB5_CRYPTO_TYPE_TRAILER, 1609 &k5_trailerlen); 1610 if (ret != 0) { 1611 return ret; 1612 } 1613 if (checksum_remain < k5_trailerlen) { 1614 return -1; 1615 } 1616 checksum_remain -= k5_trailerlen; 1617 k5_trailerofs = checksum_remain; 1618 checksum_crypt_len = checksum_remain; 1619 1620 ret = krb5_c_block_size(krb5_ctx, 1621 key->enctype, 1622 &_k5_blocksize); 1623 if (ret != 0) { 1624 return ret; 1625 } 1626 /* 1627 * The cast is required for the Windows build in order 1628 * to avoid the following warning. 1629 * 1630 * warning C4267: '-=': conversion from 'size_t' to 'guint', 1631 * possible loss of data 1632 */ 1633 k5_blocksize = (guint)_k5_blocksize; 1634 if (checksum_remain < k5_blocksize) { 1635 return -1; 1636 } 1637 checksum_remain -= k5_blocksize; 1638 if (checksum_remain < 16) { 1639 return -1; 1640 } 1641 1642 tvb_memcpy(state->gssapi_encrypted_tvb, 1643 state->gssapi_payload, 1644 0, 1645 state->gssapi_payload_len); 1646 tvb_memcpy(state->checksum_tvb, 1647 state->checksum, 1648 0, 1649 state->checksum_len); 1650 1651 iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; 1652 iov[0].data.data = state->checksum + k5_headerofs; 1653 iov[0].data.length = k5_headerlen; 1654 1655 if (state->gssapi_header_ptr != NULL) { 1656 iov[1].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; 1657 iov[1].data.data = (guint8 *)(guintptr)state->gssapi_header_ptr; 1658 iov[1].data.length = state->gssapi_header_len; 1659 } else { 1660 iov[1].flags = KRB5_CRYPTO_TYPE_EMPTY; 1661 } 1662 1663 iov[2].flags = KRB5_CRYPTO_TYPE_DATA; 1664 iov[2].data.data = state->gssapi_payload; 1665 iov[2].data.length = state->gssapi_payload_len; 1666 1667 if (state->gssapi_trailer_ptr != NULL) { 1668 iov[3].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; 1669 iov[3].data.data = (guint8 *)(guintptr)state->gssapi_trailer_ptr; 1670 iov[3].data.length = state->gssapi_trailer_len; 1671 } else { 1672 iov[3].flags = KRB5_CRYPTO_TYPE_EMPTY; 1673 } 1674 1675 iov[4].flags = KRB5_CRYPTO_TYPE_DATA; 1676 iov[4].data.data = state->checksum; 1677 iov[4].data.length = checksum_crypt_len; 1678 1679 iov[5].flags = KRB5_CRYPTO_TYPE_TRAILER; 1680 iov[5].data.data = state->checksum + k5_trailerofs; 1681 iov[5].data.length = k5_trailerlen; 1682 1683 return krb5_c_decrypt_iov(krb5_ctx, 1684 key, 1685 usage, 1686 0, 1687 iov, 1688 6); 1689 } 1690 1691 tvbuff_t * 1692 decrypt_krb5_krb_cfx_dce(proto_tree *tree, 1693 packet_info *pinfo, 1694 int usage, 1695 int keytype, 1696 tvbuff_t *gssapi_header_tvb, 1697 tvbuff_t *gssapi_encrypted_tvb, 1698 tvbuff_t *gssapi_trailer_tvb, 1699 tvbuff_t *checksum_tvb) 1700 { 1701 struct decrypt_krb5_krb_cfx_dce_state state; 1702 kerberos_private_data_t *zero_private = kerberos_new_private_data(pinfo); 1703 tvbuff_t *gssapi_decrypted_tvb = NULL; 1704 krb5_error_code ret; 1705 1706 /* don't do anything if we are not attempting to decrypt data */ 1707 if (!krb_decrypt) { 1708 return NULL; 1709 } 1710 1711 memset(&state, 0, sizeof(state)); 1712 1713 /* make sure we have all the data we need */ 1714 #define __CHECK_TVB_LEN(__tvb) (tvb_captured_length(__tvb) < tvb_reported_length(__tvb)) 1715 if (gssapi_header_tvb != NULL) { 1716 if (__CHECK_TVB_LEN(gssapi_header_tvb)) { 1717 return NULL; 1718 } 1719 1720 state.gssapi_header_len = tvb_captured_length(gssapi_header_tvb); 1721 state.gssapi_header_ptr = tvb_get_ptr(gssapi_header_tvb, 1722 0, 1723 state.gssapi_header_len); 1724 } 1725 if (gssapi_encrypted_tvb == NULL || __CHECK_TVB_LEN(gssapi_encrypted_tvb)) { 1726 return NULL; 1727 } 1728 state.gssapi_encrypted_tvb = gssapi_encrypted_tvb; 1729 state.gssapi_payload_len = tvb_captured_length(gssapi_encrypted_tvb); 1730 state.gssapi_payload = (guint8 *)wmem_alloc0(pinfo->pool, state.gssapi_payload_len); 1731 if (state.gssapi_payload == NULL) { 1732 return NULL; 1733 } 1734 if (gssapi_trailer_tvb != NULL) { 1735 if (__CHECK_TVB_LEN(gssapi_trailer_tvb)) { 1736 return NULL; 1737 } 1738 1739 state.gssapi_trailer_len = tvb_captured_length(gssapi_trailer_tvb); 1740 state.gssapi_trailer_ptr = tvb_get_ptr(gssapi_trailer_tvb, 1741 0, 1742 state.gssapi_trailer_len); 1743 } 1744 if (checksum_tvb == NULL || __CHECK_TVB_LEN(checksum_tvb)) { 1745 return NULL; 1746 } 1747 state.checksum_tvb = checksum_tvb; 1748 state.checksum_len = tvb_captured_length(checksum_tvb); 1749 state.checksum = (guint8 *)wmem_alloc0(pinfo->pool, state.checksum_len); 1750 if (state.checksum == NULL) { 1751 return NULL; 1752 } 1753 1754 ret = decrypt_krb5_with_cb(tree, 1755 pinfo, 1756 zero_private, 1757 usage, 1758 keytype, 1759 gssapi_encrypted_tvb, 1760 decrypt_krb5_krb_cfx_dce_cb, 1761 &state); 1762 wmem_free(pinfo->pool, state.checksum); 1763 if (ret != 0) { 1764 wmem_free(pinfo->pool, state.gssapi_payload); 1765 return NULL; 1766 } 1767 1768 gssapi_decrypted_tvb = tvb_new_child_real_data(gssapi_encrypted_tvb, 1769 state.gssapi_payload, 1770 state.gssapi_payload_len, 1771 state.gssapi_payload_len); 1772 if (gssapi_decrypted_tvb == NULL) { 1773 wmem_free(pinfo->pool, state.gssapi_payload); 1774 return NULL; 1775 } 1776 1777 return gssapi_decrypted_tvb; 1778 } 1779 #else /* NOT KRB5_CRYPTO_TYPE_SIGN_ONLY */ 1780 #define NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP 1 1781 #endif /* NOT KRB5_CRYPTO_TYPE_SIGN_ONLY */ 1782 1783 #ifdef HAVE_KRB5_PAC_VERIFY 1784 /* 1785 * macOS up to 10.14.5 only has a MIT shim layer on top 1786 * of heimdal. It means that krb5_pac_verify() is not available 1787 * in /usr/lib/libkrb5.dylib 1788 * 1789 * https://opensource.apple.com/tarballs/Heimdal/Heimdal-520.260.1.tar.gz 1790 * https://opensource.apple.com/tarballs/MITKerberosShim/MITKerberosShim-71.200.1.tar.gz 1791 */ 1792 1793 extern krb5_error_code 1794 krb5int_c_mandatory_cksumtype(krb5_context, krb5_enctype, krb5_cksumtype *); 1795 1796 extern void krb5_free_enc_tkt_part(krb5_context, krb5_enc_tkt_part *); 1797 extern krb5_error_code 1798 decode_krb5_enc_tkt_part(const krb5_data *output, krb5_enc_tkt_part **rep); 1799 extern krb5_error_code 1800 encode_krb5_enc_tkt_part(const krb5_enc_tkt_part *rep, krb5_data **code); 1801 1802 static int 1803 keytype_for_cksumtype(krb5_cksumtype checksum) 1804 { 1805 #define _ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) 1806 static const int keytypes[] = { 1807 18, 1808 17, 1809 23, 1810 }; 1811 guint i; 1812 1813 for (i = 0; i < _ARRAY_SIZE(keytypes); i++) { 1814 krb5_cksumtype checksumtype = 0; 1815 krb5_error_code ret; 1816 1817 ret = krb5int_c_mandatory_cksumtype(krb5_ctx, 1818 keytypes[i], 1819 &checksumtype); 1820 if (ret != 0) { 1821 continue; 1822 } 1823 if (checksum == checksumtype) { 1824 return keytypes[i]; 1825 } 1826 } 1827 1828 return -1; 1829 } 1830 1831 struct verify_krb5_pac_state { 1832 krb5_pac pac; 1833 krb5_cksumtype server_checksum; 1834 guint server_count; 1835 enc_key_t *server_ek; 1836 krb5_cksumtype kdc_checksum; 1837 guint kdc_count; 1838 enc_key_t *kdc_ek; 1839 krb5_cksumtype ticket_checksum_type; 1840 const krb5_data *ticket_checksum_data; 1841 }; 1842 1843 static void 1844 verify_krb5_pac_try_server_key(gpointer __key _U_, gpointer value, gpointer userdata) 1845 { 1846 struct verify_krb5_pac_state *state = 1847 (struct verify_krb5_pac_state *)userdata; 1848 enc_key_t *ek = (enc_key_t *)value; 1849 krb5_keyblock keyblock; 1850 krb5_cksumtype checksumtype = 0; 1851 krb5_error_code ret; 1852 1853 if (state->server_checksum == 0) { 1854 /* 1855 * nothing more todo, stop traversing. 1856 */ 1857 return; 1858 } 1859 1860 if (state->server_ek != NULL) { 1861 /* 1862 * we're done. 1863 */ 1864 return; 1865 } 1866 1867 ret = krb5int_c_mandatory_cksumtype(krb5_ctx, ek->keytype, 1868 &checksumtype); 1869 if (ret != 0) { 1870 /* 1871 * the key is not usable, keep traversing. 1872 * try the next key... 1873 */ 1874 return; 1875 } 1876 1877 keyblock.magic = KV5M_KEYBLOCK; 1878 keyblock.enctype = ek->keytype; 1879 keyblock.length = ek->keylength; 1880 keyblock.contents = (guint8 *)ek->keyvalue; 1881 1882 if (checksumtype == state->server_checksum) { 1883 state->server_count += 1; 1884 ret = krb5_pac_verify(krb5_ctx, state->pac, 0, NULL, 1885 &keyblock, NULL); 1886 if (ret == 0) { 1887 state->server_ek = ek; 1888 } 1889 } 1890 } 1891 1892 static void 1893 verify_krb5_pac_try_kdc_key(gpointer __key _U_, gpointer value, gpointer userdata) 1894 { 1895 struct verify_krb5_pac_state *state = 1896 (struct verify_krb5_pac_state *)userdata; 1897 enc_key_t *ek = (enc_key_t *)value; 1898 krb5_keyblock keyblock; 1899 krb5_cksumtype checksumtype = 0; 1900 krb5_error_code ret; 1901 1902 if (state->kdc_checksum == 0) { 1903 /* 1904 * nothing more todo, stop traversing. 1905 */ 1906 return; 1907 } 1908 1909 if (state->kdc_ek != NULL) { 1910 /* 1911 * we're done. 1912 */ 1913 return; 1914 } 1915 1916 ret = krb5int_c_mandatory_cksumtype(krb5_ctx, ek->keytype, 1917 &checksumtype); 1918 if (ret != 0) { 1919 /* 1920 * the key is not usable, keep traversing. 1921 * try the next key... 1922 */ 1923 return; 1924 } 1925 1926 keyblock.magic = KV5M_KEYBLOCK; 1927 keyblock.enctype = ek->keytype; 1928 keyblock.length = ek->keylength; 1929 keyblock.contents = (guint8 *)ek->keyvalue; 1930 1931 if (checksumtype == state->kdc_checksum) { 1932 state->kdc_count += 1; 1933 ret = krb5_pac_verify(krb5_ctx, state->pac, 0, NULL, 1934 NULL, &keyblock); 1935 if (ret == 0) { 1936 state->kdc_ek = ek; 1937 } 1938 } 1939 } 1940 1941 #define __KRB5_PAC_TICKET_CHECKSUM 16 1942 1943 static void 1944 verify_krb5_pac_ticket_checksum(proto_tree *tree _U_, 1945 asn1_ctx_t *actx _U_, 1946 tvbuff_t *pactvb _U_, 1947 struct verify_krb5_pac_state *state _U_) 1948 { 1949 #ifdef HAVE_DECODE_KRB5_ENC_TKT_PART 1950 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 1951 tvbuff_t *teptvb = private_data->last_ticket_enc_part_tvb; 1952 guint teplength = 0; 1953 const guint8 *tepbuffer = NULL; 1954 krb5_data tepdata = { .length = 0, }; 1955 krb5_enc_tkt_part *tep = NULL; 1956 krb5_data *tmpdata = NULL; 1957 krb5_error_code ret; 1958 krb5_authdata **recoded_container = NULL; 1959 gint ad_orig_idx = -1; 1960 krb5_authdata *ad_orig_ptr = NULL; 1961 gint l0idx = 0; 1962 krb5_keyblock kdc_key = { .magic = KV5M_KEYBLOCK, }; 1963 size_t checksum_length = 0; 1964 krb5_checksum checksum = { .checksum_type = 0, }; 1965 krb5_boolean valid = FALSE; 1966 1967 if (state->kdc_ek == NULL) { 1968 int keytype = keytype_for_cksumtype(state->ticket_checksum_type); 1969 missing_signing_key(tree, actx->pinfo, private_data, 1970 pactvb, state->ticket_checksum_type, 1971 keytype, 1972 "Missing KDC (for ticket)", 1973 "kdc_checksum_key", 1974 0, 1975 0); 1976 return; 1977 } 1978 1979 if (teptvb == NULL) { 1980 return; 1981 } 1982 1983 teplength = tvb_captured_length(teptvb); 1984 /* make sure we have all the data we need */ 1985 if (teplength < tvb_reported_length(teptvb)) { 1986 return; 1987 } 1988 1989 tepbuffer = tvb_get_ptr(teptvb, 0, teplength); 1990 if (tepbuffer == NULL) { 1991 return; 1992 } 1993 1994 kdc_key.magic = KV5M_KEYBLOCK; 1995 kdc_key.enctype = state->kdc_ek->keytype; 1996 kdc_key.length = state->kdc_ek->keylength; 1997 kdc_key.contents = (guint8 *)state->kdc_ek->keyvalue; 1998 1999 checksum.checksum_type = state->ticket_checksum_type; 2000 checksum.length = state->ticket_checksum_data->length; 2001 checksum.contents = (guint8 *)state->ticket_checksum_data->data; 2002 if (checksum.length >= 4) { 2003 checksum.length -= 4; 2004 checksum.contents += 4; 2005 } 2006 2007 ret = krb5_c_checksum_length(krb5_ctx, 2008 checksum.checksum_type, 2009 &checksum_length); 2010 if (ret != 0) { 2011 missing_signing_key(tree, actx->pinfo, private_data, 2012 pactvb, state->ticket_checksum_type, 2013 state->kdc_ek->keytype, 2014 "krb5_c_checksum_length failed for Ticket Signature", 2015 "kdc_checksum_key", 2016 1, 2017 0); 2018 return; 2019 } 2020 checksum.length = MIN(checksum.length, (unsigned int)checksum_length); 2021 2022 tepdata.data = (void *)(uintptr_t)tepbuffer; 2023 tepdata.length = teplength; 2024 2025 ret = decode_krb5_enc_tkt_part(&tepdata, &tep); 2026 if (ret != 0) { 2027 missing_signing_key(tree, actx->pinfo, private_data, 2028 pactvb, state->ticket_checksum_type, 2029 state->kdc_ek->keytype, 2030 "decode_krb5_enc_tkt_part failed", 2031 "kdc_checksum_key", 2032 1, 2033 0); 2034 return; 2035 } 2036 2037 for (l0idx = 0; tep->authorization_data[l0idx]; l0idx++) { 2038 krb5_authdata *adl0 = tep->authorization_data[l0idx]; 2039 krb5_authdata **decoded_container = NULL; 2040 krb5_authdata *ad_pac = NULL; 2041 gint l1idx = 0; 2042 2043 if (adl0->ad_type != KRB5_AUTHDATA_IF_RELEVANT) { 2044 continue; 2045 } 2046 2047 ret = krb5_decode_authdata_container(krb5_ctx, 2048 KRB5_AUTHDATA_IF_RELEVANT, 2049 adl0, 2050 &decoded_container); 2051 if (ret != 0) { 2052 missing_signing_key(tree, actx->pinfo, private_data, 2053 pactvb, state->ticket_checksum_type, 2054 state->kdc_ek->keytype, 2055 "krb5_decode_authdata_container failed", 2056 "kdc_checksum_key", 2057 1, 2058 0); 2059 krb5_free_enc_tkt_part(krb5_ctx, tep); 2060 return; 2061 } 2062 2063 for (l1idx = 0; decoded_container[l1idx]; l1idx++) { 2064 krb5_authdata *adl1 = decoded_container[l1idx]; 2065 2066 if (adl1->ad_type != KRB5_AUTHDATA_WIN2K_PAC) { 2067 continue; 2068 } 2069 2070 ad_pac = adl1; 2071 break; 2072 } 2073 2074 if (ad_pac == NULL) { 2075 krb5_free_authdata(krb5_ctx, decoded_container); 2076 continue; 2077 } 2078 2079 ad_pac->length = 1; 2080 ad_pac->contents[0] = '\0'; 2081 2082 ret = krb5_encode_authdata_container(krb5_ctx, 2083 KRB5_AUTHDATA_IF_RELEVANT, 2084 decoded_container, 2085 &recoded_container); 2086 krb5_free_authdata(krb5_ctx, decoded_container); 2087 decoded_container = NULL; 2088 if (ret != 0) { 2089 missing_signing_key(tree, actx->pinfo, private_data, 2090 pactvb, state->ticket_checksum_type, 2091 state->kdc_ek->keytype, 2092 "krb5_encode_authdata_container failed", 2093 "kdc_checksum_key", 2094 1, 2095 0); 2096 krb5_free_enc_tkt_part(krb5_ctx, tep); 2097 return; 2098 } 2099 2100 ad_orig_idx = l0idx; 2101 ad_orig_ptr = adl0; 2102 tep->authorization_data[l0idx] = recoded_container[0]; 2103 break; 2104 } 2105 2106 ret = encode_krb5_enc_tkt_part(tep, &tmpdata); 2107 if (ad_orig_ptr != NULL) { 2108 tep->authorization_data[ad_orig_idx] = ad_orig_ptr; 2109 } 2110 krb5_free_enc_tkt_part(krb5_ctx, tep); 2111 tep = NULL; 2112 if (recoded_container != NULL) { 2113 krb5_free_authdata(krb5_ctx, recoded_container); 2114 recoded_container = NULL; 2115 } 2116 if (ret != 0) { 2117 missing_signing_key(tree, actx->pinfo, private_data, 2118 pactvb, state->ticket_checksum_type, 2119 state->kdc_ek->keytype, 2120 "encode_krb5_enc_tkt_part failed", 2121 "kdc_checksum_key", 2122 1, 2123 0); 2124 return; 2125 } 2126 2127 ret = krb5_c_verify_checksum(krb5_ctx, &kdc_key, 2128 KRB5_KEYUSAGE_APP_DATA_CKSUM, 2129 tmpdata, &checksum, &valid); 2130 krb5_free_data(krb5_ctx, tmpdata); 2131 tmpdata = NULL; 2132 if (ret != 0) { 2133 missing_signing_key(tree, actx->pinfo, private_data, 2134 pactvb, state->ticket_checksum_type, 2135 state->kdc_ek->keytype, 2136 "krb5_c_verify_checksum failed for Ticket Signature", 2137 "kdc_checksum_key", 2138 1, 2139 1); 2140 return; 2141 } 2142 2143 if (valid == FALSE) { 2144 missing_signing_key(tree, actx->pinfo, private_data, 2145 pactvb, state->ticket_checksum_type, 2146 state->kdc_ek->keytype, 2147 "Invalid Ticket", 2148 "kdc_checksum_key", 2149 1, 2150 1); 2151 return; 2152 } 2153 2154 used_signing_key(tree, actx->pinfo, private_data, 2155 state->kdc_ek, pactvb, 2156 state->ticket_checksum_type, 2157 "Verified Ticket", 2158 "kdc_checksum_key", 2159 1, 2160 1); 2161 #endif /* HAVE_DECODE_KRB5_ENC_TKT_PART */ 2162 } 2163 2164 static void 2165 verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb) 2166 { 2167 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 2168 krb5_error_code ret; 2169 krb5_data checksum_data = {0,0,NULL}; 2170 krb5_data ticket_checksum_data = {0,0,NULL}; 2171 int length = tvb_captured_length(pactvb); 2172 const guint8 *pacbuffer = NULL; 2173 struct verify_krb5_pac_state state = { 2174 .kdc_checksum = 0, 2175 }; 2176 2177 /* don't do anything if we are not attempting to decrypt data */ 2178 if(!krb_decrypt || length < 1){ 2179 return; 2180 } 2181 2182 /* make sure we have all the data we need */ 2183 if (tvb_captured_length(pactvb) < tvb_reported_length(pactvb)) { 2184 return; 2185 } 2186 2187 pacbuffer = tvb_get_ptr(pactvb, 0, length); 2188 2189 ret = krb5_pac_parse(krb5_ctx, pacbuffer, length, &state.pac); 2190 if (ret != 0) { 2191 proto_tree_add_expert_format(tree, actx->pinfo, &ei_kerberos_decrypted_keytype, 2192 pactvb, 0, 0, 2193 "Failed to parse PAC buffer %d in frame %u", 2194 ret, actx->pinfo->fd->num); 2195 return; 2196 } 2197 2198 ret = krb5_pac_get_buffer(krb5_ctx, state.pac, KRB5_PAC_SERVER_CHECKSUM, 2199 &checksum_data); 2200 if (ret == 0) { 2201 state.server_checksum = pletoh32(checksum_data.data); 2202 krb5_free_data_contents(krb5_ctx, &checksum_data); 2203 }; 2204 ret = krb5_pac_get_buffer(krb5_ctx, state.pac, KRB5_PAC_PRIVSVR_CHECKSUM, 2205 &checksum_data); 2206 if (ret == 0) { 2207 state.kdc_checksum = pletoh32(checksum_data.data); 2208 krb5_free_data_contents(krb5_ctx, &checksum_data); 2209 }; 2210 ret = krb5_pac_get_buffer(krb5_ctx, state.pac, 2211 __KRB5_PAC_TICKET_CHECKSUM, 2212 &ticket_checksum_data); 2213 if (ret == 0) { 2214 state.ticket_checksum_data = &ticket_checksum_data; 2215 state.ticket_checksum_type = pletoh32(ticket_checksum_data.data); 2216 }; 2217 2218 read_keytab_file_from_preferences(); 2219 2220 wmem_map_foreach(kerberos_all_keys, 2221 verify_krb5_pac_try_server_key, 2222 &state); 2223 if (state.server_ek != NULL) { 2224 used_signing_key(tree, actx->pinfo, private_data, 2225 state.server_ek, pactvb, 2226 state.server_checksum, "Verified Server", 2227 "all_keys", 2228 wmem_map_size(kerberos_all_keys), 2229 state.server_count); 2230 } else { 2231 int keytype = keytype_for_cksumtype(state.server_checksum); 2232 missing_signing_key(tree, actx->pinfo, private_data, 2233 pactvb, state.server_checksum, keytype, 2234 "Missing Server", 2235 "all_keys", 2236 wmem_map_size(kerberos_all_keys), 2237 state.server_count); 2238 } 2239 wmem_map_foreach(kerberos_longterm_keys, 2240 verify_krb5_pac_try_kdc_key, 2241 &state); 2242 if (state.kdc_ek != NULL) { 2243 used_signing_key(tree, actx->pinfo, private_data, 2244 state.kdc_ek, pactvb, 2245 state.kdc_checksum, "Verified KDC", 2246 "longterm_keys", 2247 wmem_map_size(kerberos_longterm_keys), 2248 state.kdc_count); 2249 } else { 2250 int keytype = keytype_for_cksumtype(state.kdc_checksum); 2251 missing_signing_key(tree, actx->pinfo, private_data, 2252 pactvb, state.kdc_checksum, keytype, 2253 "Missing KDC", 2254 "longterm_keys", 2255 wmem_map_size(kerberos_longterm_keys), 2256 state.kdc_count); 2257 } 2258 2259 if (state.ticket_checksum_type != 0) { 2260 verify_krb5_pac_ticket_checksum(tree, actx, pactvb, &state); 2261 } 2262 2263 if (state.ticket_checksum_data != NULL) { 2264 krb5_free_data_contents(krb5_ctx, &ticket_checksum_data); 2265 } 2266 2267 krb5_pac_free(krb5_ctx, state.pac); 2268 } 2269 #endif /* HAVE_KRB5_PAC_VERIFY */ 2270 2271 #elif defined(HAVE_HEIMDAL_KERBEROS) 2272 static krb5_context krb5_ctx; 2273 2274 USES_APPLE_DEPRECATED_API 2275 2276 static void 2277 krb5_fast_key(asn1_ctx_t *actx _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, 2278 enc_key_t *ek1 _U_, const char *p1 _U_, 2279 enc_key_t *ek2 _U_, const char *p2 _U_, 2280 const char *origin _U_) 2281 { 2282 /* TODO: use krb5_crypto_fx_cf2() from Heimdal */ 2283 } 2284 void 2285 read_keytab_file(const char *filename) 2286 { 2287 krb5_keytab keytab; 2288 krb5_error_code ret; 2289 krb5_keytab_entry key; 2290 krb5_kt_cursor cursor; 2291 enc_key_t *new_key; 2292 static gboolean first_time=TRUE; 2293 2294 if (filename == NULL || filename[0] == 0) { 2295 return; 2296 } 2297 2298 if(first_time){ 2299 first_time=FALSE; 2300 ret = krb5_init_context(&krb5_ctx); 2301 if(ret){ 2302 return; 2303 } 2304 } 2305 2306 /* should use a file in the wireshark users dir */ 2307 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab); 2308 if(ret){ 2309 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename); 2310 2311 return; 2312 } 2313 2314 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor); 2315 if(ret){ 2316 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename); 2317 return; 2318 } 2319 2320 do{ 2321 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor); 2322 if(ret==0){ 2323 unsigned int i; 2324 char *pos; 2325 2326 new_key = wmem_new0(wmem_epan_scope(), enc_key_t); 2327 new_key->fd_num = -1; 2328 new_key->id = ++kerberos_longterm_ids; 2329 g_snprintf(new_key->id_str, KRB_MAX_ID_STR_LEN, "keytab.%u", new_key->id); 2330 new_key->next = enc_key_list; 2331 2332 /* generate origin string, describing where this key came from */ 2333 pos=new_key->key_origin; 2334 pos+=MIN(KRB_MAX_ORIG_LEN, 2335 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal ")); 2336 for(i=0;i<key.principal->name.name_string.len;i++){ 2337 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), 2338 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i])); 2339 } 2340 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), 2341 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm)); 2342 *pos=0; 2343 new_key->keytype=key.keyblock.keytype; 2344 new_key->keylength=(int)key.keyblock.keyvalue.length; 2345 memcpy(new_key->keyvalue, 2346 key.keyblock.keyvalue.data, 2347 MIN((guint)key.keyblock.keyvalue.length, KRB_MAX_KEY_LENGTH)); 2348 2349 enc_key_list=new_key; 2350 ret = krb5_kt_free_entry(krb5_ctx, &key); 2351 if (ret) { 2352 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret); 2353 ret = 0; /* try to continue with the next entry */ 2354 } 2355 kerberos_key_map_insert(kerberos_longterm_keys, new_key); 2356 } 2357 }while(ret==0); 2358 2359 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor); 2360 if(ret){ 2361 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret); 2362 } 2363 ret = krb5_kt_close(krb5_ctx, keytab); 2364 if(ret){ 2365 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret); 2366 } 2367 2368 } 2369 USES_APPLE_RST 2370 2371 2372 guint8 * 2373 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo, 2374 int usage, 2375 tvbuff_t *cryptotvb, 2376 int keytype, 2377 int *datalen) 2378 { 2379 kerberos_private_data_t *zero_private = kerberos_new_private_data(pinfo); 2380 krb5_error_code ret; 2381 krb5_data data; 2382 enc_key_t *ek; 2383 int length = tvb_captured_length(cryptotvb); 2384 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length); 2385 2386 /* don't do anything if we are not attempting to decrypt data */ 2387 if(!krb_decrypt){ 2388 return NULL; 2389 } 2390 2391 /* make sure we have all the data we need */ 2392 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) { 2393 return NULL; 2394 } 2395 2396 read_keytab_file_from_preferences(); 2397 2398 for(ek=enc_key_list;ek;ek=ek->next){ 2399 krb5_keytab_entry key; 2400 krb5_crypto crypto; 2401 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */ 2402 2403 /* shortcircuit and bail out if enctypes are not matching */ 2404 if((keytype != -1) && (ek->keytype != keytype)) { 2405 continue; 2406 } 2407 2408 key.keyblock.keytype=ek->keytype; 2409 key.keyblock.keyvalue.length=ek->keylength; 2410 key.keyblock.keyvalue.data=ek->keyvalue; 2411 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto); 2412 if(ret){ 2413 return NULL; 2414 } 2415 2416 /* pre-0.6.1 versions of Heimdal would sometimes change 2417 the cryptotext data even when the decryption failed. 2418 This would obviously not work since we iterate over the 2419 keys. So just give it a copy of the crypto data instead. 2420 This has been seen for RC4-HMAC blobs. 2421 */ 2422 cryptocopy = (guint8 *)wmem_memdup(pinfo->pool, cryptotext, length); 2423 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage, 2424 cryptocopy, length, 2425 &data, 2426 NULL); 2427 if((ret == 0) && (length>0)){ 2428 char *user_data; 2429 2430 used_encryption_key(tree, pinfo, zero_private, 2431 ek, usage, cryptotvb, 2432 "enc_key_list", 0, 0); 2433 2434 krb5_crypto_destroy(krb5_ctx, crypto); 2435 /* return a private wmem_alloced blob to the caller */ 2436 user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length); 2437 if (datalen) { 2438 *datalen = (int)data.length; 2439 } 2440 return user_data; 2441 } 2442 krb5_crypto_destroy(krb5_ctx, crypto); 2443 } 2444 return NULL; 2445 } 2446 2447 #define NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP 1 2448 2449 #elif defined (HAVE_LIBNETTLE) 2450 2451 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2) 2452 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */ 2453 2454 typedef struct _service_key_t { 2455 guint16 kvno; 2456 int keytype; 2457 int length; 2458 guint8 *contents; 2459 char origin[KRB_MAX_ORIG_LEN+1]; 2460 } service_key_t; 2461 GSList *service_key_list = NULL; 2462 2463 2464 static void 2465 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin) 2466 { 2467 service_key_t *new_key; 2468 2469 if(pinfo->fd->visited){ 2470 return; 2471 } 2472 2473 new_key = g_malloc(sizeof(service_key_t)); 2474 new_key->kvno = 0; 2475 new_key->keytype = keytype; 2476 new_key->length = keylength; 2477 new_key->contents = g_memdup2(keyvalue, keylength); 2478 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num); 2479 service_key_list = g_slist_append(service_key_list, (gpointer) new_key); 2480 } 2481 2482 static void 2483 save_encryption_key(tvbuff_t *tvb _U_, int offset _U_, int length _U_, 2484 asn1_ctx_t *actx _U_, proto_tree *tree _U_, 2485 int parent_hf_index _U_, 2486 int hf_index _U_) 2487 { 2488 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 2489 const char *parent = proto_registrar_get_name(parent_hf_index); 2490 const char *element = proto_registrar_get_name(hf_index); 2491 char origin[KRB_MAX_ORIG_LEN] = { 0, }; 2492 2493 g_snprintf(origin, KRB_MAX_ORIG_LEN, "%s_%s", parent, element); 2494 2495 add_encryption_key(actx->pinfo, 2496 private_data->key.keytype, 2497 private_data->key.keylength, 2498 private_data->key.keyvalue, 2499 origin); 2500 } 2501 2502 static void 2503 save_Authenticator_subkey(tvbuff_t *tvb, int offset, int length, 2504 asn1_ctx_t *actx, proto_tree *tree, 2505 int parent_hf_index, 2506 int hf_index) 2507 { 2508 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 2509 } 2510 2511 static void 2512 save_EncAPRepPart_subkey(tvbuff_t *tvb, int offset, int length, 2513 asn1_ctx_t *actx, proto_tree *tree, 2514 int parent_hf_index, 2515 int hf_index) 2516 { 2517 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 2518 } 2519 2520 static void 2521 save_EncKDCRepPart_key(tvbuff_t *tvb, int offset, int length, 2522 asn1_ctx_t *actx, proto_tree *tree, 2523 int parent_hf_index, 2524 int hf_index) 2525 { 2526 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 2527 } 2528 2529 static void 2530 save_EncTicketPart_key(tvbuff_t *tvb, int offset, int length, 2531 asn1_ctx_t *actx, proto_tree *tree, 2532 int parent_hf_index, 2533 int hf_index) 2534 { 2535 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 2536 } 2537 2538 static void 2539 save_KrbCredInfo_key(tvbuff_t *tvb, int offset, int length, 2540 asn1_ctx_t *actx, proto_tree *tree, 2541 int parent_hf_index, 2542 int hf_index) 2543 { 2544 save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index); 2545 } 2546 2547 static void 2548 save_KrbFastResponse_strengthen_key(tvbuff_t *tvb _U_, int offset _U_, int length _U_, 2549 asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) 2550 { 2551 save_encryption_key(tvb, offset, length, actx, tree, hf_index); 2552 } 2553 2554 static void 2555 clear_keytab(void) { 2556 GSList *ske; 2557 service_key_t *sk; 2558 2559 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){ 2560 sk = (service_key_t *) ske->data; 2561 if (sk) { 2562 g_free(sk->contents); 2563 g_free(sk); 2564 } 2565 } 2566 g_slist_free(service_key_list); 2567 service_key_list = NULL; 2568 } 2569 2570 static void 2571 read_keytab_file(const char *service_key_file) 2572 { 2573 FILE *skf; 2574 ws_statb64 st; 2575 service_key_t *sk; 2576 unsigned char buf[SERVICE_KEY_SIZE]; 2577 int newline_skip = 0, count = 0; 2578 2579 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) { 2580 2581 /* The service key file contains raw 192-bit (24 byte) 3DES keys. 2582 * There can be zero, one (\n), or two (\r\n) characters between 2583 * keys. Trailing characters are ignored. 2584 */ 2585 2586 /* XXX We should support the standard keytab format instead */ 2587 if (st.st_size > SERVICE_KEY_SIZE) { 2588 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) || 2589 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) { 2590 newline_skip = 1; 2591 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) || 2592 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) { 2593 newline_skip = 2; 2594 } 2595 } 2596 2597 skf = ws_fopen(service_key_file, "rb"); 2598 if (! skf) return; 2599 2600 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) { 2601 sk = g_malloc(sizeof(service_key_t)); 2602 sk->kvno = buf[0] << 8 | buf[1]; 2603 sk->keytype = KEYTYPE_DES3_CBC_MD5; 2604 sk->length = DES3_KEY_SIZE; 2605 sk->contents = g_memdup2(buf + 2, DES3_KEY_SIZE); 2606 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf)); 2607 service_key_list = g_slist_append(service_key_list, (gpointer) sk); 2608 if (fseek(skf, newline_skip, SEEK_CUR) < 0) { 2609 fprintf(stderr, "unable to seek...\n"); 2610 fclose(skf); 2611 return; 2612 } 2613 count++; 2614 } 2615 fclose(skf); 2616 } 2617 } 2618 2619 #define CONFOUNDER_PLUS_CHECKSUM 24 2620 2621 guint8 * 2622 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo, 2623 int _U_ usage, 2624 tvbuff_t *cryptotvb, 2625 int keytype, 2626 int *datalen) 2627 { 2628 tvbuff_t *encr_tvb; 2629 guint8 *decrypted_data = NULL, *plaintext = NULL; 2630 guint8 cls; 2631 gboolean pc; 2632 guint32 tag, item_len, data_len; 2633 int id_offset, offset; 2634 guint8 key[DES3_KEY_SIZE]; 2635 guint8 initial_vector[DES_BLOCK_SIZE]; 2636 gcry_md_hd_t md5_handle; 2637 guint8 *digest; 2638 guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2639 guint8 confounder[8]; 2640 gboolean ind; 2641 GSList *ske; 2642 service_key_t *sk; 2643 struct des3_ctx ctx; 2644 int length = tvb_captured_length(cryptotvb); 2645 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length); 2646 2647 2648 /* don't do anything if we are not attempting to decrypt data */ 2649 if(!krb_decrypt){ 2650 return NULL; 2651 } 2652 2653 /* make sure we have all the data we need */ 2654 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) { 2655 return NULL; 2656 } 2657 2658 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) { 2659 return NULL; 2660 } 2661 2662 decrypted_data = wmem_alloc(pinfo->pool, length); 2663 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){ 2664 gboolean do_continue = FALSE; 2665 gboolean digest_ok; 2666 sk = (service_key_t *) ske->data; 2667 2668 des_fix_parity(DES3_KEY_SIZE, key, sk->contents); 2669 2670 memset(initial_vector, 0, DES_BLOCK_SIZE); 2671 des3_set_key(&ctx, key); 2672 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector, 2673 length, decrypted_data, cryptotext); 2674 encr_tvb = tvb_new_real_data(decrypted_data, length, length); 2675 2676 tvb_memcpy(encr_tvb, confounder, 0, 8); 2677 2678 /* We have to pull the decrypted data length from the decrypted 2679 * content. If the key doesn't match or we otherwise get garbage, 2680 * an exception may get thrown while decoding the ASN.1 header. 2681 * Catch it, just in case. 2682 */ 2683 TRY { 2684 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag); 2685 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind); 2686 } 2687 CATCH_BOUNDS_ERRORS { 2688 tvb_free(encr_tvb); 2689 do_continue = TRUE; 2690 } 2691 ENDTRY; 2692 2693 if (do_continue) continue; 2694 2695 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM; 2696 if ((int) item_len + offset > length) { 2697 tvb_free(encr_tvb); 2698 continue; 2699 } 2700 2701 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { 2702 return NULL; 2703 } 2704 gcry_md_write(md5_handle, confounder, 8); 2705 gcry_md_write(md5_handle, zero_fill, 16); 2706 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len); 2707 digest = gcry_md_read(md5_handle, 0); 2708 2709 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0); 2710 gcry_md_close(md5_handle); 2711 if (digest_ok) { 2712 plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len); 2713 tvb_free(encr_tvb); 2714 2715 if (datalen) { 2716 *datalen = data_len; 2717 } 2718 return(plaintext); 2719 } 2720 tvb_free(encr_tvb); 2721 } 2722 2723 return NULL; 2724 } 2725 2726 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */ 2727 2728 #ifdef NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP 2729 tvbuff_t * 2730 decrypt_krb5_krb_cfx_dce(proto_tree *tree _U_, 2731 packet_info *pinfo _U_, 2732 int usage _U_, 2733 int keytype _U_, 2734 tvbuff_t *gssapi_header_tvb _U_, 2735 tvbuff_t *gssapi_encrypted_tvb _U_, 2736 tvbuff_t *gssapi_trailer_tvb _U_, 2737 tvbuff_t *checksum_tvb _U_) 2738 { 2739 return NULL; 2740 } 2741 #endif /* NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP */ 2742 2743 #define INET6_ADDRLEN 16 2744 2745 /* TCP Record Mark */ 2746 #define KRB_RM_RESERVED 0x80000000U 2747 #define KRB_RM_RECLEN 0x7fffffffU 2748 2749 #define KRB5_MSG_TICKET 1 /* Ticket */ 2750 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */ 2751 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */ 2752 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */ 2753 #define KRB5_MSG_AS_REP 11 /* AS-REP type */ 2754 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */ 2755 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */ 2756 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */ 2757 #define KRB5_MSG_AP_REP 15 /* AP-REP type */ 2758 #define KRB5_MSG_TGT_REQ 16 /* TGT-REQ type */ 2759 #define KRB5_MSG_TGT_REP 17 /* TGT-REP type */ 2760 2761 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */ 2762 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */ 2763 #define KRB5_MSG_CRED 22 /* KRB-CRED type */ 2764 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */ 2765 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */ 2766 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */ 2767 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */ 2768 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */ 2769 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */ 2770 2771 #define KRB5_CHKSUM_GSSAPI 0x8003 2772 /* 2773 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see 2774 * 2775 * https://tools.ietf.org/html/draft-brezak-win2k-krb-rc4-hmac-04 2776 * 2777 * unless it's expired. 2778 */ 2779 2780 /* Principal name-type */ 2781 #define KRB5_NT_UNKNOWN 0 2782 #define KRB5_NT_PRINCIPAL 1 2783 #define KRB5_NT_SRV_INST 2 2784 #define KRB5_NT_SRV_HST 3 2785 #define KRB5_NT_SRV_XHST 4 2786 #define KRB5_NT_UID 5 2787 #define KRB5_NT_X500_PRINCIPAL 6 2788 #define KRB5_NT_SMTP_NAME 7 2789 #define KRB5_NT_ENTERPRISE 10 2790 2791 /* 2792 * MS specific name types, from 2793 * 2794 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp 2795 */ 2796 #define KRB5_NT_MS_PRINCIPAL -128 2797 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129 2798 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130 2799 #define KRB5_NT_PRINCIPAL_AND_SID -131 2800 #define KRB5_NT_SRV_INST_AND_SID -132 2801 2802 /* error table constants */ 2803 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */ 2804 #define KRB5_ET_KRB5KDC_ERR_NONE 0 2805 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1 2806 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2 2807 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3 2808 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4 2809 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5 2810 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6 2811 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7 2812 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8 2813 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9 2814 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10 2815 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11 2816 #define KRB5_ET_KRB5KDC_ERR_POLICY 12 2817 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13 2818 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14 2819 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15 2820 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16 2821 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17 2822 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18 2823 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19 2824 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20 2825 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21 2826 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22 2827 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23 2828 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24 2829 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25 2830 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26 2831 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27 2832 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28 2833 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29 2834 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31 2835 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32 2836 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33 2837 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34 2838 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35 2839 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36 2840 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37 2841 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38 2842 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39 2843 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40 2844 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41 2845 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42 2846 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43 2847 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44 2848 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45 2849 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46 2850 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47 2851 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48 2852 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49 2853 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50 2854 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51 2855 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52 2856 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60 2857 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61 2858 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62 2859 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63 2860 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64 2861 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65 2862 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66 2863 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67 2864 #define KRB5_ET_KDC_ERR_WRONG_REALM 68 2865 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69 2866 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70 2867 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71 2868 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72 2869 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73 2870 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74 2871 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75 2872 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76 2873 #define KRB5_ET_KDC_ERR_PREAUTH_EXPIRED 90 2874 #define KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED 91 2875 #define KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET 92 2876 #define KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS 93 2877 2878 static const value_string krb5_error_codes[] = { 2879 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" }, 2880 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" }, 2881 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" }, 2882 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" }, 2883 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" }, 2884 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" }, 2885 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" }, 2886 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" }, 2887 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" }, 2888 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" }, 2889 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" }, 2890 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" }, 2891 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" }, 2892 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" }, 2893 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" }, 2894 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" }, 2895 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" }, 2896 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" }, 2897 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" }, 2898 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" }, 2899 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" }, 2900 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" }, 2901 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" }, 2902 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" }, 2903 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" }, 2904 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" }, 2905 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" }, 2906 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" }, 2907 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" }, 2908 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" }, 2909 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" }, 2910 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" }, 2911 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" }, 2912 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" }, 2913 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" }, 2914 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" }, 2915 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" }, 2916 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" }, 2917 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" }, 2918 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" }, 2919 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" }, 2920 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" }, 2921 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" }, 2922 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" }, 2923 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" }, 2924 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" }, 2925 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" }, 2926 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" }, 2927 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" }, 2928 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" }, 2929 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" }, 2930 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"}, 2931 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" }, 2932 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" }, 2933 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" }, 2934 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" }, 2935 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" }, 2936 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" }, 2937 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" }, 2938 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" }, 2939 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" }, 2940 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" }, 2941 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" }, 2942 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" }, 2943 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" }, 2944 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" }, 2945 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" }, 2946 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" }, 2947 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" }, 2948 { KRB5_ET_KDC_ERR_PREAUTH_EXPIRED, "KDC_ERR_PREAUTH_EXPIRED" }, 2949 { KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, "KDC_ERR_MORE_PREAUTH_DATA_REQUIRED" }, 2950 { KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET, "KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET" }, 2951 { KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, "KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS" }, 2952 { 0, NULL } 2953 }; 2954 2955 2956 #define PAC_LOGON_INFO 1 2957 #define PAC_CREDENTIAL_TYPE 2 2958 #define PAC_SERVER_CHECKSUM 6 2959 #define PAC_PRIVSVR_CHECKSUM 7 2960 #define PAC_CLIENT_INFO_TYPE 10 2961 #define PAC_S4U_DELEGATION_INFO 11 2962 #define PAC_UPN_DNS_INFO 12 2963 #define PAC_CLIENT_CLAIMS_INFO 13 2964 #define PAC_DEVICE_INFO 14 2965 #define PAC_DEVICE_CLAIMS_INFO 15 2966 #define PAC_TICKET_CHECKSUM 16 2967 static const value_string w2k_pac_types[] = { 2968 { PAC_LOGON_INFO , "Logon Info" }, 2969 { PAC_CREDENTIAL_TYPE , "Credential Type" }, 2970 { PAC_SERVER_CHECKSUM , "Server Checksum" }, 2971 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" }, 2972 { PAC_CLIENT_INFO_TYPE , "Client Info Type" }, 2973 { PAC_S4U_DELEGATION_INFO , "S4U Delegation Info" }, 2974 { PAC_UPN_DNS_INFO , "UPN DNS Info" }, 2975 { PAC_CLIENT_CLAIMS_INFO , "Client Claims Info" }, 2976 { PAC_DEVICE_INFO , "Device Info" }, 2977 { PAC_DEVICE_CLAIMS_INFO , "Device Claims Info" }, 2978 { PAC_TICKET_CHECKSUM , "Ticket Checksum" }, 2979 { 0, NULL }, 2980 }; 2981 2982 static const value_string krb5_msg_types[] = { 2983 { KRB5_MSG_TICKET, "Ticket" }, 2984 { KRB5_MSG_AUTHENTICATOR, "Authenticator" }, 2985 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" }, 2986 { KRB5_MSG_TGS_REQ, "TGS-REQ" }, 2987 { KRB5_MSG_TGS_REP, "TGS-REP" }, 2988 { KRB5_MSG_AS_REQ, "AS-REQ" }, 2989 { KRB5_MSG_AS_REP, "AS-REP" }, 2990 { KRB5_MSG_AP_REQ, "AP-REQ" }, 2991 { KRB5_MSG_AP_REP, "AP-REP" }, 2992 { KRB5_MSG_TGT_REQ, "TGT-REQ" }, 2993 { KRB5_MSG_TGT_REP, "TGT-REP" }, 2994 { KRB5_MSG_SAFE, "KRB-SAFE" }, 2995 { KRB5_MSG_PRIV, "KRB-PRIV" }, 2996 { KRB5_MSG_CRED, "KRB-CRED" }, 2997 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" }, 2998 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" }, 2999 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" }, 3000 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" }, 3001 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" }, 3002 { KRB5_MSG_ERROR, "KRB-ERROR" }, 3003 { 0, NULL }, 3004 }; 3005 3006 #define KRB5_GSS_C_DELEG_FLAG 0x01 3007 #define KRB5_GSS_C_MUTUAL_FLAG 0x02 3008 #define KRB5_GSS_C_REPLAY_FLAG 0x04 3009 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08 3010 #define KRB5_GSS_C_CONF_FLAG 0x10 3011 #define KRB5_GSS_C_INTEG_FLAG 0x20 3012 #define KRB5_GSS_C_DCE_STYLE 0x1000 3013 3014 static const true_false_string tfs_gss_flags_deleg = { 3015 "Delegate credentials to remote peer", 3016 "Do NOT delegate" 3017 }; 3018 static const true_false_string tfs_gss_flags_mutual = { 3019 "Request that remote peer authenticates itself", 3020 "Mutual authentication NOT required" 3021 }; 3022 static const true_false_string tfs_gss_flags_replay = { 3023 "Enable replay protection for signed or sealed messages", 3024 "Do NOT enable replay protection" 3025 }; 3026 static const true_false_string tfs_gss_flags_sequence = { 3027 "Enable Out-of-sequence detection for sign or sealed messages", 3028 "Do NOT enable out-of-sequence detection" 3029 }; 3030 static const true_false_string tfs_gss_flags_conf = { 3031 "Confidentiality (sealing) may be invoked", 3032 "Do NOT use Confidentiality (sealing)" 3033 }; 3034 static const true_false_string tfs_gss_flags_integ = { 3035 "Integrity protection (signing) may be invoked", 3036 "Do NOT use integrity protection" 3037 }; 3038 3039 static const true_false_string tfs_gss_flags_dce_style = { 3040 "DCE-STYLE", 3041 "Not using DCE-STYLE" 3042 }; 3043 3044 #ifdef HAVE_KERBEROS 3045 static guint8 * 3046 decrypt_krb5_data_asn1(proto_tree *tree, asn1_ctx_t *actx, 3047 int usage, tvbuff_t *cryptotvb, int *datalen) 3048 { 3049 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3050 3051 #ifdef HAVE_DECRYPT_KRB5_DATA_PRIVATE 3052 return decrypt_krb5_data_private(tree, actx->pinfo, private_data, 3053 usage, cryptotvb, 3054 private_data->etype, 3055 datalen); 3056 #else 3057 return decrypt_krb5_data(tree, actx->pinfo, usage, cryptotvb, 3058 private_data->etype, datalen); 3059 #endif 3060 } 3061 3062 static int 3063 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3064 proto_tree *tree, int hf_index _U_) 3065 { 3066 guint8 *plaintext; 3067 int length; 3068 tvbuff_t *next_tvb; 3069 3070 next_tvb=tvb_new_subset_remaining(tvb, offset); 3071 length=tvb_captured_length_remaining(tvb, offset); 3072 3073 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt : 3074 * 7.5.1 3075 * All Ticket encrypted parts use usage == 2 3076 */ 3077 plaintext=decrypt_krb5_data_asn1(tree, actx, 2, next_tvb, &length); 3078 3079 if(plaintext){ 3080 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3081 tvbuff_t *last_ticket_enc_part_tvb = private_data->last_ticket_enc_part_tvb; 3082 tvbuff_t *child_tvb; 3083 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3084 3085 /* Add the decrypted data to the data source list. */ 3086 add_new_data_source(actx->pinfo, child_tvb, "Krb5 Ticket"); 3087 3088 private_data->last_ticket_enc_part_tvb = child_tvb; 3089 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3090 private_data->last_ticket_enc_part_tvb = last_ticket_enc_part_tvb; 3091 } 3092 return offset; 3093 } 3094 3095 static int 3096 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3097 proto_tree *tree, int hf_index _U_) 3098 { 3099 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3100 guint8 *plaintext; 3101 int length; 3102 tvbuff_t *next_tvb; 3103 3104 next_tvb=tvb_new_subset_remaining(tvb, offset); 3105 length=tvb_captured_length_remaining(tvb, offset); 3106 3107 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt : 3108 * 7.5.1 3109 * Authenticators are encrypted with usage 3110 * == 7 or 3111 * == 11 3112 * 3113 * 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator 3114 * (includes TGS authenticator subkey), encrypted with the 3115 * TGS session key (section 5.5.1) 3116 * 11. AP-REQ Authenticator (includes application 3117 * authenticator subkey), encrypted with the application 3118 * session key (section 5.5.1) 3119 */ 3120 if (private_data->within_PA_TGS_REQ > 0) { 3121 plaintext=decrypt_krb5_data_asn1(tree, actx, 7, next_tvb, &length); 3122 } else { 3123 plaintext=decrypt_krb5_data_asn1(tree, actx, 11, next_tvb, &length); 3124 } 3125 3126 if(plaintext){ 3127 tvbuff_t *child_tvb; 3128 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3129 3130 /* Add the decrypted data to the data source list. */ 3131 add_new_data_source(actx->pinfo, child_tvb, "Krb5 Authenticator"); 3132 3133 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3134 } 3135 return offset; 3136 } 3137 3138 static int 3139 dissect_krb5_decrypt_authorization_data(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3140 proto_tree *tree, int hf_index _U_) 3141 { 3142 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3143 guint8 *plaintext; 3144 int length; 3145 tvbuff_t *next_tvb; 3146 3147 next_tvb=tvb_new_subset_remaining(tvb, offset); 3148 length=tvb_captured_length_remaining(tvb, offset); 3149 3150 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt : 3151 * 7.5.1 3152 * Authenticators are encrypted with usage 3153 * == 5 or 3154 * == 4 3155 * 3156 * 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with 3157 * the TGS session key (section 5.4.1) 3158 * 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with 3159 * the TGS authenticator subkey (section 5.4.1) 3160 */ 3161 if (private_data->PA_TGS_REQ_subkey != NULL) { 3162 plaintext=decrypt_krb5_data_asn1(tree, actx, 5, next_tvb, &length); 3163 } else { 3164 plaintext=decrypt_krb5_data_asn1(tree, actx, 4, next_tvb, &length); 3165 } 3166 3167 if(plaintext){ 3168 tvbuff_t *child_tvb; 3169 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3170 3171 /* Add the decrypted data to the data source list. */ 3172 add_new_data_source(actx->pinfo, child_tvb, "Krb5 AuthorizationData"); 3173 3174 offset=dissect_kerberos_AuthorizationData(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3175 } 3176 return offset; 3177 } 3178 3179 static int 3180 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3181 proto_tree *tree, int hf_index _U_) 3182 { 3183 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3184 guint8 *plaintext = NULL; 3185 int length; 3186 tvbuff_t *next_tvb; 3187 3188 next_tvb=tvb_new_subset_remaining(tvb, offset); 3189 length=tvb_captured_length_remaining(tvb, offset); 3190 3191 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt : 3192 * 7.5.1 3193 * ASREP/TGSREP encryptedparts are encrypted with usage 3194 * == 3 or 3195 * == 8 or 3196 * == 9 3197 * 3198 * 3. AS-REP encrypted part (includes TGS session key or 3199 * application session key), encrypted with the client key 3200 * (section 5.4.2) 3201 * 3202 * 8. TGS-REP encrypted part (includes application session 3203 * key), encrypted with the TGS session key (section 3204 * 5.4.2) 3205 * 9. TGS-REP encrypted part (includes application session 3206 * key), encrypted with the TGS authenticator subkey 3207 * (section 5.4.2) 3208 * 3209 * We currently don't have a way to find the TGS-REQ state 3210 * in order to check if an authenticator subkey was used. 3211 * 3212 * But if we client used FAST and we got a strengthen_key, 3213 * we're sure an authenticator subkey was used. 3214 * 3215 * Windows don't use an authenticator subkey without FAST, 3216 * but heimdal does. 3217 * 3218 * For now try 8 before 9 in order to avoid overhead and false 3219 * positives for the 'kerberos.missing_keytype' filter in pure 3220 * windows captures. 3221 */ 3222 switch (private_data->msg_type) { 3223 case KERBEROS_APPLICATIONS_AS_REP: 3224 plaintext=decrypt_krb5_data_asn1(tree, actx, 3, next_tvb, &length); 3225 break; 3226 case KERBEROS_APPLICATIONS_TGS_REP: 3227 if (private_data->fast_strengthen_key != NULL) { 3228 plaintext=decrypt_krb5_data_asn1(tree, actx, 9, next_tvb, &length); 3229 } else { 3230 plaintext=decrypt_krb5_data_asn1(tree, actx, 8, next_tvb, &length); 3231 if(!plaintext){ 3232 plaintext=decrypt_krb5_data_asn1(tree, actx, 9, next_tvb, &length); 3233 } 3234 } 3235 break; 3236 } 3237 3238 if(plaintext){ 3239 tvbuff_t *child_tvb; 3240 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3241 3242 /* Add the decrypted data to the data source list. */ 3243 add_new_data_source(actx->pinfo, child_tvb, "Krb5 KDC-REP"); 3244 3245 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3246 } 3247 return offset; 3248 } 3249 3250 static int 3251 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3252 proto_tree *tree, int hf_index _U_) 3253 { 3254 guint8 *plaintext; 3255 int length; 3256 tvbuff_t *next_tvb; 3257 3258 next_tvb=tvb_new_subset_remaining(tvb, offset); 3259 length=tvb_captured_length_remaining(tvb, offset); 3260 3261 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt : 3262 * 7.5.1 3263 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage 3264 * == 1 3265 */ 3266 plaintext=decrypt_krb5_data_asn1(tree, actx, 1, next_tvb, &length); 3267 3268 if(plaintext){ 3269 tvbuff_t *child_tvb; 3270 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3271 3272 /* Add the decrypted data to the data source list. */ 3273 add_new_data_source(actx->pinfo, child_tvb, "Krb5 EncTimestamp"); 3274 3275 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3276 } 3277 return offset; 3278 } 3279 3280 static int 3281 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3282 proto_tree *tree, int hf_index _U_) 3283 { 3284 guint8 *plaintext; 3285 int length; 3286 tvbuff_t *next_tvb; 3287 3288 next_tvb=tvb_new_subset_remaining(tvb, offset); 3289 length=tvb_captured_length_remaining(tvb, offset); 3290 3291 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt : 3292 * 7.5.1 3293 * AP-REP are encrypted with usage == 12 3294 */ 3295 plaintext=decrypt_krb5_data_asn1(tree, actx, 12, next_tvb, &length); 3296 3297 if(plaintext){ 3298 tvbuff_t *child_tvb; 3299 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3300 3301 /* Add the decrypted data to the data source list. */ 3302 add_new_data_source(actx->pinfo, child_tvb, "Krb5 AP-REP"); 3303 3304 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3305 } 3306 return offset; 3307 } 3308 3309 static int 3310 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3311 proto_tree *tree, int hf_index _U_) 3312 { 3313 guint8 *plaintext; 3314 int length; 3315 tvbuff_t *next_tvb; 3316 3317 next_tvb=tvb_new_subset_remaining(tvb, offset); 3318 length=tvb_captured_length_remaining(tvb, offset); 3319 3320 /* RFC4120 : 3321 * EncKrbPrivPart encrypted with usage 3322 * == 13 3323 */ 3324 plaintext=decrypt_krb5_data_asn1(tree, actx, 13, next_tvb, &length); 3325 3326 if(plaintext){ 3327 tvbuff_t *child_tvb; 3328 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3329 3330 /* Add the decrypted data to the data source list. */ 3331 add_new_data_source(actx->pinfo, child_tvb, "Krb5 PRIV"); 3332 3333 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3334 } 3335 return offset; 3336 } 3337 3338 static int 3339 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3340 proto_tree *tree, int hf_index _U_) 3341 { 3342 guint8 *plaintext; 3343 int length; 3344 tvbuff_t *next_tvb; 3345 3346 next_tvb=tvb_new_subset_remaining(tvb, offset); 3347 length=tvb_captured_length_remaining(tvb, offset); 3348 3349 /* RFC4120 : 3350 * EncKrbCredPart encrypted with usage 3351 * == 14 3352 */ 3353 plaintext=decrypt_krb5_data_asn1(tree, actx, 14, next_tvb, &length); 3354 3355 if(plaintext){ 3356 tvbuff_t *child_tvb; 3357 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3358 3359 /* Add the decrypted data to the data source list. */ 3360 add_new_data_source(actx->pinfo, child_tvb, "Krb5 CRED"); 3361 3362 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3363 } 3364 return offset; 3365 } 3366 3367 static int 3368 dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3369 proto_tree *tree, int hf_index _U_) 3370 { 3371 guint8 *plaintext; 3372 int length; 3373 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3374 tvbuff_t *next_tvb; 3375 3376 next_tvb=tvb_new_subset_remaining(tvb, offset); 3377 length=tvb_captured_length_remaining(tvb, offset); 3378 3379 private_data->fast_armor_key = NULL; 3380 if (private_data->PA_FAST_ARMOR_AP_subkey != NULL) { 3381 krb5_fast_key(actx, tree, tvb, 3382 private_data->PA_FAST_ARMOR_AP_subkey, 3383 "subkeyarmor", 3384 private_data->PA_FAST_ARMOR_AP_key, 3385 "ticketarmor", 3386 "KrbFastReq_FAST_armorKey"); 3387 if (private_data->PA_TGS_REQ_subkey != NULL) { 3388 enc_key_t *explicit_armor_key = private_data->last_added_key; 3389 3390 /* 3391 * See [MS-KILE] 3.3.5.7.4 Compound Identity 3392 */ 3393 krb5_fast_key(actx, tree, tvb, 3394 explicit_armor_key, 3395 "explicitarmor", 3396 private_data->PA_TGS_REQ_subkey, 3397 "tgsarmor", 3398 "KrbFastReq_explicitArmorKey"); 3399 } 3400 private_data->fast_armor_key = private_data->last_added_key; 3401 } else if (private_data->PA_TGS_REQ_subkey != NULL) { 3402 krb5_fast_key(actx, tree, tvb, 3403 private_data->PA_TGS_REQ_subkey, 3404 "subkeyarmor", 3405 private_data->PA_TGS_REQ_key, 3406 "ticketarmor", 3407 "KrbFastReq_TGS_armorKey"); 3408 private_data->fast_armor_key = private_data->last_added_key; 3409 } 3410 3411 /* RFC6113 : 3412 * KrbFastResponse encrypted with usage 3413 * KEY_USAGE_FAST_ENC 51 3414 */ 3415 plaintext=decrypt_krb5_data_asn1(tree, actx, KEY_USAGE_FAST_ENC, 3416 next_tvb, &length); 3417 3418 if(plaintext){ 3419 tvbuff_t *child_tvb; 3420 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3421 3422 /* Add the decrypted data to the data source list. */ 3423 add_new_data_source(actx->pinfo, child_tvb, "Krb5 FastReq"); 3424 3425 offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3426 } 3427 return offset; 3428 } 3429 3430 static int 3431 dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3432 proto_tree *tree, int hf_index _U_) 3433 { 3434 guint8 *plaintext; 3435 int length; 3436 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3437 tvbuff_t *next_tvb; 3438 3439 next_tvb=tvb_new_subset_remaining(tvb, offset); 3440 length=tvb_captured_length_remaining(tvb, offset); 3441 3442 /* 3443 * RFC6113 : 3444 * KrbFastResponse encrypted with usage 3445 * KEY_USAGE_FAST_REP 52 3446 */ 3447 plaintext=decrypt_krb5_data_asn1(tree, actx, KEY_USAGE_FAST_REP, 3448 next_tvb, &length); 3449 3450 if(plaintext){ 3451 tvbuff_t *child_tvb; 3452 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3453 3454 /* Add the decrypted data to the data source list. */ 3455 add_new_data_source(actx->pinfo, child_tvb, "Krb5 FastRep"); 3456 3457 private_data->fast_armor_key = private_data->last_decryption_key; 3458 offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3459 } 3460 return offset; 3461 } 3462 3463 static int 3464 dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, 3465 proto_tree *tree, int hf_index _U_) 3466 { 3467 guint8 *plaintext; 3468 int length; 3469 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3470 tvbuff_t *next_tvb; 3471 int usage = 0; 3472 const char *name = NULL; 3473 3474 next_tvb=tvb_new_subset_remaining(tvb, offset); 3475 length=tvb_captured_length_remaining(tvb, offset); 3476 3477 /* RFC6113 : 3478 * KEY_USAGE_ENC_CHALLENGE_CLIENT 54 3479 * KEY_USAGE_ENC_CHALLENGE_KDC 55 3480 */ 3481 if (kerberos_private_is_kdc_req(private_data)) { 3482 usage = KEY_USAGE_ENC_CHALLENGE_CLIENT; 3483 name = "Krb5 CHALLENGE_CLIENT"; 3484 } else { 3485 usage = KEY_USAGE_ENC_CHALLENGE_KDC; 3486 name = "Krb5 CHALLENGE_KDC"; 3487 } 3488 plaintext=decrypt_krb5_data_asn1(tree, actx, usage, next_tvb, &length); 3489 3490 if(plaintext){ 3491 tvbuff_t *child_tvb; 3492 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length); 3493 3494 /* Add the decrypted data to the data source list. */ 3495 add_new_data_source(actx->pinfo, child_tvb, name); 3496 3497 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1); 3498 } 3499 return offset; 3500 } 3501 #endif /* HAVE_KERBEROS */ 3502 3503 static int * const hf_krb_pa_supported_enctypes_fields[] = { 3504 &hf_krb_pa_supported_enctypes_des_cbc_crc, 3505 &hf_krb_pa_supported_enctypes_des_cbc_md5, 3506 &hf_krb_pa_supported_enctypes_rc4_hmac, 3507 &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96, 3508 &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96, 3509 &hf_krb_pa_supported_enctypes_fast_supported, 3510 &hf_krb_pa_supported_enctypes_compound_identity_supported, 3511 &hf_krb_pa_supported_enctypes_claims_supported, 3512 &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled, 3513 NULL, 3514 }; 3515 3516 static int 3517 dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, 3518 int offset _U_, asn1_ctx_t *actx _U_, 3519 proto_tree *tree _U_, int hf_index _U_) 3520 { 3521 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset, 3522 hf_krb_pa_supported_enctypes, 3523 ett_krb_pa_supported_enctypes, 3524 hf_krb_pa_supported_enctypes_fields, 3525 ENC_LITTLE_ENDIAN); 3526 offset += 4; 3527 3528 return offset; 3529 } 3530 3531 static int * const hf_krb_ad_ap_options_fields[] = { 3532 &hf_krb_ad_ap_options_cbt, 3533 NULL, 3534 }; 3535 3536 3537 static int 3538 dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, 3539 int offset _U_, asn1_ctx_t *actx _U_, 3540 proto_tree *tree _U_, int hf_index _U_) 3541 { 3542 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset, 3543 hf_krb_ad_ap_options, 3544 ett_krb_ad_ap_options, 3545 hf_krb_ad_ap_options_fields, 3546 ENC_LITTLE_ENDIAN); 3547 offset += 4; 3548 3549 return offset; 3550 } 3551 3552 static int 3553 dissect_kerberos_AD_TARGET_PRINCIPAL(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, 3554 int offset _U_, asn1_ctx_t *actx _U_, 3555 proto_tree *tree _U_, int hf_index _U_) 3556 { 3557 int tp_offset, tp_len; 3558 guint16 bc; 3559 3560 bc = tvb_reported_length_remaining(tvb, offset); 3561 tp_offset = offset; 3562 tp_len = bc; 3563 proto_tree_add_item(tree, hf_krb_ad_target_principal, tvb, 3564 tp_offset, tp_len, 3565 ENC_UTF_16 | ENC_LITTLE_ENDIAN); 3566 3567 return offset; 3568 } 3569 3570 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded. 3571 */ 3572 static int 3573 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb) 3574 { 3575 int offset=0; 3576 guint32 len; 3577 guint16 dlglen; 3578 3579 /* Length of Bnd field */ 3580 len=tvb_get_letohl(tvb, offset); 3581 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3582 offset += 4; 3583 3584 /* Bnd field */ 3585 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA); 3586 offset += len; 3587 3588 3589 /* flags */ 3590 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3591 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3592 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3593 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3594 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3595 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3596 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3597 offset += 4; 3598 3599 /* the next fields are optional so we have to check that we have 3600 * more data in our buffers */ 3601 if(tvb_reported_length_remaining(tvb, offset)<2){ 3602 return offset; 3603 } 3604 /* dlgopt identifier */ 3605 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN); 3606 offset += 2; 3607 3608 if(tvb_reported_length_remaining(tvb, offset)<2){ 3609 return offset; 3610 } 3611 /* dlglen identifier */ 3612 dlglen=tvb_get_letohs(tvb, offset); 3613 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN); 3614 offset += 2; 3615 3616 if(dlglen!=tvb_reported_length_remaining(tvb, offset)){ 3617 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0, 3618 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset)); 3619 return offset; 3620 } 3621 3622 /* this should now be a KRB_CRED message */ 3623 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1); 3624 3625 return offset; 3626 } 3627 3628 static int 3629 dissect_krb5_PA_PROV_SRV_LOCATION(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) 3630 { 3631 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0); 3632 3633 return offset; 3634 } 3635 3636 static int 3637 dissect_krb5_PW_SALT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) 3638 { 3639 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 3640 gint length; 3641 guint32 nt_status = 0; 3642 guint32 reserved = 0; 3643 guint32 flags = 0; 3644 3645 /* 3646 * Microsoft stores a special 12 byte blob here 3647 * [MS-KILE] 2.2.1 KERB-EXT-ERROR 3648 * guint32 NT_status 3649 * guint32 reserved (== 0) 3650 * guint32 flags (at least 0x00000001 is set) 3651 */ 3652 length = tvb_reported_length_remaining(tvb, offset); 3653 if (length <= 0) { 3654 return offset; 3655 } 3656 if (length != 12) { 3657 goto no_error; 3658 } 3659 3660 if (private_data->errorcode == 0) { 3661 goto no_error; 3662 } 3663 3664 if (!private_data->try_nt_status) { 3665 goto no_error; 3666 } 3667 3668 nt_status = tvb_get_letohl(tvb, offset); 3669 reserved = tvb_get_letohl(tvb, offset + 4); 3670 flags = tvb_get_letohl(tvb, offset + 8); 3671 3672 if (nt_status == 0 || reserved != 0 || flags == 0) { 3673 goto no_error; 3674 } 3675 3676 proto_tree_add_item(tree, hf_krb_ext_error_nt_status, tvb, offset, 4, 3677 ENC_LITTLE_ENDIAN); 3678 col_append_fstr(actx->pinfo->cinfo, COL_INFO, 3679 " NT Status: %s", 3680 val_to_str(nt_status, NT_errors, 3681 "Unknown error code %#x")); 3682 offset += 4; 3683 3684 proto_tree_add_item(tree, hf_krb_ext_error_reserved, tvb, offset, 4, 3685 ENC_LITTLE_ENDIAN); 3686 offset += 4; 3687 3688 proto_tree_add_item(tree, hf_krb_ext_error_flags, tvb, offset, 4, 3689 ENC_LITTLE_ENDIAN); 3690 offset += 4; 3691 3692 return offset; 3693 3694 no_error: 3695 proto_tree_add_item(tree, hf_krb_pw_salt, tvb, offset, length, ENC_NA); 3696 offset += length; 3697 3698 return offset; 3699 } 3700 3701 static int 3702 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep) 3703 { 3704 proto_tree *tree; 3705 guint8 val; 3706 3707 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP"); 3708 3709 val = tvb_get_guint8(tvb, offset); 3710 proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4); 3711 3712 offset++; 3713 3714 if (drep) { 3715 *drep = val; 3716 } 3717 3718 return offset; 3719 } 3720 3721 /* This might be some sort of header that MIDL generates when creating 3722 * marshalling/unmarshalling code for blobs that are not to be transported 3723 * ontop of DCERPC and where the DREP fields specifying things such as 3724 * endianess and similar are not available. 3725 */ 3726 static int 3727 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_) 3728 { 3729 proto_tree *tree; 3730 3731 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header"); 3732 3733 /* modified DREP field that is used for stuff that is transporetd ontop 3734 of non dcerpc 3735 */ 3736 proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); 3737 offset++; 3738 3739 offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep); 3740 3741 3742 proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN); 3743 offset+=2; 3744 3745 proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3746 offset += 4; 3747 3748 /* length of blob that follows */ 3749 proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN); 3750 offset += 8; 3751 3752 return offset; 3753 } 3754 3755 static int 3756 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 3757 { 3758 proto_item *item; 3759 proto_tree *tree; 3760 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */ 3761 static dcerpc_info di; /* fake dcerpc_info struct */ 3762 static dcerpc_call_value call_data; 3763 3764 item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA); 3765 tree = proto_item_add_subtree(item, ett_krb_pac_logon_info); 3766 3767 /* skip the first 16 bytes, they are some magic created by the idl 3768 * compiler the first 4 bytes might be flags? 3769 */ 3770 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx); 3771 3772 /* the PAC_LOGON_INFO blob */ 3773 /* fake whatever state the dcerpc runtime support needs */ 3774 di.conformant_run=0; 3775 /* we need di->call_data->flags.NDR64 == 0 */ 3776 di.call_data=&call_data; 3777 init_ndr_pointer_list(&di); 3778 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep, 3779 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE, 3780 "PAC_LOGON_INFO:", -1); 3781 3782 return offset; 3783 } 3784 3785 3786 static int 3787 dissect_krb5_PAC_CREDENTIAL_DATA(proto_tree *parent_tree, tvbuff_t *tvb, int offset, packet_info *pinfo _U_) 3788 { 3789 proto_tree_add_item(parent_tree, hf_krb_pac_credential_data, tvb, offset, -1, ENC_NA); 3790 3791 return offset; 3792 } 3793 3794 static int 3795 dissect_krb5_PAC_CREDENTIAL_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx) 3796 { 3797 proto_item *item; 3798 proto_tree *tree; 3799 guint8 *plaintext = NULL; 3800 int plainlen = 0; 3801 int length = 0; 3802 #define KRB5_KU_OTHER_ENCRYPTED 16 3803 #ifdef HAVE_KERBEROS 3804 guint32 etype; 3805 tvbuff_t *next_tvb; 3806 int usage = KRB5_KU_OTHER_ENCRYPTED; 3807 #endif 3808 3809 item = proto_tree_add_item(parent_tree, hf_krb_pac_credential_info, tvb, offset, -1, ENC_NA); 3810 tree = proto_item_add_subtree(item, ett_krb_pac_credential_info); 3811 3812 /* version */ 3813 proto_tree_add_item(tree, hf_krb_pac_credential_info_version, tvb, 3814 offset, 4, ENC_LITTLE_ENDIAN); 3815 offset+=4; 3816 3817 #ifdef HAVE_KERBEROS 3818 /* etype */ 3819 etype = tvb_get_letohl(tvb, offset); 3820 #endif 3821 proto_tree_add_item(tree, hf_krb_pac_credential_info_etype, tvb, 3822 offset, 4, ENC_LITTLE_ENDIAN); 3823 offset+=4; 3824 3825 #ifdef HAVE_KERBEROS 3826 /* data */ 3827 next_tvb=tvb_new_subset_remaining(tvb, offset); 3828 length=tvb_captured_length_remaining(tvb, offset); 3829 3830 plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, (int)etype, &plainlen); 3831 #endif 3832 3833 if (plaintext != NULL) { 3834 tvbuff_t *child_tvb; 3835 child_tvb = tvb_new_child_real_data(tvb, plaintext, plainlen, plainlen); 3836 3837 /* Add the decrypted data to the data source list. */ 3838 add_new_data_source(actx->pinfo, child_tvb, "Krb5 PAC_CREDENTIAL"); 3839 3840 dissect_krb5_PAC_CREDENTIAL_DATA(tree, child_tvb, 0, actx->pinfo); 3841 } 3842 3843 return offset + length; 3844 } 3845 3846 static int 3847 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx) 3848 { 3849 proto_item *item; 3850 proto_tree *tree; 3851 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */ 3852 static dcerpc_info di; /* fake dcerpc_info struct */ 3853 static dcerpc_call_value call_data; 3854 3855 item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA); 3856 tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info); 3857 3858 /* skip the first 16 bytes, they are some magic created by the idl 3859 * compiler the first 4 bytes might be flags? 3860 */ 3861 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx); 3862 3863 3864 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */ 3865 /* fake whatever state the dcerpc runtime support needs */ 3866 di.conformant_run=0; 3867 /* we need di->call_data->flags.NDR64 == 0 */ 3868 di.call_data=&call_data; 3869 init_ndr_pointer_list(&di); 3870 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep, 3871 netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE, 3872 "PAC_S4U_DELEGATION_INFO:", -1); 3873 3874 return offset; 3875 } 3876 3877 static int 3878 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 3879 { 3880 proto_item *item; 3881 proto_tree *tree; 3882 guint16 dns_offset, dns_len; 3883 guint16 upn_offset, upn_len; 3884 3885 item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA); 3886 tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info); 3887 3888 /* upn */ 3889 upn_len = tvb_get_letohs(tvb, offset); 3890 proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN); 3891 offset+=2; 3892 upn_offset = tvb_get_letohs(tvb, offset); 3893 proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); 3894 offset+=2; 3895 3896 /* dns */ 3897 dns_len = tvb_get_letohs(tvb, offset); 3898 proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN); 3899 offset+=2; 3900 dns_offset = tvb_get_letohs(tvb, offset); 3901 proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); 3902 offset+=2; 3903 3904 /* flags */ 3905 proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3906 3907 /* upn */ 3908 proto_tree_add_item(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, ENC_UTF_16|ENC_LITTLE_ENDIAN); 3909 3910 /* dns */ 3911 proto_tree_add_item(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, ENC_UTF_16|ENC_LITTLE_ENDIAN); 3912 3913 return dns_offset; 3914 } 3915 3916 static int 3917 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 3918 { 3919 int length = tvb_captured_length_remaining(tvb, offset); 3920 3921 if (length == 0) { 3922 return offset; 3923 } 3924 3925 proto_tree_add_item(parent_tree, hf_krb_pac_client_claims_info, tvb, offset, -1, ENC_NA); 3926 3927 return offset; 3928 } 3929 3930 static int 3931 dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 3932 { 3933 proto_item *item; 3934 proto_tree *tree; 3935 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */ 3936 static dcerpc_info di; /* fake dcerpc_info struct */ 3937 static dcerpc_call_value call_data; 3938 3939 item = proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA); 3940 tree = proto_item_add_subtree(item, ett_krb_pac_device_info); 3941 3942 /* skip the first 16 bytes, they are some magic created by the idl 3943 * compiler the first 4 bytes might be flags? 3944 */ 3945 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx); 3946 3947 /* the PAC_DEVICE_INFO blob */ 3948 /* fake whatever state the dcerpc runtime support needs */ 3949 di.conformant_run=0; 3950 /* we need di->call_data->flags.NDR64 == 0 */ 3951 di.call_data=&call_data; 3952 init_ndr_pointer_list(&di); 3953 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep, 3954 netlogon_dissect_PAC_DEVICE_INFO, NDR_POINTER_UNIQUE, 3955 "PAC_DEVICE_INFO:", -1); 3956 3957 return offset; 3958 } 3959 3960 static int 3961 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 3962 { 3963 int length = tvb_captured_length_remaining(tvb, offset); 3964 3965 if (length == 0) { 3966 return offset; 3967 } 3968 3969 proto_tree_add_item(parent_tree, hf_krb_pac_device_claims_info, tvb, offset, -1, ENC_NA); 3970 3971 return offset; 3972 } 3973 3974 static int 3975 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 3976 { 3977 proto_item *item; 3978 proto_tree *tree; 3979 3980 item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA); 3981 tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum); 3982 3983 /* signature type */ 3984 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); 3985 offset+=4; 3986 3987 /* signature data */ 3988 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA); 3989 3990 return offset; 3991 } 3992 3993 static int 3994 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 3995 { 3996 proto_item *item; 3997 proto_tree *tree; 3998 3999 item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA); 4000 tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum); 4001 4002 /* signature type */ 4003 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); 4004 offset+=4; 4005 4006 /* signature data */ 4007 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA); 4008 4009 return offset; 4010 } 4011 4012 static int 4013 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 4014 { 4015 proto_item *item; 4016 proto_tree *tree; 4017 guint16 namelen; 4018 4019 item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA); 4020 tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type); 4021 4022 /* clientid */ 4023 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid); 4024 4025 /* name length */ 4026 namelen=tvb_get_letohs(tvb, offset); 4027 proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen); 4028 offset+=2; 4029 4030 /* client name */ 4031 proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN); 4032 offset+=namelen; 4033 4034 return offset; 4035 } 4036 4037 static int 4038 dissect_krb5_PAC_TICKET_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 4039 { 4040 proto_item *item; 4041 proto_tree *tree; 4042 4043 item = proto_tree_add_item(parent_tree, hf_krb_pac_ticket_checksum, tvb, offset, -1, ENC_NA); 4044 tree = proto_item_add_subtree(item, ett_krb_pac_ticket_checksum); 4045 4046 /* signature type */ 4047 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); 4048 offset+=4; 4049 4050 /* signature data */ 4051 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA); 4052 4053 return offset; 4054 } 4055 4056 static int 4057 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx) 4058 { 4059 guint32 pac_type; 4060 guint32 pac_size; 4061 guint32 pac_offset; 4062 proto_item *it=NULL; 4063 proto_tree *tr=NULL; 4064 tvbuff_t *next_tvb; 4065 4066 /* type of pac data */ 4067 pac_type=tvb_get_letohl(tvb, offset); 4068 it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type); 4069 tr=proto_item_add_subtree(it, ett_krb_pac); 4070 4071 offset += 4; 4072 4073 /* size of pac data */ 4074 pac_size=tvb_get_letohl(tvb, offset); 4075 proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size); 4076 offset += 4; 4077 4078 /* offset to pac data */ 4079 pac_offset=tvb_get_letohl(tvb, offset); 4080 proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset); 4081 offset += 8; 4082 4083 next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size); 4084 switch(pac_type){ 4085 case PAC_LOGON_INFO: 4086 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx); 4087 break; 4088 case PAC_CREDENTIAL_TYPE: 4089 dissect_krb5_PAC_CREDENTIAL_INFO(tr, next_tvb, 0, actx); 4090 break; 4091 case PAC_SERVER_CHECKSUM: 4092 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx); 4093 break; 4094 case PAC_PRIVSVR_CHECKSUM: 4095 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx); 4096 break; 4097 case PAC_CLIENT_INFO_TYPE: 4098 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx); 4099 break; 4100 case PAC_S4U_DELEGATION_INFO: 4101 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx); 4102 break; 4103 case PAC_UPN_DNS_INFO: 4104 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx); 4105 break; 4106 case PAC_CLIENT_CLAIMS_INFO: 4107 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(tr, next_tvb, 0, actx); 4108 break; 4109 case PAC_DEVICE_INFO: 4110 dissect_krb5_PAC_DEVICE_INFO(tr, next_tvb, 0, actx); 4111 break; 4112 case PAC_DEVICE_CLAIMS_INFO: 4113 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(tr, next_tvb, 0, actx); 4114 break; 4115 case PAC_TICKET_CHECKSUM: 4116 dissect_krb5_PAC_TICKET_CHECKSUM(tr, next_tvb, 0, actx); 4117 break; 4118 4119 default: 4120 break; 4121 } 4122 return offset; 4123 } 4124 4125 static int 4126 dissect_krb5_AD_WIN2K_PAC(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) 4127 { 4128 guint32 entries; 4129 guint32 version; 4130 guint32 i; 4131 4132 #if defined(HAVE_MIT_KERBEROS) && defined(HAVE_KRB5_PAC_VERIFY) 4133 verify_krb5_pac(tree, actx, tvb); 4134 #endif 4135 4136 /* first in the PAC structure comes the number of entries */ 4137 entries=tvb_get_letohl(tvb, offset); 4138 proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries); 4139 offset += 4; 4140 4141 /* second comes the version */ 4142 version=tvb_get_letohl(tvb, offset); 4143 proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version); 4144 offset += 4; 4145 4146 for(i=0;i<entries;i++){ 4147 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx); 4148 } 4149 4150 return offset; 4151 } 4152 4153 #include "packet-kerberos-fn.c" 4154 4155 #ifdef HAVE_KERBEROS 4156 static const ber_sequence_t PA_ENC_TS_ENC_sequence[] = { 4157 { &hf_krb_patimestamp, BER_CLASS_CON, 0, 0, dissect_kerberos_KerberosTime }, 4158 { &hf_krb_pausec , BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_kerberos_Microseconds }, 4159 { NULL, 0, 0, 0, NULL } 4160 }; 4161 4162 static int 4163 dissect_kerberos_PA_ENC_TS_ENC(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { 4164 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, 4165 PA_ENC_TS_ENC_sequence, hf_index, ett_krb_pa_enc_ts_enc); 4166 return offset; 4167 } 4168 4169 static int 4170 dissect_kerberos_T_strengthen_key(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { 4171 #line 491 "./asn1/kerberos/kerberos.cnf" 4172 kerberos_private_data_t *private_data = kerberos_get_private_data(actx); 4173 gint save_encryption_key_parent_hf_index = private_data->save_encryption_key_parent_hf_index; 4174 kerberos_key_save_fn saved_encryption_key_fn = private_data->save_encryption_key_fn; 4175 private_data->save_encryption_key_parent_hf_index = hf_kerberos_KrbFastResponse; 4176 #ifdef HAVE_KERBEROS 4177 private_data->save_encryption_key_fn = save_KrbFastResponse_strengthen_key; 4178 #endif 4179 offset = dissect_kerberos_EncryptionKey(implicit_tag, tvb, offset, actx, tree, hf_index); 4180 4181 private_data->save_encryption_key_parent_hf_index = save_encryption_key_parent_hf_index; 4182 private_data->save_encryption_key_fn = saved_encryption_key_fn; 4183 return offset; 4184 } 4185 4186 static const ber_sequence_t KrbFastFinished_sequence[] = { 4187 { &hf_kerberos_timestamp , BER_CLASS_CON, 0, 0, dissect_kerberos_KerberosTime }, 4188 { &hf_kerberos_usec , BER_CLASS_CON, 1, 0, dissect_kerberos_Microseconds }, 4189 { &hf_kerberos_crealm , BER_CLASS_CON, 2, 0, dissect_kerberos_Realm }, 4190 { &hf_kerberos_cname_01 , BER_CLASS_CON, 3, 0, dissect_kerberos_PrincipalName }, 4191 { &hf_kerberos_ticket_checksum, BER_CLASS_CON, 4, 0, dissect_kerberos_Checksum }, 4192 { NULL, 0, 0, 0, NULL } 4193 }; 4194 4195 static int 4196 dissect_kerberos_KrbFastFinished(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { 4197 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, 4198 KrbFastFinished_sequence, hf_index, ett_kerberos_KrbFastFinished); 4199 4200 return offset; 4201 } 4202 4203 static const ber_sequence_t KrbFastResponse_sequence[] = { 4204 { &hf_kerberos_padata , BER_CLASS_CON, 0, 0, dissect_kerberos_SEQUENCE_OF_PA_DATA }, 4205 { &hf_kerberos_strengthen_key, BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_kerberos_T_strengthen_key }, 4206 { &hf_kerberos_finished , BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, dissect_kerberos_KrbFastFinished }, 4207 { &hf_kerberos_nonce , BER_CLASS_CON, 3, 0, dissect_kerberos_UInt32 }, 4208 { NULL, 0, 0, 0, NULL } 4209 }; 4210 4211 static int 4212 dissect_kerberos_KrbFastResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { 4213 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, 4214 KrbFastResponse_sequence, hf_index, ett_kerberos_KrbFastResponse); 4215 4216 return offset; 4217 } 4218 4219 static const ber_sequence_t KrbFastReq_sequence[] = { 4220 { &hf_kerberos_fast_options, BER_CLASS_CON, 0, 0, dissect_kerberos_FastOptions }, 4221 { &hf_kerberos_padata , BER_CLASS_CON, 1, 0, dissect_kerberos_SEQUENCE_OF_PA_DATA }, 4222 { &hf_kerberos_req_body , BER_CLASS_CON, 2, 0, dissect_kerberos_KDC_REQ_BODY }, 4223 { NULL, 0, 0, 0, NULL } 4224 }; 4225 4226 static int 4227 dissect_kerberos_KrbFastReq(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { 4228 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, 4229 KrbFastReq_sequence, hf_index, ett_kerberos_KrbFastReq); 4230 4231 return offset; 4232 } 4233 4234 static int * const FastOptions_bits[] = { 4235 &hf_kerberos_FastOptions_reserved, 4236 &hf_kerberos_FastOptions_hide_client_names, 4237 &hf_kerberos_FastOptions_spare_bit2, 4238 &hf_kerberos_FastOptions_spare_bit3, 4239 &hf_kerberos_FastOptions_spare_bit4, 4240 &hf_kerberos_FastOptions_spare_bit5, 4241 &hf_kerberos_FastOptions_spare_bit6, 4242 &hf_kerberos_FastOptions_spare_bit7, 4243 &hf_kerberos_FastOptions_spare_bit8, 4244 &hf_kerberos_FastOptions_spare_bit9, 4245 &hf_kerberos_FastOptions_spare_bit10, 4246 &hf_kerberos_FastOptions_spare_bit11, 4247 &hf_kerberos_FastOptions_spare_bit12, 4248 &hf_kerberos_FastOptions_spare_bit13, 4249 &hf_kerberos_FastOptions_spare_bit14, 4250 &hf_kerberos_FastOptions_spare_bit15, 4251 &hf_kerberos_FastOptions_kdc_follow_referrals, 4252 NULL 4253 }; 4254 4255 static int 4256 dissect_kerberos_FastOptions(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { 4257 offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset, 4258 FastOptions_bits, 17, hf_index, ett_kerberos_FastOptions, 4259 NULL); 4260 4261 return offset; 4262 } 4263 4264 #endif /* HAVE_KERBEROS */ 4265 4266 /* Make wrappers around exported functions for now */ 4267 int 4268 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 4269 { 4270 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum); 4271 4272 } 4273 4274 int 4275 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 4276 { 4277 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime); 4278 } 4279 4280 4281 int 4282 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 4283 { 4284 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname); 4285 } 4286 int 4287 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_) 4288 { 4289 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm); 4290 } 4291 4292 struct kerberos_display_key_state { 4293 proto_tree *tree; 4294 packet_info *pinfo; 4295 expert_field *expindex; 4296 const char *name; 4297 tvbuff_t *tvb; 4298 gint start; 4299 gint length; 4300 }; 4301 4302 static void 4303 #ifdef HAVE_KERBEROS 4304 kerberos_display_key(gpointer data, gpointer userdata) 4305 #else 4306 kerberos_display_key(gpointer data _U_, gpointer userdata _U_) 4307 #endif 4308 { 4309 #ifdef HAVE_KERBEROS 4310 struct kerberos_display_key_state *state = 4311 (struct kerberos_display_key_state *)userdata; 4312 const enc_key_t *ek = (const enc_key_t *)data; 4313 proto_item *item = NULL; 4314 enc_key_t *sek = NULL; 4315 4316 item = proto_tree_add_expert_format(state->tree, 4317 state->pinfo, 4318 state->expindex, 4319 state->tvb, 4320 state->start, 4321 state->length, 4322 "%s %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 4323 state->name, 4324 ek->key_origin, ek->keytype, 4325 ek->id_str, ek->num_same, 4326 ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF, 4327 ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF); 4328 if (ek->src1 != NULL) { 4329 sek = ek->src1; 4330 expert_add_info_format(state->pinfo, 4331 item, 4332 state->expindex, 4333 "SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 4334 sek->key_origin, sek->keytype, 4335 sek->id_str, sek->num_same, 4336 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 4337 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 4338 } 4339 if (ek->src2 != NULL) { 4340 sek = ek->src2; 4341 expert_add_info_format(state->pinfo, 4342 item, 4343 state->expindex, 4344 "SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 4345 sek->key_origin, sek->keytype, 4346 sek->id_str, sek->num_same, 4347 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 4348 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 4349 } 4350 sek = ek->same_list; 4351 while (sek != NULL) { 4352 expert_add_info_format(state->pinfo, 4353 item, 4354 state->expindex, 4355 "%s %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)", 4356 state->name, 4357 sek->key_origin, sek->keytype, 4358 sek->id_str, sek->num_same, 4359 sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF, 4360 sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF); 4361 sek = sek->same_list; 4362 } 4363 #endif /* HAVE_KERBEROS */ 4364 } 4365 4366 static const value_string KERB_LOGON_SUBMIT_TYPE[] = { 4367 { 2, "KerbInteractiveLogon" }, 4368 { 6, "KerbSmartCardLogon" }, 4369 { 7, "KerbWorkstationUnlockLogon" }, 4370 { 8, "KerbSmartCardUnlockLogon" }, 4371 { 9, "KerbProxyLogon" }, 4372 { 10, "KerbTicketLogon" }, 4373 { 11, "KerbTicketUnlockLogon" }, 4374 { 12, "KerbS4ULogon" }, 4375 { 13, "KerbCertificateLogon" }, 4376 { 14, "KerbCertificateS4ULogon" }, 4377 { 15, "KerbCertificateUnlockLogon" }, 4378 { 0, NULL } 4379 }; 4380 4381 4382 #define KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET 0x1 4383 #define KERB_LOGON_FLAG_REDIRECTED 0x2 4384 4385 static int* const ktl_flags_bits[] = { 4386 &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET, 4387 &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED, 4388 NULL 4389 }; 4390 4391 int 4392 dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree) 4393 { 4394 proto_item *item; 4395 proto_tree *subtree; 4396 guint32 ServiceTicketLength; 4397 guint32 TicketGrantingTicketLength; 4398 int orig_offset; 4399 4400 if (tvb_captured_length(tvb) < 32) 4401 return offset; 4402 4403 item = proto_tree_add_item(tree, hf_kerberos_KERB_TICKET_LOGON, tvb, offset, -1, ENC_NA); 4404 subtree = proto_item_add_subtree(item, ett_kerberos_KERB_TICKET_LOGON); 4405 4406 proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_MessageType, tvb, offset, 4, 4407 ENC_LITTLE_ENDIAN); 4408 offset+=4; 4409 4410 proto_tree_add_bitmask(subtree, tvb, offset, hf_kerberos_KERB_TICKET_LOGON_Flags, 4411 ett_kerberos, ktl_flags_bits, ENC_LITTLE_ENDIAN); 4412 offset+=4; 4413 4414 ServiceTicketLength = tvb_get_letohl(tvb, offset); 4415 proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength, tvb, 4416 offset, 4, ENC_LITTLE_ENDIAN); 4417 offset+=4; 4418 4419 TicketGrantingTicketLength = tvb_get_letohl(tvb, offset); 4420 proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength, 4421 tvb, offset, 4, ENC_LITTLE_ENDIAN); 4422 offset+=4; 4423 4424 /* Skip two PUCHAR of ServiceTicket and TicketGrantingTicket */ 4425 offset+=16; 4426 4427 if (ServiceTicketLength == 0) 4428 return offset; 4429 4430 orig_offset = offset; 4431 offset = dissect_kerberos_Ticket(FALSE, tvb, offset, actx, subtree, 4432 hf_kerberos_KERB_TICKET_LOGON_ServiceTicket); 4433 4434 if ((unsigned)(offset-orig_offset) != ServiceTicketLength) 4435 return offset; 4436 4437 if (TicketGrantingTicketLength == 0) 4438 return offset; 4439 4440 offset = dissect_kerberos_KRB_CRED(FALSE, tvb, offset, actx, subtree, 4441 hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket); 4442 4443 if ((unsigned)(offset-orig_offset) != ServiceTicketLength + TicketGrantingTicketLength) 4444 return offset; 4445 4446 return offset; 4447 } 4448 4449 static gint 4450 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, 4451 gboolean dci, gboolean do_col_protocol, gboolean have_rm, 4452 kerberos_callbacks *cb) 4453 { 4454 volatile int offset = 0; 4455 proto_tree *volatile kerberos_tree = NULL; 4456 proto_item *volatile item = NULL; 4457 kerberos_private_data_t *private_data = NULL; 4458 asn1_ctx_t asn1_ctx; 4459 4460 /* TCP record mark and length */ 4461 guint32 krb_rm = 0; 4462 gint krb_reclen = 0; 4463 4464 gbl_do_col_info=dci; 4465 4466 if (have_rm) { 4467 krb_rm = tvb_get_ntohl(tvb, offset); 4468 krb_reclen = kerberos_rm_to_reclen(krb_rm); 4469 /* 4470 * What is a reasonable size limit? 4471 */ 4472 if (krb_reclen > 10 * 1024 * 1024) { 4473 return (-1); 4474 } 4475 4476 if (do_col_protocol) { 4477 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5"); 4478 } 4479 4480 if (tree) { 4481 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA); 4482 kerberos_tree = proto_item_add_subtree(item, ett_kerberos); 4483 } 4484 4485 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm); 4486 offset += 4; 4487 } else { 4488 /* Do some sanity checking here, 4489 * All krb5 packets start with a TAG class that is BER_CLASS_APP 4490 * and a tag value that is either of the values below: 4491 * If it doesn't look like kerberos, return 0 and let someone else have 4492 * a go at it. 4493 */ 4494 gint8 tmp_class; 4495 gboolean tmp_pc; 4496 gint32 tmp_tag; 4497 4498 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); 4499 if(tmp_class!=BER_CLASS_APP){ 4500 return 0; 4501 } 4502 switch(tmp_tag){ 4503 case KRB5_MSG_TICKET: 4504 case KRB5_MSG_AUTHENTICATOR: 4505 case KRB5_MSG_ENC_TICKET_PART: 4506 case KRB5_MSG_AS_REQ: 4507 case KRB5_MSG_AS_REP: 4508 case KRB5_MSG_TGS_REQ: 4509 case KRB5_MSG_TGS_REP: 4510 case KRB5_MSG_AP_REQ: 4511 case KRB5_MSG_AP_REP: 4512 case KRB5_MSG_ENC_AS_REP_PART: 4513 case KRB5_MSG_ENC_TGS_REP_PART: 4514 case KRB5_MSG_ENC_AP_REP_PART: 4515 case KRB5_MSG_ENC_KRB_PRIV_PART: 4516 case KRB5_MSG_ENC_KRB_CRED_PART: 4517 case KRB5_MSG_SAFE: 4518 case KRB5_MSG_PRIV: 4519 case KRB5_MSG_ERROR: 4520 break; 4521 default: 4522 return 0; 4523 } 4524 if (do_col_protocol) { 4525 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5"); 4526 } 4527 if (gbl_do_col_info) { 4528 col_clear(pinfo->cinfo, COL_INFO); 4529 } 4530 if (tree) { 4531 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA); 4532 kerberos_tree = proto_item_add_subtree(item, ett_kerberos); 4533 } 4534 } 4535 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); 4536 asn1_ctx.private_data = NULL; 4537 private_data = kerberos_get_private_data(&asn1_ctx); 4538 private_data->callbacks = cb; 4539 4540 TRY { 4541 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1); 4542 } CATCH_BOUNDS_ERRORS { 4543 RETHROW; 4544 } ENDTRY; 4545 4546 if (kerberos_tree != NULL) { 4547 struct kerberos_display_key_state display_state = { 4548 .tree = kerberos_tree, 4549 .pinfo = pinfo, 4550 .expindex = &ei_kerberos_learnt_keytype, 4551 .name = "Provides", 4552 .tvb = tvb, 4553 }; 4554 4555 wmem_list_foreach(private_data->learnt_keys, 4556 kerberos_display_key, 4557 &display_state); 4558 } 4559 4560 if (kerberos_tree != NULL) { 4561 struct kerberos_display_key_state display_state = { 4562 .tree = kerberos_tree, 4563 .pinfo = pinfo, 4564 .expindex = &ei_kerberos_missing_keytype, 4565 .name = "Missing", 4566 .tvb = tvb, 4567 }; 4568 4569 wmem_list_foreach(private_data->missing_keys, 4570 kerberos_display_key, 4571 &display_state); 4572 } 4573 4574 if (kerberos_tree != NULL) { 4575 struct kerberos_display_key_state display_state = { 4576 .tree = kerberos_tree, 4577 .pinfo = pinfo, 4578 .expindex = &ei_kerberos_decrypted_keytype, 4579 .name = "Used", 4580 .tvb = tvb, 4581 }; 4582 4583 wmem_list_foreach(private_data->decryption_keys, 4584 kerberos_display_key, 4585 &display_state); 4586 } 4587 4588 proto_item_set_len(item, offset); 4589 return offset; 4590 } 4591 4592 /* 4593 * Display the TCP record mark. 4594 */ 4595 void 4596 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm) 4597 { 4598 gint rec_len; 4599 proto_tree *rm_tree; 4600 4601 if (tree == NULL) 4602 return; 4603 4604 rec_len = kerberos_rm_to_reclen(krb_rm); 4605 rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL, 4606 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes")); 4607 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm); 4608 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm); 4609 } 4610 4611 gint 4612 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb) 4613 { 4614 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb)); 4615 } 4616 4617 guint32 4618 kerberos_output_keytype(void) 4619 { 4620 return gbl_keytype; 4621 } 4622 4623 static gint 4624 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) 4625 { 4626 /* Some weird kerberos implementation apparently do krb4 on the krb5 port. 4627 Since all (except weirdo transarc krb4 stuff) use 4628 an opcode <=16 in the first byte, use this to see if it might 4629 be krb4. 4630 All krb5 commands start with an APPL tag and thus is >=0x60 4631 so if first byte is <=16 just blindly assume it is krb4 then 4632 */ 4633 if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){ 4634 if(krb4_handle){ 4635 gboolean res; 4636 4637 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL); 4638 return res; 4639 }else{ 4640 return 0; 4641 } 4642 } 4643 4644 4645 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL); 4646 } 4647 4648 gint 4649 kerberos_rm_to_reclen(guint krb_rm) 4650 { 4651 return (krb_rm & KRB_RM_RECLEN); 4652 } 4653 4654 guint 4655 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) 4656 { 4657 guint krb_rm; 4658 gint pdulen; 4659 4660 krb_rm = tvb_get_ntohl(tvb, offset); 4661 pdulen = kerberos_rm_to_reclen(krb_rm); 4662 return (pdulen + 4); 4663 } 4664 static void 4665 kerberos_prefs_apply_cb(void) { 4666 #ifdef HAVE_LIBNETTLE 4667 clear_keytab(); 4668 read_keytab_file(keytab_filename); 4669 #endif 4670 } 4671 4672 static int 4673 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) 4674 { 4675 pinfo->fragmented = TRUE; 4676 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) { 4677 /* 4678 * The dissector failed to recognize this as a valid 4679 * Kerberos message. Mark it as a continuation packet. 4680 */ 4681 col_set_str(pinfo->cinfo, COL_INFO, "Continuation"); 4682 } 4683 4684 return tvb_captured_length(tvb); 4685 } 4686 4687 static int 4688 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) 4689 { 4690 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5"); 4691 col_clear(pinfo->cinfo, COL_INFO); 4692 4693 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len, 4694 dissect_kerberos_tcp_pdu, data); 4695 return tvb_captured_length(tvb); 4696 } 4697 4698 /*--- proto_register_kerberos -------------------------------------------*/ 4699 void proto_register_kerberos(void) { 4700 4701 /* List of fields */ 4702 4703 static hf_register_info hf[] = { 4704 { &hf_krb_rm_reserved, { 4705 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32, 4706 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }}, 4707 { &hf_krb_rm_reclen, { 4708 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC, 4709 NULL, KRB_RM_RECLEN, NULL, HFILL }}, 4710 { &hf_krb_provsrv_location, { 4711 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE, 4712 NULL, 0, "PacketCable PROV SRV Location", HFILL }}, 4713 { &hf_krb_pw_salt, 4714 { "pw-salt", "kerberos.pw_salt", FT_BYTES, BASE_NONE, 4715 NULL, 0, NULL, HFILL }}, 4716 { &hf_krb_ext_error_nt_status, /* we keep kerberos.smb.nt_status for compat reasons */ 4717 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX, 4718 VALS(NT_errors), 0, "NT Status code", HFILL }}, 4719 { &hf_krb_ext_error_reserved, 4720 { "Reserved", "kerberos.ext_error.reserved", FT_UINT32, BASE_HEX, 4721 NULL, 0, NULL, HFILL }}, 4722 { &hf_krb_ext_error_flags, 4723 { "Flags", "kerberos.ext_error.flags", FT_UINT32, BASE_HEX, 4724 NULL, 0, NULL, HFILL }}, 4725 { &hf_krb_address_ip, { 4726 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE, 4727 NULL, 0, NULL, HFILL }}, 4728 { &hf_krb_address_ipv6, { 4729 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE, 4730 NULL, 0, NULL, HFILL }}, 4731 { &hf_krb_address_netbios, { 4732 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE, 4733 NULL, 0, "NetBIOS Address and type", HFILL }}, 4734 { &hf_krb_gssapi_len, { 4735 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC, 4736 NULL, 0, "Length of GSSAPI Bnd field", HFILL }}, 4737 { &hf_krb_gssapi_bnd, { 4738 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE, 4739 NULL, 0, "GSSAPI Bnd field", HFILL }}, 4740 { &hf_krb_gssapi_c_flag_deleg, { 4741 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32, 4742 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }}, 4743 { &hf_krb_gssapi_c_flag_mutual, { 4744 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32, 4745 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }}, 4746 { &hf_krb_gssapi_c_flag_replay, { 4747 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32, 4748 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }}, 4749 { &hf_krb_gssapi_c_flag_sequence, { 4750 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32, 4751 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }}, 4752 { &hf_krb_gssapi_c_flag_conf, { 4753 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32, 4754 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }}, 4755 { &hf_krb_gssapi_c_flag_integ, { 4756 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32, 4757 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }}, 4758 { &hf_krb_gssapi_c_flag_dce_style, { 4759 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32, 4760 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }}, 4761 { &hf_krb_gssapi_dlgopt, { 4762 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC, 4763 NULL, 0, "GSSAPI DlgOpt", HFILL }}, 4764 { &hf_krb_gssapi_dlglen, { 4765 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC, 4766 NULL, 0, "GSSAPI DlgLen", HFILL }}, 4767 { &hf_krb_midl_blob_len, { 4768 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC, 4769 NULL, 0, "Length of NDR encoded data that follows", HFILL }}, 4770 { &hf_krb_midl_fill_bytes, { 4771 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX, 4772 NULL, 0, "Just some fill bytes", HFILL }}, 4773 { &hf_krb_midl_version, { 4774 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC, 4775 NULL, 0, "Version of pickling", HFILL }}, 4776 { &hf_krb_midl_hdr_len, { 4777 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC, 4778 NULL, 0, "Length of header", HFILL }}, 4779 { &hf_krb_pac_signature_type, { 4780 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC, 4781 NULL, 0, "PAC Signature Type", HFILL }}, 4782 { &hf_krb_pac_signature_signature, { 4783 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE, 4784 NULL, 0, "A PAC signature blob", HFILL }}, 4785 { &hf_krb_w2k_pac_entries, { 4786 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC, 4787 NULL, 0, "Number of W2k PAC entries", HFILL }}, 4788 { &hf_krb_w2k_pac_version, { 4789 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC, 4790 NULL, 0, "Version of PAC structures", HFILL }}, 4791 { &hf_krb_w2k_pac_type, { 4792 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC, 4793 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }}, 4794 { &hf_krb_w2k_pac_size, { 4795 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC, 4796 NULL, 0, "Size of W2k PAC entry", HFILL }}, 4797 { &hf_krb_w2k_pac_offset, { 4798 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC, 4799 NULL, 0, "Offset to W2k PAC entry", HFILL }}, 4800 { &hf_krb_pac_clientid, { 4801 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, 4802 NULL, 0, "ClientID Timestamp", HFILL }}, 4803 { &hf_krb_pac_namelen, { 4804 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC, 4805 NULL, 0, "Length of client name", HFILL }}, 4806 { &hf_krb_pac_clientname, { 4807 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE, 4808 NULL, 0, "Name of the Client in the PAC structure", HFILL }}, 4809 { &hf_krb_pac_logon_info, { 4810 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE, 4811 NULL, 0, "PAC_LOGON_INFO structure", HFILL }}, 4812 { &hf_krb_pac_credential_data, { 4813 "PAC_CREDENTIAL_DATA", "kerberos.pac_credential_data", FT_BYTES, BASE_NONE, 4814 NULL, 0, "PAC_CREDENTIAL_DATA structure", HFILL }}, 4815 { &hf_krb_pac_credential_info, { 4816 "PAC_CREDENTIAL_INFO", "kerberos.pac_credential_info", FT_BYTES, BASE_NONE, 4817 NULL, 0, "PAC_CREDENTIAL_INFO structure", HFILL }}, 4818 { &hf_krb_pac_credential_info_version, { 4819 "Version", "kerberos.pac_credential_info.version", FT_UINT32, BASE_DEC, 4820 NULL, 0, NULL, HFILL }}, 4821 { &hf_krb_pac_credential_info_etype, { 4822 "Etype", "kerberos.pac_credential_info.etype", FT_UINT32, BASE_DEC, 4823 NULL, 0, NULL, HFILL }}, 4824 { &hf_krb_pac_server_checksum, { 4825 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE, 4826 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }}, 4827 { &hf_krb_pac_privsvr_checksum, { 4828 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE, 4829 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }}, 4830 { &hf_krb_pac_client_info_type, { 4831 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE, 4832 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }}, 4833 { &hf_krb_pac_s4u_delegation_info, { 4834 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE, 4835 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }}, 4836 { &hf_krb_pac_upn_dns_info, { 4837 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE, 4838 NULL, 0, "UPN_DNS_INFO structure", HFILL }}, 4839 { &hf_krb_pac_upn_flags, { 4840 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX, 4841 NULL, 0, "UPN flags", HFILL }}, 4842 { &hf_krb_pac_upn_dns_offset, { 4843 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC, 4844 NULL, 0, NULL, HFILL }}, 4845 { &hf_krb_pac_upn_dns_len, { 4846 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC, 4847 NULL, 0, NULL, HFILL }}, 4848 { &hf_krb_pac_upn_upn_offset, { 4849 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC, 4850 NULL, 0, NULL, HFILL }}, 4851 { &hf_krb_pac_upn_upn_len, { 4852 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC, 4853 NULL, 0, NULL, HFILL }}, 4854 { &hf_krb_pac_upn_upn_name, { 4855 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE, 4856 NULL, 0, NULL, HFILL }}, 4857 { &hf_krb_pac_upn_dns_name, { 4858 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE, 4859 NULL, 0, NULL, HFILL }}, 4860 { &hf_krb_pac_client_claims_info, { 4861 "PAC_CLIENT_CLAIMS_INFO", "kerberos.pac_client_claims_info", FT_BYTES, BASE_NONE, 4862 NULL, 0, "PAC_CLIENT_CLAIMS_INFO structure", HFILL }}, 4863 { &hf_krb_pac_device_info, { 4864 "PAC_DEVICE_INFO", "kerberos.pac_device_info", FT_BYTES, BASE_NONE, 4865 NULL, 0, "PAC_DEVICE_INFO structure", HFILL }}, 4866 { &hf_krb_pac_device_claims_info, { 4867 "PAC_DEVICE_CLAIMS_INFO", "kerberos.pac_device_claims_info", FT_BYTES, BASE_NONE, 4868 NULL, 0, "PAC_DEVICE_CLAIMS_INFO structure", HFILL }}, 4869 { &hf_krb_pac_ticket_checksum, { 4870 "PAC_TICKET_CHECKSUM", "kerberos.pac_ticket_checksum", FT_BYTES, BASE_NONE, 4871 NULL, 0, "PAC_TICKET_CHECKSUM structure", HFILL }}, 4872 { &hf_krb_pa_supported_enctypes, 4873 { "SupportedEnctypes", "kerberos.supported_entypes", 4874 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, 4875 { &hf_krb_pa_supported_enctypes_des_cbc_crc, 4876 { "des-cbc-crc", "kerberos.supported_entypes.des-cbc-crc", 4877 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000001, NULL, HFILL }}, 4878 { &hf_krb_pa_supported_enctypes_des_cbc_md5, 4879 { "des-cbc-md5", "kerberos.supported_entypes.des-cbc-md5", 4880 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000002, NULL, HFILL }}, 4881 { &hf_krb_pa_supported_enctypes_rc4_hmac, 4882 { "rc4-hmac", "kerberos.supported_entypes.rc4-hmac", 4883 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000004, NULL, HFILL }}, 4884 { &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96, 4885 { "aes128-cts-hmac-sha1-96", "kerberos.supported_entypes.aes128-cts-hmac-sha1-96", 4886 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000008, NULL, HFILL }}, 4887 { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96, 4888 { "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96", 4889 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000010, NULL, HFILL }}, 4890 { &hf_krb_pa_supported_enctypes_fast_supported, 4891 { "fast-supported", "kerberos.supported_entypes.fast-supported", 4892 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00010000, NULL, HFILL }}, 4893 { &hf_krb_pa_supported_enctypes_compound_identity_supported, 4894 { "compound-identity-supported", "kerberos.supported_entypes.compound-identity-supported", 4895 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00020000, NULL, HFILL }}, 4896 { &hf_krb_pa_supported_enctypes_claims_supported, 4897 { "claims-supported", "kerberos.supported_entypes.claims-supported", 4898 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00040000, NULL, HFILL }}, 4899 { &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled, 4900 { "resource-sid-compression-disabled", "kerberos.supported_entypes.resource-sid-compression-disabled", 4901 FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00080000, NULL, HFILL }}, 4902 { &hf_krb_ad_ap_options, 4903 { "AD-AP-Options", "kerberos.ad_ap_options", 4904 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, 4905 { &hf_krb_ad_ap_options_cbt, 4906 { "ChannelBindings", "kerberos.ad_ap_options.cbt", 4907 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00004000, NULL, HFILL }}, 4908 { &hf_krb_ad_target_principal, 4909 { "Target Principal", "kerberos.ad_target_principal", 4910 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, 4911 { &hf_krb_key_hidden_item, 4912 { "KeyHiddenItem", "krb5.key_hidden_item", 4913 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 4914 { &hf_kerberos_KERB_TICKET_LOGON, 4915 { "KERB_TICKET_LOGON", "kerberos.KERB_TICKET_LOGON", 4916 FT_NONE, BASE_NONE, NULL, 0, 4917 NULL, HFILL }}, 4918 { &hf_kerberos_KERB_TICKET_LOGON_MessageType, 4919 { "MessageType", "kerberos.KERB_TICKET_LOGON.MessageType", 4920 FT_UINT32, BASE_DEC, VALS(KERB_LOGON_SUBMIT_TYPE), 0, 4921 NULL, HFILL }}, 4922 { &hf_kerberos_KERB_TICKET_LOGON_Flags, 4923 { "Flags", "kerberos.KERB_TICKET_LOGON.Flags", 4924 FT_UINT32, BASE_DEC, NULL, 0, 4925 NULL, HFILL }}, 4926 { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength, 4927 { "ServiceTicketLength", "kerberos.KERB_TICKET_LOGON.ServiceTicketLength", 4928 FT_UINT32, BASE_DEC, NULL, 0, 4929 NULL, HFILL }}, 4930 { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength, 4931 { "TicketGrantingTicketLength", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicketLength", 4932 FT_UINT32, BASE_DEC, NULL, 0, 4933 NULL, HFILL }}, 4934 { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicket, 4935 { "ServiceTicket", "kerberos.KERB_TICKET_LOGON.ServiceTicket", 4936 FT_NONE, BASE_NONE, NULL, 0, 4937 NULL, HFILL }}, 4938 { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket, 4939 { "TicketGrantingTicket", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicket", 4940 FT_NONE, BASE_NONE, NULL, 0, 4941 NULL, HFILL }}, 4942 { &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET, 4943 { "allow_expired_ticket", "kerberos.KERB_TICKET_LOGON.FLAG_ALLOW_EXPIRED_TICKET", 4944 FT_BOOLEAN, 32, NULL, KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET, 4945 NULL, HFILL }}, 4946 { &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED, 4947 { "redirected", "kerberos.KERB_TICKET_LOGON.FLAG_REDIRECTED", 4948 FT_BOOLEAN, 32, NULL, KERB_LOGON_FLAG_REDIRECTED, 4949 NULL, HFILL }}, 4950 #ifdef HAVE_KERBEROS 4951 { &hf_kerberos_KrbFastResponse, 4952 { "KrbFastResponse", "kerberos.KrbFastResponse_element", 4953 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, 4954 { &hf_kerberos_strengthen_key, 4955 { "strengthen-key", "kerberos.strengthen_key_element", 4956 FT_NONE, BASE_NONE, NULL, 0, 4957 NULL, HFILL }}, 4958 { &hf_kerberos_finished, 4959 { "finished", "kerberos.finished_element", 4960 FT_NONE, BASE_NONE, NULL, 0, 4961 "KrbFastFinished", HFILL }}, 4962 { &hf_kerberos_fast_options, 4963 { "fast-options", "kerberos.fast_options", 4964 FT_BYTES, BASE_NONE, NULL, 0, 4965 "FastOptions", HFILL }}, 4966 { &hf_kerberos_FastOptions_reserved, 4967 { "reserved", "kerberos.FastOptions.reserved", 4968 FT_BOOLEAN, 8, NULL, 0x80, 4969 NULL, HFILL }}, 4970 { &hf_kerberos_FastOptions_hide_client_names, 4971 { "hide-client-names", "kerberos.FastOptions.hide.client.names", 4972 FT_BOOLEAN, 8, NULL, 0x40, 4973 NULL, HFILL }}, 4974 { &hf_kerberos_FastOptions_spare_bit2, 4975 { "spare_bit2", "kerberos.FastOptions.spare.bit2", 4976 FT_BOOLEAN, 8, NULL, 0x20, 4977 NULL, HFILL }}, 4978 { &hf_kerberos_FastOptions_spare_bit3, 4979 { "spare_bit3", "kerberos.FastOptions.spare.bit3", 4980 FT_BOOLEAN, 8, NULL, 0x10, 4981 NULL, HFILL }}, 4982 { &hf_kerberos_FastOptions_spare_bit4, 4983 { "spare_bit4", "kerberos.FastOptions.spare.bit4", 4984 FT_BOOLEAN, 8, NULL, 0x08, 4985 NULL, HFILL }}, 4986 { &hf_kerberos_FastOptions_spare_bit5, 4987 { "spare_bit5", "kerberos.FastOptions.spare.bit5", 4988 FT_BOOLEAN, 8, NULL, 0x04, 4989 NULL, HFILL }}, 4990 { &hf_kerberos_FastOptions_spare_bit6, 4991 { "spare_bit6", "kerberos.FastOptions.spare.bit6", 4992 FT_BOOLEAN, 8, NULL, 0x02, 4993 NULL, HFILL }}, 4994 { &hf_kerberos_FastOptions_spare_bit7, 4995 { "spare_bit7", "kerberos.FastOptions.spare.bit7", 4996 FT_BOOLEAN, 8, NULL, 0x01, 4997 NULL, HFILL }}, 4998 { &hf_kerberos_FastOptions_spare_bit8, 4999 { "spare_bit8", "kerberos.FastOptions.spare.bit8", 5000 FT_BOOLEAN, 8, NULL, 0x80, 5001 NULL, HFILL }}, 5002 { &hf_kerberos_FastOptions_spare_bit9, 5003 { "spare_bit9", "kerberos.FastOptions.spare.bit9", 5004 FT_BOOLEAN, 8, NULL, 0x40, 5005 NULL, HFILL }}, 5006 { &hf_kerberos_FastOptions_spare_bit10, 5007 { "spare_bit10", "kerberos.FastOptions.spare.bit10", 5008 FT_BOOLEAN, 8, NULL, 0x20, 5009 NULL, HFILL }}, 5010 { &hf_kerberos_FastOptions_spare_bit11, 5011 { "spare_bit11", "kerberos.FastOptions.spare.bit11", 5012 FT_BOOLEAN, 8, NULL, 0x10, 5013 NULL, HFILL }}, 5014 { &hf_kerberos_FastOptions_spare_bit12, 5015 { "spare_bit12", "kerberos.FastOptions.spare.bit12", 5016 FT_BOOLEAN, 8, NULL, 0x08, 5017 NULL, HFILL }}, 5018 { &hf_kerberos_FastOptions_spare_bit13, 5019 { "spare_bit13", "kerberos.FastOptions.spare.bit13", 5020 FT_BOOLEAN, 8, NULL, 0x04, 5021 NULL, HFILL }}, 5022 { &hf_kerberos_FastOptions_spare_bit14, 5023 { "spare_bit14", "kerberos.FastOptions.spare.bit14", 5024 FT_BOOLEAN, 8, NULL, 0x02, 5025 NULL, HFILL }}, 5026 { &hf_kerberos_FastOptions_spare_bit15, 5027 { "spare_bit15", "kerberos.FastOptions.spare.bit15", 5028 FT_BOOLEAN, 8, NULL, 0x01, 5029 NULL, HFILL }}, 5030 { &hf_kerberos_FastOptions_kdc_follow_referrals, 5031 { "kdc-follow-referrals", "kerberos.FastOptions.kdc.follow.referrals", 5032 FT_BOOLEAN, 8, NULL, 0x80, 5033 NULL, HFILL }}, 5034 { &hf_kerberos_ticket_checksum, 5035 { "ticket-checksum", "kerberos.ticket_checksum_element", 5036 FT_NONE, BASE_NONE, NULL, 0, 5037 "Checksum", HFILL }}, 5038 { &hf_krb_patimestamp, 5039 { "patimestamp", "kerberos.patimestamp", 5040 FT_STRING, BASE_NONE, NULL, 0, "KerberosTime", HFILL }}, 5041 { &hf_krb_pausec, 5042 { "pausec", "kerberos.pausec", 5043 FT_UINT32, BASE_DEC, NULL, 0, "Microseconds", HFILL }}, 5044 #endif /* HAVE_KERBEROS */ 5045 5046 #include "packet-kerberos-hfarr.c" 5047 }; 5048 5049 /* List of subtrees */ 5050 static gint *ett[] = { 5051 &ett_kerberos, 5052 &ett_krb_recordmark, 5053 &ett_krb_pac, 5054 &ett_krb_pac_drep, 5055 &ett_krb_pac_midl_blob, 5056 &ett_krb_pac_logon_info, 5057 &ett_krb_pac_credential_info, 5058 &ett_krb_pac_s4u_delegation_info, 5059 &ett_krb_pac_upn_dns_info, 5060 &ett_krb_pac_device_info, 5061 &ett_krb_pac_server_checksum, 5062 &ett_krb_pac_privsvr_checksum, 5063 &ett_krb_pac_client_info_type, 5064 &ett_krb_pac_ticket_checksum, 5065 &ett_krb_pa_supported_enctypes, 5066 &ett_krb_ad_ap_options, 5067 &ett_kerberos_KERB_TICKET_LOGON, 5068 #ifdef HAVE_KERBEROS 5069 &ett_krb_pa_enc_ts_enc, 5070 &ett_kerberos_KrbFastFinished, 5071 &ett_kerberos_KrbFastResponse, 5072 &ett_kerberos_KrbFastReq, 5073 &ett_kerberos_FastOptions, 5074 #endif 5075 #include "packet-kerberos-ettarr.c" 5076 }; 5077 5078 static ei_register_info ei[] = { 5079 { &ei_kerberos_missing_keytype, { "kerberos.missing_keytype", PI_DECRYPTION, PI_WARN, "Missing keytype", EXPFILL }}, 5080 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decrypted keytype", EXPFILL }}, 5081 { &ei_kerberos_learnt_keytype, { "kerberos.learnt_keytype", PI_SECURITY, PI_CHAT, "Learnt keytype", EXPFILL }}, 5082 { &ei_kerberos_address, { "kerberos.address.unknown", PI_UNDECODED, PI_WARN, "KRB Address: I don't know how to parse this type of address yet", EXPFILL }}, 5083 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }}, 5084 }; 5085 5086 expert_module_t* expert_krb; 5087 module_t *krb_module; 5088 5089 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos"); 5090 proto_register_field_array(proto_kerberos, hf, array_length(hf)); 5091 proto_register_subtree_array(ett, array_length(ett)); 5092 expert_krb = expert_register_protocol(proto_kerberos); 5093 expert_register_field_array(expert_krb, ei, array_length(ei)); 5094 5095 /* Register preferences */ 5096 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb); 5097 prefs_register_bool_preference(krb_module, "desegment", 5098 "Reassemble Kerberos over TCP messages spanning multiple TCP segments", 5099 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments." 5100 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", 5101 &krb_desegment); 5102 #ifdef HAVE_KERBEROS 5103 prefs_register_bool_preference(krb_module, "decrypt", 5104 "Try to decrypt Kerberos blobs", 5105 "Whether the dissector should try to decrypt " 5106 "encrypted Kerberos blobs. This requires that the proper " 5107 "keytab file is installed as well.", &krb_decrypt); 5108 5109 prefs_register_filename_preference(krb_module, "file", 5110 "Kerberos keytab file", 5111 "The keytab file containing all the secrets", 5112 &keytab_filename, FALSE); 5113 5114 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) 5115 wmem_register_callback(wmem_epan_scope(), enc_key_list_cb, NULL); 5116 kerberos_longterm_keys = wmem_map_new(wmem_epan_scope(), 5117 enc_key_content_hash, 5118 enc_key_content_equal); 5119 kerberos_all_keys = wmem_map_new_autoreset(wmem_epan_scope(), 5120 wmem_file_scope(), 5121 enc_key_content_hash, 5122 enc_key_content_equal); 5123 kerberos_app_session_keys = wmem_map_new_autoreset(wmem_epan_scope(), 5124 wmem_file_scope(), 5125 enc_key_content_hash, 5126 enc_key_content_equal); 5127 #endif /* defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) */ 5128 #endif /* HAVE_KERBEROS */ 5129 5130 } 5131 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo, 5132 proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_) 5133 { 5134 tvbuff_t *auth_tvb; 5135 5136 auth_tvb = tvb_new_subset_remaining(tvb, offset); 5137 5138 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL); 5139 5140 return tvb_captured_length_remaining(tvb, offset); 5141 } 5142 5143 5144 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = { 5145 wrap_dissect_gss_kerb, /* Bind */ 5146 wrap_dissect_gss_kerb, /* Bind ACK */ 5147 wrap_dissect_gss_kerb, /* AUTH3 */ 5148 NULL, /* Request verifier */ 5149 NULL, /* Response verifier */ 5150 NULL, /* Request data */ 5151 NULL /* Response data */ 5152 }; 5153 5154 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = { 5155 wrap_dissect_gss_kerb, /* Bind */ 5156 wrap_dissect_gss_kerb, /* Bind ACK */ 5157 wrap_dissect_gss_kerb, /* AUTH3 */ 5158 wrap_dissect_gssapi_verf, /* Request verifier */ 5159 wrap_dissect_gssapi_verf, /* Response verifier */ 5160 NULL, /* Request data */ 5161 NULL /* Response data */ 5162 }; 5163 5164 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = { 5165 wrap_dissect_gss_kerb, /* Bind */ 5166 wrap_dissect_gss_kerb, /* Bind ACK */ 5167 wrap_dissect_gss_kerb, /* AUTH3 */ 5168 wrap_dissect_gssapi_verf, /* Request verifier */ 5169 wrap_dissect_gssapi_verf, /* Response verifier */ 5170 wrap_dissect_gssapi_payload, /* Request data */ 5171 wrap_dissect_gssapi_payload /* Response data */ 5172 }; 5173 5174 5175 5176 void 5177 proto_reg_handoff_kerberos(void) 5178 { 5179 dissector_handle_t kerberos_handle_tcp; 5180 5181 krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos); 5182 5183 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp, 5184 proto_kerberos); 5185 5186 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp, 5187 proto_kerberos); 5188 5189 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp); 5190 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp); 5191 5192 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT, 5193 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS, 5194 &gss_kerb_auth_connect_fns); 5195 5196 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY, 5197 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS, 5198 &gss_kerb_auth_sign_fns); 5199 5200 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY, 5201 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS, 5202 &gss_kerb_auth_seal_fns); 5203 } 5204 5205 /* 5206 * Editor modelines - https://www.wireshark.org/tools/modelines.html 5207 * 5208 * Local variables: 5209 * c-basic-offset: 8 5210 * tab-width: 8 5211 * indent-tabs-mode: t 5212 * End: 5213 * 5214 * vi: set shiftwidth=8 tabstop=8 noexpandtab: 5215 * :indentSize=8:tabSize=8:noTabs=false: 5216 */ 5217