2 * Routines for Kerberos v4 packet dissection
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * PDU structure based on the document :
30 * Kerberos Authentication and Authorization System
32 * by S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H. Saltzer
41 #include <epan/packet.h>
42 #include <epan/conversation.h>
44 static int proto_krb4 = -1;
45 static int hf_krb4_version = -1;
46 static int hf_krb4_auth_msg_type = -1;
47 static int hf_krb4_m_type = -1;
48 static int hf_krb4_byte_order = -1;
49 static int hf_krb4_name = -1;
50 static int hf_krb4_instance = -1;
51 static int hf_krb4_realm = -1;
52 static int hf_krb4_time_sec = -1;
53 static int hf_krb4_exp_date = -1;
54 static int hf_krb4_req_date = -1;
55 static int hf_krb4_lifetime = -1;
56 static int hf_krb4_s_name = -1;
57 static int hf_krb4_s_instance = -1;
58 static int hf_krb4_kvno = -1;
59 static int hf_krb4_length = -1;
60 static int hf_krb4_ticket_length = -1;
61 static int hf_krb4_request_length = -1;
62 static int hf_krb4_ticket_blob = -1;
63 static int hf_krb4_request_blob = -1;
64 static int hf_krb4_encrypted_blob = -1;
65 static int hf_krb4_unknown_transarc_blob = -1;
67 static gint ett_krb4 = -1;
68 static gint ett_krb4_auth_msg_type = -1;
70 #define UDP_PORT_KRB4 750
71 #define TRANSARC_SPECIAL_VERSION 0x63
73 static const value_string byte_order_vals[] = {
75 { 1, "Little Endian" },
79 #define AUTH_MSG_KDC_REQUEST 1
80 #define AUTH_MSG_KDC_REPLY 2
81 #define AUTH_MSG_APPL_REQUEST 3
82 #define AUTH_MSG_APPL_REQUEST_MUTUAL 4
83 #define AUTH_MSG_ERR_REPLY 5
84 #define AUTH_MSG_PRIVATE 6
85 #define AUTH_MSG_SAFE 7
86 #define AUTH_MSG_APPL_ERR 8
87 #define AUTH_MSG_DIE 63
88 static const value_string m_type_vals[] = {
89 { AUTH_MSG_KDC_REQUEST, "KDC Request" },
90 { AUTH_MSG_KDC_REPLY, "KDC Reply" },
91 { AUTH_MSG_APPL_REQUEST, "Appl Request" },
92 { AUTH_MSG_APPL_REQUEST_MUTUAL, "Appl Request Mutual" },
93 { AUTH_MSG_ERR_REPLY, "Err Reply" },
94 { AUTH_MSG_PRIVATE, "Private" },
95 { AUTH_MSG_SAFE, "Safe" },
96 { AUTH_MSG_APPL_ERR, "Appl Err" },
97 { AUTH_MSG_DIE, "Die" },
103 dissect_krb4_string(packet_info *pinfo _U_, int hf_index, proto_tree *tree, tvbuff_t *tvb, int offset)
105 proto_tree_add_item(tree, hf_index, tvb, offset, -1, FALSE);
106 while(tvb_get_guint8(tvb, offset)!=0){
115 dissect_krb4_kdc_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean little_endian, int version)
120 if(version==TRANSARC_SPECIAL_VERSION){
121 proto_tree_add_item(tree, hf_krb4_unknown_transarc_blob, tvb, offset, 8, FALSE);
126 offset=dissect_krb4_string(pinfo, hf_krb4_name, tree, tvb, offset);
129 offset=dissect_krb4_string(pinfo, hf_krb4_instance, tree, tvb, offset);
132 offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
135 time_sec.secs=little_endian?tvb_get_letohl(tvb, offset):tvb_get_ntohl(tvb, offset);
137 proto_tree_add_time(tree, hf_krb4_time_sec, tvb, offset, 4, &time_sec);
141 lifetime=tvb_get_guint8(tvb, offset);
142 proto_tree_add_uint_format(tree, hf_krb4_lifetime, tvb, offset, 1, lifetime, "Lifetime: %d (%d minutes)", lifetime, lifetime*5);
146 offset=dissect_krb4_string(pinfo, hf_krb4_s_name, tree, tvb, offset);
148 /* service Instance */
149 offset=dissect_krb4_string(pinfo, hf_krb4_s_instance, tree, tvb, offset);
156 dissect_krb4_kdc_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean little_endian)
162 offset=dissect_krb4_string(pinfo, hf_krb4_name, tree, tvb, offset);
165 offset=dissect_krb4_string(pinfo, hf_krb4_instance, tree, tvb, offset);
168 offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
171 time_sec.secs=little_endian?tvb_get_letohl(tvb, offset):tvb_get_ntohl(tvb, offset);
173 proto_tree_add_time(tree, hf_krb4_time_sec, tvb, offset, 4, &time_sec);
176 /*XXX unknown byte here */
180 time_sec.secs=little_endian?tvb_get_letohl(tvb, offset):tvb_get_ntohl(tvb, offset);
182 proto_tree_add_time(tree, hf_krb4_exp_date, tvb, offset, 4, &time_sec);
186 proto_tree_add_item(tree, hf_krb4_kvno, tvb, offset, 1, FALSE);
190 length=little_endian?tvb_get_letohs(tvb, offset):tvb_get_ntohs(tvb, offset);
191 proto_tree_add_uint_format(tree, hf_krb4_length, tvb, offset, 2, length, "Length: %d", length);
195 proto_tree_add_item(tree, hf_krb4_encrypted_blob, tvb, offset, length, FALSE);
203 dissect_krb4_appl_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean little_endian)
210 proto_tree_add_item(tree, hf_krb4_kvno, tvb, offset, 1, FALSE);
214 offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
217 tlen=tvb_get_guint8(tvb, offset);
218 proto_tree_add_item(tree, hf_krb4_ticket_length, tvb, offset, 1, FALSE);
222 rlen=tvb_get_guint8(tvb, offset);
223 proto_tree_add_item(tree, hf_krb4_request_length, tvb, offset, 1, FALSE);
227 proto_tree_add_item(tree, hf_krb4_ticket_blob, tvb, offset, tlen, FALSE);
231 proto_tree_add_item(tree, hf_krb4_request_blob, tvb, offset, rlen, FALSE);
235 time_sec.secs=little_endian?tvb_get_letohl(tvb, offset):tvb_get_ntohl(tvb, offset);
237 proto_tree_add_time(tree, hf_krb4_req_date, tvb, offset, 4, &time_sec);
241 lifetime=tvb_get_guint8(tvb, offset);
242 proto_tree_add_uint_format(tree, hf_krb4_lifetime, tvb, offset, 1, lifetime, "Lifetime: %d (%d minutes)", lifetime, lifetime*5);
246 offset=dissect_krb4_string(pinfo, hf_krb4_s_name, tree, tvb, offset);
248 /* service Instance */
249 offset=dissect_krb4_string(pinfo, hf_krb4_s_instance, tree, tvb, offset);
257 dissect_krb4_auth_msg_type(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, int version)
261 guint8 auth_msg_type;
263 auth_msg_type=tvb_get_guint8(tvb, offset);
264 item = proto_tree_add_item(parent_tree, hf_krb4_auth_msg_type, tvb, offset, 1, FALSE);
265 tree = proto_item_add_subtree(item, ett_krb4_auth_msg_type);
268 proto_tree_add_item(tree, hf_krb4_m_type, tvb, offset, 1, FALSE);
269 if (check_col(pinfo->cinfo, COL_INFO))
270 col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s",
271 (version==TRANSARC_SPECIAL_VERSION)?"TRANSARC-":"",
272 val_to_str(auth_msg_type>>1, m_type_vals, "Unknown (0x%04x)"));
273 proto_item_append_text(item, " %s%s",
274 (version==TRANSARC_SPECIAL_VERSION)?"TRANSARC-":"",
275 val_to_str(auth_msg_type>>1, m_type_vals, "Unknown (0x%04x)"));
278 proto_tree_add_item(tree, hf_krb4_byte_order, tvb, offset, 1, FALSE);
279 proto_item_append_text(item, " (%s)", val_to_str(auth_msg_type&0x01, byte_order_vals, "Unknown (0x%04x)"));
286 dissect_krb4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
290 guint8 version, opcode;
293 /* this should better have the value 4 or it might be a weirdo
294 * Transarc AFS special unknown thing.
296 version=tvb_get_guint8(tvb, offset);
297 if((version!=4)&&(version!=TRANSARC_SPECIAL_VERSION)){
301 opcode=tvb_get_guint8(tvb, offset+1);
303 case AUTH_MSG_KDC_REQUEST:
304 case AUTH_MSG_KDC_REPLY:
305 case AUTH_MSG_APPL_REQUEST:
306 case AUTH_MSG_APPL_REQUEST_MUTUAL:
307 case AUTH_MSG_ERR_REPLY:
308 case AUTH_MSG_PRIVATE:
310 case AUTH_MSG_APPL_ERR:
317 /* create a tree for krb4 */
318 item = proto_tree_add_item(parent_tree, proto_krb4, tvb, offset, -1, FALSE);
319 tree = proto_item_add_subtree(item, ett_krb4);
321 if (check_col(pinfo->cinfo, COL_PROTOCOL))
322 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB4");
323 if (check_col(pinfo->cinfo, COL_INFO))
324 col_clear(pinfo->cinfo, COL_INFO);
327 proto_tree_add_item(tree, hf_krb4_version, tvb, offset, 1, FALSE);
331 offset = dissect_krb4_auth_msg_type(pinfo, tree, tvb, offset, version);
334 case AUTH_MSG_KDC_REQUEST:
335 offset = dissect_krb4_kdc_request(pinfo, tree, tvb, offset, opcode&0x01, version);
337 case AUTH_MSG_KDC_REPLY:
338 offset = dissect_krb4_kdc_reply(pinfo, tree, tvb, offset, opcode&0x01);
340 case AUTH_MSG_APPL_REQUEST:
341 offset = dissect_krb4_appl_request(pinfo, tree, tvb, offset, opcode&0x01);
343 case AUTH_MSG_APPL_REQUEST_MUTUAL:
344 case AUTH_MSG_ERR_REPLY:
345 case AUTH_MSG_PRIVATE:
347 case AUTH_MSG_APPL_ERR:
355 proto_register_krb4(void)
357 static hf_register_info hf[] = {
359 { "Version", "krb4.version",
360 FT_UINT8, BASE_DEC, NULL, 0x0,
361 "Kerberos(v4) version number", HFILL }},
362 { &hf_krb4_auth_msg_type,
363 { "Msg Type", "krb4.auth_msg_type",
364 FT_UINT8, BASE_HEX, NULL, 0x0,
365 "Message Type/Byte Order", HFILL }},
367 { "M Type", "krb4.m_type",
368 FT_UINT8, BASE_HEX, VALS(m_type_vals), 0xfe,
369 "Message Type", HFILL }},
370 { &hf_krb4_byte_order,
371 { "Byte Order", "krb4.byte_order",
372 FT_UINT8, BASE_HEX, VALS(byte_order_vals), 0x01,
373 "Byte Order", HFILL }},
375 { "Name", "krb4.name",
376 FT_STRINGZ, BASE_NONE, NULL, 0x00,
379 { "Instance", "krb4.instance",
380 FT_STRINGZ, BASE_NONE, NULL, 0x00,
381 "Instance", HFILL }},
383 { "Realm", "krb4.realm",
384 FT_STRINGZ, BASE_NONE, NULL, 0x00,
387 { "Time Sec", "krb4.time_sec",
388 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
389 "Time Sec", HFILL }},
391 { "Exp Date", "krb4.exp_date",
392 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
393 "Exp Date", HFILL }},
395 { "Req Date", "krb4.req_date",
396 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
397 "Req Date", HFILL }},
399 { "Lifetime", "krb4.lifetime",
400 FT_UINT8, BASE_DEC, NULL, 0x00,
401 "Lifetime (in 5 min units)", HFILL }},
403 { "Service Name", "krb4.s_name",
404 FT_STRINGZ, BASE_NONE, NULL, 0x00,
405 "Service Name", HFILL }},
406 { &hf_krb4_s_instance,
407 { "Service Instance", "krb4.s_instance",
408 FT_STRINGZ, BASE_NONE, NULL, 0x00,
409 "Service Instance", HFILL }},
411 { "Kvno", "krb4.kvno",
412 FT_UINT8, BASE_DEC, NULL, 0x00,
413 "Key Version No", HFILL }},
415 { "Length", "krb4.length",
416 FT_UINT32, BASE_DEC, NULL, 0x00,
417 "Length of encrypted blob", HFILL }},
418 { &hf_krb4_ticket_length,
419 { "Ticket Length", "krb4.ticket.length",
420 FT_UINT8, BASE_DEC, NULL, 0x00,
421 "Length of ticket", HFILL }},
422 { &hf_krb4_request_length,
423 { "Request Length", "krb4.request.length",
424 FT_UINT8, BASE_DEC, NULL, 0x00,
425 "Length of request", HFILL }},
426 { &hf_krb4_ticket_blob,
427 { "Ticket Blob", "krb4.ticket.blob",
428 FT_BYTES, BASE_HEX, NULL, 0x00,
429 "Ticket blob", HFILL }},
430 { &hf_krb4_request_blob,
431 { "Request Blob", "krb4.request.blob",
432 FT_BYTES, BASE_HEX, NULL, 0x00,
433 "Request Blob", HFILL }},
434 { &hf_krb4_encrypted_blob,
435 { "Encrypted Blob", "krb4.encrypted_blob",
436 FT_BYTES, BASE_HEX, NULL, 0x00,
437 "Encrypted blob", HFILL }},
438 { &hf_krb4_unknown_transarc_blob,
439 { "Unknown Transarc Blob", "krb4.unknown_transarc_blob",
440 FT_BYTES, BASE_HEX, NULL, 0x00,
441 "Unknown blob only present in Transarc packets", HFILL }},
443 static gint *ett[] = {
445 &ett_krb4_auth_msg_type,
448 proto_krb4 = proto_register_protocol("Kerberos v4",
450 new_register_dissector("krb4", dissect_krb4, proto_krb4);
451 proto_register_field_array(proto_krb4, hf, array_length(hf));
452 proto_register_subtree_array(ett, array_length(ett));
456 proto_reg_handoff_krb4(void)
458 dissector_handle_t krb4_handle;
460 krb4_handle = new_create_dissector_handle(dissect_krb4, proto_krb4);
461 dissector_add("udp.port", UDP_PORT_KRB4, krb4_handle);