2 * Routines for Kerberos v4 packet dissection
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 * PDU structure based on the document:
15 * Athena Technical Plan
17 * Kerberos Authentication and Authorization System
18 * by S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H. Saltzer
20 * http://web.mit.edu/Saltzer/www/publications/athenaplan/e.2.1.pdf
22 * 7. Appendix I Design Specifications
27 #include <epan/packet.h>
29 void proto_register_krb4(void);
30 void proto_reg_handoff_krb4(void);
32 static int proto_krb4
;
33 static int hf_krb4_version
;
34 static int hf_krb4_auth_msg_type
;
35 static int hf_krb4_m_type
;
36 static int hf_krb4_byte_order
;
37 static int hf_krb4_name
;
38 static int hf_krb4_instance
;
39 static int hf_krb4_realm
;
40 static int hf_krb4_time_sec
;
41 static int hf_krb4_exp_date
;
42 static int hf_krb4_req_date
;
43 static int hf_krb4_lifetime
;
44 static int hf_krb4_s_name
;
45 static int hf_krb4_s_instance
;
46 static int hf_krb4_kvno
;
47 static int hf_krb4_length
;
48 static int hf_krb4_ticket_length
;
49 static int hf_krb4_request_length
;
50 static int hf_krb4_ticket_blob
;
51 static int hf_krb4_request_blob
;
52 static int hf_krb4_encrypted_blob
;
53 static int hf_krb4_unknown_transarc_blob
;
56 static int ett_krb4_auth_msg_type
;
58 static dissector_handle_t krb4_handle
;
60 #define UDP_PORT_KRB4 750
61 #define TRANSARC_SPECIAL_VERSION 0x63
63 static const value_string byte_order_vals
[] = {
65 { 1, "Little Endian" },
69 #define AUTH_MSG_KDC_REQUEST 1
70 #define AUTH_MSG_KDC_REPLY 2
71 #define AUTH_MSG_APPL_REQUEST 3
72 #define AUTH_MSG_APPL_REQUEST_MUTUAL 4
73 #define AUTH_MSG_ERR_REPLY 5
74 #define AUTH_MSG_PRIVATE 6
75 #define AUTH_MSG_SAFE 7
76 #define AUTH_MSG_APPL_ERR 8
77 #define AUTH_MSG_DIE 63
78 static const value_string m_type_vals
[] = {
79 { AUTH_MSG_KDC_REQUEST
, "KDC Request" },
80 { AUTH_MSG_KDC_REPLY
, "KDC Reply" },
81 { AUTH_MSG_APPL_REQUEST
, "Appl Request" },
82 { AUTH_MSG_APPL_REQUEST_MUTUAL
, "Appl Request Mutual" },
83 { AUTH_MSG_ERR_REPLY
, "Err Reply" },
84 { AUTH_MSG_PRIVATE
, "Private" },
85 { AUTH_MSG_SAFE
, "Safe" },
86 { AUTH_MSG_APPL_ERR
, "Appl Err" },
87 { AUTH_MSG_DIE
, "Die" },
93 dissect_krb4_string(packet_info
*pinfo _U_
, int hf_index
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
96 proto_tree_add_item_ret_length(tree
, hf_index
, tvb
, offset
, -1, ENC_ASCII
|ENC_NA
, &length
);
98 return offset
+ length
;
102 dissect_krb4_kdc_request(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, const unsigned encoding
, int version
)
106 if(version
==TRANSARC_SPECIAL_VERSION
){
107 proto_tree_add_item(tree
, hf_krb4_unknown_transarc_blob
, tvb
, offset
, 8, ENC_NA
);
112 offset
=dissect_krb4_string(pinfo
, hf_krb4_name
, tree
, tvb
, offset
);
115 offset
=dissect_krb4_string(pinfo
, hf_krb4_instance
, tree
, tvb
, offset
);
118 offset
=dissect_krb4_string(pinfo
, hf_krb4_realm
, tree
, tvb
, offset
);
121 proto_tree_add_item(tree
, hf_krb4_time_sec
, tvb
, offset
, 4, ENC_TIME_SECS
|encoding
);
125 lifetime
=tvb_get_uint8(tvb
, offset
);
126 proto_tree_add_uint_format_value(tree
, hf_krb4_lifetime
, tvb
, offset
, 1, lifetime
, "%d (%d minutes)", lifetime
, lifetime
*5);
130 offset
=dissect_krb4_string(pinfo
, hf_krb4_s_name
, tree
, tvb
, offset
);
132 /* service Instance */
133 offset
=dissect_krb4_string(pinfo
, hf_krb4_s_instance
, tree
, tvb
, offset
);
140 dissect_krb4_kdc_reply(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, const unsigned encoding
)
145 offset
=dissect_krb4_string(pinfo
, hf_krb4_name
, tree
, tvb
, offset
);
148 offset
=dissect_krb4_string(pinfo
, hf_krb4_instance
, tree
, tvb
, offset
);
151 offset
=dissect_krb4_string(pinfo
, hf_krb4_realm
, tree
, tvb
, offset
);
154 proto_tree_add_item(tree
, hf_krb4_time_sec
, tvb
, offset
, 4, ENC_TIME_SECS
|encoding
);
157 /*XXX unknown byte here */
161 proto_tree_add_item(tree
, hf_krb4_exp_date
, tvb
, offset
, 4, ENC_TIME_SECS
|encoding
);
165 proto_tree_add_item(tree
, hf_krb4_kvno
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
169 proto_tree_add_item_ret_uint(tree
, hf_krb4_length
, tvb
, offset
, 2, encoding
, &length
);
173 proto_tree_add_item(tree
, hf_krb4_encrypted_blob
, tvb
, offset
, length
, ENC_NA
);
181 dissect_krb4_appl_request(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, const unsigned encoding
)
187 proto_tree_add_item(tree
, hf_krb4_kvno
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
191 offset
=dissect_krb4_string(pinfo
, hf_krb4_realm
, tree
, tvb
, offset
);
194 tlen
=tvb_get_uint8(tvb
, offset
);
195 proto_tree_add_item(tree
, hf_krb4_ticket_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
199 rlen
=tvb_get_uint8(tvb
, offset
);
200 proto_tree_add_item(tree
, hf_krb4_request_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
204 proto_tree_add_item(tree
, hf_krb4_ticket_blob
, tvb
, offset
, tlen
, ENC_NA
);
208 proto_tree_add_item(tree
, hf_krb4_request_blob
, tvb
, offset
, rlen
, ENC_NA
);
212 proto_tree_add_item(tree
, hf_krb4_req_date
, tvb
, offset
, 4, ENC_TIME_SECS
|encoding
);
216 lifetime
=tvb_get_uint8(tvb
, offset
);
217 proto_tree_add_uint_format_value(tree
, hf_krb4_lifetime
, tvb
, offset
, 1, lifetime
, "%d (%d minutes)", lifetime
, lifetime
*5);
221 offset
=dissect_krb4_string(pinfo
, hf_krb4_s_name
, tree
, tvb
, offset
);
223 /* service Instance */
224 offset
=dissect_krb4_string(pinfo
, hf_krb4_s_instance
, tree
, tvb
, offset
);
232 dissect_krb4_auth_msg_type(packet_info
*pinfo
, proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
, int version
)
236 uint8_t auth_msg_type
;
238 auth_msg_type
=tvb_get_uint8(tvb
, offset
);
239 item
= proto_tree_add_item(parent_tree
, hf_krb4_auth_msg_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
240 tree
= proto_item_add_subtree(item
, ett_krb4_auth_msg_type
);
243 proto_tree_add_item(tree
, hf_krb4_m_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
244 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s%s",
245 (version
==TRANSARC_SPECIAL_VERSION
)?"TRANSARC-":"",
246 val_to_str(auth_msg_type
>>1, m_type_vals
, "Unknown (0x%04x)"));
247 proto_item_append_text(item
, " %s%s",
248 (version
==TRANSARC_SPECIAL_VERSION
)?"TRANSARC-":"",
249 val_to_str(auth_msg_type
>>1, m_type_vals
, "Unknown (0x%04x)"));
252 proto_tree_add_item(tree
, hf_krb4_byte_order
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
253 proto_item_append_text(item
, " (%s)", val_to_str(auth_msg_type
&0x01, byte_order_vals
, "Unknown (0x%04x)"));
260 dissect_krb4(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void *data _U_
)
264 uint8_t version
, opcode
;
268 /* this should better have the value 4 or it might be a weirdo
269 * Transarc AFS special unknown thing.
271 version
=tvb_get_uint8(tvb
, offset
);
272 if((version
!=4)&&(version
!=TRANSARC_SPECIAL_VERSION
)){
276 opcode
=tvb_get_uint8(tvb
, offset
+1);
278 case AUTH_MSG_KDC_REQUEST
:
279 case AUTH_MSG_KDC_REPLY
:
280 case AUTH_MSG_APPL_REQUEST
:
281 case AUTH_MSG_APPL_REQUEST_MUTUAL
:
282 case AUTH_MSG_ERR_REPLY
:
283 case AUTH_MSG_PRIVATE
:
285 case AUTH_MSG_APPL_ERR
:
292 /* create a tree for krb4 */
293 item
= proto_tree_add_item(parent_tree
, proto_krb4
, tvb
, offset
, -1, ENC_NA
);
294 tree
= proto_item_add_subtree(item
, ett_krb4
);
296 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "KRB4");
297 col_clear(pinfo
->cinfo
, COL_INFO
);
300 proto_tree_add_item(tree
, hf_krb4_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
304 offset
= dissect_krb4_auth_msg_type(pinfo
, tree
, tvb
, offset
, version
);
306 encoding
= opcode
&0x01 ? ENC_LITTLE_ENDIAN
: ENC_BIG_ENDIAN
;
308 case AUTH_MSG_KDC_REQUEST
:
309 dissect_krb4_kdc_request(pinfo
, tree
, tvb
, offset
, encoding
, version
);
311 case AUTH_MSG_KDC_REPLY
:
312 dissect_krb4_kdc_reply(pinfo
, tree
, tvb
, offset
, encoding
);
314 case AUTH_MSG_APPL_REQUEST
:
315 dissect_krb4_appl_request(pinfo
, tree
, tvb
, offset
, encoding
);
317 case AUTH_MSG_APPL_REQUEST_MUTUAL
:
318 case AUTH_MSG_ERR_REPLY
:
319 case AUTH_MSG_PRIVATE
:
321 case AUTH_MSG_APPL_ERR
:
329 proto_register_krb4(void)
331 static hf_register_info hf
[] = {
333 { "Version", "krb4.version",
334 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
335 "Kerberos(v4) version number", HFILL
}},
336 { &hf_krb4_auth_msg_type
,
337 { "Msg Type", "krb4.auth_msg_type",
338 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
339 "Message Type/Byte Order", HFILL
}},
341 { "M Type", "krb4.m_type",
342 FT_UINT8
, BASE_HEX
, VALS(m_type_vals
), 0xfe,
343 "Message Type", HFILL
}},
344 { &hf_krb4_byte_order
,
345 { "Byte Order", "krb4.byte_order",
346 FT_UINT8
, BASE_HEX
, VALS(byte_order_vals
), 0x01,
349 { "Name", "krb4.name",
350 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
353 { "Instance", "krb4.instance",
354 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
357 { "Realm", "krb4.realm",
358 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
361 { "Time Sec", "krb4.time_sec",
362 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
365 { "Exp Date", "krb4.exp_date",
366 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
369 { "Req Date", "krb4.req_date",
370 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
373 { "Lifetime", "krb4.lifetime",
374 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
375 "Lifetime (in 5 min units)", HFILL
}},
377 { "Service Name", "krb4.s_name",
378 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
380 { &hf_krb4_s_instance
,
381 { "Service Instance", "krb4.s_instance",
382 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
385 { "Kvno", "krb4.kvno",
386 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
387 "Key Version No", HFILL
}},
389 { "Length", "krb4.length",
390 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
391 "Length of encrypted blob", HFILL
}},
392 { &hf_krb4_ticket_length
,
393 { "Ticket Length", "krb4.ticket.length",
394 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
395 "Length of ticket", HFILL
}},
396 { &hf_krb4_request_length
,
397 { "Request Length", "krb4.request.length",
398 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
399 "Length of request", HFILL
}},
400 { &hf_krb4_ticket_blob
,
401 { "Ticket Blob", "krb4.ticket.blob",
402 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
404 { &hf_krb4_request_blob
,
405 { "Request Blob", "krb4.request.blob",
406 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
408 { &hf_krb4_encrypted_blob
,
409 { "Encrypted Blob", "krb4.encrypted_blob",
410 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
412 { &hf_krb4_unknown_transarc_blob
,
413 { "Unknown Transarc Blob", "krb4.unknown_transarc_blob",
414 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
415 "Unknown blob only present in Transarc packets", HFILL
}},
417 static int *ett
[] = {
419 &ett_krb4_auth_msg_type
,
422 proto_krb4
= proto_register_protocol("Kerberos v4", "KRB4", "krb4");
423 krb4_handle
= register_dissector("krb4", dissect_krb4
, proto_krb4
);
424 proto_register_field_array(proto_krb4
, hf
, array_length(hf
));
425 proto_register_subtree_array(ett
, array_length(ett
));
429 proto_reg_handoff_krb4(void)
431 dissector_add_uint_with_preference("udp.port", UDP_PORT_KRB4
, krb4_handle
);
435 * Editor modelines - https://www.wireshark.org/tools/modelines.html
440 * indent-tabs-mode: t
443 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
444 * :indentSize=8:tabSize=8:noTabs=false: