Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-kerberos4.c
blobe0c505419d7429731e785fef9d5a3f8edc3cda99
1 /* packet-kerberos4.c
2 * Routines for Kerberos v4 packet dissection
4 * Ronnie Sahlberg 2004
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
16 * Section E.2.1
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
25 #include "config.h"
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;
55 static int ett_krb4;
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[] = {
64 { 0, "Big Endian" },
65 { 1, "Little Endian" },
66 { 0, NULL }
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" },
88 { 0, NULL }
92 static int
93 dissect_krb4_string(packet_info *pinfo _U_, int hf_index, proto_tree *tree, tvbuff_t *tvb, int offset)
95 int length;
96 proto_tree_add_item_ret_length(tree, hf_index, tvb, offset, -1, ENC_ASCII|ENC_NA, &length);
98 return offset + length;
101 static int
102 dissect_krb4_kdc_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, const unsigned encoding, int version)
104 uint8_t lifetime;
106 if(version==TRANSARC_SPECIAL_VERSION){
107 proto_tree_add_item(tree, hf_krb4_unknown_transarc_blob, tvb, offset, 8, ENC_NA);
108 offset+=8;
111 /* Name */
112 offset=dissect_krb4_string(pinfo, hf_krb4_name, tree, tvb, offset);
114 /* Instance */
115 offset=dissect_krb4_string(pinfo, hf_krb4_instance, tree, tvb, offset);
117 /* Realm */
118 offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
120 /* Time sec */
121 proto_tree_add_item(tree, hf_krb4_time_sec, tvb, offset, 4, ENC_TIME_SECS|encoding);
122 offset+=4;
124 /* lifetime */
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);
127 offset++;
129 /* service Name */
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);
135 return offset;
139 static int
140 dissect_krb4_kdc_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, const unsigned encoding)
142 uint32_t length;
144 /* Name */
145 offset=dissect_krb4_string(pinfo, hf_krb4_name, tree, tvb, offset);
147 /* Instance */
148 offset=dissect_krb4_string(pinfo, hf_krb4_instance, tree, tvb, offset);
150 /* Realm */
151 offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
153 /* Time sec */
154 proto_tree_add_item(tree, hf_krb4_time_sec, tvb, offset, 4, ENC_TIME_SECS|encoding);
155 offset+=4;
157 /*XXX unknown byte here */
158 offset++;
160 /* exp date */
161 proto_tree_add_item(tree, hf_krb4_exp_date, tvb, offset, 4, ENC_TIME_SECS|encoding);
162 offset+=4;
164 /* kvno */
165 proto_tree_add_item(tree, hf_krb4_kvno, tvb, offset, 1, ENC_BIG_ENDIAN);
166 offset++;
168 /* length2 */
169 proto_tree_add_item_ret_uint(tree, hf_krb4_length, tvb, offset, 2, encoding, &length);
170 offset+=2;
172 /* encrypted blob */
173 proto_tree_add_item(tree, hf_krb4_encrypted_blob, tvb, offset, length, ENC_NA);
174 offset+=length;
176 return offset;
180 static int
181 dissect_krb4_appl_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, const unsigned encoding)
183 uint8_t tlen, rlen;
184 uint8_t lifetime;
186 /* kvno */
187 proto_tree_add_item(tree, hf_krb4_kvno, tvb, offset, 1, ENC_BIG_ENDIAN);
188 offset++;
190 /* Realm */
191 offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
193 /* ticket length */
194 tlen=tvb_get_uint8(tvb, offset);
195 proto_tree_add_item(tree, hf_krb4_ticket_length, tvb, offset, 1, ENC_BIG_ENDIAN);
196 offset++;
198 /* request length */
199 rlen=tvb_get_uint8(tvb, offset);
200 proto_tree_add_item(tree, hf_krb4_request_length, tvb, offset, 1, ENC_BIG_ENDIAN);
201 offset++;
203 /* ticket */
204 proto_tree_add_item(tree, hf_krb4_ticket_blob, tvb, offset, tlen, ENC_NA);
205 offset+=tlen;
207 /* request */
208 proto_tree_add_item(tree, hf_krb4_request_blob, tvb, offset, rlen, ENC_NA);
209 offset+=rlen;
211 /* request time */
212 proto_tree_add_item(tree, hf_krb4_req_date, tvb, offset, 4, ENC_TIME_SECS|encoding);
213 offset+=4;
215 /* lifetime */
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);
218 offset++;
220 /* service Name */
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);
226 return offset;
231 static int
232 dissect_krb4_auth_msg_type(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, int version)
234 proto_tree *tree;
235 proto_item *item;
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);
242 /* m_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)"));
251 /* byte order */
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)"));
255 offset++;
256 return offset;
259 static gboolean
260 dissect_krb4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
262 proto_tree *tree;
263 proto_item *item;
264 uint8_t version, opcode;
265 int offset = 0;
266 unsigned encoding;
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)){
273 return FALSE;
276 opcode=tvb_get_uint8(tvb, offset+1);
277 switch(opcode>>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:
284 case AUTH_MSG_SAFE:
285 case AUTH_MSG_APPL_ERR:
286 case AUTH_MSG_DIE:
287 break;
288 default:
289 return FALSE;
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);
299 /* version */
300 proto_tree_add_item(tree, hf_krb4_version, tvb, offset, 1, ENC_BIG_ENDIAN);
301 offset++;
303 /* auth_msg_type */
304 offset = dissect_krb4_auth_msg_type(pinfo, tree, tvb, offset, version);
306 encoding = opcode&0x01 ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
307 switch(opcode>>1){
308 case AUTH_MSG_KDC_REQUEST:
309 dissect_krb4_kdc_request(pinfo, tree, tvb, offset, encoding, version);
310 break;
311 case AUTH_MSG_KDC_REPLY:
312 dissect_krb4_kdc_reply(pinfo, tree, tvb, offset, encoding);
313 break;
314 case AUTH_MSG_APPL_REQUEST:
315 dissect_krb4_appl_request(pinfo, tree, tvb, offset, encoding);
316 break;
317 case AUTH_MSG_APPL_REQUEST_MUTUAL:
318 case AUTH_MSG_ERR_REPLY:
319 case AUTH_MSG_PRIVATE:
320 case AUTH_MSG_SAFE:
321 case AUTH_MSG_APPL_ERR:
322 case AUTH_MSG_DIE:
323 break;
325 return TRUE;
328 void
329 proto_register_krb4(void)
331 static hf_register_info hf[] = {
332 { &hf_krb4_version,
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 }},
340 { &hf_krb4_m_type,
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,
347 NULL, HFILL }},
348 { &hf_krb4_name,
349 { "Name", "krb4.name",
350 FT_STRINGZ, BASE_NONE, NULL, 0x00,
351 NULL, HFILL }},
352 { &hf_krb4_instance,
353 { "Instance", "krb4.instance",
354 FT_STRINGZ, BASE_NONE, NULL, 0x00,
355 NULL, HFILL }},
356 { &hf_krb4_realm,
357 { "Realm", "krb4.realm",
358 FT_STRINGZ, BASE_NONE, NULL, 0x00,
359 NULL, HFILL }},
360 { &hf_krb4_time_sec,
361 { "Time Sec", "krb4.time_sec",
362 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
363 NULL, HFILL }},
364 { &hf_krb4_exp_date,
365 { "Exp Date", "krb4.exp_date",
366 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
367 NULL, HFILL }},
368 { &hf_krb4_req_date,
369 { "Req Date", "krb4.req_date",
370 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
371 NULL, HFILL }},
372 { &hf_krb4_lifetime,
373 { "Lifetime", "krb4.lifetime",
374 FT_UINT8, BASE_DEC, NULL, 0x00,
375 "Lifetime (in 5 min units)", HFILL }},
376 { &hf_krb4_s_name,
377 { "Service Name", "krb4.s_name",
378 FT_STRINGZ, BASE_NONE, NULL, 0x00,
379 NULL, HFILL }},
380 { &hf_krb4_s_instance,
381 { "Service Instance", "krb4.s_instance",
382 FT_STRINGZ, BASE_NONE, NULL, 0x00,
383 NULL, HFILL }},
384 { &hf_krb4_kvno,
385 { "Kvno", "krb4.kvno",
386 FT_UINT8, BASE_DEC, NULL, 0x00,
387 "Key Version No", HFILL }},
388 { &hf_krb4_length,
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,
403 NULL, HFILL }},
404 { &hf_krb4_request_blob,
405 { "Request Blob", "krb4.request.blob",
406 FT_BYTES, BASE_NONE, NULL, 0x00,
407 NULL, HFILL }},
408 { &hf_krb4_encrypted_blob,
409 { "Encrypted Blob", "krb4.encrypted_blob",
410 FT_BYTES, BASE_NONE, NULL, 0x00,
411 NULL, HFILL }},
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[] = {
418 &ett_krb4,
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));
428 void
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
437 * Local variables:
438 * c-basic-offset: 8
439 * tab-width: 8
440 * indent-tabs-mode: t
441 * End:
443 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
444 * :indentSize=8:tabSize=8:noTabs=false: