2 * Routines for Kerberos
3 * Wes Hardaker (c) 2000
4 * wjhardaker@ucdavis.edu
5 * Richard Sharpe (C) 2002, rsharpe@samba.org, modularized a bit more and
6 * added AP-REQ and AP-REP dissection
8 * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API.
9 * decryption of kerberos blobs if keytab is provided
11 * See RFC 1510, and various I-Ds and other documents showing additions,
12 * e.g. ones listed under
14 * http://clifford.neuman.name/krb-revisions/
18 * https://tools.ietf.org/html/rfc4120
22 * https://tools.ietf.org/html/rfc6806
24 * Some structures from RFC2630
26 * Wireshark - Network traffic analyzer
27 * By Gerald Combs <gerald@wireshark.org>
28 * Copyright 1998 Gerald Combs
30 * SPDX-License-Identifier: GPL-2.0-or-later
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
47 // krb5.h needs to be included before the defines in packet-kerberos.h
48 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
50 /* prevent redefinition warnings in krb5's win-mac.h */
51 #define SSIZE_T_DEFINED
56 #include <epan/packet.h>
57 #include <epan/proto_data.h>
58 #include <epan/exceptions.h>
59 #include <epan/strutil.h>
60 #include <epan/conversation.h>
61 #include <epan/expert.h>
62 #include <epan/prefs.h>
63 #include <epan/srt_table.h>
65 #include <wsutil/wsgcrypt.h>
66 #include <wsutil/file_util.h>
67 #include <wsutil/str_util.h>
68 #include <wsutil/pint.h>
69 #include <wsutil/array.h>
70 #include "packet-kerberos.h"
71 #include "packet-netbios.h"
72 #include "packet-tcp.h"
73 #include "packet-ber.h"
74 #include "packet-pkinit.h"
75 #include "packet-cms.h"
76 #include "packet-windows-common.h"
78 #include "read_keytab_file.h"
80 #include "packet-dcerpc-netlogon.h"
81 #include "packet-dcerpc.h"
83 #include "packet-gssapi.h"
84 #include "packet-x509af.h"
86 #define KEY_USAGE_FAST_REQ_CHKSUM 50
87 #define KEY_USAGE_FAST_ENC 51
88 #define KEY_USAGE_FAST_REP 52
89 #define KEY_USAGE_FAST_FINISHED 53
90 #define KEY_USAGE_ENC_CHALLENGE_CLIENT 54
91 #define KEY_USAGE_ENC_CHALLENGE_KDC 55
93 void proto_register_kerberos(void);
94 void proto_reg_handoff_kerberos(void);
96 #define UDP_PORT_KERBEROS 88
97 #define TCP_PORT_KERBEROS 88
99 #define ADDRESS_STR_BUFSIZ 256
101 typedef struct kerberos_key
{
104 const uint8_t *keyvalue
;
107 typedef void (*kerberos_key_save_fn
)(tvbuff_t
*tvb _U_
, int offset _U_
, int length _U_
,
108 asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
,
109 int parent_hf_index _U_
,
112 typedef struct kerberos_conv_t
{
116 typedef struct kerberos_frame_t
{
117 struct kerberos_frame_t
*req
;
126 bool is_win2k_pkinit
;
129 uint32_t padata_type
;
130 uint32_t is_enc_padata
;
133 proto_tree
*key_tree
;
134 proto_item
*key_hidden_item
;
136 kerberos_callbacks
*callbacks
;
139 uint32_t checksum_type
;
141 enc_key_t
*last_decryption_key
;
142 enc_key_t
*last_added_key
;
143 enc_key_t
*current_ticket_key
;
144 tvbuff_t
*last_ticket_enc_part_tvb
;
146 int save_encryption_key_parent_hf_index
;
147 kerberos_key_save_fn save_encryption_key_fn
;
148 unsigned learnt_key_ids
;
149 unsigned missing_key_ids
;
150 wmem_list_t
*decryption_keys
;
151 wmem_list_t
*learnt_keys
;
152 wmem_list_t
*missing_keys
;
153 uint32_t within_PA_TGS_REQ
;
154 struct _kerberos_PA_FX_FAST_REQUEST
{
158 } PA_FX_FAST_REQUEST
;
160 enc_key_t
*PA_TGS_REQ_key
;
161 enc_key_t
*PA_TGS_REQ_subkey
;
164 uint32_t fast_armor_within_armor_value
;
166 enc_key_t
*PA_FAST_ARMOR_AP_key
;
167 enc_key_t
*PA_FAST_ARMOR_AP_subkey
;
168 enc_key_t
*fast_armor_key
;
169 enc_key_t
*fast_strengthen_key
;
171 kerberos_conv_t
*krb5_conv
;
172 uint32_t frame_req
, frame_rep
;
174 } kerberos_private_data_t
;
176 static dissector_handle_t kerberos_handle_tcp
;
177 static dissector_handle_t kerberos_handle_udp
;
179 /* Forward declarations */
180 static kerberos_private_data_t
*kerberos_get_private_data(asn1_ctx_t
*actx
);
181 static int dissect_kerberos_Applications(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
182 static int dissect_kerberos_AuthorizationData(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
183 static int dissect_kerberos_PA_ENC_TIMESTAMP(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
185 static int dissect_kerberos_PA_ENC_TS_ENC(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
187 static int dissect_kerberos_PA_PAC_REQUEST(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
188 static int dissect_kerberos_PA_S4U2Self(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
189 static int dissect_kerberos_PA_S4U_X509_USER(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
190 static int dissect_kerberos_ETYPE_INFO(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
191 static int dissect_kerberos_ETYPE_INFO2(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
192 static int dissect_kerberos_AD_IF_RELEVANT(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
193 static int dissect_kerberos_PA_AUTHENTICATION_SET_ELEM(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
194 static int dissect_kerberos_PA_FX_FAST_REQUEST(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
195 static int dissect_kerberos_EncryptedChallenge(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
196 static int dissect_kerberos_PA_KERB_KEY_LIST_REQ(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
197 static int dissect_kerberos_PA_KERB_KEY_LIST_REP(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
198 static int dissect_kerberos_PA_FX_FAST_REPLY(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
199 static int dissect_kerberos_PA_PAC_OPTIONS(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
200 static int dissect_kerberos_KERB_AD_RESTRICTION_ENTRY(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
201 static int dissect_kerberos_SEQUENCE_OF_ENCTYPE(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
202 static int dissect_kerberos_PA_SPAKE(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
203 static int dissect_kerberos_PA_DATA(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
204 static int dissect_kerberos_T_rEP_SEQUENCE_OF_PA_DATA(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
206 static int dissect_kerberos_KrbFastReq(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
207 static int dissect_kerberos_KrbFastResponse(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
208 static int dissect_kerberos_FastOptions(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
210 static int dissect_kerberos_KRB5_SRP_PA_ANNOUNCE(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
211 static int dissect_kerberos_KRB5_SRP_PA_INIT(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
212 static int dissect_kerberos_KRB5_SRP_PA_SERVER_CHALLENGE(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
213 static int dissect_kerberos_KRB5_SRP_PA_CLIENT_RESPONSE(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
214 static int dissect_kerberos_KRB5_SRP_PA_SERVER_VERIFIER(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
);
216 /* Desegment Kerberos over TCP messages */
217 static bool krb_desegment
= true;
219 static int proto_kerberos
;
220 static int kerberos_tap
;
222 static int hf_krb_response_to
;
223 static int hf_krb_response_in
;
224 static int hf_krb_time
;
225 static int hf_krb_rm_reserved
;
226 static int hf_krb_rm_reclen
;
227 static int hf_krb_provsrv_location
;
228 static int hf_krb_pw_salt
;
229 static int hf_krb_ext_error_nt_status
;
230 static int hf_krb_ext_error_reserved
;
231 static int hf_krb_ext_error_flags
;
232 static int hf_krb_address_ip
;
233 static int hf_krb_address_netbios
;
234 static int hf_krb_address_ipv6
;
235 static int hf_krb_gssapi_len
;
236 static int hf_krb_gssapi_bnd
;
237 static int hf_krb_gssapi_dlgopt
;
238 static int hf_krb_gssapi_dlglen
;
239 static int hf_krb_gssapi_c_flag_deleg
;
240 static int hf_krb_gssapi_c_flag_mutual
;
241 static int hf_krb_gssapi_c_flag_replay
;
242 static int hf_krb_gssapi_c_flag_sequence
;
243 static int hf_krb_gssapi_c_flag_conf
;
244 static int hf_krb_gssapi_c_flag_integ
;
245 static int hf_krb_gssapi_c_flag_dce_style
;
246 static int hf_krb_midl_version
;
247 static int hf_krb_midl_hdr_len
;
248 static int hf_krb_midl_fill_bytes
;
249 static int hf_krb_midl_blob_len
;
250 static int hf_krb_pac_signature_type
;
251 static int hf_krb_pac_signature_signature
;
252 static int hf_krb_w2k_pac_entries
;
253 static int hf_krb_w2k_pac_version
;
254 static int hf_krb_w2k_pac_type
;
255 static int hf_krb_w2k_pac_size
;
256 static int hf_krb_w2k_pac_offset
;
257 static int hf_krb_pac_clientid
;
258 static int hf_krb_pac_namelen
;
259 static int hf_krb_pac_clientname
;
260 static int hf_krb_pac_logon_info
;
261 static int hf_krb_pac_credential_data
;
262 static int hf_krb_pac_credential_info
;
263 static int hf_krb_pac_credential_info_version
;
264 static int hf_krb_pac_credential_info_etype
;
265 static int hf_krb_pac_s4u_delegation_info
;
266 static int hf_krb_pac_upn_dns_info
;
267 static int hf_krb_pac_upn_flags
;
268 static int hf_krb_pac_upn_flag_upn_constructed
;
269 static int hf_krb_pac_upn_flag_has_sam_name_and_sid
;
270 static int hf_krb_pac_upn_upn_offset
;
271 static int hf_krb_pac_upn_upn_len
;
272 static int hf_krb_pac_upn_upn_name
;
273 static int hf_krb_pac_upn_dns_offset
;
274 static int hf_krb_pac_upn_dns_len
;
275 static int hf_krb_pac_upn_dns_name
;
276 static int hf_krb_pac_upn_samaccountname_offset
;
277 static int hf_krb_pac_upn_samaccountname_len
;
278 static int hf_krb_pac_upn_samaccountname
;
279 static int hf_krb_pac_upn_objectsid_offset
;
280 static int hf_krb_pac_upn_objectsid_len
;
281 static int hf_krb_pac_server_checksum
;
282 static int hf_krb_pac_privsvr_checksum
;
283 static int hf_krb_pac_client_info_type
;
284 static int hf_krb_pac_client_claims_info
;
285 static int hf_krb_pac_device_info
;
286 static int hf_krb_pac_device_claims_info
;
287 static int hf_krb_pac_ticket_checksum
;
288 static int hf_krb_pac_attributes_info
;
289 static int hf_krb_pac_attributes_info_length
;
290 static int hf_krb_pac_attributes_info_flags
;
291 static int hf_krb_pac_attributes_info_flags_pac_was_requested
;
292 static int hf_krb_pac_attributes_info_flags_pac_was_given_implicitly
;
293 static int hf_krb_pac_requester_sid
;
294 static int hf_krb_pac_full_checksum
;
295 static int hf_krb_pa_supported_enctypes
;
296 static int hf_krb_pa_supported_enctypes_des_cbc_crc
;
297 static int hf_krb_pa_supported_enctypes_des_cbc_md5
;
298 static int hf_krb_pa_supported_enctypes_rc4_hmac
;
299 static int hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96
;
300 static int hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96
;
301 static int hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96_sk
;
302 static int hf_krb_pa_supported_enctypes_fast_supported
;
303 static int hf_krb_pa_supported_enctypes_compound_identity_supported
;
304 static int hf_krb_pa_supported_enctypes_claims_supported
;
305 static int hf_krb_pa_supported_enctypes_resource_sid_compression_disabled
;
306 static int hf_krb_ad_ap_options
;
307 static int hf_krb_ad_ap_options_cbt
;
308 static int hf_krb_ad_ap_options_unverified_target_name
;
309 static int hf_krb_ad_target_principal
;
310 static int hf_krb_key_hidden_item
;
311 static int hf_kerberos_KERB_TICKET_LOGON
;
312 static int hf_kerberos_KERB_TICKET_LOGON_MessageType
;
313 static int hf_kerberos_KERB_TICKET_LOGON_Flags
;
314 static int hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength
;
315 static int hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength
;
316 static int hf_kerberos_KERB_TICKET_LOGON_ServiceTicket
;
317 static int hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket
;
318 static int hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET
;
319 static int hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED
;
321 static int hf_kerberos_KrbFastResponse
;
322 static int hf_kerberos_strengthen_key
;
323 static int hf_kerberos_finished
;
324 static int hf_kerberos_fast_options
;
325 static int hf_kerberos_ticket_checksum
;
326 static int hf_krb_patimestamp
;
327 static int hf_krb_pausec
;
328 static int hf_kerberos_FastOptions_reserved
;
329 static int hf_kerberos_FastOptions_hide_client_names
;
330 static int hf_kerberos_FastOptions_spare_bit2
;
331 static int hf_kerberos_FastOptions_spare_bit3
;
332 static int hf_kerberos_FastOptions_spare_bit4
;
333 static int hf_kerberos_FastOptions_spare_bit5
;
334 static int hf_kerberos_FastOptions_spare_bit6
;
335 static int hf_kerberos_FastOptions_spare_bit7
;
336 static int hf_kerberos_FastOptions_spare_bit8
;
337 static int hf_kerberos_FastOptions_spare_bit9
;
338 static int hf_kerberos_FastOptions_spare_bit10
;
339 static int hf_kerberos_FastOptions_spare_bit11
;
340 static int hf_kerberos_FastOptions_spare_bit12
;
341 static int hf_kerberos_FastOptions_spare_bit13
;
342 static int hf_kerberos_FastOptions_spare_bit14
;
343 static int hf_kerberos_FastOptions_spare_bit15
;
344 static int hf_kerberos_FastOptions_kdc_follow_referrals
;
347 #include "packet-kerberos-hf.c"
349 /* Initialize the subtree pointers */
350 static int ett_kerberos
;
351 static int ett_krb_recordmark
;
352 static int ett_krb_pac
;
353 static int ett_krb_pac_drep
;
354 static int ett_krb_pac_midl_blob
;
355 static int ett_krb_pac_logon_info
;
356 static int ett_krb_pac_credential_info
;
357 static int ett_krb_pac_s4u_delegation_info
;
358 static int ett_krb_pac_upn_dns_info
;
359 static int ett_krb_pac_upn_dns_info_flags
;
360 static int ett_krb_pac_device_info
;
361 static int ett_krb_pac_server_checksum
;
362 static int ett_krb_pac_privsvr_checksum
;
363 static int ett_krb_pac_client_info_type
;
364 static int ett_krb_pac_ticket_checksum
;
365 static int ett_krb_pac_attributes_info
;
366 static int ett_krb_pac_attributes_info_flags
;
367 static int ett_krb_pac_requester_sid
;
368 static int ett_krb_pac_full_checksum
;
369 static int ett_krb_pa_supported_enctypes
;
370 static int ett_krb_ad_ap_options
;
371 static int ett_kerberos_KERB_TICKET_LOGON
;
373 static int ett_krb_pa_enc_ts_enc
;
374 static int ett_kerberos_KrbFastFinished
;
375 static int ett_kerberos_KrbFastResponse
;
376 static int ett_kerberos_KrbFastReq
;
377 static int ett_kerberos_FastOptions
;
379 #include "packet-kerberos-ett.c"
381 static expert_field ei_kerberos_missing_keytype
;
382 static expert_field ei_kerberos_decrypted_keytype
;
383 static expert_field ei_kerberos_learnt_keytype
;
384 static expert_field ei_kerberos_address
;
385 static expert_field ei_krb_gssapi_dlglen
;
387 static dissector_handle_t krb4_handle
;
389 /* Global variables */
390 static uint32_t gbl_keytype
;
391 static bool gbl_do_col_info
;
393 #include "packet-kerberos-val.h"
396 call_kerberos_callbacks(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int tag
, kerberos_callbacks
*cb
)
404 cb
->callback(pinfo
, tvb
, tree
);
413 krb5_frame_compare(gconstpointer a
, gconstpointer b
)
415 kerberos_frame_t
*fa
= (kerberos_frame_t
*)a
;
416 kerberos_frame_t
*fb
= (kerberos_frame_t
*)b
;
418 return fa
->frame
- fb
->frame
;
421 static kerberos_conv_t
*krb5_conv_find_or_create(packet_info
*pinfo
)
423 conversation_t
*conversation
= NULL
;
424 kerberos_conv_t
*kconv
= NULL
;
426 conversation
= find_or_create_conversation(pinfo
);
427 kconv
= (kerberos_conv_t
*)conversation_get_proto_data(conversation
,
430 kconv
= wmem_new0(wmem_file_scope(), kerberos_conv_t
);
431 kconv
->frames
= wmem_list_new(wmem_file_scope());
433 conversation_add_proto_data(conversation
, proto_kerberos
, kconv
);
439 static void krb5_conf_add_request(asn1_ctx_t
*actx
)
441 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
442 packet_info
*pinfo
= actx
->pinfo
;
443 kerberos_frame_t _krqf
= { .frame
= 0, };
444 kerberos_frame_t
*krqf
= NULL
;
445 wmem_list_frame_t
*wf
= NULL
;
446 kerberos_frame_t
*krpf
= NULL
;
448 if (private_data
->krb5_conv
== NULL
)
451 if (!pinfo
->fd
->visited
) {
452 krqf
= wmem_new0(wmem_file_scope(), kerberos_frame_t
);
460 krqf
->frame
= pinfo
->num
;
461 krqf
->time
= pinfo
->abs_ts
;
462 krqf
->msg_type
= private_data
->msg_type
;
465 if (!pinfo
->fd
->visited
) {
466 wmem_list_insert_sorted(private_data
->krb5_conv
->frames
,
467 krqf
, krb5_frame_compare
);
470 wf
= wmem_list_find_custom(private_data
->krb5_conv
->frames
,
471 krqf
, krb5_frame_compare
);
473 /* The next one should be the response */
474 wf
= wmem_list_frame_next(wf
);
479 krpf
= (kerberos_frame_t
*)wmem_list_frame_data(wf
);
481 switch (krpf
->msg_type
) {
482 case KERBEROS_APPLICATIONS_AS_REP
:
483 case KERBEROS_APPLICATIONS_TGS_REP
:
484 case KERBEROS_APPLICATIONS_KRB_ERROR
:
490 private_data
->frame_rep
= krpf
->frame
;
493 static void krb5_conf_add_response(asn1_ctx_t
*actx
)
495 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
496 packet_info
*pinfo
= actx
->pinfo
;
497 kerberos_frame_t _krpf
= { .frame
= 0, };
498 kerberos_frame_t
*krpf
= NULL
;
499 wmem_list_frame_t
*wf
= NULL
;
500 kerberos_frame_t
*krqf
= NULL
;
502 if (private_data
->krb5_conv
== NULL
)
505 if (!pinfo
->fd
->visited
) {
506 krpf
= wmem_new0(wmem_file_scope(), kerberos_frame_t
);
514 krpf
->frame
= pinfo
->num
;
515 krpf
->time
= pinfo
->abs_ts
;
516 krpf
->msg_type
= private_data
->msg_type
;
519 if (!pinfo
->fd
->visited
) {
520 wmem_list_insert_sorted(private_data
->krb5_conv
->frames
,
521 krpf
, krb5_frame_compare
);
524 wf
= wmem_list_find_custom(private_data
->krb5_conv
->frames
,
525 krpf
, krb5_frame_compare
);
528 * replace the pointer with the one allocated on
531 krpf
= (kerberos_frame_t
*)wmem_list_frame_data(wf
);
532 /* The previous one should be the request */
533 wf
= wmem_list_frame_prev(wf
);
538 krqf
= (kerberos_frame_t
*)wmem_list_frame_data(wf
);
541 switch (krqf
->msg_type
) {
542 case KERBEROS_APPLICATIONS_AS_REQ
:
543 if (private_data
->msg_type
== KERBEROS_APPLICATIONS_AS_REP
) {
547 if (private_data
->msg_type
== KERBEROS_APPLICATIONS_KRB_ERROR
) {
552 case KERBEROS_APPLICATIONS_TGS_REQ
:
553 if (private_data
->msg_type
== KERBEROS_APPLICATIONS_TGS_REP
) {
557 if (private_data
->msg_type
== KERBEROS_APPLICATIONS_KRB_ERROR
) {
566 private_data
->frame_req
= krqf
->frame
;
567 private_data
->req_time
= krqf
->time
;
569 tap_queue_packet(kerberos_tap
, pinfo
, krpf
);
573 krb5stat_init(struct register_srt
* srt _U_
, GArray
* srt_array _U_
)
575 srt_stat_table
*krb5_srt_table
= NULL
;
577 krb5_srt_table
= init_srt_table("Kerberos", "krb5", srt_array
, 4, NULL
, "kerberos.msg_type", NULL
);
578 init_srt_table_row(krb5_srt_table
, 0, "AS-REP");
579 init_srt_table_row(krb5_srt_table
, 1, "AS-ERROR");
580 init_srt_table_row(krb5_srt_table
, 2, "TGS-REP");
581 init_srt_table_row(krb5_srt_table
, 3, "TGS-ERROR");
584 static tap_packet_status
585 krb5stat_packet(void *pss _U_
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *prv
, tap_flags_t flags _U_
)
587 srt_stat_table
*krb5_srt_table
= NULL
;
588 srt_data_t
*data
= (srt_data_t
*)pss
;
589 kerberos_frame_t
*krpf
= (kerberos_frame_t
*)prv
;
592 return TAP_PACKET_DONT_REDRAW
;
594 if (krpf
->req
== NULL
)
595 return TAP_PACKET_DONT_REDRAW
;
597 krb5_srt_table
= g_array_index(data
->srt_array
, srt_stat_table
*, 0);
598 add_srt_table_data(krb5_srt_table
, krpf
->srt_idx
, &krpf
->req
->time
, pinfo
);
599 return TAP_PACKET_REDRAW
;
602 static kerberos_private_data_t
*
603 kerberos_new_private_data(packet_info
*pinfo
)
605 kerberos_private_data_t
*p
;
608 p
= wmem_new0(pinfo
->pool
, kerberos_private_data_t
);
612 p
->frame_req
= UINT32_MAX
;
613 p
->frame_rep
= UINT32_MAX
;
615 p
->decryption_keys
= wmem_list_new(pinfo
->pool
);
616 p
->learnt_keys
= wmem_list_new(pinfo
->pool
);
617 p
->missing_keys
= wmem_list_new(pinfo
->pool
);
619 existing
= p_get_proto_data(pinfo
->pool
, pinfo
, proto_kerberos
, 0);
620 if (existing
!= NULL
) {
622 * We only remember the first one.
627 p_add_proto_data(pinfo
->pool
, pinfo
, proto_kerberos
, 0, p
);
628 p
->krb5_conv
= krb5_conv_find_or_create(pinfo
);
632 static kerberos_private_data_t
*
633 kerberos_get_private_data(asn1_ctx_t
*actx
)
635 if (!actx
->private_data
) {
636 actx
->private_data
= kerberos_new_private_data(actx
->pinfo
);
638 return (kerberos_private_data_t
*)(actx
->private_data
);
642 kerberos_private_is_kdc_req(kerberos_private_data_t
*private_data
)
644 switch (private_data
->msg_type
) {
645 case KERBEROS_APPLICATIONS_AS_REQ
:
646 case KERBEROS_APPLICATIONS_TGS_REQ
:
654 kerberos_is_win2k_pkinit(asn1_ctx_t
*actx
)
656 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
658 return private_data
->is_win2k_pkinit
;
661 static int dissect_kerberos_defer_PA_FX_FAST_REQUEST(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
)
663 kerberos_private_data_t
* private_data
= kerberos_get_private_data(actx
);
666 * dissect_ber_octet_string_wcb() always passes
667 * implicit_tag=false, offset=0 and hf_index=-1
669 * It means we only need to remember tvb and tree
670 * in order to replay dissect_kerberos_PA_FX_FAST_REQUEST()
671 * in dissect_kerberos_T_rEQ_SEQUENCE_OF_PA_DATA()
673 ws_assert(implicit_tag
== false);
674 ws_assert(offset
== 0);
675 ws_assert(hf_index
<= 0);
677 if (private_data
->PA_FX_FAST_REQUEST
.defer
) {
679 * Remember the tvb (and the optional tree)
681 private_data
->PA_FX_FAST_REQUEST
.tvb
= tvb
;
682 private_data
->PA_FX_FAST_REQUEST
.tree
= tree
;
684 * only handle the first PA_FX_FAST_REQUEST...
686 private_data
->PA_FX_FAST_REQUEST
.defer
= false;
687 return tvb_reported_length_remaining(tvb
, offset
);
690 return dissect_kerberos_PA_FX_FAST_REQUEST(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
695 /* Decrypt Kerberos blobs */
698 /* keytab filename */
699 static const char *keytab_filename
= "";
702 read_keytab_file_from_preferences(void)
704 static char *last_keytab
= NULL
;
710 if (keytab_filename
== NULL
) {
714 if (last_keytab
&& !strcmp(last_keytab
, keytab_filename
)) {
719 last_keytab
= g_strdup(keytab_filename
);
721 read_keytab_file(last_keytab
);
723 #endif /* HAVE_KERBEROS */
725 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
726 enc_key_t
*enc_key_list
=NULL
;
727 enc_key_t
*kerberos_last_decryption_key
=NULL
;
728 static unsigned kerberos_longterm_ids
;
729 wmem_map_t
*kerberos_longterm_keys
;
730 static wmem_map_t
*kerberos_all_keys
;
731 static wmem_map_t
*kerberos_app_session_keys
;
734 enc_key_list_cb(wmem_allocator_t
* allocator _U_
, wmem_cb_event_t event _U_
, void *user_data _U_
)
737 kerberos_longterm_ids
= 0;
738 /* keep the callback registered */
742 static int enc_key_cmp_id(const void *k1
, const void *k2
)
744 const enc_key_t
*key1
= (const enc_key_t
*)k1
;
745 const enc_key_t
*key2
= (const enc_key_t
*)k2
;
747 if (key1
->fd_num
< key2
->fd_num
) {
750 if (key1
->fd_num
> key2
->fd_num
) {
754 if (key1
->id
< key2
->id
) {
757 if (key1
->id
> key2
->id
) {
765 enc_key_content_equal(const void *k1
, const void *k2
)
767 const enc_key_t
*key1
= (const enc_key_t
*)k1
;
768 const enc_key_t
*key2
= (const enc_key_t
*)k2
;
771 if (key1
->keytype
!= key2
->keytype
) {
775 if (key1
->keylength
!= key2
->keylength
) {
779 cmp
= memcmp(key1
->keyvalue
, key2
->keyvalue
, key1
->keylength
);
788 enc_key_content_hash(const void *k
)
790 const enc_key_t
*key
= (const enc_key_t
*)k
;
793 ret
+= wmem_strong_hash((const uint8_t *)&key
->keytype
,
794 sizeof(key
->keytype
));
795 ret
+= wmem_strong_hash((const uint8_t *)&key
->keylength
,
796 sizeof(key
->keylength
));
797 ret
+= wmem_strong_hash((const uint8_t *)key
->keyvalue
,
804 kerberos_key_map_insert(wmem_map_t
*key_map
, enc_key_t
*new_key
)
806 enc_key_t
*existing
= NULL
;
807 enc_key_t
*cur
= NULL
;
810 existing
= (enc_key_t
*)wmem_map_lookup(key_map
, new_key
);
811 if (existing
== NULL
) {
812 wmem_map_insert(key_map
, new_key
, new_key
);
816 if (key_map
!= kerberos_all_keys
) {
818 * It should already be linked to the existing key...
823 if (existing
->fd_num
== -1 && new_key
->fd_num
!= -1) {
825 * We can't reference a learnt key
826 * from a longterm key. As they have
827 * a shorter lifetime.
829 * So just let the learnt key remember the
832 new_key
->same_list
= existing
;
833 new_key
->num_same
= existing
->num_same
+ 1;
838 * If a key with the same content (keytype,keylength,keyvalue)
839 * already exists, we want the earliest key to be
842 cmp
= enc_key_cmp_id(new_key
, existing
);
845 * It's the same, nothing to do...
850 /* The new key has should be added to the list. */
851 new_key
->same_list
= existing
;
852 new_key
->num_same
= existing
->num_same
+ 1;
853 wmem_map_insert(key_map
, new_key
, new_key
);
858 * We want to link the new_key to the existing one.
860 * But we want keep the list sorted, so we need to forward
861 * to the correct spot.
863 for (cur
= existing
; cur
->same_list
!= NULL
; cur
= cur
->same_list
) {
864 cmp
= enc_key_cmp_id(new_key
, cur
->same_list
);
867 * It's the same, nothing to do...
874 * We found the correct spot,
875 * the new_key should added
876 * between existing and existing->same_list
878 new_key
->same_list
= cur
->same_list
;
879 new_key
->num_same
= cur
->num_same
;
885 * finally link new_key to existing
886 * and fix up the numbers
888 cur
->same_list
= new_key
;
889 for (cur
= existing
; cur
!= new_key
; cur
= cur
->same_list
) {
896 struct insert_longterm_keys_into_key_map_state
{
900 static void insert_longterm_keys_into_key_map_cb(void *__key _U_
,
904 struct insert_longterm_keys_into_key_map_state
*state
=
905 (struct insert_longterm_keys_into_key_map_state
*)user_data
;
906 enc_key_t
*key
= (enc_key_t
*)value
;
908 kerberos_key_map_insert(state
->key_map
, key
);
911 static void insert_longterm_keys_into_key_map(wmem_map_t
*key_map
)
914 * Because the kerberos_longterm_keys are allocated on
915 * wmem_epan_scope() and kerberos_all_keys are allocated
916 * on wmem_file_scope(), we need to plug the longterm keys
917 * back to kerberos_all_keys if a new file was loaded
918 * and wmem_file_scope() got cleared.
920 if (wmem_map_size(key_map
) < wmem_map_size(kerberos_longterm_keys
)) {
921 struct insert_longterm_keys_into_key_map_state state
= {
925 * Reference all longterm keys into kerberos_all_keys
927 wmem_map_foreach(kerberos_longterm_keys
,
928 insert_longterm_keys_into_key_map_cb
,
934 kerberos_key_list_append(wmem_list_t
*key_list
, enc_key_t
*new_key
)
936 enc_key_t
*existing
= NULL
;
938 existing
= (enc_key_t
*)wmem_list_find(key_list
, new_key
);
939 if (existing
!= NULL
) {
943 wmem_list_append(key_list
, new_key
);
947 kerberos_inject_longterm_key(packet_info
*pinfo
,
948 proto_tree
*key_tree
,
949 proto_item
*key_hidden_item
,
951 int keytype
, int keylength
, const uint8_t *keyvalue
,
954 wmem_allocator_t
*key_scope
= NULL
;
955 enc_key_t
*new_key
= NULL
;
956 const char *methodl
= "learnt";
957 const char *methodu
= "Learnt";
958 proto_item
*item
= NULL
;
960 if(pinfo
->fd
->visited
){
962 * We already processed this,
963 * we can use a shortterm scope
965 key_scope
= pinfo
->pool
;
968 * As long as we have enc_key_list, we need to
969 * use wmem_epan_scope(), when that's gone
970 * we can dynamically select the scope based on
971 * how long we'll need the particular key.
973 key_scope
= wmem_epan_scope();
976 new_key
= wmem_new0(key_scope
, enc_key_t
);
977 snprintf(new_key
->key_origin
, KRB_MAX_ORIG_LEN
, "%s %s in frame %u",
978 methodl
, origin
, pinfo
->num
);
979 new_key
->fd_num
= -1; /* indication for longterm key for FAST */
980 new_key
->id
= ++kerberos_longterm_ids
;
981 snprintf(new_key
->id_str
, KRB_MAX_ID_STR_LEN
, "learnt.%d.%u",
982 pinfo
->num
, new_key
->id
);
983 new_key
->keytype
=keytype
;
984 new_key
->keylength
=keylength
;
985 memcpy(new_key
->keyvalue
, keyvalue
, MIN(keylength
, KRB_MAX_KEY_LENGTH
));
987 if(!pinfo
->fd
->visited
){
989 * Only keep it if we don't processed it before.
991 new_key
->next
=enc_key_list
;
992 enc_key_list
=new_key
;
993 kerberos_key_map_insert(kerberos_longterm_keys
, new_key
);
994 insert_longterm_keys_into_key_map(kerberos_all_keys
);
995 kerberos_key_map_insert(kerberos_all_keys
, new_key
);
998 item
= proto_tree_add_expert_format(key_tree
, pinfo
, &ei_kerberos_learnt_keytype
,
999 key_tvb
, 0, keylength
,
1000 "%s %s keytype %d (id=%s) (%02x%02x%02x%02x...)",
1001 methodu
, origin
, keytype
, new_key
->id_str
,
1002 keyvalue
[0] & 0xFF, keyvalue
[1] & 0xFF,
1003 keyvalue
[2] & 0xFF, keyvalue
[3] & 0xFF);
1004 if (item
!= NULL
&& key_hidden_item
!= NULL
) {
1005 proto_tree_move_item(key_tree
, key_hidden_item
, item
);
1010 add_encryption_key(packet_info
*pinfo
,
1011 kerberos_private_data_t
*private_data
,
1012 proto_tree
*key_tree
,
1013 proto_item
*key_hidden_item
,
1015 int keytype
, int keylength
, const char *keyvalue
,
1017 enc_key_t
*src1
, enc_key_t
*src2
)
1019 wmem_allocator_t
*key_scope
= NULL
;
1020 enc_key_t
*new_key
= NULL
;
1021 const char *methodl
= "learnt";
1022 const char *methodu
= "Learnt";
1023 proto_item
*item
= NULL
;
1025 private_data
->last_added_key
= NULL
;
1027 if (src1
!= NULL
&& src2
!= NULL
) {
1028 methodl
= "derived";
1029 methodu
= "Derived";
1032 if(pinfo
->fd
->visited
){
1034 * We already processed this,
1035 * we can use a shortterm scope
1037 key_scope
= pinfo
->pool
;
1040 * As long as we have enc_key_list, we need to
1041 * use wmem_epan_scope(), when that's gone
1042 * we can dynamically select the scope based on
1043 * how long we'll need the particular key.
1045 key_scope
= wmem_epan_scope();
1048 new_key
= wmem_new0(key_scope
, enc_key_t
);
1049 snprintf(new_key
->key_origin
, KRB_MAX_ORIG_LEN
, "%s %s in frame %u",
1050 methodl
, origin
, pinfo
->num
);
1051 new_key
->fd_num
= pinfo
->num
;
1052 new_key
->id
= ++private_data
->learnt_key_ids
;
1053 snprintf(new_key
->id_str
, KRB_MAX_ID_STR_LEN
, "%d.%u",
1054 new_key
->fd_num
, new_key
->id
);
1055 new_key
->keytype
=keytype
;
1056 new_key
->keylength
=keylength
;
1057 memcpy(new_key
->keyvalue
, keyvalue
, MIN(keylength
, KRB_MAX_KEY_LENGTH
));
1058 new_key
->src1
= src1
;
1059 new_key
->src2
= src2
;
1061 if(!pinfo
->fd
->visited
){
1063 * Only keep it if we don't processed it before.
1065 new_key
->next
=enc_key_list
;
1066 enc_key_list
=new_key
;
1067 insert_longterm_keys_into_key_map(kerberos_all_keys
);
1068 kerberos_key_map_insert(kerberos_all_keys
, new_key
);
1071 item
= proto_tree_add_expert_format(key_tree
, pinfo
, &ei_kerberos_learnt_keytype
,
1072 key_tvb
, 0, keylength
,
1073 "%s %s keytype %d (id=%d.%u) (%02x%02x%02x%02x...)",
1074 methodu
, origin
, keytype
, pinfo
->num
, new_key
->id
,
1075 keyvalue
[0] & 0xFF, keyvalue
[1] & 0xFF,
1076 keyvalue
[2] & 0xFF, keyvalue
[3] & 0xFF);
1077 if (item
!= NULL
&& key_hidden_item
!= NULL
) {
1078 proto_tree_move_item(key_tree
, key_hidden_item
, item
);
1081 enc_key_t
*sek
= src1
;
1082 expert_add_info_format(pinfo
, item
, &ei_kerberos_learnt_keytype
,
1083 "SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
1084 sek
->key_origin
, sek
->keytype
,
1085 sek
->id_str
, sek
->num_same
,
1086 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
1087 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
1090 enc_key_t
*sek
= src2
;
1091 expert_add_info_format(pinfo
, item
, &ei_kerberos_learnt_keytype
,
1092 "SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
1093 sek
->key_origin
, sek
->keytype
,
1094 sek
->id_str
, sek
->num_same
,
1095 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
1096 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
1099 kerberos_key_list_append(private_data
->learnt_keys
, new_key
);
1100 private_data
->last_added_key
= new_key
;
1104 save_encryption_key(tvbuff_t
*tvb _U_
, int offset _U_
, int length _U_
,
1105 asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
,
1106 int parent_hf_index _U_
,
1109 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
1110 const char *parent
= proto_registrar_get_name(parent_hf_index
);
1111 const char *element
= proto_registrar_get_name(hf_index
);
1112 char origin
[KRB_MAX_ORIG_LEN
] = { 0, };
1114 snprintf(origin
, KRB_MAX_ORIG_LEN
, "%s_%s", parent
, element
);
1116 add_encryption_key(actx
->pinfo
,
1118 private_data
->key_tree
,
1119 private_data
->key_hidden_item
,
1120 private_data
->key_tvb
,
1121 private_data
->key
.keytype
,
1122 private_data
->key
.keylength
,
1123 private_data
->key
.keyvalue
,
1130 save_Authenticator_subkey(tvbuff_t
*tvb
, int offset
, int length
,
1131 asn1_ctx_t
*actx
, proto_tree
*tree
,
1132 int parent_hf_index
,
1135 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
1137 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
1139 if (private_data
->last_decryption_key
== NULL
) {
1142 if (private_data
->last_added_key
== NULL
) {
1146 if (private_data
->within_PA_TGS_REQ
!= 0) {
1147 private_data
->PA_TGS_REQ_key
= private_data
->last_decryption_key
;
1148 private_data
->PA_TGS_REQ_subkey
= private_data
->last_added_key
;
1150 if (private_data
->fast_armor_within_armor_value
!= 0) {
1151 private_data
->PA_FAST_ARMOR_AP_key
= private_data
->last_decryption_key
;
1152 private_data
->PA_FAST_ARMOR_AP_subkey
= private_data
->last_added_key
;
1157 save_EncAPRepPart_subkey(tvbuff_t
*tvb
, int offset
, int length
,
1158 asn1_ctx_t
*actx
, proto_tree
*tree
,
1159 int parent_hf_index
,
1162 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
1164 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
1166 if (actx
->pinfo
->fd
->visited
) {
1170 if (private_data
->last_added_key
== NULL
) {
1174 private_data
->last_added_key
->is_ap_rep_key
= true;
1176 if (private_data
->last_decryption_key
!= NULL
&&
1177 private_data
->last_decryption_key
->is_ticket_key
)
1179 enc_key_t
*ak
= private_data
->last_added_key
;
1180 enc_key_t
*tk
= private_data
->last_decryption_key
;
1183 * The enc_key_t structures and their strings
1184 * in pac_names are all allocated on wmem_epan_scope(),
1185 * so we don't need to copy the content.
1187 ak
->pac_names
= tk
->pac_names
;
1190 kerberos_key_map_insert(kerberos_app_session_keys
, private_data
->last_added_key
);
1194 save_EncKDCRepPart_key(tvbuff_t
*tvb
, int offset
, int length
,
1195 asn1_ctx_t
*actx
, proto_tree
*tree
,
1196 int parent_hf_index
,
1199 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
1203 save_EncTicketPart_key(tvbuff_t
*tvb
, int offset
, int length
,
1204 asn1_ctx_t
*actx
, proto_tree
*tree
,
1205 int parent_hf_index
,
1208 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
1210 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
1212 if (actx
->pinfo
->fd
->visited
) {
1216 if (private_data
->last_added_key
== NULL
) {
1220 private_data
->current_ticket_key
= private_data
->last_added_key
;
1221 private_data
->current_ticket_key
->is_ticket_key
= true;
1225 save_KrbCredInfo_key(tvbuff_t
*tvb
, int offset
, int length
,
1226 asn1_ctx_t
*actx
, proto_tree
*tree
,
1227 int parent_hf_index
,
1230 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
1234 save_KrbFastResponse_strengthen_key(tvbuff_t
*tvb
, int offset
, int length
,
1235 asn1_ctx_t
*actx
, proto_tree
*tree
,
1236 int parent_hf_index
,
1239 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
1241 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
1243 private_data
->fast_strengthen_key
= private_data
->last_added_key
;
1246 static void used_encryption_key(proto_tree
*tree
, packet_info
*pinfo
,
1247 kerberos_private_data_t
*private_data
,
1248 enc_key_t
*ek
, int usage
, tvbuff_t
*cryptotvb
,
1249 const char *keymap_name
,
1250 unsigned keymap_size
,
1251 unsigned decryption_count
)
1253 proto_item
*item
= NULL
;
1254 enc_key_t
*sek
= NULL
;
1256 item
= proto_tree_add_expert_format(tree
, pinfo
, &ei_kerberos_decrypted_keytype
,
1258 "Decrypted keytype %d usage %d "
1259 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)",
1260 ek
->keytype
, usage
, ek
->key_origin
, ek
->id_str
, ek
->num_same
,
1261 ek
->keyvalue
[0] & 0xFF, ek
->keyvalue
[1] & 0xFF,
1262 ek
->keyvalue
[2] & 0xFF, ek
->keyvalue
[3] & 0xFF);
1263 expert_add_info_format(pinfo
, item
, &ei_kerberos_decrypted_keytype
,
1264 "Used keymap=%s num_keys=%u num_tries=%u)",
1268 if (ek
->src1
!= NULL
) {
1270 expert_add_info_format(pinfo
, item
, &ei_kerberos_decrypted_keytype
,
1271 "SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
1272 sek
->key_origin
, sek
->keytype
,
1273 sek
->id_str
, sek
->num_same
,
1274 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
1275 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
1277 if (ek
->src2
!= NULL
) {
1279 expert_add_info_format(pinfo
, item
, &ei_kerberos_decrypted_keytype
,
1280 "SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
1281 sek
->key_origin
, sek
->keytype
,
1282 sek
->id_str
, sek
->num_same
,
1283 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
1284 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
1286 sek
= ek
->same_list
;
1287 while (sek
!= NULL
) {
1288 expert_add_info_format(pinfo
, item
, &ei_kerberos_decrypted_keytype
,
1289 "Decrypted keytype %d usage %d "
1290 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)",
1291 sek
->keytype
, usage
, sek
->key_origin
, sek
->id_str
, sek
->num_same
,
1292 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
1293 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
1294 sek
= sek
->same_list
;
1296 kerberos_key_list_append(private_data
->decryption_keys
, ek
);
1297 private_data
->last_decryption_key
= ek
;
1298 kerberos_last_decryption_key
= ek
;
1300 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
1302 #ifdef HAVE_MIT_KERBEROS
1304 static void missing_encryption_key(proto_tree
*tree
, packet_info
*pinfo
,
1305 kerberos_private_data_t
*private_data
,
1306 int keytype
, int usage
, tvbuff_t
*cryptotvb
,
1307 const char *keymap_name
,
1308 unsigned keymap_size
,
1309 unsigned decryption_count
)
1311 proto_item
*item
= NULL
;
1312 enc_key_t
*mek
= NULL
;
1314 mek
= wmem_new0(pinfo
->pool
, enc_key_t
);
1315 snprintf(mek
->key_origin
, KRB_MAX_ORIG_LEN
,
1316 "keytype %d usage %d missing in frame %u",
1317 keytype
, usage
, pinfo
->num
);
1318 mek
->fd_num
= pinfo
->num
;
1319 mek
->id
= ++private_data
->missing_key_ids
;
1320 snprintf(mek
->id_str
, KRB_MAX_ID_STR_LEN
, "missing.%u",
1322 mek
->keytype
=keytype
;
1324 item
= proto_tree_add_expert_format(tree
, pinfo
, &ei_kerberos_missing_keytype
,
1326 "Missing keytype %d usage %d (id=%s)",
1327 keytype
, usage
, mek
->id_str
);
1328 expert_add_info_format(pinfo
, item
, &ei_kerberos_missing_keytype
,
1329 "Used keymap=%s num_keys=%u num_tries=%u)",
1334 kerberos_key_list_append(private_data
->missing_keys
, mek
);
1337 #ifdef HAVE_KRB5_PAC_VERIFY
1338 static void used_signing_key(proto_tree
*tree
, packet_info
*pinfo
,
1339 kerberos_private_data_t
*private_data
,
1340 enc_key_t
*ek
, tvbuff_t
*tvb
,
1341 krb5_cksumtype checksum
,
1343 const char *keymap_name
,
1344 unsigned keymap_size
,
1345 unsigned verify_count
)
1347 proto_item
*item
= NULL
;
1348 enc_key_t
*sek
= NULL
;
1350 item
= proto_tree_add_expert_format(tree
, pinfo
, &ei_kerberos_decrypted_keytype
,
1352 "%s checksum %d keytype %d "
1353 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)",
1354 reason
, checksum
, ek
->keytype
, ek
->key_origin
,
1355 ek
->id_str
, ek
->num_same
,
1356 ek
->keyvalue
[0] & 0xFF, ek
->keyvalue
[1] & 0xFF,
1357 ek
->keyvalue
[2] & 0xFF, ek
->keyvalue
[3] & 0xFF);
1358 expert_add_info_format(pinfo
, item
, &ei_kerberos_decrypted_keytype
,
1359 "Used keymap=%s num_keys=%u num_tries=%u)",
1363 sek
= ek
->same_list
;
1364 while (sek
!= NULL
) {
1365 expert_add_info_format(pinfo
, item
, &ei_kerberos_decrypted_keytype
,
1366 "%s checksum %d keytype %d "
1367 "using %s (id=%s same=%u) (%02x%02x%02x%02x...)",
1368 reason
, checksum
, sek
->keytype
, sek
->key_origin
,
1369 sek
->id_str
, sek
->num_same
,
1370 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
1371 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
1372 sek
= sek
->same_list
;
1374 kerberos_key_list_append(private_data
->decryption_keys
, ek
);
1377 static void missing_signing_key(proto_tree
*tree
, packet_info
*pinfo
,
1378 kerberos_private_data_t
*private_data
,
1380 krb5_cksumtype checksum
,
1383 const char *keymap_name
,
1384 unsigned keymap_size
,
1385 unsigned verify_count
)
1387 proto_item
*item
= NULL
;
1388 enc_key_t
*mek
= NULL
;
1390 mek
= wmem_new0(pinfo
->pool
, enc_key_t
);
1391 snprintf(mek
->key_origin
, KRB_MAX_ORIG_LEN
,
1392 "checksum %d keytype %d missing in frame %u",
1393 checksum
, keytype
, pinfo
->num
);
1394 mek
->fd_num
= pinfo
->num
;
1395 mek
->id
= ++private_data
->missing_key_ids
;
1396 snprintf(mek
->id_str
, KRB_MAX_ID_STR_LEN
, "missing.%u",
1398 mek
->keytype
=keytype
;
1400 item
= proto_tree_add_expert_format(tree
, pinfo
, &ei_kerberos_missing_keytype
,
1402 "%s checksum %d keytype %d (id=%s)",
1403 reason
, checksum
, keytype
, mek
->id_str
);
1404 expert_add_info_format(pinfo
, item
, &ei_kerberos_missing_keytype
,
1405 "Used keymap=%s num_keys=%u num_tries=%u)",
1410 kerberos_key_list_append(private_data
->missing_keys
, mek
);
1413 #endif /* HAVE_KRB5_PAC_VERIFY */
1415 static krb5_context krb5_ctx
;
1417 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
1419 krb5_fast_key(asn1_ctx_t
*actx
, proto_tree
*tree
, tvbuff_t
*tvb
,
1420 enc_key_t
*ek1 _U_
, const char *p1 _U_
,
1421 enc_key_t
*ek2 _U_
, const char *p2 _U_
,
1422 const char *origin _U_
)
1424 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
1425 krb5_error_code ret
;
1428 krb5_keyblock
*k
= NULL
;
1442 k1
.magic
= KV5M_KEYBLOCK
;
1443 k1
.enctype
= ek1
->keytype
;
1444 k1
.length
= ek1
->keylength
;
1445 k1
.contents
= (uint8_t *)ek1
->keyvalue
;
1447 k2
.magic
= KV5M_KEYBLOCK
;
1448 k2
.enctype
= ek2
->keytype
;
1449 k2
.length
= ek2
->keylength
;
1450 k2
.contents
= (uint8_t *)ek2
->keyvalue
;
1452 ret
= krb5_c_fx_cf2_simple(krb5_ctx
, &k1
, p1
, &k2
, p2
, &k
);
1457 add_encryption_key(actx
->pinfo
,
1460 k
->enctype
, k
->length
,
1461 (const char *)k
->contents
,
1465 krb5_free_keyblock(krb5_ctx
, k
);
1467 #else /* HAVE_KRB5_C_FX_CF2_SIMPLE */
1469 krb5_fast_key(asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, tvbuff_t
*tvb _U_
,
1470 enc_key_t
*ek1 _U_
, const char *p1 _U_
,
1471 enc_key_t
*ek2 _U_
, const char *p2 _U_
,
1472 const char *origin _U_
)
1475 #endif /* HAVE_KRB5_C_FX_CF2_SIMPLE */
1477 USES_APPLE_DEPRECATED_API
1479 read_keytab_file(const char *filename
)
1482 krb5_error_code ret
;
1483 krb5_keytab_entry key
;
1484 krb5_kt_cursor cursor
;
1485 static bool first_time
=true;
1487 if (filename
== NULL
|| filename
[0] == 0) {
1493 ret
= krb5_init_context(&krb5_ctx
);
1494 if(ret
&& ret
!= KRB5_CONFIG_CANTOPEN
){
1499 /* should use a file in the wireshark users dir */
1500 ret
= krb5_kt_resolve(krb5_ctx
, filename
, &keytab
);
1502 fprintf(stderr
, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename
);
1507 ret
= krb5_kt_start_seq_get(krb5_ctx
, keytab
, &cursor
);
1509 fprintf(stderr
, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename
);
1514 ret
= krb5_kt_next_entry(krb5_ctx
, keytab
, &key
, &cursor
);
1520 new_key
= wmem_new0(wmem_epan_scope(), enc_key_t
);
1521 new_key
->fd_num
= -1;
1522 new_key
->id
= ++kerberos_longterm_ids
;
1523 snprintf(new_key
->id_str
, KRB_MAX_ID_STR_LEN
, "keytab.%u", new_key
->id
);
1524 new_key
->next
= enc_key_list
;
1526 /* generate origin string, describing where this key came from */
1527 pos
=new_key
->key_origin
;
1528 pos
+=MIN(KRB_MAX_ORIG_LEN
,
1529 snprintf(pos
, KRB_MAX_ORIG_LEN
, "keytab principal "));
1530 for(i
=0;i
<key
.principal
->length
;i
++){
1531 pos
+=MIN(KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
),
1532 snprintf(pos
, KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
), "%s%s",(i
?"/":""),(key
.principal
->data
[i
]).data
));
1534 pos
+=MIN(KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
),
1535 snprintf(pos
, KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
), "@%s",key
.principal
->realm
.data
));
1537 new_key
->keytype
=key
.key
.enctype
;
1538 new_key
->keylength
=key
.key
.length
;
1539 memcpy(new_key
->keyvalue
,
1541 MIN(key
.key
.length
, KRB_MAX_KEY_LENGTH
));
1543 enc_key_list
=new_key
;
1544 ret
= krb5_free_keytab_entry_contents(krb5_ctx
, &key
);
1546 fprintf(stderr
, "KERBEROS ERROR: Could not release the entry: %d", ret
);
1547 ret
= 0; /* try to continue with the next entry */
1549 kerberos_key_map_insert(kerberos_longterm_keys
, new_key
);
1553 ret
= krb5_kt_end_seq_get(krb5_ctx
, keytab
, &cursor
);
1555 fprintf(stderr
, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret
);
1557 ret
= krb5_kt_close(krb5_ctx
, keytab
);
1559 fprintf(stderr
, "KERBEROS ERROR: Could not close the key table handle: %d", ret
);
1563 struct decrypt_krb5_with_cb_state
{
1566 kerberos_private_data_t
*private_data
;
1569 tvbuff_t
*cryptotvb
;
1570 krb5_error_code (*decrypt_cb_fn
)(
1571 const krb5_keyblock
*key
,
1573 void *decrypt_cb_data
);
1574 void *decrypt_cb_data
;
1580 decrypt_krb5_with_cb_try_key(void *__key _U_
, void *value
, void *userdata
)
1582 struct decrypt_krb5_with_cb_state
*state
=
1583 (struct decrypt_krb5_with_cb_state
*)userdata
;
1584 enc_key_t
*ek
= (enc_key_t
*)value
;
1585 krb5_error_code ret
;
1586 krb5_keytab_entry key
;
1587 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
1588 enc_key_t
*ak
= state
->private_data
->fast_armor_key
;
1589 enc_key_t
*sk
= state
->private_data
->fast_strengthen_key
;
1590 bool try_with_armor_key
= false;
1591 bool try_with_strengthen_key
= false;
1594 if (state
->ek
!= NULL
) {
1601 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
1602 if (ak
!= NULL
&& ak
!= ek
&& ak
->keytype
== state
->keytype
&& ek
->fd_num
== -1) {
1603 switch (state
->usage
) {
1604 case KEY_USAGE_ENC_CHALLENGE_CLIENT
:
1605 case KEY_USAGE_ENC_CHALLENGE_KDC
:
1606 if (ek
->fd_num
== -1) {
1607 /* Challenges are based on a long term key */
1608 try_with_armor_key
= true;
1614 * If we already have a strengthen_key
1615 * we don't need to try with the armor key
1619 try_with_armor_key
= false;
1623 if (sk
!= NULL
&& sk
!= ek
&& sk
->keytype
== state
->keytype
&& sk
->keytype
== ek
->keytype
) {
1624 switch (state
->usage
) {
1626 if (ek
->fd_num
== -1) {
1627 /* AS-REP is based on a long term key */
1628 try_with_strengthen_key
= true;
1633 if (ek
->fd_num
!= -1) {
1634 /* TGS-REP is not based on a long term key */
1635 try_with_strengthen_key
= true;
1641 if (try_with_armor_key
) {
1644 krb5_keyblock
*k
= NULL
;
1645 const char *p1
= NULL
;
1647 k1
.magic
= KV5M_KEYBLOCK
;
1648 k1
.enctype
= ak
->keytype
;
1649 k1
.length
= ak
->keylength
;
1650 k1
.contents
= (uint8_t *)ak
->keyvalue
;
1652 k2
.magic
= KV5M_KEYBLOCK
;
1653 k2
.enctype
= ek
->keytype
;
1654 k2
.length
= ek
->keylength
;
1655 k2
.contents
= (uint8_t *)ek
->keyvalue
;
1657 switch (state
->usage
) {
1658 case KEY_USAGE_ENC_CHALLENGE_CLIENT
:
1659 p1
= "clientchallengearmor";
1661 case KEY_USAGE_ENC_CHALLENGE_KDC
:
1662 p1
= "kdcchallengearmor";
1666 * Should never be called!
1669 * try the next one...
1674 ret
= krb5_c_fx_cf2_simple(krb5_ctx
,
1676 &k2
, "challengelongterm",
1680 * try the next one...
1686 ret
= state
->decrypt_cb_fn(k
,
1688 state
->decrypt_cb_data
);
1690 add_encryption_key(state
->pinfo
,
1691 state
->private_data
,
1695 k
->enctype
, k
->length
,
1696 (const char *)k
->contents
,
1699 krb5_free_keyblock(krb5_ctx
, k
);
1701 * remember the key and stop traversing
1703 state
->ek
= state
->private_data
->last_added_key
;
1706 krb5_free_keyblock(krb5_ctx
, k
);
1708 * don't stop traversing...
1709 * try the next one...
1714 if (try_with_strengthen_key
) {
1717 krb5_keyblock
*k
= NULL
;
1719 k1
.magic
= KV5M_KEYBLOCK
;
1720 k1
.enctype
= sk
->keytype
;
1721 k1
.length
= sk
->keylength
;
1722 k1
.contents
= (uint8_t *)sk
->keyvalue
;
1724 k2
.magic
= KV5M_KEYBLOCK
;
1725 k2
.enctype
= ek
->keytype
;
1726 k2
.length
= ek
->keylength
;
1727 k2
.contents
= (uint8_t *)ek
->keyvalue
;
1729 ret
= krb5_c_fx_cf2_simple(krb5_ctx
,
1730 &k1
, "strengthenkey",
1735 * try the next one...
1741 ret
= state
->decrypt_cb_fn(k
,
1743 state
->decrypt_cb_data
);
1745 add_encryption_key(state
->pinfo
,
1746 state
->private_data
,
1750 k
->enctype
, k
->length
,
1751 (const char *)k
->contents
,
1752 "strengthen-reply-key",
1754 krb5_free_keyblock(krb5_ctx
, k
);
1756 * remember the key and stop traversing
1758 state
->ek
= state
->private_data
->last_added_key
;
1761 krb5_free_keyblock(krb5_ctx
, k
);
1763 * don't stop traversing...
1764 * try the next one...
1768 #endif /* HAVE_KRB5_C_FX_CF2_SIMPLE */
1770 /* shortcircuit and bail out if enctypes are not matching */
1771 if ((state
->keytype
!= -1) && (ek
->keytype
!= state
->keytype
)) {
1773 * don't stop traversing...
1774 * try the next one...
1779 key
.key
.enctype
=ek
->keytype
;
1780 key
.key
.length
=ek
->keylength
;
1781 key
.key
.contents
=ek
->keyvalue
;
1783 ret
= state
->decrypt_cb_fn(&(key
.key
),
1785 state
->decrypt_cb_data
);
1788 * don't stop traversing...
1789 * try the next one...
1795 * we're done, remember the key
1800 static krb5_error_code
1801 decrypt_krb5_with_cb(proto_tree
*tree
,
1803 kerberos_private_data_t
*private_data
,
1806 tvbuff_t
*cryptotvb
,
1807 krb5_error_code (*decrypt_cb_fn
)(
1808 const krb5_keyblock
*key
,
1810 void *decrypt_cb_data
),
1811 void *decrypt_cb_data
)
1813 const char *key_map_name
= NULL
;
1814 wmem_map_t
*key_map
= NULL
;
1815 struct decrypt_krb5_with_cb_state state
= {
1818 .private_data
= private_data
,
1820 .cryptotvb
= cryptotvb
,
1822 .decrypt_cb_fn
= decrypt_cb_fn
,
1823 .decrypt_cb_data
= decrypt_cb_data
,
1826 read_keytab_file_from_preferences();
1829 case KRB5_KU_USAGE_INITIATOR_SEAL
:
1830 case KRB5_KU_USAGE_ACCEPTOR_SEAL
:
1831 key_map_name
= "app_session_keys";
1832 key_map
= kerberos_app_session_keys
;
1835 key_map_name
= "all_keys";
1836 key_map
= kerberos_all_keys
;
1837 insert_longterm_keys_into_key_map(key_map
);
1841 wmem_map_foreach(key_map
, decrypt_krb5_with_cb_try_key
, &state
);
1842 if (state
.ek
!= NULL
) {
1843 used_encryption_key(tree
, pinfo
, private_data
,
1844 state
.ek
, usage
, cryptotvb
,
1846 wmem_map_size(key_map
),
1851 missing_encryption_key(tree
, pinfo
, private_data
,
1852 keytype
, usage
, cryptotvb
,
1854 wmem_map_size(key_map
),
1859 struct decrypt_krb5_data_state
{
1864 static krb5_error_code
1865 decrypt_krb5_data_cb(const krb5_keyblock
*key
,
1867 void *decrypt_cb_data
)
1869 struct decrypt_krb5_data_state
*state
=
1870 (struct decrypt_krb5_data_state
*)decrypt_cb_data
;
1871 krb5_enc_data input
;
1873 memset(&input
, 0, sizeof(input
));
1874 input
.enctype
= key
->enctype
;
1875 input
.ciphertext
= state
->input
;
1877 return krb5_c_decrypt(krb5_ctx
,
1886 decrypt_krb5_data_private(proto_tree
*tree _U_
, packet_info
*pinfo
,
1887 kerberos_private_data_t
*private_data
,
1888 int usage
, tvbuff_t
*cryptotvb
, int keytype
,
1891 #define HAVE_DECRYPT_KRB5_DATA_PRIVATE 1
1892 struct decrypt_krb5_data_state state
;
1893 krb5_error_code ret
;
1894 int length
= tvb_captured_length(cryptotvb
);
1895 const uint8_t *cryptotext
= tvb_get_ptr(cryptotvb
, 0, length
);
1897 /* don't do anything if we are not attempting to decrypt data */
1898 if(!krb_decrypt
|| length
< 1){
1902 /* make sure we have all the data we need */
1903 if (tvb_captured_length(cryptotvb
) < tvb_reported_length(cryptotvb
)) {
1907 memset(&state
, 0, sizeof(state
));
1908 state
.input
.length
= length
;
1909 state
.input
.data
= (uint8_t *)cryptotext
;
1910 state
.output
.data
= (char *)wmem_alloc(pinfo
->pool
, length
);
1911 state
.output
.length
= length
;
1913 ret
= decrypt_krb5_with_cb(tree
,
1919 decrypt_krb5_data_cb
,
1926 *datalen
= state
.output
.length
;
1928 return (uint8_t *)state
.output
.data
;
1932 decrypt_krb5_data(proto_tree
*tree _U_
, packet_info
*pinfo
,
1934 tvbuff_t
*cryptotvb
,
1938 kerberos_private_data_t
*zero_private
= kerberos_new_private_data(pinfo
);
1939 return decrypt_krb5_data_private(tree
, pinfo
, zero_private
,
1940 usage
, cryptotvb
, keytype
,
1946 #ifdef KRB5_CRYPTO_TYPE_SIGN_ONLY
1947 struct decrypt_krb5_krb_cfx_dce_state
{
1948 const uint8_t *gssapi_header_ptr
;
1949 unsigned gssapi_header_len
;
1950 tvbuff_t
*gssapi_encrypted_tvb
;
1951 uint8_t *gssapi_payload
;
1952 unsigned gssapi_payload_len
;
1953 const uint8_t *gssapi_trailer_ptr
;
1954 unsigned gssapi_trailer_len
;
1955 tvbuff_t
*checksum_tvb
;
1957 unsigned checksum_len
;
1960 static krb5_error_code
1961 decrypt_krb5_krb_cfx_dce_cb(const krb5_keyblock
*key
,
1963 void *decrypt_cb_data
)
1965 struct decrypt_krb5_krb_cfx_dce_state
*state
=
1966 (struct decrypt_krb5_krb_cfx_dce_state
*)decrypt_cb_data
;
1967 unsigned int k5_headerlen
= 0;
1968 unsigned int k5_headerofs
= 0;
1969 unsigned int k5_trailerlen
= 0;
1970 unsigned int k5_trailerofs
= 0;
1971 size_t _k5_blocksize
= 0;
1972 unsigned k5_blocksize
;
1973 krb5_crypto_iov iov
[6];
1974 krb5_error_code ret
;
1975 unsigned checksum_remain
= state
->checksum_len
;
1976 unsigned checksum_crypt_len
;
1978 memset(iov
, 0, sizeof(iov
));
1980 ret
= krb5_c_crypto_length(krb5_ctx
,
1982 KRB5_CRYPTO_TYPE_HEADER
,
1987 if (checksum_remain
< k5_headerlen
) {
1990 checksum_remain
-= k5_headerlen
;
1991 k5_headerofs
= checksum_remain
;
1992 ret
= krb5_c_crypto_length(krb5_ctx
,
1994 KRB5_CRYPTO_TYPE_TRAILER
,
1999 if (checksum_remain
< k5_trailerlen
) {
2002 checksum_remain
-= k5_trailerlen
;
2003 k5_trailerofs
= checksum_remain
;
2004 checksum_crypt_len
= checksum_remain
;
2006 ret
= krb5_c_block_size(krb5_ctx
,
2013 * The cast is required for the Windows build in order
2014 * to avoid the following warning.
2016 * warning C4267: '-=': conversion from 'size_t' to 'unsigned',
2017 * possible loss of data
2019 k5_blocksize
= (unsigned)_k5_blocksize
;
2020 if (checksum_remain
< k5_blocksize
) {
2023 checksum_remain
-= k5_blocksize
;
2024 if (checksum_remain
< 16) {
2028 tvb_memcpy(state
->gssapi_encrypted_tvb
,
2029 state
->gssapi_payload
,
2031 state
->gssapi_payload_len
);
2032 tvb_memcpy(state
->checksum_tvb
,
2035 state
->checksum_len
);
2037 iov
[0].flags
= KRB5_CRYPTO_TYPE_HEADER
;
2038 iov
[0].data
.data
= state
->checksum
+ k5_headerofs
;
2039 iov
[0].data
.length
= k5_headerlen
;
2041 if (state
->gssapi_header_ptr
!= NULL
) {
2042 iov
[1].flags
= KRB5_CRYPTO_TYPE_SIGN_ONLY
;
2043 iov
[1].data
.data
= (uint8_t *)(uintptr_t)state
->gssapi_header_ptr
;
2044 iov
[1].data
.length
= state
->gssapi_header_len
;
2046 iov
[1].flags
= KRB5_CRYPTO_TYPE_EMPTY
;
2049 iov
[2].flags
= KRB5_CRYPTO_TYPE_DATA
;
2050 iov
[2].data
.data
= state
->gssapi_payload
;
2051 iov
[2].data
.length
= state
->gssapi_payload_len
;
2053 if (state
->gssapi_trailer_ptr
!= NULL
) {
2054 iov
[3].flags
= KRB5_CRYPTO_TYPE_SIGN_ONLY
;
2055 iov
[3].data
.data
= (uint8_t *)(uintptr_t)state
->gssapi_trailer_ptr
;
2056 iov
[3].data
.length
= state
->gssapi_trailer_len
;
2058 iov
[3].flags
= KRB5_CRYPTO_TYPE_EMPTY
;
2061 iov
[4].flags
= KRB5_CRYPTO_TYPE_DATA
;
2062 iov
[4].data
.data
= state
->checksum
;
2063 iov
[4].data
.length
= checksum_crypt_len
;
2065 iov
[5].flags
= KRB5_CRYPTO_TYPE_TRAILER
;
2066 iov
[5].data
.data
= state
->checksum
+ k5_trailerofs
;
2067 iov
[5].data
.length
= k5_trailerlen
;
2069 return krb5_c_decrypt_iov(krb5_ctx
,
2078 decrypt_krb5_krb_cfx_dce(proto_tree
*tree
,
2082 tvbuff_t
*gssapi_header_tvb
,
2083 tvbuff_t
*gssapi_encrypted_tvb
,
2084 tvbuff_t
*gssapi_trailer_tvb
,
2085 tvbuff_t
*checksum_tvb
)
2087 struct decrypt_krb5_krb_cfx_dce_state state
;
2088 kerberos_private_data_t
*zero_private
= kerberos_new_private_data(pinfo
);
2089 tvbuff_t
*gssapi_decrypted_tvb
= NULL
;
2090 krb5_error_code ret
;
2092 /* don't do anything if we are not attempting to decrypt data */
2097 memset(&state
, 0, sizeof(state
));
2099 /* make sure we have all the data we need */
2100 #define __CHECK_TVB_LEN(__tvb) (tvb_captured_length(__tvb) < tvb_reported_length(__tvb))
2101 if (gssapi_header_tvb
!= NULL
) {
2102 if (__CHECK_TVB_LEN(gssapi_header_tvb
)) {
2106 state
.gssapi_header_len
= tvb_captured_length(gssapi_header_tvb
);
2107 state
.gssapi_header_ptr
= tvb_get_ptr(gssapi_header_tvb
,
2109 state
.gssapi_header_len
);
2111 if (gssapi_encrypted_tvb
== NULL
|| __CHECK_TVB_LEN(gssapi_encrypted_tvb
)) {
2114 state
.gssapi_encrypted_tvb
= gssapi_encrypted_tvb
;
2115 state
.gssapi_payload_len
= tvb_captured_length(gssapi_encrypted_tvb
);
2116 state
.gssapi_payload
= (uint8_t *)wmem_alloc0(pinfo
->pool
, state
.gssapi_payload_len
);
2117 if (state
.gssapi_payload
== NULL
) {
2120 if (gssapi_trailer_tvb
!= NULL
) {
2121 if (__CHECK_TVB_LEN(gssapi_trailer_tvb
)) {
2125 state
.gssapi_trailer_len
= tvb_captured_length(gssapi_trailer_tvb
);
2126 state
.gssapi_trailer_ptr
= tvb_get_ptr(gssapi_trailer_tvb
,
2128 state
.gssapi_trailer_len
);
2130 if (checksum_tvb
== NULL
|| __CHECK_TVB_LEN(checksum_tvb
)) {
2133 state
.checksum_tvb
= checksum_tvb
;
2134 state
.checksum_len
= tvb_captured_length(checksum_tvb
);
2135 state
.checksum
= (uint8_t *)wmem_alloc0(pinfo
->pool
, state
.checksum_len
);
2136 if (state
.checksum
== NULL
) {
2140 ret
= decrypt_krb5_with_cb(tree
,
2145 gssapi_encrypted_tvb
,
2146 decrypt_krb5_krb_cfx_dce_cb
,
2148 wmem_free(pinfo
->pool
, state
.checksum
);
2150 wmem_free(pinfo
->pool
, state
.gssapi_payload
);
2154 gssapi_decrypted_tvb
= tvb_new_child_real_data(gssapi_encrypted_tvb
,
2155 state
.gssapi_payload
,
2156 state
.gssapi_payload_len
,
2157 state
.gssapi_payload_len
);
2158 if (gssapi_decrypted_tvb
== NULL
) {
2159 wmem_free(pinfo
->pool
, state
.gssapi_payload
);
2163 return gssapi_decrypted_tvb
;
2165 #else /* NOT KRB5_CRYPTO_TYPE_SIGN_ONLY */
2166 #define NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP 1
2167 #endif /* NOT KRB5_CRYPTO_TYPE_SIGN_ONLY */
2169 #ifdef HAVE_KRB5_PAC_VERIFY
2171 * macOS up to 10.14.5 only has a MIT shim layer on top
2172 * of heimdal. It means that krb5_pac_verify() is not available
2173 * in /usr/lib/libkrb5.dylib
2175 * https://opensource.apple.com/tarballs/Heimdal/Heimdal-520.260.1.tar.gz
2176 * https://opensource.apple.com/tarballs/MITKerberosShim/MITKerberosShim-71.200.1.tar.gz
2179 extern krb5_error_code
2180 krb5int_c_mandatory_cksumtype(krb5_context
, krb5_enctype
, krb5_cksumtype
*);
2182 extern void krb5_free_enc_tkt_part(krb5_context
, krb5_enc_tkt_part
*);
2183 extern krb5_error_code
2184 decode_krb5_enc_tkt_part(const krb5_data
*output
, krb5_enc_tkt_part
**rep
);
2185 extern krb5_error_code
2186 encode_krb5_enc_tkt_part(const krb5_enc_tkt_part
*rep
, krb5_data
**code
);
2189 keytype_for_cksumtype(krb5_cksumtype checksum
)
2191 static const int keytypes
[] = {
2198 for (i
= 0; i
< array_length(keytypes
); i
++) {
2199 krb5_cksumtype checksumtype
= 0;
2200 krb5_error_code ret
;
2202 ret
= krb5int_c_mandatory_cksumtype(krb5_ctx
,
2208 if (checksum
== checksumtype
) {
2216 struct verify_krb5_pac_state
{
2217 int pacbuffer_length
;
2218 const uint8_t *pacbuffer
;
2220 krb5_cksumtype server_checksum
;
2221 unsigned server_count
;
2222 enc_key_t
*server_ek
;
2223 krb5_cksumtype kdc_checksum
;
2226 krb5_cksumtype ticket_checksum_type
;
2227 const krb5_data
*ticket_checksum_data
;
2228 krb5_cksumtype full_checksum_type
;
2229 const krb5_data
*full_checksum_data
;
2230 unsigned full_count
;
2235 verify_krb5_pac_try_server_key(void *__key _U_
, void *value
, void *userdata
)
2237 struct verify_krb5_pac_state
*state
=
2238 (struct verify_krb5_pac_state
*)userdata
;
2239 enc_key_t
*ek
= (enc_key_t
*)value
;
2240 krb5_keyblock keyblock
;
2241 krb5_cksumtype checksumtype
= 0;
2242 krb5_error_code ret
;
2244 if (state
->server_checksum
== 0) {
2246 * nothing more todo, stop traversing.
2251 if (state
->server_ek
!= NULL
) {
2258 ret
= krb5int_c_mandatory_cksumtype(krb5_ctx
, ek
->keytype
,
2262 * the key is not usable, keep traversing.
2263 * try the next key...
2268 keyblock
.magic
= KV5M_KEYBLOCK
;
2269 keyblock
.enctype
= ek
->keytype
;
2270 keyblock
.length
= ek
->keylength
;
2271 keyblock
.contents
= (uint8_t *)ek
->keyvalue
;
2273 if (checksumtype
== state
->server_checksum
) {
2274 state
->server_count
+= 1;
2275 ret
= krb5_pac_verify(krb5_ctx
, state
->pac
, 0, NULL
,
2278 state
->server_ek
= ek
;
2284 verify_krb5_pac_try_kdc_key(void *__key _U_
, void *value
, void *userdata
)
2286 struct verify_krb5_pac_state
*state
=
2287 (struct verify_krb5_pac_state
*)userdata
;
2288 enc_key_t
*ek
= (enc_key_t
*)value
;
2289 krb5_keyblock keyblock
;
2290 krb5_cksumtype checksumtype
= 0;
2291 krb5_error_code ret
;
2293 if (state
->kdc_checksum
== 0) {
2295 * nothing more todo, stop traversing.
2300 if (state
->kdc_ek
!= NULL
) {
2307 ret
= krb5int_c_mandatory_cksumtype(krb5_ctx
, ek
->keytype
,
2311 * the key is not usable, keep traversing.
2312 * try the next key...
2317 keyblock
.magic
= KV5M_KEYBLOCK
;
2318 keyblock
.enctype
= ek
->keytype
;
2319 keyblock
.length
= ek
->keylength
;
2320 keyblock
.contents
= (uint8_t *)ek
->keyvalue
;
2322 if (checksumtype
== state
->kdc_checksum
) {
2323 state
->kdc_count
+= 1;
2324 ret
= krb5_pac_verify(krb5_ctx
, state
->pac
, 0, NULL
,
2332 #define __KRB5_PAC_TICKET_CHECKSUM 16
2335 verify_krb5_pac_ticket_checksum(proto_tree
*tree _U_
,
2336 asn1_ctx_t
*actx _U_
,
2337 tvbuff_t
*pactvb _U_
,
2338 struct verify_krb5_pac_state
*state _U_
)
2340 #ifdef HAVE_DECODE_KRB5_ENC_TKT_PART
2341 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
2342 tvbuff_t
*teptvb
= private_data
->last_ticket_enc_part_tvb
;
2343 unsigned teplength
= 0;
2344 const uint8_t *tepbuffer
= NULL
;
2345 krb5_data tepdata
= { .length
= 0, };
2346 krb5_enc_tkt_part
*tep
= NULL
;
2347 krb5_data
*tmpdata
= NULL
;
2348 krb5_error_code ret
;
2349 krb5_authdata
**recoded_container
= NULL
;
2350 int ad_orig_idx
= -1;
2351 krb5_authdata
*ad_orig_ptr
= NULL
;
2353 krb5_keyblock kdc_key
= { .magic
= KV5M_KEYBLOCK
, };
2354 size_t checksum_length
= 0;
2355 krb5_checksum checksum
= { .checksum_type
= 0, };
2356 krb5_boolean valid
= false;
2358 if (state
->kdc_ek
== NULL
) {
2359 int keytype
= keytype_for_cksumtype(state
->ticket_checksum_type
);
2360 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2361 pactvb
, state
->ticket_checksum_type
,
2363 "Missing KDC (for ticket)",
2370 if (teptvb
== NULL
) {
2374 teplength
= tvb_captured_length(teptvb
);
2375 /* make sure we have all the data we need */
2376 if (teplength
< tvb_reported_length(teptvb
)) {
2380 tepbuffer
= tvb_get_ptr(teptvb
, 0, teplength
);
2381 if (tepbuffer
== NULL
) {
2385 kdc_key
.magic
= KV5M_KEYBLOCK
;
2386 kdc_key
.enctype
= state
->kdc_ek
->keytype
;
2387 kdc_key
.length
= state
->kdc_ek
->keylength
;
2388 kdc_key
.contents
= (uint8_t *)state
->kdc_ek
->keyvalue
;
2390 checksum
.checksum_type
= state
->ticket_checksum_type
;
2391 checksum
.length
= state
->ticket_checksum_data
->length
;
2392 checksum
.contents
= (uint8_t *)state
->ticket_checksum_data
->data
;
2393 if (checksum
.length
>= 4) {
2394 checksum
.length
-= 4;
2395 checksum
.contents
+= 4;
2398 ret
= krb5_c_checksum_length(krb5_ctx
,
2399 checksum
.checksum_type
,
2402 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2403 pactvb
, state
->ticket_checksum_type
,
2404 state
->kdc_ek
->keytype
,
2405 "krb5_c_checksum_length failed for Ticket Signature",
2411 checksum
.length
= MIN(checksum
.length
, (unsigned int)checksum_length
);
2413 tepdata
.data
= (void *)tepbuffer
;
2414 tepdata
.length
= teplength
;
2416 ret
= decode_krb5_enc_tkt_part(&tepdata
, &tep
);
2418 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2419 pactvb
, state
->ticket_checksum_type
,
2420 state
->kdc_ek
->keytype
,
2421 "decode_krb5_enc_tkt_part failed",
2428 for (l0idx
= 0; tep
->authorization_data
[l0idx
]; l0idx
++) {
2429 krb5_authdata
*adl0
= tep
->authorization_data
[l0idx
];
2430 krb5_authdata
**decoded_container
= NULL
;
2431 krb5_authdata
*ad_pac
= NULL
;
2434 if (adl0
->ad_type
!= KRB5_AUTHDATA_IF_RELEVANT
) {
2438 ret
= krb5_decode_authdata_container(krb5_ctx
,
2439 KRB5_AUTHDATA_IF_RELEVANT
,
2441 &decoded_container
);
2443 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2444 pactvb
, state
->ticket_checksum_type
,
2445 state
->kdc_ek
->keytype
,
2446 "krb5_decode_authdata_container failed",
2450 krb5_free_enc_tkt_part(krb5_ctx
, tep
);
2454 for (l1idx
= 0; decoded_container
[l1idx
]; l1idx
++) {
2455 krb5_authdata
*adl1
= decoded_container
[l1idx
];
2457 if (adl1
->ad_type
!= KRB5_AUTHDATA_WIN2K_PAC
) {
2465 if (ad_pac
== NULL
) {
2466 krb5_free_authdata(krb5_ctx
, decoded_container
);
2471 ad_pac
->contents
[0] = '\0';
2473 ret
= krb5_encode_authdata_container(krb5_ctx
,
2474 KRB5_AUTHDATA_IF_RELEVANT
,
2476 &recoded_container
);
2477 krb5_free_authdata(krb5_ctx
, decoded_container
);
2478 decoded_container
= NULL
;
2480 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2481 pactvb
, state
->ticket_checksum_type
,
2482 state
->kdc_ek
->keytype
,
2483 "krb5_encode_authdata_container failed",
2487 krb5_free_enc_tkt_part(krb5_ctx
, tep
);
2491 ad_orig_idx
= l0idx
;
2493 tep
->authorization_data
[l0idx
] = recoded_container
[0];
2497 ret
= encode_krb5_enc_tkt_part(tep
, &tmpdata
);
2498 if (ad_orig_ptr
!= NULL
) {
2499 tep
->authorization_data
[ad_orig_idx
] = ad_orig_ptr
;
2501 krb5_free_enc_tkt_part(krb5_ctx
, tep
);
2503 if (recoded_container
!= NULL
) {
2504 krb5_free_authdata(krb5_ctx
, recoded_container
);
2505 recoded_container
= NULL
;
2508 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2509 pactvb
, state
->ticket_checksum_type
,
2510 state
->kdc_ek
->keytype
,
2511 "encode_krb5_enc_tkt_part failed",
2518 ret
= krb5_c_verify_checksum(krb5_ctx
, &kdc_key
,
2519 KRB5_KEYUSAGE_APP_DATA_CKSUM
,
2520 tmpdata
, &checksum
, &valid
);
2521 krb5_free_data(krb5_ctx
, tmpdata
);
2524 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2525 pactvb
, state
->ticket_checksum_type
,
2526 state
->kdc_ek
->keytype
,
2527 "krb5_c_verify_checksum failed for Ticket Signature",
2534 if (valid
== false) {
2535 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2536 pactvb
, state
->ticket_checksum_type
,
2537 state
->kdc_ek
->keytype
,
2545 used_signing_key(tree
, actx
->pinfo
, private_data
,
2546 state
->kdc_ek
, pactvb
,
2547 state
->ticket_checksum_type
,
2552 #endif /* HAVE_DECODE_KRB5_ENC_TKT_PART */
2555 #define __KRB5_PAC_FULL_CHECKSUM 19
2558 verify_krb5_pac_full_checksum(proto_tree
*tree
,
2560 tvbuff_t
*orig_pactvb
,
2561 struct verify_krb5_pac_state
*state
)
2563 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
2564 krb5_error_code ret
;
2565 krb5_keyblock kdc_key
= { .magic
= KV5M_KEYBLOCK
, };
2566 size_t checksum_length
= 0;
2567 krb5_checksum checksum
= { .checksum_type
= 0, };
2568 krb5_data pac_data
= { .length
= 0, };
2569 tvbuff_t
*copy_pactvb
= NULL
;
2570 uint32_t cur_offset
;
2571 uint32_t num_buffers
;
2573 krb5_boolean valid
= false;
2575 if (state
->kdc_ek
== NULL
) {
2576 int keytype
= keytype_for_cksumtype(state
->full_checksum_type
);
2577 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2578 orig_pactvb
, state
->full_checksum_type
,
2580 "Missing KDC (for full)",
2587 kdc_key
.magic
= KV5M_KEYBLOCK
;
2588 kdc_key
.enctype
= state
->kdc_ek
->keytype
;
2589 kdc_key
.length
= state
->kdc_ek
->keylength
;
2590 kdc_key
.contents
= (uint8_t *)state
->kdc_ek
->keyvalue
;
2592 ret
= krb5_c_checksum_length(krb5_ctx
,
2593 state
->full_checksum_type
,
2596 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2597 orig_pactvb
, state
->full_checksum_type
,
2598 state
->kdc_ek
->keytype
,
2599 "krb5_c_checksum_length failed for Full Signature",
2607 * The checksum element begins with 4 bytes of type
2608 * (state->full_checksum_type) before the crypto checksum
2610 if (state
->full_checksum_data
->length
< (4 + checksum_length
)) {
2611 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2612 orig_pactvb
, state
->full_checksum_type
,
2613 state
->kdc_ek
->keytype
,
2614 "pacbuffer_length too short for Full Signature",
2621 pac_data
.data
= wmem_memdup(actx
->pinfo
->pool
, state
->pacbuffer
, state
->pacbuffer_length
);
2622 if (pac_data
.data
== NULL
) {
2623 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2624 orig_pactvb
, state
->full_checksum_type
,
2625 state
->kdc_ek
->keytype
,
2626 "wmem_memdup(pacbuffer) failed",
2632 pac_data
.length
= state
->pacbuffer_length
;
2634 copy_pactvb
= tvb_new_child_real_data(orig_pactvb
,
2635 (uint8_t *)pac_data
.data
,
2638 if (copy_pactvb
== NULL
) {
2639 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2640 orig_pactvb
, state
->full_checksum_type
,
2641 state
->kdc_ek
->keytype
,
2642 "tvb_new_child_real_data(pac_copy) failed",
2649 #define __PAC_CHECK_OFFSET_SIZE(__offset, __length, __reason) do { \
2650 uint64_t __end = state->pacbuffer_length; \
2651 uint64_t __offset64 = __offset; \
2652 uint64_t __length64 = __length; \
2654 if (__offset64 > INT32_MAX) { \
2655 missing_signing_key(tree, actx->pinfo, private_data, \
2656 orig_pactvb, state->full_checksum_type, \
2657 state->kdc_ek->keytype, \
2659 "kdc_checksum_key", \
2664 if (__length64 > INT32_MAX) { \
2665 missing_signing_key(tree, actx->pinfo, private_data, \
2666 orig_pactvb, state->full_checksum_type, \
2667 state->kdc_ek->keytype, \
2669 "kdc_checksum_key", \
2674 __last = __offset64 + __length64; \
2675 if (__last > __end) { \
2676 missing_signing_key(tree, actx->pinfo, private_data, \
2677 orig_pactvb, state->full_checksum_type, \
2678 state->kdc_ek->keytype, \
2680 "kdc_checksum_key", \
2688 __PAC_CHECK_OFFSET_SIZE(cur_offset
, 8, "PACTYPE Header");
2689 num_buffers
= tvb_get_uint32(copy_pactvb
, cur_offset
, ENC_LITTLE_ENDIAN
);
2691 /* ignore 4 byte version */
2694 for (idx
= 0; idx
< num_buffers
; idx
++) {
2699 __PAC_CHECK_OFFSET_SIZE(cur_offset
, 16, "PAC_INFO_BUFFER Header");
2700 b_type
= tvb_get_uint32(copy_pactvb
, cur_offset
, ENC_LITTLE_ENDIAN
);
2702 b_length
= tvb_get_uint32(copy_pactvb
, cur_offset
, ENC_LITTLE_ENDIAN
);
2704 b_offset
= tvb_get_uint64(copy_pactvb
, cur_offset
, ENC_LITTLE_ENDIAN
);
2707 __PAC_CHECK_OFFSET_SIZE(b_offset
, b_length
, "PAC_INFO_BUFFER Payload");
2709 if (b_length
<= 4) {
2714 * Leave PAC_TICKET_CHECKSUM and clear all other checksums
2715 * and their possible RODC identifier, but leaving their
2716 * checksum type as is.
2719 case KRB5_PAC_SERVER_CHECKSUM
:
2720 case KRB5_PAC_PRIVSVR_CHECKSUM
:
2721 case __KRB5_PAC_FULL_CHECKSUM
:
2722 memset(pac_data
.data
+ b_offset
+4, 0, b_length
-4);
2727 checksum
.checksum_type
= state
->full_checksum_type
;
2728 checksum
.contents
= (uint8_t *)state
->full_checksum_data
->data
+ 4;
2729 checksum
.length
= (unsigned)checksum_length
;
2731 ret
= krb5_c_verify_checksum(krb5_ctx
, &kdc_key
,
2732 KRB5_KEYUSAGE_APP_DATA_CKSUM
,
2733 &pac_data
, &checksum
, &valid
);
2735 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2736 orig_pactvb
, state
->full_checksum_type
,
2737 state
->kdc_ek
->keytype
,
2738 "krb5_c_verify_checksum failed for Full PAC Signature",
2745 if (valid
== false) {
2746 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2747 orig_pactvb
, state
->full_checksum_type
,
2748 state
->kdc_ek
->keytype
,
2749 "Invalid Full PAC Signature",
2756 used_signing_key(tree
, actx
->pinfo
, private_data
,
2757 state
->kdc_ek
, orig_pactvb
,
2758 state
->full_checksum_type
,
2759 "Verified Full PAC",
2766 verify_krb5_pac(proto_tree
*tree _U_
, asn1_ctx_t
*actx
, tvbuff_t
*pactvb
)
2768 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
2769 krb5_error_code ret
;
2770 krb5_data checksum_data
= {0,0,NULL
};
2771 krb5_data ticket_checksum_data
= {0,0,NULL
};
2772 krb5_data full_checksum_data
= {0,0,NULL
};
2773 int length
= tvb_captured_length(pactvb
);
2774 const uint8_t *pacbuffer
= NULL
;
2775 struct verify_krb5_pac_state state
= {
2779 /* don't do anything if we are not attempting to decrypt data */
2780 if(!krb_decrypt
|| length
< 1){
2784 /* make sure we have all the data we need */
2785 if (tvb_captured_length(pactvb
) < tvb_reported_length(pactvb
)) {
2789 pacbuffer
= tvb_get_ptr(pactvb
, 0, length
);
2790 state
.pacbuffer_length
= length
;
2791 state
.pacbuffer
= pacbuffer
;
2793 ret
= krb5_pac_parse(krb5_ctx
, pacbuffer
, length
, &state
.pac
);
2795 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_kerberos_decrypted_keytype
,
2797 "Failed to parse PAC buffer %d in frame %u",
2798 ret
, actx
->pinfo
->fd
->num
);
2802 ret
= krb5_pac_get_buffer(krb5_ctx
, state
.pac
, KRB5_PAC_SERVER_CHECKSUM
,
2805 state
.server_checksum
= pletoh32(checksum_data
.data
);
2806 krb5_free_data_contents(krb5_ctx
, &checksum_data
);
2808 ret
= krb5_pac_get_buffer(krb5_ctx
, state
.pac
, KRB5_PAC_PRIVSVR_CHECKSUM
,
2811 state
.kdc_checksum
= pletoh32(checksum_data
.data
);
2812 krb5_free_data_contents(krb5_ctx
, &checksum_data
);
2814 ret
= krb5_pac_get_buffer(krb5_ctx
, state
.pac
,
2815 __KRB5_PAC_TICKET_CHECKSUM
,
2816 &ticket_checksum_data
);
2818 state
.ticket_checksum_data
= &ticket_checksum_data
;
2819 state
.ticket_checksum_type
= pletoh32(ticket_checksum_data
.data
);
2821 ret
= krb5_pac_get_buffer(krb5_ctx
, state
.pac
,
2822 __KRB5_PAC_FULL_CHECKSUM
,
2823 &full_checksum_data
);
2825 state
.full_checksum_data
= &full_checksum_data
;
2826 state
.full_checksum_type
= pletoh32(full_checksum_data
.data
);
2829 read_keytab_file_from_preferences();
2831 wmem_map_foreach(kerberos_all_keys
,
2832 verify_krb5_pac_try_server_key
,
2834 if (state
.server_ek
!= NULL
) {
2835 used_signing_key(tree
, actx
->pinfo
, private_data
,
2836 state
.server_ek
, pactvb
,
2837 state
.server_checksum
, "Verified Server",
2839 wmem_map_size(kerberos_all_keys
),
2840 state
.server_count
);
2842 int keytype
= keytype_for_cksumtype(state
.server_checksum
);
2843 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2844 pactvb
, state
.server_checksum
, keytype
,
2847 wmem_map_size(kerberos_all_keys
),
2848 state
.server_count
);
2850 wmem_map_foreach(kerberos_longterm_keys
,
2851 verify_krb5_pac_try_kdc_key
,
2853 if (state
.kdc_ek
!= NULL
) {
2854 used_signing_key(tree
, actx
->pinfo
, private_data
,
2855 state
.kdc_ek
, pactvb
,
2856 state
.kdc_checksum
, "Verified KDC",
2858 wmem_map_size(kerberos_longterm_keys
),
2861 int keytype
= keytype_for_cksumtype(state
.kdc_checksum
);
2862 missing_signing_key(tree
, actx
->pinfo
, private_data
,
2863 pactvb
, state
.kdc_checksum
, keytype
,
2866 wmem_map_size(kerberos_longterm_keys
),
2870 if (state
.ticket_checksum_type
!= 0) {
2871 verify_krb5_pac_ticket_checksum(tree
, actx
, pactvb
, &state
);
2874 if (state
.ticket_checksum_data
!= NULL
) {
2875 krb5_free_data_contents(krb5_ctx
, &ticket_checksum_data
);
2878 if (state
.full_checksum_type
!= 0) {
2879 verify_krb5_pac_full_checksum(tree
, actx
, pactvb
, &state
);
2882 if (state
.full_checksum_data
!= NULL
) {
2883 krb5_free_data_contents(krb5_ctx
, &full_checksum_data
);
2886 krb5_pac_free(krb5_ctx
, state
.pac
);
2888 #endif /* HAVE_KRB5_PAC_VERIFY */
2890 #elif defined(HAVE_HEIMDAL_KERBEROS)
2891 static krb5_context krb5_ctx
;
2893 USES_APPLE_DEPRECATED_API
2896 krb5_fast_key(asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, tvbuff_t
*tvb _U_
,
2897 enc_key_t
*ek1 _U_
, const char *p1 _U_
,
2898 enc_key_t
*ek2 _U_
, const char *p2 _U_
,
2899 const char *origin _U_
)
2901 /* TODO: use krb5_crypto_fx_cf2() from Heimdal */
2904 read_keytab_file(const char *filename
)
2907 krb5_error_code ret
;
2908 krb5_keytab_entry key
;
2909 krb5_kt_cursor cursor
;
2911 static bool first_time
=true;
2913 if (filename
== NULL
|| filename
[0] == 0) {
2919 ret
= krb5_init_context(&krb5_ctx
);
2925 /* should use a file in the wireshark users dir */
2926 ret
= krb5_kt_resolve(krb5_ctx
, filename
, &keytab
);
2928 fprintf(stderr
, "KERBEROS ERROR: Could not open keytab file :%s\n",filename
);
2933 ret
= krb5_kt_start_seq_get(krb5_ctx
, keytab
, &cursor
);
2935 fprintf(stderr
, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename
);
2940 ret
= krb5_kt_next_entry(krb5_ctx
, keytab
, &key
, &cursor
);
2945 new_key
= wmem_new0(wmem_epan_scope(), enc_key_t
);
2946 new_key
->fd_num
= -1;
2947 new_key
->id
= ++kerberos_longterm_ids
;
2948 snprintf(new_key
->id_str
, KRB_MAX_ID_STR_LEN
, "keytab.%u", new_key
->id
);
2949 new_key
->next
= enc_key_list
;
2951 /* generate origin string, describing where this key came from */
2952 pos
=new_key
->key_origin
;
2953 pos
+=MIN(KRB_MAX_ORIG_LEN
,
2954 snprintf(pos
, KRB_MAX_ORIG_LEN
, "keytab principal "));
2955 for(i
=0;i
<key
.principal
->name
.name_string
.len
;i
++){
2956 pos
+=MIN(KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
),
2957 snprintf(pos
, KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
), "%s%s",(i
?"/":""),key
.principal
->name
.name_string
.val
[i
]));
2959 pos
+=MIN(KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
),
2960 snprintf(pos
, KRB_MAX_ORIG_LEN
-(pos
-new_key
->key_origin
), "@%s",key
.principal
->realm
));
2962 new_key
->keytype
=key
.keyblock
.keytype
;
2963 new_key
->keylength
=(int)key
.keyblock
.keyvalue
.length
;
2964 memcpy(new_key
->keyvalue
,
2965 key
.keyblock
.keyvalue
.data
,
2966 MIN((unsigned)key
.keyblock
.keyvalue
.length
, KRB_MAX_KEY_LENGTH
));
2968 enc_key_list
=new_key
;
2969 ret
= krb5_kt_free_entry(krb5_ctx
, &key
);
2971 fprintf(stderr
, "KERBEROS ERROR: Could not release the entry: %d", ret
);
2972 ret
= 0; /* try to continue with the next entry */
2974 kerberos_key_map_insert(kerberos_longterm_keys
, new_key
);
2978 ret
= krb5_kt_end_seq_get(krb5_ctx
, keytab
, &cursor
);
2980 fprintf(stderr
, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret
);
2982 ret
= krb5_kt_close(krb5_ctx
, keytab
);
2984 fprintf(stderr
, "KERBEROS ERROR: Could not close the key table handle: %d", ret
);
2992 decrypt_krb5_data(proto_tree
*tree _U_
, packet_info
*pinfo
,
2994 tvbuff_t
*cryptotvb
,
2998 kerberos_private_data_t
*zero_private
= kerberos_new_private_data(pinfo
);
2999 krb5_error_code ret
;
3002 int length
= tvb_captured_length(cryptotvb
);
3003 const uint8_t *cryptotext
= tvb_get_ptr(cryptotvb
, 0, length
);
3005 /* don't do anything if we are not attempting to decrypt data */
3010 /* make sure we have all the data we need */
3011 if (tvb_captured_length(cryptotvb
) < tvb_reported_length(cryptotvb
)) {
3015 read_keytab_file_from_preferences();
3017 for(ek
=enc_key_list
;ek
;ek
=ek
->next
){
3018 krb5_keytab_entry key
;
3020 uint8_t *cryptocopy
; /* workaround for pre-0.6.1 heimdal bug */
3022 /* shortcircuit and bail out if enctypes are not matching */
3023 if((keytype
!= -1) && (ek
->keytype
!= keytype
)) {
3027 key
.keyblock
.keytype
=ek
->keytype
;
3028 key
.keyblock
.keyvalue
.length
=ek
->keylength
;
3029 key
.keyblock
.keyvalue
.data
=ek
->keyvalue
;
3030 ret
= krb5_crypto_init(krb5_ctx
, &(key
.keyblock
), (krb5_enctype
)ENCTYPE_NULL
, &crypto
);
3035 /* pre-0.6.1 versions of Heimdal would sometimes change
3036 the cryptotext data even when the decryption failed.
3037 This would obviously not work since we iterate over the
3038 keys. So just give it a copy of the crypto data instead.
3039 This has been seen for RC4-HMAC blobs.
3041 cryptocopy
= (uint8_t *)wmem_memdup(pinfo
->pool
, cryptotext
, length
);
3042 ret
= krb5_decrypt_ivec(krb5_ctx
, crypto
, usage
,
3046 if((ret
== 0) && (length
>0)){
3049 used_encryption_key(tree
, pinfo
, zero_private
,
3050 ek
, usage
, cryptotvb
,
3051 "enc_key_list", 0, 0);
3053 krb5_crypto_destroy(krb5_ctx
, crypto
);
3054 /* return a private wmem_alloced blob to the caller */
3055 user_data
= (char *)wmem_memdup(pinfo
->pool
, data
.data
, (unsigned)data
.length
);
3057 *datalen
= (int)data
.length
;
3061 krb5_crypto_destroy(krb5_ctx
, crypto
);
3066 #define NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP 1
3068 #elif defined (HAVE_LIBNETTLE)
3070 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
3071 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
3073 typedef struct _service_key_t
{
3078 char origin
[KRB_MAX_ORIG_LEN
+1];
3080 GSList
*service_key_list
;
3084 add_encryption_key(packet_info
*pinfo
, int keytype
, int keylength
, const char *keyvalue
, const char *origin
)
3086 service_key_t
*new_key
;
3088 if(pinfo
->fd
->visited
){
3092 new_key
= g_malloc(sizeof(service_key_t
));
3094 new_key
->keytype
= keytype
;
3095 new_key
->length
= keylength
;
3096 new_key
->contents
= g_memdup2(keyvalue
, keylength
);
3097 snprintf(new_key
->origin
, KRB_MAX_ORIG_LEN
, "%s learnt from frame %u", origin
, pinfo
->num
);
3098 service_key_list
= g_slist_append(service_key_list
, (void *) new_key
);
3102 save_encryption_key(tvbuff_t
*tvb _U_
, int offset _U_
, int length _U_
,
3103 asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
,
3104 int parent_hf_index _U_
,
3107 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
3108 const char *parent
= proto_registrar_get_name(parent_hf_index
);
3109 const char *element
= proto_registrar_get_name(hf_index
);
3110 char origin
[KRB_MAX_ORIG_LEN
] = { 0, };
3112 snprintf(origin
, KRB_MAX_ORIG_LEN
, "%s_%s", parent
, element
);
3114 add_encryption_key(actx
->pinfo
,
3115 private_data
->key
.keytype
,
3116 private_data
->key
.keylength
,
3117 private_data
->key
.keyvalue
,
3122 save_Authenticator_subkey(tvbuff_t
*tvb
, int offset
, int length
,
3123 asn1_ctx_t
*actx
, proto_tree
*tree
,
3124 int parent_hf_index
,
3127 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
3131 save_EncAPRepPart_subkey(tvbuff_t
*tvb
, int offset
, int length
,
3132 asn1_ctx_t
*actx
, proto_tree
*tree
,
3133 int parent_hf_index
,
3136 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
3140 save_EncKDCRepPart_key(tvbuff_t
*tvb
, int offset
, int length
,
3141 asn1_ctx_t
*actx
, proto_tree
*tree
,
3142 int parent_hf_index
,
3145 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
3149 save_EncTicketPart_key(tvbuff_t
*tvb
, int offset
, int length
,
3150 asn1_ctx_t
*actx
, proto_tree
*tree
,
3151 int parent_hf_index
,
3154 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
3158 save_KrbCredInfo_key(tvbuff_t
*tvb
, int offset
, int length
,
3159 asn1_ctx_t
*actx
, proto_tree
*tree
,
3160 int parent_hf_index
,
3163 save_encryption_key(tvb
, offset
, length
, actx
, tree
, parent_hf_index
, hf_index
);
3167 save_KrbFastResponse_strengthen_key(tvbuff_t
*tvb _U_
, int offset _U_
, int length _U_
,
3168 asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
)
3170 save_encryption_key(tvb
, offset
, length
, actx
, tree
, hf_index
);
3174 clear_keytab(void) {
3178 for(ske
= service_key_list
; ske
!= NULL
; ske
= g_slist_next(ske
)){
3179 sk
= (service_key_t
*) ske
->data
;
3181 g_free(sk
->contents
);
3185 g_slist_free(service_key_list
);
3186 service_key_list
= NULL
;
3190 read_keytab_file(const char *service_key_file
)
3195 unsigned char buf
[SERVICE_KEY_SIZE
];
3196 int newline_skip
= 0, count
= 0;
3198 if (service_key_file
!= NULL
&& ws_stat64 (service_key_file
, &st
) == 0) {
3200 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
3201 * There can be zero, one (\n), or two (\r\n) characters between
3202 * keys. Trailing characters are ignored.
3205 /* XXX We should support the standard keytab format instead */
3206 if (st
.st_size
> SERVICE_KEY_SIZE
) {
3207 if ( (st
.st_size
% (SERVICE_KEY_SIZE
+ 1) == 0) ||
3208 (st
.st_size
% (SERVICE_KEY_SIZE
+ 1) == SERVICE_KEY_SIZE
) ) {
3210 } else if ( (st
.st_size
% (SERVICE_KEY_SIZE
+ 2) == 0) ||
3211 (st
.st_size
% (SERVICE_KEY_SIZE
+ 2) == SERVICE_KEY_SIZE
) ) {
3216 skf
= ws_fopen(service_key_file
, "rb");
3219 while (fread(buf
, SERVICE_KEY_SIZE
, 1, skf
) == 1) {
3220 sk
= g_malloc(sizeof(service_key_t
));
3221 sk
->kvno
= buf
[0] << 8 | buf
[1];
3222 sk
->keytype
= KEYTYPE_DES3_CBC_MD5
;
3223 sk
->length
= DES3_KEY_SIZE
;
3224 sk
->contents
= g_memdup2(buf
+ 2, DES3_KEY_SIZE
);
3225 snprintf(sk
->origin
, KRB_MAX_ORIG_LEN
, "3DES service key file, key #%d, offset %ld", count
, ftell(skf
));
3226 service_key_list
= g_slist_append(service_key_list
, (void *) sk
);
3227 if (fseek(skf
, newline_skip
, SEEK_CUR
) < 0) {
3228 fprintf(stderr
, "unable to seek...\n");
3238 #define CONFOUNDER_PLUS_CHECKSUM 24
3241 decrypt_krb5_data(proto_tree
*tree
, packet_info
*pinfo
,
3243 tvbuff_t
*cryptotvb
,
3248 uint8_t *decrypted_data
= NULL
, *plaintext
= NULL
;
3251 uint32_t tag
, item_len
, data_len
;
3252 int id_offset
, offset
;
3253 uint8_t key
[DES3_KEY_SIZE
];
3254 uint8_t initial_vector
[DES_BLOCK_SIZE
];
3255 gcry_md_hd_t md5_handle
;
3257 uint8_t zero_fill
[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3258 uint8_t confounder
[8];
3262 struct des3_ctx ctx
;
3263 int length
= tvb_captured_length(cryptotvb
);
3264 const uint8_t *cryptotext
= tvb_get_ptr(cryptotvb
, 0, length
);
3267 /* don't do anything if we are not attempting to decrypt data */
3272 /* make sure we have all the data we need */
3273 if (tvb_captured_length(cryptotvb
) < tvb_reported_length(cryptotvb
)) {
3277 if (keytype
!= KEYTYPE_DES3_CBC_MD5
|| service_key_list
== NULL
) {
3281 decrypted_data
= wmem_alloc(pinfo
->pool
, length
);
3282 for(ske
= service_key_list
; ske
!= NULL
; ske
= g_slist_next(ske
)){
3283 bool do_continue
= false;
3285 sk
= (service_key_t
*) ske
->data
;
3287 des_fix_parity(DES3_KEY_SIZE
, key
, sk
->contents
);
3289 memset(initial_vector
, 0, DES_BLOCK_SIZE
);
3290 des3_set_key(&ctx
, key
);
3291 cbc_decrypt(&ctx
, des3_decrypt
, DES_BLOCK_SIZE
, initial_vector
,
3292 length
, decrypted_data
, cryptotext
);
3293 encr_tvb
= tvb_new_real_data(decrypted_data
, length
, length
);
3295 tvb_memcpy(encr_tvb
, confounder
, 0, 8);
3297 /* We have to pull the decrypted data length from the decrypted
3298 * content. If the key doesn't match or we otherwise get garbage,
3299 * an exception may get thrown while decoding the ASN.1 header.
3300 * Catch it, just in case.
3303 id_offset
= get_ber_identifier(encr_tvb
, CONFOUNDER_PLUS_CHECKSUM
, &cls
, &pc
, &tag
);
3304 offset
= get_ber_length(encr_tvb
, id_offset
, &item_len
, &ind
);
3306 CATCH_BOUNDS_ERRORS
{
3312 if (do_continue
) continue;
3314 data_len
= item_len
+ offset
- CONFOUNDER_PLUS_CHECKSUM
;
3315 if ((int) item_len
+ offset
> length
) {
3320 if (gcry_md_open(&md5_handle
, GCRY_MD_MD5
, 0)) {
3323 gcry_md_write(md5_handle
, confounder
, 8);
3324 gcry_md_write(md5_handle
, zero_fill
, 16);
3325 gcry_md_write(md5_handle
, decrypted_data
+ CONFOUNDER_PLUS_CHECKSUM
, data_len
);
3326 digest
= gcry_md_read(md5_handle
, 0);
3328 digest_ok
= (tvb_memeql (encr_tvb
, 8, digest
, HASH_MD5_LENGTH
) == 0);
3329 gcry_md_close(md5_handle
);
3331 plaintext
= (uint8_t* )tvb_memdup(pinfo
->pool
, encr_tvb
, CONFOUNDER_PLUS_CHECKSUM
, data_len
);
3335 *datalen
= data_len
;
3345 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
3347 #ifdef NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP
3349 decrypt_krb5_krb_cfx_dce(proto_tree
*tree _U_
,
3350 packet_info
*pinfo _U_
,
3353 tvbuff_t
*gssapi_header_tvb _U_
,
3354 tvbuff_t
*gssapi_encrypted_tvb _U_
,
3355 tvbuff_t
*gssapi_trailer_tvb _U_
,
3356 tvbuff_t
*checksum_tvb _U_
)
3360 #endif /* NEED_DECRYPT_KRB5_KRB_CFX_DCE_NOOP */
3362 #define INET6_ADDRLEN 16
3364 /* TCP Record Mark */
3365 #define KRB_RM_RESERVED 0x80000000U
3366 #define KRB_RM_RECLEN 0x7fffffffU
3368 #define KRB5_MSG_TICKET 1 /* Ticket */
3369 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
3370 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
3371 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
3372 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
3373 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
3374 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
3375 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
3376 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
3377 #define KRB5_MSG_TGT_REQ 16 /* TGT-REQ type */
3378 #define KRB5_MSG_TGT_REP 17 /* TGT-REP type */
3380 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
3381 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
3382 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
3383 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
3384 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
3385 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
3386 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
3387 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
3388 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
3390 #define KRB5_CHKSUM_GSSAPI 0x8003
3392 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
3394 * https://tools.ietf.org/html/draft-brezak-win2k-krb-rc4-hmac-04
3396 * unless it's expired.
3399 /* Principal name-type */
3400 #define KRB5_NT_UNKNOWN 0
3401 #define KRB5_NT_PRINCIPAL 1
3402 #define KRB5_NT_SRV_INST 2
3403 #define KRB5_NT_SRV_HST 3
3404 #define KRB5_NT_SRV_XHST 4
3405 #define KRB5_NT_UID 5
3406 #define KRB5_NT_X500_PRINCIPAL 6
3407 #define KRB5_NT_SMTP_NAME 7
3408 #define KRB5_NT_ENTERPRISE 10
3411 * MS specific name types, from
3413 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
3415 #define KRB5_NT_MS_PRINCIPAL -128
3416 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
3417 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
3418 #define KRB5_NT_PRINCIPAL_AND_SID -131
3419 #define KRB5_NT_SRV_INST_AND_SID -132
3421 /* error table constants */
3422 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
3423 #define KRB5_ET_KRB5KDC_ERR_NONE 0
3424 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
3425 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
3426 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
3427 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
3428 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
3429 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
3430 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
3431 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
3432 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
3433 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
3434 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
3435 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
3436 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
3437 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
3438 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
3439 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
3440 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
3441 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
3442 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
3443 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
3444 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
3445 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
3446 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
3447 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
3448 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
3449 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
3450 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
3451 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
3452 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
3453 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
3454 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
3455 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
3456 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
3457 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
3458 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
3459 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
3460 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
3461 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
3462 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
3463 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
3464 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
3465 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
3466 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
3467 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
3468 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
3469 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
3470 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
3471 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
3472 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
3473 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
3474 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
3475 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
3476 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
3477 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
3478 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
3479 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
3480 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
3481 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
3482 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
3483 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
3484 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
3485 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
3486 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
3487 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
3488 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
3489 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
3490 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
3491 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
3492 #define KRB5_ET_KDC_ERR_PREAUTH_EXPIRED 90
3493 #define KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED 91
3494 #define KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET 92
3495 #define KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS 93
3497 static const value_string krb5_error_codes
[] = {
3498 { KRB5_ET_KRB5KDC_ERR_NONE
, "KRB5KDC_ERR_NONE" },
3499 { KRB5_ET_KRB5KDC_ERR_NAME_EXP
, "KRB5KDC_ERR_NAME_EXP" },
3500 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP
, "KRB5KDC_ERR_SERVICE_EXP" },
3501 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO
, "KRB5KDC_ERR_BAD_PVNO" },
3502 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO
, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
3503 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO
, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
3504 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
3505 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
3506 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE
, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
3507 { KRB5_ET_KRB5KDC_ERR_NULL_KEY
, "KRB5KDC_ERR_NULL_KEY" },
3508 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE
, "KRB5KDC_ERR_CANNOT_POSTDATE" },
3509 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID
, "KRB5KDC_ERR_NEVER_VALID" },
3510 { KRB5_ET_KRB5KDC_ERR_POLICY
, "KRB5KDC_ERR_POLICY" },
3511 { KRB5_ET_KRB5KDC_ERR_BADOPTION
, "KRB5KDC_ERR_BADOPTION" },
3512 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP
, "KRB5KDC_ERR_ETYPE_NOSUPP" },
3513 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP
, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
3514 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP
, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
3515 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP
, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
3516 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED
, "KRB5KDC_ERR_CLIENT_REVOKED" },
3517 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED
, "KRB5KDC_ERR_SERVICE_REVOKED" },
3518 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED
, "KRB5KDC_ERR_TGT_REVOKED" },
3519 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET
, "KRB5KDC_ERR_CLIENT_NOTYET" },
3520 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET
, "KRB5KDC_ERR_SERVICE_NOTYET" },
3521 { KRB5_ET_KRB5KDC_ERR_KEY_EXP
, "KRB5KDC_ERR_KEY_EXP" },
3522 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED
, "KRB5KDC_ERR_PREAUTH_FAILED" },
3523 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED
, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
3524 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH
, "KRB5KDC_ERR_SERVER_NOMATCH" },
3525 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER
, "KRB5KDC_ERR_MUST_USE_USER2USER" },
3526 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED
, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
3527 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE
, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
3528 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY
, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
3529 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED
, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
3530 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV
, "KRB5KRB_AP_ERR_TKT_NYV" },
3531 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT
, "KRB5KRB_AP_ERR_REPEAT" },
3532 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US
, "KRB5KRB_AP_ERR_NOT_US" },
3533 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH
, "KRB5KRB_AP_ERR_BADMATCH" },
3534 { KRB5_ET_KRB5KRB_AP_ERR_SKEW
, "KRB5KRB_AP_ERR_SKEW" },
3535 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR
, "KRB5KRB_AP_ERR_BADADDR" },
3536 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION
, "KRB5KRB_AP_ERR_BADVERSION" },
3537 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE
, "KRB5KRB_AP_ERR_MSG_TYPE" },
3538 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED
, "KRB5KRB_AP_ERR_MODIFIED" },
3539 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER
, "KRB5KRB_AP_ERR_BADORDER" },
3540 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT
, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
3541 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER
, "KRB5KRB_AP_ERR_BADKEYVER" },
3542 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY
, "KRB5KRB_AP_ERR_NOKEY" },
3543 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL
, "KRB5KRB_AP_ERR_MUT_FAIL" },
3544 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION
, "KRB5KRB_AP_ERR_BADDIRECTION" },
3545 { KRB5_ET_KRB5KRB_AP_ERR_METHOD
, "KRB5KRB_AP_ERR_METHOD" },
3546 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ
, "KRB5KRB_AP_ERR_BADSEQ" },
3547 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM
, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
3548 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED
, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
3549 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG
, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
3550 { KRB5_ET_KRB5KRB_ERR_GENERIC
, "KRB5KRB_ERR_GENERIC" },
3551 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG
, "KRB5KRB_ERR_FIELD_TOOLONG" },
3552 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED
, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
3553 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED
, "KDC_ERROR_KDC_NOT_TRUSTED" },
3554 { KRB5_ET_KDC_ERROR_INVALID_SIG
, "KDC_ERROR_INVALID_SIG" },
3555 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK
, "KDC_ERR_KEY_TOO_WEAK" },
3556 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH
, "KDC_ERR_CERTIFICATE_MISMATCH" },
3557 { KRB5_ET_KRB_AP_ERR_NO_TGT
, "KRB_AP_ERR_NO_TGT" },
3558 { KRB5_ET_KDC_ERR_WRONG_REALM
, "KDC_ERR_WRONG_REALM" },
3559 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED
, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
3560 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE
, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
3561 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE
, "KDC_ERR_INVALID_CERTIFICATE" },
3562 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE
, "KDC_ERR_REVOKED_CERTIFICATE" },
3563 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN
, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
3564 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE
, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
3565 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH
, "KDC_ERR_CLIENT_NAME_MISMATCH" },
3566 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH
, "KDC_ERR_KDC_NAME_MISMATCH" },
3567 { KRB5_ET_KDC_ERR_PREAUTH_EXPIRED
, "KDC_ERR_PREAUTH_EXPIRED" },
3568 { KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
, "KDC_ERR_MORE_PREAUTH_DATA_REQUIRED" },
3569 { KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET
, "KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET" },
3570 { KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS
, "KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS" },
3575 #define PAC_LOGON_INFO 1
3576 #define PAC_CREDENTIAL_TYPE 2
3577 #define PAC_SERVER_CHECKSUM 6
3578 #define PAC_PRIVSVR_CHECKSUM 7
3579 #define PAC_CLIENT_INFO_TYPE 10
3580 #define PAC_S4U_DELEGATION_INFO 11
3581 #define PAC_UPN_DNS_INFO 12
3582 #define PAC_CLIENT_CLAIMS_INFO 13
3583 #define PAC_DEVICE_INFO 14
3584 #define PAC_DEVICE_CLAIMS_INFO 15
3585 #define PAC_TICKET_CHECKSUM 16
3586 #define PAC_ATTRIBUTES_INFO 17
3587 #define PAC_REQUESTER_SID 18
3588 #define PAC_FULL_CHECKSUM 19
3589 static const value_string w2k_pac_types
[] = {
3590 { PAC_LOGON_INFO
, "Logon Info" },
3591 { PAC_CREDENTIAL_TYPE
, "Credential Type" },
3592 { PAC_SERVER_CHECKSUM
, "Server Checksum" },
3593 { PAC_PRIVSVR_CHECKSUM
, "Privsvr Checksum" },
3594 { PAC_CLIENT_INFO_TYPE
, "Client Info Type" },
3595 { PAC_S4U_DELEGATION_INFO
, "S4U Delegation Info" },
3596 { PAC_UPN_DNS_INFO
, "UPN DNS Info" },
3597 { PAC_CLIENT_CLAIMS_INFO
, "Client Claims Info" },
3598 { PAC_DEVICE_INFO
, "Device Info" },
3599 { PAC_DEVICE_CLAIMS_INFO
, "Device Claims Info" },
3600 { PAC_TICKET_CHECKSUM
, "Ticket Checksum" },
3601 { PAC_ATTRIBUTES_INFO
, "Attributes Info" },
3602 { PAC_REQUESTER_SID
, "Requester Sid" },
3603 { PAC_FULL_CHECKSUM
, "Full Checksum" },
3607 static const value_string krb5_msg_types
[] = {
3608 { KRB5_MSG_TICKET
, "Ticket" },
3609 { KRB5_MSG_AUTHENTICATOR
, "Authenticator" },
3610 { KRB5_MSG_ENC_TICKET_PART
, "EncTicketPart" },
3611 { KRB5_MSG_TGS_REQ
, "TGS-REQ" },
3612 { KRB5_MSG_TGS_REP
, "TGS-REP" },
3613 { KRB5_MSG_AS_REQ
, "AS-REQ" },
3614 { KRB5_MSG_AS_REP
, "AS-REP" },
3615 { KRB5_MSG_AP_REQ
, "AP-REQ" },
3616 { KRB5_MSG_AP_REP
, "AP-REP" },
3617 { KRB5_MSG_TGT_REQ
, "TGT-REQ" },
3618 { KRB5_MSG_TGT_REP
, "TGT-REP" },
3619 { KRB5_MSG_SAFE
, "KRB-SAFE" },
3620 { KRB5_MSG_PRIV
, "KRB-PRIV" },
3621 { KRB5_MSG_CRED
, "KRB-CRED" },
3622 { KRB5_MSG_ENC_AS_REP_PART
, "EncASRepPart" },
3623 { KRB5_MSG_ENC_TGS_REP_PART
, "EncTGSRepPart" },
3624 { KRB5_MSG_ENC_AP_REP_PART
, "EncAPRepPart" },
3625 { KRB5_MSG_ENC_KRB_PRIV_PART
, "EncKrbPrivPart" },
3626 { KRB5_MSG_ENC_KRB_CRED_PART
, "EncKrbCredPart" },
3627 { KRB5_MSG_ERROR
, "KRB-ERROR" },
3631 #define KRB5_GSS_C_DELEG_FLAG 0x00000001
3632 #define KRB5_GSS_C_MUTUAL_FLAG 0x00000002
3633 #define KRB5_GSS_C_REPLAY_FLAG 0x00000004
3634 #define KRB5_GSS_C_SEQUENCE_FLAG 0x00000008
3635 #define KRB5_GSS_C_CONF_FLAG 0x00000010
3636 #define KRB5_GSS_C_INTEG_FLAG 0x00000020
3637 #define KRB5_GSS_C_DCE_STYLE 0x00001000
3639 static const true_false_string tfs_gss_flags_deleg
= {
3640 "Delegate credentials to remote peer",
3643 static const true_false_string tfs_gss_flags_mutual
= {
3644 "Request that remote peer authenticates itself",
3645 "Mutual authentication NOT required"
3647 static const true_false_string tfs_gss_flags_replay
= {
3648 "Enable replay protection for signed or sealed messages",
3649 "Do NOT enable replay protection"
3651 static const true_false_string tfs_gss_flags_sequence
= {
3652 "Enable Out-of-sequence detection for sign or sealed messages",
3653 "Do NOT enable out-of-sequence detection"
3655 static const true_false_string tfs_gss_flags_conf
= {
3656 "Confidentiality (sealing) may be invoked",
3657 "Do NOT use Confidentiality (sealing)"
3659 static const true_false_string tfs_gss_flags_integ
= {
3660 "Integrity protection (signing) may be invoked",
3661 "Do NOT use integrity protection"
3664 static const true_false_string tfs_gss_flags_dce_style
= {
3666 "Not using DCE-STYLE"
3669 static int dissect_kerberos_KRB5_SRP_PA_APPLICATIONS(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
)
3671 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
3672 proto_item
*pi1
= proto_item_get_parent(actx
->created_item
);
3673 proto_item
*pi2
= proto_item_get_parent(pi1
);
3679 * dissect_ber_octet_string_wcb() always passes
3680 * implicit_tag=false, offset=0 and hf_index=-1
3682 ws_assert(implicit_tag
== false);
3683 ws_assert(offset
== 0);
3684 ws_assert(hf_index
<= 0);
3686 get_ber_identifier(tvb
, offset
, &ber_class
, &pc
, &tag
);
3687 if (ber_class
!= BER_CLASS_APP
) {
3688 if (kerberos_private_is_kdc_req(private_data
)) {
3691 if (private_data
->errorcode
!= KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED
) {
3695 proto_item_append_text(pi1
, " KRB5_SRP_PA_ANNOUNCE");
3696 proto_item_append_text(pi2
, ": KRB5_SRP_PA_ANNOUNCE");
3697 return dissect_kerberos_KRB5_SRP_PA_ANNOUNCE(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
3702 proto_item_append_text(pi1
, " KRB5_SRP_PA_INIT");
3703 proto_item_append_text(pi2
, ": KRB5_SRP_PA_INIT");
3704 return dissect_kerberos_KRB5_SRP_PA_INIT(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
3706 proto_item_append_text(pi1
, " KRB5_SRP_PA_SERVER_CHALLENGE");
3707 proto_item_append_text(pi2
, ": KRB5_SRP_PA_SERVER_CHALLENGE");
3708 return dissect_kerberos_KRB5_SRP_PA_SERVER_CHALLENGE(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
3710 proto_item_append_text(pi1
, " KRB5_SRP_PA_CLIENT_RESPONSE");
3711 proto_item_append_text(pi2
, ": KRB5_SRP_PA_CLIENT_RESPONSE");
3712 return dissect_kerberos_KRB5_SRP_PA_CLIENT_RESPONSE(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
3714 proto_item_append_text(pi1
, " KRB5_SRP_PA_SERVER_VERIFIER");
3715 proto_item_append_text(pi2
, ": KRB5_SRP_PA_SERVER_VERIFIER");
3716 return dissect_kerberos_KRB5_SRP_PA_SERVER_VERIFIER(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
3722 proto_item_append_text(pi1
, " KRB5_SRP_PA_UNKNOWN: ber_class:%u ber_pc=%u ber_tag:%"PRIu32
"", ber_class
, pc
, tag
);
3723 proto_item_append_text(pi2
, ": KRB5_SRP_PA_UNKNOWN");
3724 return tvb_reported_length_remaining(tvb
, offset
);
3727 #ifdef HAVE_KERBEROS
3729 decrypt_krb5_data_asn1(proto_tree
*tree
, asn1_ctx_t
*actx
,
3730 int usage
, tvbuff_t
*cryptotvb
, int *datalen
)
3732 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
3734 #ifdef HAVE_DECRYPT_KRB5_DATA_PRIVATE
3735 return decrypt_krb5_data_private(tree
, actx
->pinfo
, private_data
,
3737 private_data
->etype
,
3740 return decrypt_krb5_data(tree
, actx
->pinfo
, usage
, cryptotvb
,
3741 private_data
->etype
, datalen
);
3746 dissect_krb5_decrypt_ticket_data (bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
3747 proto_tree
*tree
, int hf_index _U_
)
3753 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
3754 length
=tvb_captured_length_remaining(tvb
, offset
);
3756 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3758 * All Ticket encrypted parts use usage == 2
3760 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 2, next_tvb
, &length
);
3763 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
3764 tvbuff_t
*last_ticket_enc_part_tvb
= private_data
->last_ticket_enc_part_tvb
;
3765 enc_key_t
*current_ticket_key
= private_data
->current_ticket_key
;
3766 tvbuff_t
*child_tvb
;
3767 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
3769 /* Add the decrypted data to the data source list. */
3770 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 Ticket");
3772 private_data
->last_ticket_enc_part_tvb
= child_tvb
;
3773 private_data
->current_ticket_key
= NULL
;
3774 offset
=dissect_kerberos_Applications(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
3775 private_data
->current_ticket_key
= current_ticket_key
;
3776 private_data
->last_ticket_enc_part_tvb
= last_ticket_enc_part_tvb
;
3782 dissect_krb5_decrypt_authenticator_data (bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
3783 proto_tree
*tree
, int hf_index _U_
)
3785 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
3790 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
3791 length
=tvb_captured_length_remaining(tvb
, offset
);
3793 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3795 * Authenticators are encrypted with usage
3799 * 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator
3800 * (includes TGS authenticator subkey), encrypted with the
3801 * TGS session key (section 5.5.1)
3802 * 11. AP-REQ Authenticator (includes application
3803 * authenticator subkey), encrypted with the application
3804 * session key (section 5.5.1)
3806 if (private_data
->within_PA_TGS_REQ
> 0) {
3807 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 7, next_tvb
, &length
);
3809 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 11, next_tvb
, &length
);
3813 tvbuff_t
*child_tvb
;
3814 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
3816 /* Add the decrypted data to the data source list. */
3817 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 Authenticator");
3819 offset
=dissect_kerberos_Applications(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
3825 dissect_krb5_decrypt_authorization_data(bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
3826 proto_tree
*tree
, int hf_index _U_
)
3828 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
3833 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
3834 length
=tvb_captured_length_remaining(tvb
, offset
);
3836 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3838 * Authenticators are encrypted with usage
3842 * 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with
3843 * the TGS session key (section 5.4.1)
3844 * 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with
3845 * the TGS authenticator subkey (section 5.4.1)
3847 if (private_data
->PA_TGS_REQ_subkey
!= NULL
) {
3848 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 5, next_tvb
, &length
);
3850 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 4, next_tvb
, &length
);
3854 tvbuff_t
*child_tvb
;
3855 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
3857 /* Add the decrypted data to the data source list. */
3858 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 AuthorizationData");
3860 offset
=dissect_kerberos_AuthorizationData(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
3866 dissect_krb5_decrypt_KDC_REP_data (bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
3867 proto_tree
*tree
, int hf_index _U_
)
3869 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
3870 uint8_t *plaintext
= NULL
;
3874 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
3875 length
=tvb_captured_length_remaining(tvb
, offset
);
3877 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3879 * ASREP/TGSREP encryptedparts are encrypted with usage
3884 * 3. AS-REP encrypted part (includes TGS session key or
3885 * application session key), encrypted with the client key
3888 * 8. TGS-REP encrypted part (includes application session
3889 * key), encrypted with the TGS session key (section
3891 * 9. TGS-REP encrypted part (includes application session
3892 * key), encrypted with the TGS authenticator subkey
3895 * We currently don't have a way to find the TGS-REQ state
3896 * in order to check if an authenticator subkey was used.
3898 * But if we client used FAST and we got a strengthen_key,
3899 * we're sure an authenticator subkey was used.
3901 * Windows don't use an authenticator subkey without FAST,
3904 * For now try 8 before 9 in order to avoid overhead and false
3905 * positives for the 'kerberos.missing_keytype' filter in pure
3908 switch (private_data
->msg_type
) {
3909 case KERBEROS_APPLICATIONS_AS_REP
:
3910 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 3, next_tvb
, &length
);
3912 case KERBEROS_APPLICATIONS_TGS_REP
:
3913 if (private_data
->fast_strengthen_key
!= NULL
) {
3914 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 9, next_tvb
, &length
);
3916 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 8, next_tvb
, &length
);
3918 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 9, next_tvb
, &length
);
3925 tvbuff_t
*child_tvb
;
3926 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
3928 /* Add the decrypted data to the data source list. */
3929 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 KDC-REP");
3931 offset
=dissect_kerberos_Applications(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
3937 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
3938 proto_tree
*tree
, int hf_index _U_
)
3944 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
3945 length
=tvb_captured_length_remaining(tvb
, offset
);
3947 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3949 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
3952 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 1, next_tvb
, &length
);
3955 tvbuff_t
*child_tvb
;
3956 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
3958 /* Add the decrypted data to the data source list. */
3959 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 EncTimestamp");
3961 offset
=dissect_kerberos_PA_ENC_TS_ENC(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
3967 dissect_krb5_decrypt_AP_REP_data (bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
3968 proto_tree
*tree
, int hf_index _U_
)
3974 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
3975 length
=tvb_captured_length_remaining(tvb
, offset
);
3977 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
3979 * AP-REP are encrypted with usage == 12
3981 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 12, next_tvb
, &length
);
3984 tvbuff_t
*child_tvb
;
3985 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
3987 /* Add the decrypted data to the data source list. */
3988 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 AP-REP");
3990 offset
=dissect_kerberos_Applications(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
3996 dissect_krb5_decrypt_PRIV_data (bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
3997 proto_tree
*tree
, int hf_index _U_
)
4003 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
4004 length
=tvb_captured_length_remaining(tvb
, offset
);
4007 * EncKrbPrivPart encrypted with usage
4010 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 13, next_tvb
, &length
);
4013 tvbuff_t
*child_tvb
;
4014 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
4016 /* Add the decrypted data to the data source list. */
4017 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 PRIV");
4019 offset
=dissect_kerberos_Applications(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
4025 dissect_krb5_decrypt_CRED_data (bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
4026 proto_tree
*tree
, int hf_index _U_
)
4028 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
4033 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
4034 length
=tvb_captured_length_remaining(tvb
, offset
);
4036 if (private_data
->etype
== 0) {
4037 offset
=dissect_kerberos_Applications(false, next_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
4042 * EncKrbCredPart encrypted with usage
4045 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, 14, next_tvb
, &length
);
4048 tvbuff_t
*child_tvb
;
4049 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
4051 /* Add the decrypted data to the data source list. */
4052 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 CRED");
4054 offset
=dissect_kerberos_Applications(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
4060 dissect_krb5_decrypt_KrbFastReq(bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
4061 proto_tree
*tree
, int hf_index _U_
)
4065 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
4068 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
4069 length
=tvb_captured_length_remaining(tvb
, offset
);
4071 private_data
->fast_armor_key
= NULL
;
4072 if (private_data
->PA_FAST_ARMOR_AP_subkey
!= NULL
) {
4073 krb5_fast_key(actx
, tree
, tvb
,
4074 private_data
->PA_FAST_ARMOR_AP_subkey
,
4076 private_data
->PA_FAST_ARMOR_AP_key
,
4078 "KrbFastReq_FAST_armorKey");
4079 if (private_data
->PA_TGS_REQ_subkey
!= NULL
) {
4080 enc_key_t
*explicit_armor_key
= private_data
->last_added_key
;
4083 * See [MS-KILE] 3.3.5.7.4 Compound Identity
4085 krb5_fast_key(actx
, tree
, tvb
,
4088 private_data
->PA_TGS_REQ_subkey
,
4090 "KrbFastReq_explicitArmorKey");
4092 private_data
->fast_armor_key
= private_data
->last_added_key
;
4093 } else if (private_data
->PA_TGS_REQ_subkey
!= NULL
) {
4094 krb5_fast_key(actx
, tree
, tvb
,
4095 private_data
->PA_TGS_REQ_subkey
,
4097 private_data
->PA_TGS_REQ_key
,
4099 "KrbFastReq_TGS_armorKey");
4100 private_data
->fast_armor_key
= private_data
->last_added_key
;
4104 * KrbFastResponse encrypted with usage
4105 * KEY_USAGE_FAST_ENC 51
4107 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, KEY_USAGE_FAST_ENC
,
4111 tvbuff_t
*child_tvb
;
4112 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
4114 /* Add the decrypted data to the data source list. */
4115 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 FastReq");
4117 offset
=dissect_kerberos_KrbFastReq(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
4123 dissect_krb5_decrypt_KrbFastResponse(bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
4124 proto_tree
*tree
, int hf_index _U_
)
4128 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
4131 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
4132 length
=tvb_captured_length_remaining(tvb
, offset
);
4136 * KrbFastResponse encrypted with usage
4137 * KEY_USAGE_FAST_REP 52
4139 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, KEY_USAGE_FAST_REP
,
4143 tvbuff_t
*child_tvb
;
4144 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
4146 /* Add the decrypted data to the data source list. */
4147 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 FastRep");
4149 private_data
->fast_armor_key
= private_data
->last_decryption_key
;
4150 offset
=dissect_kerberos_KrbFastResponse(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
4156 dissect_krb5_decrypt_EncryptedChallenge(bool imp_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
,
4157 proto_tree
*tree
, int hf_index _U_
)
4161 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
4164 const char *name
= NULL
;
4166 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
4167 length
=tvb_captured_length_remaining(tvb
, offset
);
4170 * KEY_USAGE_ENC_CHALLENGE_CLIENT 54
4171 * KEY_USAGE_ENC_CHALLENGE_KDC 55
4173 if (kerberos_private_is_kdc_req(private_data
)) {
4174 usage
= KEY_USAGE_ENC_CHALLENGE_CLIENT
;
4175 name
= "Krb5 CHALLENGE_CLIENT";
4177 usage
= KEY_USAGE_ENC_CHALLENGE_KDC
;
4178 name
= "Krb5 CHALLENGE_KDC";
4180 plaintext
=decrypt_krb5_data_asn1(tree
, actx
, usage
, next_tvb
, &length
);
4183 tvbuff_t
*child_tvb
;
4184 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, length
, length
);
4186 /* Add the decrypted data to the data source list. */
4187 add_new_data_source(actx
->pinfo
, child_tvb
, name
);
4189 offset
=dissect_kerberos_PA_ENC_TS_ENC(false, child_tvb
, 0, actx
, tree
, /* hf_index*/ -1);
4193 #endif /* HAVE_KERBEROS */
4195 static int * const hf_krb_pa_supported_enctypes_fields
[] = {
4196 &hf_krb_pa_supported_enctypes_des_cbc_crc
,
4197 &hf_krb_pa_supported_enctypes_des_cbc_md5
,
4198 &hf_krb_pa_supported_enctypes_rc4_hmac
,
4199 &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96
,
4200 &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96
,
4201 &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96_sk
,
4202 &hf_krb_pa_supported_enctypes_fast_supported
,
4203 &hf_krb_pa_supported_enctypes_compound_identity_supported
,
4204 &hf_krb_pa_supported_enctypes_claims_supported
,
4205 &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled
,
4210 dissect_kerberos_PA_SUPPORTED_ENCTYPES(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
,
4211 int offset _U_
, asn1_ctx_t
*actx _U_
,
4212 proto_tree
*tree _U_
, int hf_index _U_
)
4214 actx
->created_item
= proto_tree_add_bitmask(tree
, tvb
, offset
,
4215 hf_krb_pa_supported_enctypes
,
4216 ett_krb_pa_supported_enctypes
,
4217 hf_krb_pa_supported_enctypes_fields
,
4224 static int * const hf_krb_ad_ap_options_fields
[] = {
4225 &hf_krb_ad_ap_options_cbt
,
4226 &hf_krb_ad_ap_options_unverified_target_name
,
4232 dissect_kerberos_AD_AP_OPTIONS(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
,
4233 int offset _U_
, asn1_ctx_t
*actx _U_
,
4234 proto_tree
*tree _U_
, int hf_index _U_
)
4236 actx
->created_item
= proto_tree_add_bitmask(tree
, tvb
, offset
,
4237 hf_krb_ad_ap_options
,
4238 ett_krb_ad_ap_options
,
4239 hf_krb_ad_ap_options_fields
,
4247 dissect_kerberos_AD_TARGET_PRINCIPAL(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
,
4248 int offset _U_
, asn1_ctx_t
*actx _U_
,
4249 proto_tree
*tree _U_
, int hf_index _U_
)
4251 int tp_offset
, tp_len
;
4254 bc
= tvb_reported_length_remaining(tvb
, offset
);
4257 proto_tree_add_item(tree
, hf_krb_ad_target_principal
, tvb
,
4259 ENC_UTF_16
| ENC_LITTLE_ENDIAN
);
4264 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
4267 dissect_krb5_rfc1964_checksum(asn1_ctx_t
*actx _U_
, proto_tree
*tree
, tvbuff_t
*tvb
)
4273 /* Length of Bnd field */
4274 len
=tvb_get_letohl(tvb
, offset
);
4275 proto_tree_add_item(tree
, hf_krb_gssapi_len
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4279 proto_tree_add_item(tree
, hf_krb_gssapi_bnd
, tvb
, offset
, len
, ENC_NA
);
4284 proto_tree_add_item(tree
, hf_krb_gssapi_c_flag_dce_style
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4285 proto_tree_add_item(tree
, hf_krb_gssapi_c_flag_integ
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4286 proto_tree_add_item(tree
, hf_krb_gssapi_c_flag_conf
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4287 proto_tree_add_item(tree
, hf_krb_gssapi_c_flag_sequence
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4288 proto_tree_add_item(tree
, hf_krb_gssapi_c_flag_replay
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4289 proto_tree_add_item(tree
, hf_krb_gssapi_c_flag_mutual
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4290 proto_tree_add_item(tree
, hf_krb_gssapi_c_flag_deleg
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4293 /* the next fields are optional so we have to check that we have
4294 * more data in our buffers */
4295 if(tvb_reported_length_remaining(tvb
, offset
)<2){
4298 /* dlgopt identifier */
4299 proto_tree_add_item(tree
, hf_krb_gssapi_dlgopt
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4302 if(tvb_reported_length_remaining(tvb
, offset
)<2){
4305 /* dlglen identifier */
4306 dlglen
=tvb_get_letohs(tvb
, offset
);
4307 proto_tree_add_item(tree
, hf_krb_gssapi_dlglen
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4310 if(dlglen
!=tvb_reported_length_remaining(tvb
, offset
)){
4311 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_krb_gssapi_dlglen
, tvb
, 0, 0,
4312 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen
, tvb_captured_length_remaining(tvb
, offset
));
4316 /* this should now be a KRB_CRED message */
4317 offset
=dissect_kerberos_Applications(false, tvb
, offset
, actx
, tree
, /* hf_index */ -1);
4323 dissect_krb5_PA_PROV_SRV_LOCATION(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
)
4325 offset
=dissect_ber_GeneralString(actx
, tree
, tvb
, offset
, hf_krb_provsrv_location
, NULL
, 0);
4331 dissect_krb5_PW_SALT(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
)
4333 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
4335 uint32_t nt_status
= 0;
4336 uint32_t reserved
= 0;
4340 * Microsoft stores a special 12 byte blob here
4341 * [MS-KILE] 2.2.1 KERB-EXT-ERROR
4342 * uint32_t NT_status
4343 * uint32_t reserved (== 0)
4344 * uint32_t flags (at least 0x00000001 is set)
4346 length
= tvb_reported_length_remaining(tvb
, offset
);
4354 if (private_data
->errorcode
== 0) {
4358 nt_status
= tvb_get_letohl(tvb
, offset
);
4359 reserved
= tvb_get_letohl(tvb
, offset
+ 4);
4360 flags
= tvb_get_letohl(tvb
, offset
+ 8);
4362 if (reserved
!= 0 || (flags
& 1) != 1 || !try_val_to_str_ext(nt_status
, &NT_errors_ext
)) {
4366 proto_tree_add_item(tree
, hf_krb_ext_error_nt_status
, tvb
, offset
, 4,
4368 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
,
4370 val_to_str_ext(nt_status
, &NT_errors_ext
,
4371 "Unknown error code %#x"));
4374 proto_tree_add_item(tree
, hf_krb_ext_error_reserved
, tvb
, offset
, 4,
4378 proto_tree_add_item(tree
, hf_krb_ext_error_flags
, tvb
, offset
, 4,
4385 proto_tree_add_item(tree
, hf_krb_pw_salt
, tvb
, offset
, length
, ENC_NA
);
4392 dissect_krb5_PAC_DREP(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, uint8_t *drep
)
4397 tree
= proto_tree_add_subtree(parent_tree
, tvb
, offset
, 16, ett_krb_pac_drep
, NULL
, "DREP");
4399 val
= tvb_get_uint8(tvb
, offset
);
4400 proto_tree_add_uint(tree
, hf_dcerpc_drep_byteorder
, tvb
, offset
, 1, val
>>4);
4411 /* This might be some sort of header that MIDL generates when creating
4412 * marshalling/unmarshalling code for blobs that are not to be transported
4413 * ontop of DCERPC and where the DREP fields specifying things such as
4414 * endianess and similar are not available.
4417 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, uint8_t *drep
)
4421 tree
= proto_tree_add_subtree(parent_tree
, tvb
, offset
, 16, ett_krb_pac_midl_blob
, NULL
, "MES header");
4423 /* modified DREP field that is used for stuff that is transporetd ontop
4426 proto_tree_add_item(tree
, hf_krb_midl_version
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4429 offset
= dissect_krb5_PAC_DREP(tree
, tvb
, offset
, drep
);
4432 proto_tree_add_item(tree
, hf_krb_midl_hdr_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4435 proto_tree_add_item(tree
, hf_krb_midl_fill_bytes
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4438 /* length of blob that follows */
4439 proto_tree_add_item(tree
, hf_krb_midl_blob_len
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
4446 dissect_krb5_PAC_LOGON_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4450 uint8_t drep
[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
4451 /* fake dcerpc_info struct */
4452 dcerpc_call_value call_data
= { .flags
= 0, };
4453 dcerpc_info di
= { .ptype
= UINT8_MAX
, .call_data
= &call_data
, };
4455 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_logon_info
, tvb
, offset
, -1, ENC_NA
);
4456 tree
= proto_item_add_subtree(item
, ett_krb_pac_logon_info
);
4458 /* skip the first 16 bytes, they are some magic created by the idl
4459 * compiler the first 4 bytes might be flags?
4461 offset
= dissect_krb5_PAC_NDRHEADERBLOB(tree
, tvb
, offset
, &drep
[0]);
4463 /* the PAC_LOGON_INFO blob */
4464 init_ndr_pointer_list(&di
);
4465 offset
= dissect_ndr_pointer(tvb
, offset
, actx
->pinfo
, tree
, &di
, drep
,
4466 netlogon_dissect_PAC_LOGON_INFO
, NDR_POINTER_UNIQUE
,
4467 "PAC_LOGON_INFO:", -1);
4468 free_ndr_pointer_list(&di
);
4475 dissect_krb5_PAC_CREDENTIAL_DATA(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
)
4477 proto_tree_add_item(parent_tree
, hf_krb_pac_credential_data
, tvb
, offset
, -1, ENC_NA
);
4483 dissect_krb5_PAC_CREDENTIAL_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
)
4487 uint8_t *plaintext
= NULL
;
4490 #define KRB5_KU_OTHER_ENCRYPTED 16
4491 #ifdef HAVE_KERBEROS
4494 int usage
= KRB5_KU_OTHER_ENCRYPTED
;
4497 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_credential_info
, tvb
, offset
, -1, ENC_NA
);
4498 tree
= proto_item_add_subtree(item
, ett_krb_pac_credential_info
);
4501 proto_tree_add_item(tree
, hf_krb_pac_credential_info_version
, tvb
,
4502 offset
, 4, ENC_LITTLE_ENDIAN
);
4505 #ifdef HAVE_KERBEROS
4507 etype
= tvb_get_letohl(tvb
, offset
);
4509 proto_tree_add_item(tree
, hf_krb_pac_credential_info_etype
, tvb
,
4510 offset
, 4, ENC_LITTLE_ENDIAN
);
4513 #ifdef HAVE_KERBEROS
4515 next_tvb
=tvb_new_subset_remaining(tvb
, offset
);
4516 length
=tvb_captured_length_remaining(tvb
, offset
);
4518 plaintext
=decrypt_krb5_data(tree
, actx
->pinfo
, usage
, next_tvb
, (int)etype
, &plainlen
);
4521 if (plaintext
!= NULL
) {
4522 tvbuff_t
*child_tvb
;
4523 child_tvb
= tvb_new_child_real_data(tvb
, plaintext
, plainlen
, plainlen
);
4525 /* Add the decrypted data to the data source list. */
4526 add_new_data_source(actx
->pinfo
, child_tvb
, "Krb5 PAC_CREDENTIAL");
4528 dissect_krb5_PAC_CREDENTIAL_DATA(tree
, child_tvb
, 0, actx
->pinfo
);
4531 return offset
+ length
;
4535 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
)
4539 uint8_t drep
[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
4540 /* fake dcerpc_info struct */
4541 dcerpc_call_value call_data
= { .flags
= 0, };
4542 dcerpc_info di
= { .ptype
= UINT8_MAX
, .call_data
= &call_data
, };
4544 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_s4u_delegation_info
, tvb
, offset
, -1, ENC_NA
);
4545 tree
= proto_item_add_subtree(item
, ett_krb_pac_s4u_delegation_info
);
4547 /* skip the first 16 bytes, they are some magic created by the idl
4548 * compiler the first 4 bytes might be flags?
4550 offset
= dissect_krb5_PAC_NDRHEADERBLOB(tree
, tvb
, offset
, &drep
[0]);
4552 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
4553 init_ndr_pointer_list(&di
);
4554 offset
= dissect_ndr_pointer(tvb
, offset
, actx
->pinfo
, tree
, &di
, drep
,
4555 netlogon_dissect_PAC_S4U_DELEGATION_INFO
, NDR_POINTER_UNIQUE
,
4556 "PAC_S4U_DELEGATION_INFO:", -1);
4557 free_ndr_pointer_list(&di
);
4562 #define PAC_UPN_DNS_FLAG_CONSTRUCTED 0x00000001
4563 #define PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID 0x00000002
4564 static const true_false_string tfs_krb_pac_upn_flag_upn_constructed
= {
4565 "UPN Name is Constructed",
4566 "UPN Name is NOT Constructed",
4568 static const true_false_string tfs_krb_pac_upn_flag_has_sam_name_and_sid
= {
4569 "SAM_NAME and SID are included",
4570 "SAM_NAME and SID are NOT included",
4572 static int * const hf_krb_pac_upn_flags_fields
[] = {
4573 &hf_krb_pac_upn_flag_upn_constructed
,
4574 &hf_krb_pac_upn_flag_has_sam_name_and_sid
,
4579 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4581 #ifdef HAVE_KERBEROS
4582 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
4583 #endif /* HAVE_KERBEROS */
4586 uint16_t dns_offset
, dns_len
;
4587 uint16_t upn_offset
, upn_len
;
4588 uint16_t samaccountname_offset
= 0, samaccountname_len
= 0;
4589 uint16_t objectsid_offset
= 0, objectsid_len
= 0;
4590 char *sid_str
= NULL
;
4593 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_upn_dns_info
, tvb
, offset
, -1, ENC_NA
);
4594 tree
= proto_item_add_subtree(item
, ett_krb_pac_upn_dns_info
);
4597 upn_len
= tvb_get_letohs(tvb
, offset
);
4598 proto_tree_add_item(tree
, hf_krb_pac_upn_upn_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4600 upn_offset
= tvb_get_letohs(tvb
, offset
);
4601 proto_tree_add_item(tree
, hf_krb_pac_upn_upn_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4605 dns_len
= tvb_get_letohs(tvb
, offset
);
4606 proto_tree_add_item(tree
, hf_krb_pac_upn_dns_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4608 dns_offset
= tvb_get_letohs(tvb
, offset
);
4609 proto_tree_add_item(tree
, hf_krb_pac_upn_dns_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4613 flags
= tvb_get_letohl(tvb
, offset
);
4614 proto_tree_add_bitmask(tree
, tvb
, offset
,
4615 hf_krb_pac_upn_flags
,
4616 ett_krb_pac_upn_dns_info_flags
,
4617 hf_krb_pac_upn_flags_fields
,
4621 if (flags
& PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID
) {
4622 samaccountname_len
= tvb_get_letohs(tvb
, offset
);
4623 proto_tree_add_item(tree
, hf_krb_pac_upn_samaccountname_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4625 samaccountname_offset
= tvb_get_letohs(tvb
, offset
);
4626 proto_tree_add_item(tree
, hf_krb_pac_upn_samaccountname_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4629 objectsid_len
= tvb_get_letohs(tvb
, offset
);
4630 proto_tree_add_item(tree
, hf_krb_pac_upn_objectsid_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4632 objectsid_offset
= tvb_get_letohs(tvb
, offset
);
4633 proto_tree_add_item(tree
, hf_krb_pac_upn_objectsid_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4638 proto_tree_add_item(tree
, hf_krb_pac_upn_upn_name
, tvb
, upn_offset
, upn_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
4641 proto_tree_add_item(tree
, hf_krb_pac_upn_dns_name
, tvb
, dns_offset
, dns_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
4643 /* samaccountname */
4644 if (samaccountname_offset
!= 0 && samaccountname_len
!= 0) {
4645 proto_tree_add_item(tree
, hf_krb_pac_upn_samaccountname
, tvb
, samaccountname_offset
, samaccountname_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
4648 if (objectsid_offset
!= 0 && objectsid_len
!= 0) {
4650 sid_tvb
=tvb_new_subset_length(tvb
, objectsid_offset
, objectsid_len
);
4651 dissect_nt_sid(sid_tvb
, 0, tree
, "objectSid", &sid_str
, -1);
4654 #ifdef HAVE_KERBEROS
4655 if (private_data
->current_ticket_key
!= NULL
) {
4656 enc_key_t
*ek
= private_data
->current_ticket_key
;
4658 if (samaccountname_offset
!= 0 && samaccountname_len
!= 0) {
4659 ek
->pac_names
.account_name
= tvb_get_string_enc(wmem_epan_scope(),
4661 samaccountname_offset
,
4663 ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
4665 ek
->pac_names
.account_name
= tvb_get_string_enc(wmem_epan_scope(),
4669 ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
4671 ek
->pac_names
.account_domain
= tvb_get_string_enc(wmem_epan_scope(),
4675 ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
4676 if (sid_str
!= NULL
) {
4677 ek
->pac_names
.account_sid
= wmem_strdup(wmem_epan_scope(),
4681 #endif /* HAVE_KERBEROS */
4687 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4689 int length
= tvb_captured_length_remaining(tvb
, offset
);
4695 proto_tree_add_item(parent_tree
, hf_krb_pac_client_claims_info
, tvb
, offset
, -1, ENC_NA
);
4701 dissect_krb5_PAC_DEVICE_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4703 #ifdef HAVE_KERBEROS
4704 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
4705 const char *device_sid
= NULL
;
4706 #endif /* HAVE_KERBEROS */
4709 uint8_t drep
[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
4710 /* fake dcerpc_info struct */
4711 dcerpc_call_value call_data
= { .flags
= 0, };
4712 dcerpc_info di
= { .ptype
= UINT8_MAX
, .call_data
= &call_data
, };
4714 #ifdef HAVE_KERBEROS
4715 if (private_data
->current_ticket_key
!= NULL
) {
4716 call_data
.private_data
= (void*)&device_sid
;
4718 #endif /* HAVE_KERBEROS */
4720 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_device_info
, tvb
, offset
, -1, ENC_NA
);
4721 tree
= proto_item_add_subtree(item
, ett_krb_pac_device_info
);
4723 /* skip the first 16 bytes, they are some magic created by the idl
4724 * compiler the first 4 bytes might be flags?
4726 offset
= dissect_krb5_PAC_NDRHEADERBLOB(tree
, tvb
, offset
, &drep
[0]);
4728 /* the PAC_DEVICE_INFO blob */
4729 init_ndr_pointer_list(&di
);
4730 offset
= dissect_ndr_pointer(tvb
, offset
, actx
->pinfo
, tree
, &di
, drep
,
4731 netlogon_dissect_PAC_DEVICE_INFO
, NDR_POINTER_UNIQUE
,
4732 "PAC_DEVICE_INFO:", -1);
4733 free_ndr_pointer_list(&di
);
4735 #ifdef HAVE_KERBEROS
4736 if (private_data
->current_ticket_key
!= NULL
) {
4737 enc_key_t
*ek
= private_data
->current_ticket_key
;
4740 * netlogon_dissect_PAC_DEVICE_INFO allocated on
4741 * wmem_epan_scope() for us
4743 ek
->pac_names
.device_sid
= device_sid
;
4745 #endif /* HAVE_KERBEROS */
4751 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4753 int length
= tvb_captured_length_remaining(tvb
, offset
);
4759 proto_tree_add_item(parent_tree
, hf_krb_pac_device_claims_info
, tvb
, offset
, -1, ENC_NA
);
4765 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4770 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_server_checksum
, tvb
, offset
, -1, ENC_NA
);
4771 tree
= proto_item_add_subtree(item
, ett_krb_pac_server_checksum
);
4773 /* signature type */
4774 proto_tree_add_item(tree
, hf_krb_pac_signature_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4777 /* signature data */
4778 proto_tree_add_item(tree
, hf_krb_pac_signature_signature
, tvb
, offset
, -1, ENC_NA
);
4784 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4789 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_privsvr_checksum
, tvb
, offset
, -1, ENC_NA
);
4790 tree
= proto_item_add_subtree(item
, ett_krb_pac_privsvr_checksum
);
4792 /* signature type */
4793 proto_tree_add_item(tree
, hf_krb_pac_signature_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4796 /* signature data */
4797 proto_tree_add_item(tree
, hf_krb_pac_signature_signature
, tvb
, offset
, -1, ENC_NA
);
4803 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4809 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_client_info_type
, tvb
, offset
, -1, ENC_NA
);
4810 tree
= proto_item_add_subtree(item
, ett_krb_pac_client_info_type
);
4813 dissect_nttime(tvb
, tree
, offset
, hf_krb_pac_clientid
, ENC_LITTLE_ENDIAN
);
4817 namelen
=tvb_get_letohs(tvb
, offset
);
4818 proto_tree_add_uint(tree
, hf_krb_pac_namelen
, tvb
, offset
, 2, namelen
);
4822 proto_tree_add_item(tree
, hf_krb_pac_clientname
, tvb
, offset
, namelen
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
4829 dissect_krb5_PAC_TICKET_CHECKSUM(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4834 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_ticket_checksum
, tvb
, offset
, -1, ENC_NA
);
4835 tree
= proto_item_add_subtree(item
, ett_krb_pac_ticket_checksum
);
4837 /* signature type */
4838 proto_tree_add_item(tree
, hf_krb_pac_signature_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4841 /* signature data */
4842 proto_tree_add_item(tree
, hf_krb_pac_signature_signature
, tvb
, offset
, -1, ENC_NA
);
4847 #define PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED 0x00000001
4848 #define PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY 0x00000002
4849 static const true_false_string tfs_krb_pac_attributes_info_pac_was_requested
= {
4850 "PAC was requested",
4851 "PAC was NOT requested",
4853 static const true_false_string tfs_krb_pac_attributes_info_pac_was_given_implicitly
= {
4854 "PAC was given implicitly",
4855 "PAC was NOT given implicitly",
4857 static int * const hf_krb_pac_attributes_info_flags_fields
[] = {
4858 &hf_krb_pac_attributes_info_flags_pac_was_requested
,
4859 &hf_krb_pac_attributes_info_flags_pac_was_given_implicitly
,
4864 dissect_krb5_PAC_ATTRIBUTES_INFO(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4869 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_attributes_info
, tvb
, offset
, -1, ENC_NA
);
4870 tree
= proto_item_add_subtree(item
, ett_krb_pac_attributes_info
);
4873 proto_tree_add_item(tree
, hf_krb_pac_attributes_info_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4877 proto_tree_add_bitmask(tree
, tvb
, offset
,
4878 hf_krb_pac_attributes_info_flags
,
4879 ett_krb_pac_attributes_info_flags
,
4880 hf_krb_pac_attributes_info_flags_fields
,
4888 dissect_krb5_PAC_REQUESTER_SID(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4893 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_requester_sid
, tvb
, offset
, -1, ENC_NA
);
4894 tree
= proto_item_add_subtree(item
, ett_krb_pac_requester_sid
);
4896 offset
= dissect_nt_sid(tvb
, offset
, tree
, "RequesterSid", NULL
, -1);
4902 dissect_krb5_PAC_FULL_CHECKSUM(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
4907 item
= proto_tree_add_item(parent_tree
, hf_krb_pac_full_checksum
, tvb
, offset
, -1, ENC_NA
);
4908 tree
= proto_item_add_subtree(item
, ett_krb_pac_full_checksum
);
4910 /* signature type */
4911 proto_tree_add_item(tree
, hf_krb_pac_signature_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4914 /* signature data */
4915 proto_tree_add_item(tree
, hf_krb_pac_signature_signature
, tvb
, offset
, -1, ENC_NA
);
4921 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
)
4925 uint32_t pac_offset
;
4926 proto_item
*it
=NULL
;
4927 proto_tree
*tr
=NULL
;
4930 /* type of pac data */
4931 pac_type
=tvb_get_letohl(tvb
, offset
);
4932 it
=proto_tree_add_uint(tree
, hf_krb_w2k_pac_type
, tvb
, offset
, 4, pac_type
);
4933 tr
=proto_item_add_subtree(it
, ett_krb_pac
);
4937 /* size of pac data */
4938 pac_size
=tvb_get_letohl(tvb
, offset
);
4939 proto_tree_add_uint(tr
, hf_krb_w2k_pac_size
, tvb
, offset
, 4, pac_size
);
4942 /* offset to pac data */
4943 pac_offset
=tvb_get_letohl(tvb
, offset
);
4944 proto_tree_add_uint(tr
, hf_krb_w2k_pac_offset
, tvb
, offset
, 4, pac_offset
);
4947 next_tvb
=tvb_new_subset_length_caplen(tvb
, pac_offset
, pac_size
, pac_size
);
4949 case PAC_LOGON_INFO
:
4950 dissect_krb5_PAC_LOGON_INFO(tr
, next_tvb
, 0, actx
);
4952 case PAC_CREDENTIAL_TYPE
:
4953 dissect_krb5_PAC_CREDENTIAL_INFO(tr
, next_tvb
, 0, actx
);
4955 case PAC_SERVER_CHECKSUM
:
4956 dissect_krb5_PAC_SERVER_CHECKSUM(tr
, next_tvb
, 0, actx
);
4958 case PAC_PRIVSVR_CHECKSUM
:
4959 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr
, next_tvb
, 0, actx
);
4961 case PAC_CLIENT_INFO_TYPE
:
4962 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr
, next_tvb
, 0, actx
);
4964 case PAC_S4U_DELEGATION_INFO
:
4965 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr
, next_tvb
, 0, actx
);
4967 case PAC_UPN_DNS_INFO
:
4968 dissect_krb5_PAC_UPN_DNS_INFO(tr
, next_tvb
, 0, actx
);
4970 case PAC_CLIENT_CLAIMS_INFO
:
4971 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(tr
, next_tvb
, 0, actx
);
4973 case PAC_DEVICE_INFO
:
4974 dissect_krb5_PAC_DEVICE_INFO(tr
, next_tvb
, 0, actx
);
4976 case PAC_DEVICE_CLAIMS_INFO
:
4977 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(tr
, next_tvb
, 0, actx
);
4979 case PAC_TICKET_CHECKSUM
:
4980 dissect_krb5_PAC_TICKET_CHECKSUM(tr
, next_tvb
, 0, actx
);
4982 case PAC_ATTRIBUTES_INFO
:
4983 dissect_krb5_PAC_ATTRIBUTES_INFO(tr
, next_tvb
, 0, actx
);
4985 case PAC_REQUESTER_SID
:
4986 dissect_krb5_PAC_REQUESTER_SID(tr
, next_tvb
, 0, actx
);
4988 case PAC_FULL_CHECKSUM
:
4989 dissect_krb5_PAC_FULL_CHECKSUM(tr
, next_tvb
, 0, actx
);
4999 dissect_krb5_AD_WIN2K_PAC(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index _U_
)
5005 #if defined(HAVE_MIT_KERBEROS) && defined(HAVE_KRB5_PAC_VERIFY)
5006 verify_krb5_pac(tree
, actx
, tvb
);
5009 /* first in the PAC structure comes the number of entries */
5010 entries
=tvb_get_letohl(tvb
, offset
);
5011 proto_tree_add_uint(tree
, hf_krb_w2k_pac_entries
, tvb
, offset
, 4, entries
);
5014 /* second comes the version */
5015 version
=tvb_get_letohl(tvb
, offset
);
5016 proto_tree_add_uint(tree
, hf_krb_w2k_pac_version
, tvb
, offset
, 4, version
);
5019 for(i
=0;i
<entries
;i
++){
5020 offset
=dissect_krb5_AD_WIN2K_PAC_struct(tree
, tvb
, offset
, actx
);
5026 static int dissect_kerberos_T_e_data_octets(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
)
5037 * dissect_ber_octet_string_wcb() always passes
5038 * implicit_tag=false, offset=0 and hf_index=-1
5040 ws_assert(implicit_tag
== false);
5041 ws_assert(offset
== 0);
5042 ws_assert(hf_index
<= 0);
5044 len_offset
= get_ber_identifier(tvb
, offset
, &ber_class
, &pc
, &tag
);
5045 if (ber_class
!= BER_CLASS_UNI
|| !pc
|| tag
!= BER_UNI_TAG_SEQUENCE
) {
5048 next_offset
= get_ber_length(tvb
, len_offset
, &len
, &ind
);
5052 get_ber_identifier(tvb
, next_offset
, &ber_class
, &pc
, &tag
);
5053 if (ber_class
== BER_CLASS_CON
&& pc
&& tag
== 1) {
5054 return dissect_kerberos_PA_DATA(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
5056 if (ber_class
== BER_CLASS_UNI
&& pc
&& tag
== BER_UNI_TAG_SEQUENCE
) {
5057 return dissect_kerberos_T_rEP_SEQUENCE_OF_PA_DATA(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
5060 return tvb_reported_length_remaining(tvb
, offset
);
5063 #include "packet-kerberos-fn.c"
5065 #ifdef HAVE_KERBEROS
5066 static const ber_sequence_t PA_ENC_TS_ENC_sequence
[] = {
5067 { &hf_krb_patimestamp
, BER_CLASS_CON
, 0, 0, dissect_kerberos_KerberosTime
},
5068 { &hf_krb_pausec
, BER_CLASS_CON
, 1, BER_FLAGS_OPTIONAL
, dissect_kerberos_Microseconds
},
5069 { NULL
, 0, 0, 0, NULL
}
5073 dissect_kerberos_PA_ENC_TS_ENC(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
5074 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
5075 PA_ENC_TS_ENC_sequence
, hf_index
, ett_krb_pa_enc_ts_enc
);
5080 dissect_kerberos_T_strengthen_key(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
5081 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
5082 int save_encryption_key_parent_hf_index
= private_data
->save_encryption_key_parent_hf_index
;
5083 kerberos_key_save_fn saved_encryption_key_fn
= private_data
->save_encryption_key_fn
;
5084 private_data
->save_encryption_key_parent_hf_index
= hf_kerberos_KrbFastResponse
;
5085 #ifdef HAVE_KERBEROS
5086 private_data
->save_encryption_key_fn
= save_KrbFastResponse_strengthen_key
;
5088 offset
= dissect_kerberos_EncryptionKey(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
5090 private_data
->save_encryption_key_parent_hf_index
= save_encryption_key_parent_hf_index
;
5091 private_data
->save_encryption_key_fn
= saved_encryption_key_fn
;
5095 static const ber_sequence_t KrbFastFinished_sequence
[] = {
5096 { &hf_kerberos_timestamp
, BER_CLASS_CON
, 0, 0, dissect_kerberos_KerberosTime
},
5097 { &hf_kerberos_usec
, BER_CLASS_CON
, 1, 0, dissect_kerberos_Microseconds
},
5098 { &hf_kerberos_crealm
, BER_CLASS_CON
, 2, 0, dissect_kerberos_Realm
},
5099 { &hf_kerberos_cname_01
, BER_CLASS_CON
, 3, 0, dissect_kerberos_PrincipalName
},
5100 { &hf_kerberos_ticket_checksum
, BER_CLASS_CON
, 4, 0, dissect_kerberos_Checksum
},
5101 { NULL
, 0, 0, 0, NULL
}
5105 dissect_kerberos_KrbFastFinished(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
5106 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
5107 KrbFastFinished_sequence
, hf_index
, ett_kerberos_KrbFastFinished
);
5112 static const ber_sequence_t KrbFastResponse_sequence
[] = {
5113 { &hf_kerberos_rEP_SEQUENCE_OF_PA_DATA
, BER_CLASS_CON
, 0, 0, dissect_kerberos_T_rEP_SEQUENCE_OF_PA_DATA
},
5114 { &hf_kerberos_strengthen_key
, BER_CLASS_CON
, 1, BER_FLAGS_OPTIONAL
, dissect_kerberos_T_strengthen_key
},
5115 { &hf_kerberos_finished
, BER_CLASS_CON
, 2, BER_FLAGS_OPTIONAL
, dissect_kerberos_KrbFastFinished
},
5116 { &hf_kerberos_nonce
, BER_CLASS_CON
, 3, 0, dissect_kerberos_UInt32
},
5117 { NULL
, 0, 0, 0, NULL
}
5121 dissect_kerberos_KrbFastResponse(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
5122 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
5123 KrbFastResponse_sequence
, hf_index
, ett_kerberos_KrbFastResponse
);
5128 static const ber_sequence_t KrbFastReq_sequence
[] = {
5129 { &hf_kerberos_fast_options
, BER_CLASS_CON
, 0, 0, dissect_kerberos_FastOptions
},
5130 { &hf_kerberos_rEQ_SEQUENCE_OF_PA_DATA
, BER_CLASS_CON
, 1, 0, dissect_kerberos_T_rEQ_SEQUENCE_OF_PA_DATA
},
5131 { &hf_kerberos_req_body
, BER_CLASS_CON
, 2, 0, dissect_kerberos_KDC_REQ_BODY
},
5132 { NULL
, 0, 0, 0, NULL
}
5136 dissect_kerberos_KrbFastReq(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
5137 kerberos_private_data_t
*private_data
= kerberos_get_private_data(actx
);
5138 struct _kerberos_PA_FX_FAST_REQUEST saved_stack
= private_data
->PA_FX_FAST_REQUEST
;
5139 private_data
->PA_FX_FAST_REQUEST
= (struct _kerberos_PA_FX_FAST_REQUEST
) { .defer
= false, };
5140 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
5141 KrbFastReq_sequence
, hf_index
, ett_kerberos_KrbFastReq
);
5142 private_data
->PA_FX_FAST_REQUEST
= saved_stack
;
5147 static int * const FastOptions_bits
[] = {
5148 &hf_kerberos_FastOptions_reserved
,
5149 &hf_kerberos_FastOptions_hide_client_names
,
5150 &hf_kerberos_FastOptions_spare_bit2
,
5151 &hf_kerberos_FastOptions_spare_bit3
,
5152 &hf_kerberos_FastOptions_spare_bit4
,
5153 &hf_kerberos_FastOptions_spare_bit5
,
5154 &hf_kerberos_FastOptions_spare_bit6
,
5155 &hf_kerberos_FastOptions_spare_bit7
,
5156 &hf_kerberos_FastOptions_spare_bit8
,
5157 &hf_kerberos_FastOptions_spare_bit9
,
5158 &hf_kerberos_FastOptions_spare_bit10
,
5159 &hf_kerberos_FastOptions_spare_bit11
,
5160 &hf_kerberos_FastOptions_spare_bit12
,
5161 &hf_kerberos_FastOptions_spare_bit13
,
5162 &hf_kerberos_FastOptions_spare_bit14
,
5163 &hf_kerberos_FastOptions_spare_bit15
,
5164 &hf_kerberos_FastOptions_kdc_follow_referrals
,
5169 dissect_kerberos_FastOptions(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
5170 offset
= dissect_ber_bitstring(implicit_tag
, actx
, tree
, tvb
, offset
,
5171 FastOptions_bits
, 17, hf_index
, ett_kerberos_FastOptions
,
5177 #endif /* HAVE_KERBEROS */
5179 /* Make wrappers around exported functions for now */
5181 dissect_krb5_Checksum(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
5183 return dissect_kerberos_Checksum(false, tvb
, offset
, actx
, tree
, hf_kerberos_cksum
);
5188 dissect_krb5_ctime(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
5190 return dissect_kerberos_KerberosTime(false, tvb
, offset
, actx
, tree
, hf_kerberos_ctime
);
5195 dissect_krb5_cname(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
5197 return dissect_kerberos_PrincipalName(false, tvb
, offset
, actx
, tree
, hf_kerberos_cname
);
5200 dissect_krb5_realm(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
)
5202 return dissect_kerberos_Realm(false, tvb
, offset
, actx
, tree
, hf_kerberos_realm
);
5205 struct kerberos_display_key_state
{
5208 expert_field
*expindex
;
5216 #ifdef HAVE_KERBEROS
5217 kerberos_display_key(void *data
, void *userdata
)
5219 kerberos_display_key(void *data _U_
, void *userdata _U_
)
5222 #ifdef HAVE_KERBEROS
5223 struct kerberos_display_key_state
*state
=
5224 (struct kerberos_display_key_state
*)userdata
;
5225 const enc_key_t
*ek
= (const enc_key_t
*)data
;
5226 proto_item
*item
= NULL
;
5227 enc_key_t
*sek
= NULL
;
5229 item
= proto_tree_add_expert_format(state
->tree
,
5235 "%s %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
5237 ek
->key_origin
, ek
->keytype
,
5238 ek
->id_str
, ek
->num_same
,
5239 ek
->keyvalue
[0] & 0xFF, ek
->keyvalue
[1] & 0xFF,
5240 ek
->keyvalue
[2] & 0xFF, ek
->keyvalue
[3] & 0xFF);
5241 if (ek
->src1
!= NULL
) {
5243 expert_add_info_format(state
->pinfo
,
5246 "SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
5247 sek
->key_origin
, sek
->keytype
,
5248 sek
->id_str
, sek
->num_same
,
5249 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
5250 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
5252 if (ek
->src2
!= NULL
) {
5254 expert_add_info_format(state
->pinfo
,
5257 "SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
5258 sek
->key_origin
, sek
->keytype
,
5259 sek
->id_str
, sek
->num_same
,
5260 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
5261 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
5263 sek
= ek
->same_list
;
5264 while (sek
!= NULL
) {
5265 expert_add_info_format(state
->pinfo
,
5268 "%s %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
5270 sek
->key_origin
, sek
->keytype
,
5271 sek
->id_str
, sek
->num_same
,
5272 sek
->keyvalue
[0] & 0xFF, sek
->keyvalue
[1] & 0xFF,
5273 sek
->keyvalue
[2] & 0xFF, sek
->keyvalue
[3] & 0xFF);
5274 sek
= sek
->same_list
;
5276 #endif /* HAVE_KERBEROS */
5279 static const value_string KERB_LOGON_SUBMIT_TYPE
[] = {
5280 { 2, "KerbInteractiveLogon" },
5281 { 6, "KerbSmartCardLogon" },
5282 { 7, "KerbWorkstationUnlockLogon" },
5283 { 8, "KerbSmartCardUnlockLogon" },
5284 { 9, "KerbProxyLogon" },
5285 { 10, "KerbTicketLogon" },
5286 { 11, "KerbTicketUnlockLogon" },
5287 { 12, "KerbS4ULogon" },
5288 { 13, "KerbCertificateLogon" },
5289 { 14, "KerbCertificateS4ULogon" },
5290 { 15, "KerbCertificateUnlockLogon" },
5295 #define KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET 0x1
5296 #define KERB_LOGON_FLAG_REDIRECTED 0x2
5298 static int* const ktl_flags_bits
[] = {
5299 &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET
,
5300 &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED
,
5305 dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
)
5308 proto_tree
*subtree
;
5309 uint32_t ServiceTicketLength
;
5310 uint32_t TicketGrantingTicketLength
;
5313 if (tvb_captured_length(tvb
) < 32)
5316 item
= proto_tree_add_item(tree
, hf_kerberos_KERB_TICKET_LOGON
, tvb
, offset
, -1, ENC_NA
);
5317 subtree
= proto_item_add_subtree(item
, ett_kerberos_KERB_TICKET_LOGON
);
5319 proto_tree_add_item(subtree
, hf_kerberos_KERB_TICKET_LOGON_MessageType
, tvb
, offset
, 4,
5323 proto_tree_add_bitmask(subtree
, tvb
, offset
, hf_kerberos_KERB_TICKET_LOGON_Flags
,
5324 ett_kerberos
, ktl_flags_bits
, ENC_LITTLE_ENDIAN
);
5327 ServiceTicketLength
= tvb_get_letohl(tvb
, offset
);
5328 proto_tree_add_item(subtree
, hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength
, tvb
,
5329 offset
, 4, ENC_LITTLE_ENDIAN
);
5332 TicketGrantingTicketLength
= tvb_get_letohl(tvb
, offset
);
5333 proto_tree_add_item(subtree
, hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength
,
5334 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
5337 /* Skip two PUCHAR of ServiceTicket and TicketGrantingTicket */
5340 if (ServiceTicketLength
== 0)
5343 orig_offset
= offset
;
5344 offset
= dissect_kerberos_Ticket(false, tvb
, offset
, actx
, subtree
,
5345 hf_kerberos_KERB_TICKET_LOGON_ServiceTicket
);
5347 if ((unsigned)(offset
-orig_offset
) != ServiceTicketLength
)
5350 if (TicketGrantingTicketLength
== 0)
5353 offset
= dissect_kerberos_KRB_CRED(false, tvb
, offset
, actx
, subtree
,
5354 hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket
);
5356 if ((unsigned)(offset
-orig_offset
) != ServiceTicketLength
+ TicketGrantingTicketLength
)
5363 dissect_kerberos_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
5364 bool dci
, bool do_col_protocol
, bool have_rm
,
5365 kerberos_callbacks
*cb
)
5367 volatile int offset
= 0;
5368 proto_tree
*volatile kerberos_tree
= NULL
;
5369 proto_item
*volatile item
= NULL
;
5370 kerberos_private_data_t
*private_data
= NULL
;
5371 asn1_ctx_t asn1_ctx
;
5373 /* TCP record mark and length */
5374 uint32_t krb_rm
= 0;
5377 gbl_do_col_info
=dci
;
5380 krb_rm
= tvb_get_ntohl(tvb
, offset
);
5381 krb_reclen
= kerberos_rm_to_reclen(krb_rm
);
5383 * What is a reasonable size limit?
5385 if (krb_reclen
> 10 * 1024 * 1024) {
5389 if (do_col_protocol
) {
5390 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "KRB5");
5394 item
= proto_tree_add_item(tree
, proto_kerberos
, tvb
, 0, -1, ENC_NA
);
5395 kerberos_tree
= proto_item_add_subtree(item
, ett_kerberos
);
5398 show_krb_recordmark(kerberos_tree
, tvb
, offset
, krb_rm
);
5401 /* Do some sanity checking here,
5402 * All krb5 packets start with a TAG class that is BER_CLASS_APP
5403 * and a tag value that is either of the values below:
5404 * If it doesn't look like kerberos, return 0 and let someone else have
5411 get_ber_identifier(tvb
, offset
, &tmp_class
, &tmp_pc
, &tmp_tag
);
5412 if(tmp_class
!=BER_CLASS_APP
){
5416 case KRB5_MSG_TICKET
:
5417 case KRB5_MSG_AUTHENTICATOR
:
5418 case KRB5_MSG_ENC_TICKET_PART
:
5419 case KRB5_MSG_AS_REQ
:
5420 case KRB5_MSG_AS_REP
:
5421 case KRB5_MSG_TGS_REQ
:
5422 case KRB5_MSG_TGS_REP
:
5423 case KRB5_MSG_AP_REQ
:
5424 case KRB5_MSG_AP_REP
:
5425 case KRB5_MSG_ENC_AS_REP_PART
:
5426 case KRB5_MSG_ENC_TGS_REP_PART
:
5427 case KRB5_MSG_ENC_AP_REP_PART
:
5428 case KRB5_MSG_ENC_KRB_PRIV_PART
:
5429 case KRB5_MSG_ENC_KRB_CRED_PART
:
5432 case KRB5_MSG_ERROR
:
5437 if (do_col_protocol
) {
5438 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "KRB5");
5440 if (gbl_do_col_info
) {
5441 col_clear(pinfo
->cinfo
, COL_INFO
);
5444 item
= proto_tree_add_item(tree
, proto_kerberos
, tvb
, 0, -1, ENC_NA
);
5445 kerberos_tree
= proto_item_add_subtree(item
, ett_kerberos
);
5448 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
5449 asn1_ctx
.private_data
= NULL
;
5450 private_data
= kerberos_get_private_data(&asn1_ctx
);
5451 private_data
->callbacks
= cb
;
5454 offset
=dissect_kerberos_Applications(false, tvb
, offset
, &asn1_ctx
, kerberos_tree
, /* hf_index */ -1);
5455 } CATCH_BOUNDS_ERRORS
{
5459 if (private_data
->frame_rep
!= UINT32_MAX
) {
5460 proto_item
*tmp_item
;
5462 tmp_item
= proto_tree_add_uint(kerberos_tree
, hf_krb_response_in
, tvb
, 0, 0, private_data
->frame_rep
);
5463 proto_item_set_generated(tmp_item
);
5466 if (private_data
->frame_req
!= UINT32_MAX
) {
5467 proto_item
*tmp_item
;
5470 tmp_item
= proto_tree_add_uint(kerberos_tree
, hf_krb_response_to
, tvb
, 0, 0, private_data
->frame_req
);
5471 proto_item_set_generated(tmp_item
);
5474 nstime_delta(&deltat
, &t
, &private_data
->req_time
);
5475 tmp_item
= proto_tree_add_time(kerberos_tree
, hf_krb_time
, tvb
, 0, 0, &deltat
);
5476 proto_item_set_generated(tmp_item
);
5479 if (kerberos_tree
!= NULL
) {
5480 struct kerberos_display_key_state display_state
= {
5481 .tree
= kerberos_tree
,
5483 .expindex
= &ei_kerberos_learnt_keytype
,
5488 wmem_list_foreach(private_data
->learnt_keys
,
5489 kerberos_display_key
,
5493 if (kerberos_tree
!= NULL
) {
5494 struct kerberos_display_key_state display_state
= {
5495 .tree
= kerberos_tree
,
5497 .expindex
= &ei_kerberos_missing_keytype
,
5502 wmem_list_foreach(private_data
->missing_keys
,
5503 kerberos_display_key
,
5507 if (kerberos_tree
!= NULL
) {
5508 struct kerberos_display_key_state display_state
= {
5509 .tree
= kerberos_tree
,
5511 .expindex
= &ei_kerberos_decrypted_keytype
,
5516 wmem_list_foreach(private_data
->decryption_keys
,
5517 kerberos_display_key
,
5521 proto_item_set_len(item
, offset
);
5526 * Display the TCP record mark.
5529 show_krb_recordmark(proto_tree
*tree
, tvbuff_t
*tvb
, int start
, uint32_t krb_rm
)
5532 proto_tree
*rm_tree
;
5537 rec_len
= kerberos_rm_to_reclen(krb_rm
);
5538 rm_tree
= proto_tree_add_subtree_format(tree
, tvb
, start
, 4, ett_krb_recordmark
, NULL
,
5539 "Record Mark: %u %s", rec_len
, plurality(rec_len
, "byte", "bytes"));
5540 proto_tree_add_boolean(rm_tree
, hf_krb_rm_reserved
, tvb
, start
, 4, krb_rm
);
5541 proto_tree_add_uint(rm_tree
, hf_krb_rm_reclen
, tvb
, start
, 4, krb_rm
);
5545 dissect_kerberos_main(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, bool do_col_info
, kerberos_callbacks
*cb
)
5547 return (dissect_kerberos_common(tvb
, pinfo
, tree
, do_col_info
, false, false, cb
));
5551 kerberos_output_keytype(void)
5557 dissect_kerberos_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
5559 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
5560 Since all (except weirdo transarc krb4 stuff) use
5561 an opcode <=16 in the first byte, use this to see if it might
5563 All krb5 commands start with an APPL tag and thus is >=0x60
5564 so if first byte is <=16 just blindly assume it is krb4 then
5566 if(tvb_captured_length(tvb
) >= 1 && tvb_get_uint8(tvb
, 0)<=0x10){
5570 res
=call_dissector_only(krb4_handle
, tvb
, pinfo
, tree
, NULL
);
5578 return dissect_kerberos_common(tvb
, pinfo
, tree
, true, true, false, NULL
);
5582 kerberos_rm_to_reclen(unsigned krb_rm
)
5584 return (krb_rm
& KRB_RM_RECLEN
);
5588 get_krb_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
5593 krb_rm
= tvb_get_ntohl(tvb
, offset
);
5594 pdulen
= kerberos_rm_to_reclen(krb_rm
);
5595 return (pdulen
+ 4);
5598 kerberos_prefs_apply_cb(void) {
5599 #ifdef HAVE_LIBNETTLE
5601 read_keytab_file(keytab_filename
);
5606 dissect_kerberos_tcp_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
5608 pinfo
->fragmented
= true;
5609 if (dissect_kerberos_common(tvb
, pinfo
, tree
, true, true, true, NULL
) < 0) {
5611 * The dissector failed to recognize this as a valid
5612 * Kerberos message. Mark it as a continuation packet.
5614 col_set_str(pinfo
->cinfo
, COL_INFO
, "Continuation");
5617 return tvb_captured_length(tvb
);
5621 dissect_kerberos_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
5623 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "KRB5");
5624 col_clear(pinfo
->cinfo
, COL_INFO
);
5626 tcp_dissect_pdus(tvb
, pinfo
, tree
, krb_desegment
, 4, get_krb_pdu_len
,
5627 dissect_kerberos_tcp_pdu
, data
);
5628 return tvb_captured_length(tvb
);
5631 /*--- proto_register_kerberos -------------------------------------------*/
5632 void proto_register_kerberos(void) {
5634 /* List of fields */
5636 static hf_register_info hf
[] = {
5637 { &hf_krb_response_to
,
5638 { "Response to", "kerberos.response_to", FT_FRAMENUM
, BASE_NONE
,
5639 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0, "This packet is a response to the packet in this frame", HFILL
}},
5640 { &hf_krb_response_in
,
5641 { "Response in", "kerberos.response_in", FT_FRAMENUM
, BASE_NONE
,
5642 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0, "The response to this packet is in this packet", HFILL
}},
5644 { "Time from request", "kerberos.time", FT_RELATIVE_TIME
, BASE_NONE
,
5645 NULL
, 0, "Time between Request and Response for Kerberos KDC requests", HFILL
}},
5646 { &hf_krb_rm_reserved
, {
5647 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN
, 32,
5648 TFS(&tfs_set_notset
), KRB_RM_RESERVED
, "Record mark reserved bit", HFILL
}},
5649 { &hf_krb_rm_reclen
, {
5650 "Record Length", "kerberos.rm.length", FT_UINT32
, BASE_DEC
,
5651 NULL
, KRB_RM_RECLEN
, NULL
, HFILL
}},
5652 { &hf_krb_provsrv_location
, {
5653 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING
, BASE_NONE
,
5654 NULL
, 0, "PacketCable PROV SRV Location", HFILL
}},
5656 { "pw-salt", "kerberos.pw_salt", FT_BYTES
, BASE_NONE
,
5657 NULL
, 0, NULL
, HFILL
}},
5658 { &hf_krb_ext_error_nt_status
, /* we keep kerberos.smb.nt_status for compat reasons */
5659 { "NT Status", "kerberos.smb.nt_status", FT_UINT32
, BASE_HEX
|BASE_EXT_STRING
,
5660 &NT_errors_ext
, 0, "NT Status code", HFILL
}},
5661 { &hf_krb_ext_error_reserved
,
5662 { "Reserved", "kerberos.ext_error.reserved", FT_UINT32
, BASE_HEX
,
5663 NULL
, 0, NULL
, HFILL
}},
5664 { &hf_krb_ext_error_flags
,
5665 { "Flags", "kerberos.ext_error.flags", FT_UINT32
, BASE_HEX
,
5666 NULL
, 0, NULL
, HFILL
}},
5667 { &hf_krb_address_ip
, {
5668 "IP Address", "kerberos.addr_ip", FT_IPv4
, BASE_NONE
,
5669 NULL
, 0, NULL
, HFILL
}},
5670 { &hf_krb_address_ipv6
, {
5671 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6
, BASE_NONE
,
5672 NULL
, 0, NULL
, HFILL
}},
5673 { &hf_krb_address_netbios
, {
5674 "NetBIOS Address", "kerberos.addr_nb", FT_STRING
, BASE_NONE
,
5675 NULL
, 0, "NetBIOS Address and type", HFILL
}},
5676 { &hf_krb_gssapi_len
, {
5677 "Length", "kerberos.gssapi.len", FT_UINT32
, BASE_DEC
,
5678 NULL
, 0, "Length of GSSAPI Bnd field", HFILL
}},
5679 { &hf_krb_gssapi_bnd
, {
5680 "Bnd", "kerberos.gssapi.bdn", FT_BYTES
, BASE_NONE
,
5681 NULL
, 0, "GSSAPI Bnd field", HFILL
}},
5682 { &hf_krb_gssapi_c_flag_deleg
, {
5683 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN
, 32,
5684 TFS(&tfs_gss_flags_deleg
), KRB5_GSS_C_DELEG_FLAG
, NULL
, HFILL
}},
5685 { &hf_krb_gssapi_c_flag_mutual
, {
5686 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN
, 32,
5687 TFS(&tfs_gss_flags_mutual
), KRB5_GSS_C_MUTUAL_FLAG
, NULL
, HFILL
}},
5688 { &hf_krb_gssapi_c_flag_replay
, {
5689 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN
, 32,
5690 TFS(&tfs_gss_flags_replay
), KRB5_GSS_C_REPLAY_FLAG
, NULL
, HFILL
}},
5691 { &hf_krb_gssapi_c_flag_sequence
, {
5692 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN
, 32,
5693 TFS(&tfs_gss_flags_sequence
), KRB5_GSS_C_SEQUENCE_FLAG
, NULL
, HFILL
}},
5694 { &hf_krb_gssapi_c_flag_conf
, {
5695 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN
, 32,
5696 TFS(&tfs_gss_flags_conf
), KRB5_GSS_C_CONF_FLAG
, NULL
, HFILL
}},
5697 { &hf_krb_gssapi_c_flag_integ
, {
5698 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN
, 32,
5699 TFS(&tfs_gss_flags_integ
), KRB5_GSS_C_INTEG_FLAG
, NULL
, HFILL
}},
5700 { &hf_krb_gssapi_c_flag_dce_style
, {
5701 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN
, 32,
5702 TFS(&tfs_gss_flags_dce_style
), KRB5_GSS_C_DCE_STYLE
, NULL
, HFILL
}},
5703 { &hf_krb_gssapi_dlgopt
, {
5704 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16
, BASE_DEC
,
5705 NULL
, 0, "GSSAPI DlgOpt", HFILL
}},
5706 { &hf_krb_gssapi_dlglen
, {
5707 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16
, BASE_DEC
,
5708 NULL
, 0, "GSSAPI DlgLen", HFILL
}},
5709 { &hf_krb_midl_blob_len
, {
5710 "Blob Length", "kerberos.midl_blob_len", FT_UINT64
, BASE_DEC
,
5711 NULL
, 0, "Length of NDR encoded data that follows", HFILL
}},
5712 { &hf_krb_midl_fill_bytes
, {
5713 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32
, BASE_HEX
,
5714 NULL
, 0, "Just some fill bytes", HFILL
}},
5715 { &hf_krb_midl_version
, {
5716 "Version", "kerberos.midl.version", FT_UINT8
, BASE_DEC
,
5717 NULL
, 0, "Version of pickling", HFILL
}},
5718 { &hf_krb_midl_hdr_len
, {
5719 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16
, BASE_DEC
,
5720 NULL
, 0, "Length of header", HFILL
}},
5721 { &hf_krb_pac_signature_type
, {
5722 "Type", "kerberos.pac.signature.type", FT_INT32
, BASE_DEC
,
5723 NULL
, 0, "PAC Signature Type", HFILL
}},
5724 { &hf_krb_pac_signature_signature
, {
5725 "Signature", "kerberos.pac.signature.signature", FT_BYTES
, BASE_NONE
,
5726 NULL
, 0, "A PAC signature blob", HFILL
}},
5727 { &hf_krb_w2k_pac_entries
, {
5728 "Num Entries", "kerberos.pac.entries", FT_UINT32
, BASE_DEC
,
5729 NULL
, 0, "Number of W2k PAC entries", HFILL
}},
5730 { &hf_krb_w2k_pac_version
, {
5731 "Version", "kerberos.pac.version", FT_UINT32
, BASE_DEC
,
5732 NULL
, 0, "Version of PAC structures", HFILL
}},
5733 { &hf_krb_w2k_pac_type
, {
5734 "Type", "kerberos.pac.type", FT_UINT32
, BASE_DEC
,
5735 VALS(w2k_pac_types
), 0, "Type of W2k PAC entry", HFILL
}},
5736 { &hf_krb_w2k_pac_size
, {
5737 "Size", "kerberos.pac.size", FT_UINT32
, BASE_DEC
,
5738 NULL
, 0, "Size of W2k PAC entry", HFILL
}},
5739 { &hf_krb_w2k_pac_offset
, {
5740 "Offset", "kerberos.pac.offset", FT_UINT32
, BASE_DEC
,
5741 NULL
, 0, "Offset to W2k PAC entry", HFILL
}},
5742 { &hf_krb_pac_clientid
, {
5743 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
5744 NULL
, 0, "ClientID Timestamp", HFILL
}},
5745 { &hf_krb_pac_namelen
, {
5746 "Name Length", "kerberos.pac.namelen", FT_UINT16
, BASE_DEC
,
5747 NULL
, 0, "Length of client name", HFILL
}},
5748 { &hf_krb_pac_clientname
, {
5749 "Name", "kerberos.pac.name", FT_STRING
, BASE_NONE
,
5750 NULL
, 0, "Name of the Client in the PAC structure", HFILL
}},
5751 { &hf_krb_pac_logon_info
, {
5752 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES
, BASE_NONE
,
5753 NULL
, 0, "PAC_LOGON_INFO structure", HFILL
}},
5754 { &hf_krb_pac_credential_data
, {
5755 "PAC_CREDENTIAL_DATA", "kerberos.pac_credential_data", FT_BYTES
, BASE_NONE
,
5756 NULL
, 0, "PAC_CREDENTIAL_DATA structure", HFILL
}},
5757 { &hf_krb_pac_credential_info
, {
5758 "PAC_CREDENTIAL_INFO", "kerberos.pac_credential_info", FT_BYTES
, BASE_NONE
,
5759 NULL
, 0, "PAC_CREDENTIAL_INFO structure", HFILL
}},
5760 { &hf_krb_pac_credential_info_version
, {
5761 "Version", "kerberos.pac_credential_info.version", FT_UINT32
, BASE_DEC
,
5762 NULL
, 0, NULL
, HFILL
}},
5763 { &hf_krb_pac_credential_info_etype
, {
5764 "Etype", "kerberos.pac_credential_info.etype", FT_UINT32
, BASE_DEC
,
5765 NULL
, 0, NULL
, HFILL
}},
5766 { &hf_krb_pac_server_checksum
, {
5767 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES
, BASE_NONE
,
5768 NULL
, 0, "PAC_SERVER_CHECKSUM structure", HFILL
}},
5769 { &hf_krb_pac_privsvr_checksum
, {
5770 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES
, BASE_NONE
,
5771 NULL
, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL
}},
5772 { &hf_krb_pac_client_info_type
, {
5773 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES
, BASE_NONE
,
5774 NULL
, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL
}},
5775 { &hf_krb_pac_s4u_delegation_info
, {
5776 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES
, BASE_NONE
,
5777 NULL
, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL
}},
5778 { &hf_krb_pac_upn_dns_info
, {
5779 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES
, BASE_NONE
,
5780 NULL
, 0, "UPN_DNS_INFO structure", HFILL
}},
5781 { &hf_krb_pac_upn_flags
, {
5782 "Flags", "kerberos.pac.upn.flags", FT_UINT32
, BASE_HEX
,
5783 NULL
, 0, "UPN flags", HFILL
}},
5784 { &hf_krb_pac_upn_flag_upn_constructed
, {
5785 "UPN Name Constructed",
5786 "kerberos.pac.upn.flags.upn_constructed",
5788 TFS(&tfs_krb_pac_upn_flag_upn_constructed
),
5789 PAC_UPN_DNS_FLAG_CONSTRUCTED
,
5790 "Is the UPN Name constructed?", HFILL
}},
5791 { &hf_krb_pac_upn_flag_has_sam_name_and_sid
, {
5792 "SAM_NAME and SID Included",
5793 "kerberos.pac.upn.flags.has_sam_name_and_sid",
5795 TFS(&tfs_krb_pac_upn_flag_has_sam_name_and_sid
),
5796 PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID
,
5797 "Are SAM_NAME and SID included?", HFILL
}},
5798 { &hf_krb_pac_upn_upn_offset
, {
5799 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16
, BASE_DEC
,
5800 NULL
, 0, NULL
, HFILL
}},
5801 { &hf_krb_pac_upn_upn_len
, {
5802 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16
, BASE_DEC
,
5803 NULL
, 0, NULL
, HFILL
}},
5804 { &hf_krb_pac_upn_upn_name
, {
5805 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING
, BASE_NONE
,
5806 NULL
, 0, NULL
, HFILL
}},
5807 { &hf_krb_pac_upn_dns_offset
, {
5808 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16
, BASE_DEC
,
5809 NULL
, 0, NULL
, HFILL
}},
5810 { &hf_krb_pac_upn_dns_len
, {
5811 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16
, BASE_DEC
,
5812 NULL
, 0, NULL
, HFILL
}},
5813 { &hf_krb_pac_upn_dns_name
, {
5814 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING
, BASE_NONE
,
5815 NULL
, 0, NULL
, HFILL
}},
5816 { &hf_krb_pac_upn_samaccountname_offset
, {
5817 "sAMAccountName Offset", "kerberos.pac.upn.samaccountname_offset", FT_UINT16
, BASE_DEC
,
5818 NULL
, 0, NULL
, HFILL
}},
5819 { &hf_krb_pac_upn_samaccountname_len
, {
5820 "sAMAccountName Len", "kerberos.pac.upn.samaccountname_len", FT_UINT16
, BASE_DEC
,
5821 NULL
, 0, NULL
, HFILL
}},
5822 { &hf_krb_pac_upn_samaccountname
, {
5823 "sAMAccountName", "kerberos.pac.upn.samaccountname", FT_STRING
, BASE_NONE
,
5824 NULL
, 0, NULL
, HFILL
}},
5825 { &hf_krb_pac_upn_objectsid_offset
, {
5826 "objectSid Offset", "kerberos.pac.upn.objectsid_offset", FT_UINT16
, BASE_DEC
,
5827 NULL
, 0, NULL
, HFILL
}},
5828 { &hf_krb_pac_upn_objectsid_len
, {
5829 "objectSid Len", "kerberos.pac.upn.objectsid_len", FT_UINT16
, BASE_DEC
,
5830 NULL
, 0, NULL
, HFILL
}},
5831 { &hf_krb_pac_client_claims_info
, {
5832 "PAC_CLIENT_CLAIMS_INFO", "kerberos.pac_client_claims_info", FT_BYTES
, BASE_NONE
,
5833 NULL
, 0, "PAC_CLIENT_CLAIMS_INFO structure", HFILL
}},
5834 { &hf_krb_pac_device_info
, {
5835 "PAC_DEVICE_INFO", "kerberos.pac_device_info", FT_BYTES
, BASE_NONE
,
5836 NULL
, 0, "PAC_DEVICE_INFO structure", HFILL
}},
5837 { &hf_krb_pac_device_claims_info
, {
5838 "PAC_DEVICE_CLAIMS_INFO", "kerberos.pac_device_claims_info", FT_BYTES
, BASE_NONE
,
5839 NULL
, 0, "PAC_DEVICE_CLAIMS_INFO structure", HFILL
}},
5840 { &hf_krb_pac_ticket_checksum
, {
5841 "PAC_TICKET_CHECKSUM", "kerberos.pac_ticket_checksum", FT_BYTES
, BASE_NONE
,
5842 NULL
, 0, "PAC_TICKET_CHECKSUM structure", HFILL
}},
5843 { &hf_krb_pac_attributes_info
, {
5844 "PAC_ATTRIBUTES_INFO", "kerberos.pac_attributes_info", FT_BYTES
, BASE_NONE
,
5845 NULL
, 0, "PAC_ATTRIBUTES_INFO structure", HFILL
}},
5846 { &hf_krb_pac_attributes_info_length
, {
5847 "Flags Valid Length", "kerberos.pac.attributes_info.length", FT_UINT32
, BASE_DEC
,
5848 NULL
, 0, NULL
, HFILL
}},
5849 { &hf_krb_pac_attributes_info_flags
, {
5850 "Flags", "kerberos.pac.attributes_info.flags",
5851 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
5852 { &hf_krb_pac_attributes_info_flags_pac_was_requested
, {
5854 "kerberos.pac.attributes.flags.pac_was_requested",
5856 TFS(&tfs_krb_pac_attributes_info_pac_was_requested
),
5857 PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED
,
5858 "Was a PAC requested?", HFILL
}},
5859 { &hf_krb_pac_attributes_info_flags_pac_was_given_implicitly
, {
5860 "PAC given Implicitly",
5861 "kerberos.pac.attributes.flags.pac_was_given_implicitly",
5863 TFS(&tfs_krb_pac_attributes_info_pac_was_given_implicitly
),
5864 PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY
,
5865 "Was PAC given implicitly?", HFILL
}},
5866 { &hf_krb_pac_requester_sid
, {
5867 "PAC_REQUESTER_SID", "kerberos.pac_requester_sid", FT_BYTES
, BASE_NONE
,
5868 NULL
, 0, "PAC_REQUESTER_SID structure", HFILL
}},
5869 { &hf_krb_pac_full_checksum
, {
5870 "PAC_FULL_CHECKSUM", "kerberos.pac_full_checksum", FT_BYTES
, BASE_NONE
,
5871 NULL
, 0, "PAC_FULL_CHECKSUM structure", HFILL
}},
5872 { &hf_krb_pa_supported_enctypes
,
5873 { "SupportedEnctypes", "kerberos.supported_entypes",
5874 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
5875 { &hf_krb_pa_supported_enctypes_des_cbc_crc
,
5876 { "des-cbc-crc", "kerberos.supported_entypes.des-cbc-crc",
5877 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00000001, NULL
, HFILL
}},
5878 { &hf_krb_pa_supported_enctypes_des_cbc_md5
,
5879 { "des-cbc-md5", "kerberos.supported_entypes.des-cbc-md5",
5880 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00000002, NULL
, HFILL
}},
5881 { &hf_krb_pa_supported_enctypes_rc4_hmac
,
5882 { "rc4-hmac", "kerberos.supported_entypes.rc4-hmac",
5883 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00000004, NULL
, HFILL
}},
5884 { &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96
,
5885 { "aes128-cts-hmac-sha1-96", "kerberos.supported_entypes.aes128-cts-hmac-sha1-96",
5886 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00000008, NULL
, HFILL
}},
5887 { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96
,
5888 { "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96",
5889 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00000010, NULL
, HFILL
}},
5890 { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96_sk
,
5891 { "aes256-cts-hmac-sha1-96-sk", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96-sk",
5892 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00000020, NULL
, HFILL
}},
5893 { &hf_krb_pa_supported_enctypes_fast_supported
,
5894 { "fast-supported", "kerberos.supported_entypes.fast-supported",
5895 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00010000, NULL
, HFILL
}},
5896 { &hf_krb_pa_supported_enctypes_compound_identity_supported
,
5897 { "compound-identity-supported", "kerberos.supported_entypes.compound-identity-supported",
5898 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00020000, NULL
, HFILL
}},
5899 { &hf_krb_pa_supported_enctypes_claims_supported
,
5900 { "claims-supported", "kerberos.supported_entypes.claims-supported",
5901 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00040000, NULL
, HFILL
}},
5902 { &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled
,
5903 { "resource-sid-compression-disabled", "kerberos.supported_entypes.resource-sid-compression-disabled",
5904 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00080000, NULL
, HFILL
}},
5905 { &hf_krb_ad_ap_options
,
5906 { "AD-AP-Options", "kerberos.ad_ap_options",
5907 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
5908 { &hf_krb_ad_ap_options_cbt
,
5909 { "ChannelBindings", "kerberos.ad_ap_options.cbt",
5910 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), 0x00004000, NULL
, HFILL
}},
5911 { &hf_krb_ad_ap_options_unverified_target_name
,
5912 { "UnverifiedTargetName", "kerberos.ad_ap_options.unverified_target_name",
5913 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), 0x00008000, NULL
, HFILL
}},
5914 { &hf_krb_ad_target_principal
,
5915 { "Target Principal", "kerberos.ad_target_principal",
5916 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
5917 { &hf_krb_key_hidden_item
,
5918 { "KeyHiddenItem", "krb5.key_hidden_item",
5919 FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5920 { &hf_kerberos_KERB_TICKET_LOGON
,
5921 { "KERB_TICKET_LOGON", "kerberos.KERB_TICKET_LOGON",
5922 FT_NONE
, BASE_NONE
, NULL
, 0,
5924 { &hf_kerberos_KERB_TICKET_LOGON_MessageType
,
5925 { "MessageType", "kerberos.KERB_TICKET_LOGON.MessageType",
5926 FT_UINT32
, BASE_DEC
, VALS(KERB_LOGON_SUBMIT_TYPE
), 0,
5928 { &hf_kerberos_KERB_TICKET_LOGON_Flags
,
5929 { "Flags", "kerberos.KERB_TICKET_LOGON.Flags",
5930 FT_UINT32
, BASE_DEC
, NULL
, 0,
5932 { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength
,
5933 { "ServiceTicketLength", "kerberos.KERB_TICKET_LOGON.ServiceTicketLength",
5934 FT_UINT32
, BASE_DEC
, NULL
, 0,
5936 { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength
,
5937 { "TicketGrantingTicketLength", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicketLength",
5938 FT_UINT32
, BASE_DEC
, NULL
, 0,
5940 { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicket
,
5941 { "ServiceTicket", "kerberos.KERB_TICKET_LOGON.ServiceTicket",
5942 FT_NONE
, BASE_NONE
, NULL
, 0,
5944 { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket
,
5945 { "TicketGrantingTicket", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicket",
5946 FT_NONE
, BASE_NONE
, NULL
, 0,
5948 { &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET
,
5949 { "allow_expired_ticket", "kerberos.KERB_TICKET_LOGON.FLAG_ALLOW_EXPIRED_TICKET",
5950 FT_BOOLEAN
, 32, NULL
, KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET
,
5952 { &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED
,
5953 { "redirected", "kerberos.KERB_TICKET_LOGON.FLAG_REDIRECTED",
5954 FT_BOOLEAN
, 32, NULL
, KERB_LOGON_FLAG_REDIRECTED
,
5956 #ifdef HAVE_KERBEROS
5957 { &hf_kerberos_KrbFastResponse
,
5958 { "KrbFastResponse", "kerberos.KrbFastResponse_element",
5959 FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
5960 { &hf_kerberos_strengthen_key
,
5961 { "strengthen-key", "kerberos.strengthen_key_element",
5962 FT_NONE
, BASE_NONE
, NULL
, 0,
5964 { &hf_kerberos_finished
,
5965 { "finished", "kerberos.finished_element",
5966 FT_NONE
, BASE_NONE
, NULL
, 0,
5967 "KrbFastFinished", HFILL
}},
5968 { &hf_kerberos_fast_options
,
5969 { "fast-options", "kerberos.fast_options",
5970 FT_BYTES
, BASE_NONE
, NULL
, 0,
5971 "FastOptions", HFILL
}},
5972 { &hf_kerberos_FastOptions_reserved
,
5973 { "reserved", "kerberos.FastOptions.reserved",
5974 FT_BOOLEAN
, 8, NULL
, 0x80,
5976 { &hf_kerberos_FastOptions_hide_client_names
,
5977 { "hide-client-names", "kerberos.FastOptions.hide.client.names",
5978 FT_BOOLEAN
, 8, NULL
, 0x40,
5980 { &hf_kerberos_FastOptions_spare_bit2
,
5981 { "spare_bit2", "kerberos.FastOptions.spare.bit2",
5982 FT_BOOLEAN
, 8, NULL
, 0x20,
5984 { &hf_kerberos_FastOptions_spare_bit3
,
5985 { "spare_bit3", "kerberos.FastOptions.spare.bit3",
5986 FT_BOOLEAN
, 8, NULL
, 0x10,
5988 { &hf_kerberos_FastOptions_spare_bit4
,
5989 { "spare_bit4", "kerberos.FastOptions.spare.bit4",
5990 FT_BOOLEAN
, 8, NULL
, 0x08,
5992 { &hf_kerberos_FastOptions_spare_bit5
,
5993 { "spare_bit5", "kerberos.FastOptions.spare.bit5",
5994 FT_BOOLEAN
, 8, NULL
, 0x04,
5996 { &hf_kerberos_FastOptions_spare_bit6
,
5997 { "spare_bit6", "kerberos.FastOptions.spare.bit6",
5998 FT_BOOLEAN
, 8, NULL
, 0x02,
6000 { &hf_kerberos_FastOptions_spare_bit7
,
6001 { "spare_bit7", "kerberos.FastOptions.spare.bit7",
6002 FT_BOOLEAN
, 8, NULL
, 0x01,
6004 { &hf_kerberos_FastOptions_spare_bit8
,
6005 { "spare_bit8", "kerberos.FastOptions.spare.bit8",
6006 FT_BOOLEAN
, 8, NULL
, 0x80,
6008 { &hf_kerberos_FastOptions_spare_bit9
,
6009 { "spare_bit9", "kerberos.FastOptions.spare.bit9",
6010 FT_BOOLEAN
, 8, NULL
, 0x40,
6012 { &hf_kerberos_FastOptions_spare_bit10
,
6013 { "spare_bit10", "kerberos.FastOptions.spare.bit10",
6014 FT_BOOLEAN
, 8, NULL
, 0x20,
6016 { &hf_kerberos_FastOptions_spare_bit11
,
6017 { "spare_bit11", "kerberos.FastOptions.spare.bit11",
6018 FT_BOOLEAN
, 8, NULL
, 0x10,
6020 { &hf_kerberos_FastOptions_spare_bit12
,
6021 { "spare_bit12", "kerberos.FastOptions.spare.bit12",
6022 FT_BOOLEAN
, 8, NULL
, 0x08,
6024 { &hf_kerberos_FastOptions_spare_bit13
,
6025 { "spare_bit13", "kerberos.FastOptions.spare.bit13",
6026 FT_BOOLEAN
, 8, NULL
, 0x04,
6028 { &hf_kerberos_FastOptions_spare_bit14
,
6029 { "spare_bit14", "kerberos.FastOptions.spare.bit14",
6030 FT_BOOLEAN
, 8, NULL
, 0x02,
6032 { &hf_kerberos_FastOptions_spare_bit15
,
6033 { "spare_bit15", "kerberos.FastOptions.spare.bit15",
6034 FT_BOOLEAN
, 8, NULL
, 0x01,
6036 { &hf_kerberos_FastOptions_kdc_follow_referrals
,
6037 { "kdc-follow-referrals", "kerberos.FastOptions.kdc.follow.referrals",
6038 FT_BOOLEAN
, 8, NULL
, 0x80,
6040 { &hf_kerberos_ticket_checksum
,
6041 { "ticket-checksum", "kerberos.ticket_checksum_element",
6042 FT_NONE
, BASE_NONE
, NULL
, 0,
6043 "Checksum", HFILL
}},
6044 { &hf_krb_patimestamp
,
6045 { "patimestamp", "kerberos.patimestamp",
6046 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0, "KerberosTime", HFILL
}},
6048 { "pausec", "kerberos.pausec",
6049 FT_UINT32
, BASE_DEC
, NULL
, 0, "Microseconds", HFILL
}},
6050 #endif /* HAVE_KERBEROS */
6052 #include "packet-kerberos-hfarr.c"
6055 /* List of subtrees */
6056 static int *ett
[] = {
6058 &ett_krb_recordmark
,
6061 &ett_krb_pac_midl_blob
,
6062 &ett_krb_pac_logon_info
,
6063 &ett_krb_pac_credential_info
,
6064 &ett_krb_pac_s4u_delegation_info
,
6065 &ett_krb_pac_upn_dns_info
,
6066 &ett_krb_pac_upn_dns_info_flags
,
6067 &ett_krb_pac_device_info
,
6068 &ett_krb_pac_server_checksum
,
6069 &ett_krb_pac_privsvr_checksum
,
6070 &ett_krb_pac_client_info_type
,
6071 &ett_krb_pac_ticket_checksum
,
6072 &ett_krb_pac_attributes_info
,
6073 &ett_krb_pac_attributes_info_flags
,
6074 &ett_krb_pac_requester_sid
,
6075 &ett_krb_pac_full_checksum
,
6076 &ett_krb_pa_supported_enctypes
,
6077 &ett_krb_ad_ap_options
,
6078 &ett_kerberos_KERB_TICKET_LOGON
,
6079 #ifdef HAVE_KERBEROS
6080 &ett_krb_pa_enc_ts_enc
,
6081 &ett_kerberos_KrbFastFinished
,
6082 &ett_kerberos_KrbFastResponse
,
6083 &ett_kerberos_KrbFastReq
,
6084 &ett_kerberos_FastOptions
,
6086 #include "packet-kerberos-ettarr.c"
6089 static ei_register_info ei
[] = {
6090 { &ei_kerberos_missing_keytype
, { "kerberos.missing_keytype", PI_DECRYPTION
, PI_WARN
, "Missing keytype", EXPFILL
}},
6091 { &ei_kerberos_decrypted_keytype
, { "kerberos.decrypted_keytype", PI_SECURITY
, PI_CHAT
, "Decrypted keytype", EXPFILL
}},
6092 { &ei_kerberos_learnt_keytype
, { "kerberos.learnt_keytype", PI_SECURITY
, PI_CHAT
, "Learnt keytype", EXPFILL
}},
6093 { &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
}},
6094 { &ei_krb_gssapi_dlglen
, { "kerberos.gssapi.dlglen.error", PI_MALFORMED
, PI_ERROR
, "DlgLen is not the same as number of bytes remaining", EXPFILL
}},
6097 expert_module_t
* expert_krb
;
6098 module_t
*krb_module
;
6100 proto_kerberos
= proto_register_protocol("Kerberos", "KRB5", "kerberos");
6101 proto_register_field_array(proto_kerberos
, hf
, array_length(hf
));
6102 proto_register_subtree_array(ett
, array_length(ett
));
6103 expert_krb
= expert_register_protocol(proto_kerberos
);
6104 expert_register_field_array(expert_krb
, ei
, array_length(ei
));
6106 kerberos_tap
= register_tap("kerberos");
6107 register_srt_table(proto_kerberos
, NULL
, 1, krb5stat_packet
, krb5stat_init
, NULL
);
6109 /* Register dissectors */
6110 kerberos_handle_udp
= register_dissector("kerberos.udp", dissect_kerberos_udp
, proto_kerberos
);
6111 kerberos_handle_tcp
= register_dissector("kerberos.tcp", dissect_kerberos_tcp
, proto_kerberos
);
6113 /* Register preferences */
6114 krb_module
= prefs_register_protocol(proto_kerberos
, kerberos_prefs_apply_cb
);
6115 prefs_register_bool_preference(krb_module
, "desegment",
6116 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
6117 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
6118 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
6120 #ifdef HAVE_KERBEROS
6121 prefs_register_bool_preference(krb_module
, "decrypt",
6122 "Try to decrypt Kerberos blobs",
6123 "Whether the dissector should try to decrypt "
6124 "encrypted Kerberos blobs. This requires that the proper "
6125 "keytab file is installed as well.", &krb_decrypt
);
6127 prefs_register_filename_preference(krb_module
, "file",
6128 "Kerberos keytab file",
6129 "The keytab file containing all the secrets",
6130 &keytab_filename
, false);
6132 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
6133 wmem_register_callback(wmem_epan_scope(), enc_key_list_cb
, NULL
);
6134 kerberos_longterm_keys
= wmem_map_new(wmem_epan_scope(),
6135 enc_key_content_hash
,
6136 enc_key_content_equal
);
6137 kerberos_all_keys
= wmem_map_new_autoreset(wmem_epan_scope(),
6139 enc_key_content_hash
,
6140 enc_key_content_equal
);
6141 kerberos_app_session_keys
= wmem_map_new_autoreset(wmem_epan_scope(),
6143 enc_key_content_hash
,
6144 enc_key_content_equal
);
6145 #endif /* defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) */
6146 #endif /* HAVE_KERBEROS */
6149 static int wrap_dissect_gss_kerb(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
6150 proto_tree
*tree
, dcerpc_info
*di _U_
,uint8_t *drep _U_
)
6154 auth_tvb
= tvb_new_subset_remaining(tvb
, offset
);
6156 dissect_kerberos_main(auth_tvb
, pinfo
, tree
, false, NULL
);
6158 return tvb_captured_length_remaining(tvb
, offset
);
6162 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns
= {
6163 wrap_dissect_gss_kerb
, /* Bind */
6164 wrap_dissect_gss_kerb
, /* Bind ACK */
6165 wrap_dissect_gss_kerb
, /* AUTH3 */
6166 NULL
, /* Request verifier */
6167 NULL
, /* Response verifier */
6168 NULL
, /* Request data */
6169 NULL
/* Response data */
6172 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns
= {
6173 wrap_dissect_gss_kerb
, /* Bind */
6174 wrap_dissect_gss_kerb
, /* Bind ACK */
6175 wrap_dissect_gss_kerb
, /* AUTH3 */
6176 wrap_dissect_gssapi_verf
, /* Request verifier */
6177 wrap_dissect_gssapi_verf
, /* Response verifier */
6178 NULL
, /* Request data */
6179 NULL
/* Response data */
6182 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns
= {
6183 wrap_dissect_gss_kerb
, /* Bind */
6184 wrap_dissect_gss_kerb
, /* Bind ACK */
6185 wrap_dissect_gss_kerb
, /* AUTH3 */
6186 wrap_dissect_gssapi_verf
, /* Request verifier */
6187 wrap_dissect_gssapi_verf
, /* Response verifier */
6188 wrap_dissect_gssapi_payload
, /* Request data */
6189 wrap_dissect_gssapi_payload
/* Response data */
6195 proto_reg_handoff_kerberos(void)
6197 krb4_handle
= find_dissector_add_dependency("krb4", proto_kerberos
);
6199 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS
, kerberos_handle_udp
);
6200 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS
, kerberos_handle_tcp
);
6202 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT
,
6203 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS
,
6204 &gss_kerb_auth_connect_fns
);
6206 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY
,
6207 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS
,
6208 &gss_kerb_auth_sign_fns
);
6210 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY
,
6211 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS
,
6212 &gss_kerb_auth_seal_fns
);
6216 * Editor modelines - https://www.wireshark.org/tools/modelines.html
6221 * indent-tabs-mode: t
6224 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
6225 * :indentSize=8:tabSize=8:noTabs=false: