Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-kerberos4.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-kerberos4.c
2
 * Routines for Kerberos v4 packet dissection
3
 *
4
 * Ronnie Sahlberg 2004
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
/*
13
 * PDU structure based on the document:
14
 *
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
19
 *
20
 * http://web.mit.edu/Saltzer/www/publications/athenaplan/e.2.1.pdf
21
 *
22
 * 7. Appendix I Design Specifications
23
 */
24
25
#include "config.h"
26
27
#include <epan/packet.h>
28
29
void proto_register_krb4(void);
30
void proto_reg_handoff_krb4(void);
31
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;
54
55
static int ett_krb4;
56
static int ett_krb4_auth_msg_type;
57
58
static dissector_handle_t krb4_handle;
59
60
14
#define UDP_PORT_KRB4    750
61
3
#define TRANSARC_SPECIAL_VERSION 0x63
62
63
static const value_string byte_order_vals[] = {
64
  { 0,  "Big Endian" },
65
  { 1,  "Little Endian" },
66
  { 0,  NULL }
67
};
68
69
0
#define AUTH_MSG_KDC_REQUEST    1
70
0
#define AUTH_MSG_KDC_REPLY    2
71
0
#define AUTH_MSG_APPL_REQUEST   3
72
0
#define AUTH_MSG_APPL_REQUEST_MUTUAL  4
73
0
#define AUTH_MSG_ERR_REPLY    5
74
0
#define AUTH_MSG_PRIVATE    6
75
0
#define AUTH_MSG_SAFE     7
76
0
#define AUTH_MSG_APPL_ERR   8
77
0
#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 }
89
};
90
91
92
static int
93
dissect_krb4_string(packet_info *pinfo _U_, int hf_index, proto_tree *tree, tvbuff_t *tvb, int offset)
94
0
{
95
0
  int length;
96
0
  proto_tree_add_item_ret_length(tree, hf_index, tvb, offset, -1, ENC_ASCII|ENC_NA, &length);
97
98
0
  return offset + length;
99
0
}
100
101
static int
102
dissect_krb4_kdc_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, const unsigned encoding, int version)
103
0
{
104
0
  uint8_t  lifetime;
105
106
0
  if(version==TRANSARC_SPECIAL_VERSION){
107
0
    proto_tree_add_item(tree, hf_krb4_unknown_transarc_blob, tvb, offset, 8, ENC_NA);
108
0
    offset+=8;
109
0
  }
110
111
  /* Name */
112
0
  offset=dissect_krb4_string(pinfo, hf_krb4_name, tree, tvb, offset);
113
114
  /* Instance */
115
0
  offset=dissect_krb4_string(pinfo, hf_krb4_instance, tree, tvb, offset);
116
117
  /* Realm */
118
0
  offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
119
120
  /* Time sec */
121
0
  proto_tree_add_item(tree, hf_krb4_time_sec, tvb, offset, 4, ENC_TIME_SECS|encoding);
122
0
  offset+=4;
123
124
  /* lifetime */
125
0
  lifetime=tvb_get_uint8(tvb, offset);
126
0
  proto_tree_add_uint_format_value(tree, hf_krb4_lifetime, tvb, offset, 1, lifetime, "%d (%d minutes)", lifetime, lifetime*5);
127
0
  offset++;
128
129
  /* service Name */
130
0
  offset=dissect_krb4_string(pinfo, hf_krb4_s_name, tree, tvb, offset);
131
132
  /* service Instance */
133
0
  offset=dissect_krb4_string(pinfo, hf_krb4_s_instance, tree, tvb, offset);
134
135
0
  return offset;
136
0
}
137
138
139
static int
140
dissect_krb4_kdc_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, const unsigned encoding)
141
0
{
142
0
  uint32_t length;
143
144
  /* Name */
145
0
  offset=dissect_krb4_string(pinfo, hf_krb4_name, tree, tvb, offset);
146
147
  /* Instance */
148
0
  offset=dissect_krb4_string(pinfo, hf_krb4_instance, tree, tvb, offset);
149
150
  /* Realm */
151
0
  offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
152
153
  /* Time sec */
154
0
  proto_tree_add_item(tree, hf_krb4_time_sec, tvb, offset, 4, ENC_TIME_SECS|encoding);
155
0
  offset+=4;
156
157
  /*XXX unknown byte here */
158
0
  offset++;
159
160
  /* exp date */
161
0
  proto_tree_add_item(tree, hf_krb4_exp_date, tvb, offset, 4, ENC_TIME_SECS|encoding);
162
0
  offset+=4;
163
164
  /* kvno */
165
0
  proto_tree_add_item(tree, hf_krb4_kvno, tvb, offset, 1, ENC_BIG_ENDIAN);
166
0
  offset++;
167
168
  /* length2 */
169
0
  proto_tree_add_item_ret_uint(tree, hf_krb4_length, tvb, offset, 2, encoding, &length);
170
0
  offset+=2;
171
172
  /* encrypted blob */
173
0
  proto_tree_add_item(tree, hf_krb4_encrypted_blob, tvb, offset, length, ENC_NA);
174
0
  offset+=length;
175
176
0
  return offset;
177
0
}
178
179
180
static int
181
dissect_krb4_appl_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, const unsigned encoding)
182
0
{
183
0
  uint8_t  tlen, rlen;
184
0
  uint8_t  lifetime;
185
186
  /* kvno */
187
0
  proto_tree_add_item(tree, hf_krb4_kvno, tvb, offset, 1, ENC_BIG_ENDIAN);
188
0
  offset++;
189
190
  /* Realm */
191
0
  offset=dissect_krb4_string(pinfo, hf_krb4_realm, tree, tvb, offset);
192
193
  /* ticket length */
194
0
  tlen=tvb_get_uint8(tvb, offset);
195
0
  proto_tree_add_item(tree, hf_krb4_ticket_length, tvb, offset, 1, ENC_BIG_ENDIAN);
196
0
  offset++;
197
198
  /* request length */
199
0
  rlen=tvb_get_uint8(tvb, offset);
200
0
  proto_tree_add_item(tree, hf_krb4_request_length, tvb, offset, 1, ENC_BIG_ENDIAN);
201
0
  offset++;
202
203
  /* ticket */
204
0
  proto_tree_add_item(tree, hf_krb4_ticket_blob, tvb, offset, tlen, ENC_NA);
205
0
  offset+=tlen;
206
207
  /* request */
208
0
  proto_tree_add_item(tree, hf_krb4_request_blob, tvb, offset, rlen, ENC_NA);
209
0
  offset+=rlen;
210
211
  /* request time */
212
0
  proto_tree_add_item(tree, hf_krb4_req_date, tvb, offset, 4, ENC_TIME_SECS|encoding);
213
0
  offset+=4;
214
215
  /* lifetime */
216
0
  lifetime=tvb_get_uint8(tvb, offset);
217
0
  proto_tree_add_uint_format_value(tree, hf_krb4_lifetime, tvb, offset, 1, lifetime, "%d (%d minutes)", lifetime, lifetime*5);
218
0
  offset++;
219
220
  /* service Name */
221
0
  offset=dissect_krb4_string(pinfo, hf_krb4_s_name, tree, tvb, offset);
222
223
  /* service Instance */
224
0
  offset=dissect_krb4_string(pinfo, hf_krb4_s_instance, tree, tvb, offset);
225
226
0
  return offset;
227
0
}
228
229
230
231
static int
232
dissect_krb4_auth_msg_type(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, int version)
233
0
{
234
0
  proto_tree *tree;
235
0
  proto_item *item;
236
0
  uint8_t     auth_msg_type;
237
238
0
  auth_msg_type=tvb_get_uint8(tvb, offset);
239
0
  item = proto_tree_add_item(parent_tree, hf_krb4_auth_msg_type, tvb, offset, 1, ENC_BIG_ENDIAN);
240
0
  tree = proto_item_add_subtree(item, ett_krb4_auth_msg_type);
241
242
  /* m_type */
243
0
  proto_tree_add_item(tree, hf_krb4_m_type, tvb, offset, 1, ENC_BIG_ENDIAN);
244
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s",
245
0
     (version==TRANSARC_SPECIAL_VERSION)?"TRANSARC-":"",
246
0
      val_to_str(auth_msg_type>>1, m_type_vals, "Unknown (0x%04x)"));
247
0
  proto_item_append_text(item, " %s%s",
248
0
     (version==TRANSARC_SPECIAL_VERSION)?"TRANSARC-":"",
249
0
     val_to_str(auth_msg_type>>1, m_type_vals, "Unknown (0x%04x)"));
250
251
  /* byte order */
252
0
  proto_tree_add_item(tree, hf_krb4_byte_order, tvb, offset, 1, ENC_BIG_ENDIAN);
253
0
  proto_item_append_text(item, " (%s)", val_to_str(auth_msg_type&0x01, byte_order_vals, "Unknown (0x%04x)"));
254
255
0
  offset++;
256
0
  return offset;
257
0
}
258
259
static gboolean
260
dissect_krb4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
261
3
{
262
3
  proto_tree *tree;
263
3
  proto_item *item;
264
3
  uint8_t     version, opcode;
265
3
  int         offset = 0;
266
3
  unsigned    encoding;
267
268
  /* this should better have the value 4 or it might be a weirdo
269
   * Transarc AFS special unknown thing.
270
   */
271
3
  version=tvb_get_uint8(tvb, offset);
272
3
  if((version!=4)&&(version!=TRANSARC_SPECIAL_VERSION)){
273
3
    return FALSE;
274
3
  }
275
276
0
  opcode=tvb_get_uint8(tvb, offset+1);
277
0
  switch(opcode>>1){
278
0
  case AUTH_MSG_KDC_REQUEST:
279
0
  case AUTH_MSG_KDC_REPLY:
280
0
  case AUTH_MSG_APPL_REQUEST:
281
0
  case AUTH_MSG_APPL_REQUEST_MUTUAL:
282
0
  case AUTH_MSG_ERR_REPLY:
283
0
  case AUTH_MSG_PRIVATE:
284
0
  case AUTH_MSG_SAFE:
285
0
  case AUTH_MSG_APPL_ERR:
286
0
  case AUTH_MSG_DIE:
287
0
    break;
288
0
  default:
289
0
    return FALSE;
290
0
  }
291
292
  /* create a tree for krb4 */
293
0
  item = proto_tree_add_item(parent_tree, proto_krb4, tvb, offset, -1, ENC_NA);
294
0
  tree = proto_item_add_subtree(item, ett_krb4);
295
296
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB4");
297
0
  col_clear(pinfo->cinfo, COL_INFO);
298
299
  /* version */
300
0
  proto_tree_add_item(tree, hf_krb4_version, tvb, offset, 1, ENC_BIG_ENDIAN);
301
0
  offset++;
302
303
  /* auth_msg_type */
304
0
  offset = dissect_krb4_auth_msg_type(pinfo, tree, tvb, offset, version);
305
306
0
  encoding = opcode&0x01 ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
307
0
  switch(opcode>>1){
308
0
  case AUTH_MSG_KDC_REQUEST:
309
0
    dissect_krb4_kdc_request(pinfo, tree, tvb, offset, encoding, version);
310
0
    break;
311
0
  case AUTH_MSG_KDC_REPLY:
312
0
    dissect_krb4_kdc_reply(pinfo, tree, tvb, offset, encoding);
313
0
    break;
314
0
  case AUTH_MSG_APPL_REQUEST:
315
0
    dissect_krb4_appl_request(pinfo, tree, tvb, offset, encoding);
316
0
    break;
317
0
  case AUTH_MSG_APPL_REQUEST_MUTUAL:
318
0
  case AUTH_MSG_ERR_REPLY:
319
0
  case AUTH_MSG_PRIVATE:
320
0
  case AUTH_MSG_SAFE:
321
0
  case AUTH_MSG_APPL_ERR:
322
0
  case AUTH_MSG_DIE:
323
0
    break;
324
0
  }
325
0
  return TRUE;
326
0
}
327
328
void
329
proto_register_krb4(void)
330
14
{
331
14
  static hf_register_info hf[] = {
332
14
    { &hf_krb4_version,
333
14
      { "Version", "krb4.version",
334
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
335
14
        "Kerberos(v4) version number", HFILL }},
336
14
    { &hf_krb4_auth_msg_type,
337
14
      { "Msg Type", "krb4.auth_msg_type",
338
14
        FT_UINT8, BASE_HEX, NULL, 0x0,
339
14
        "Message Type/Byte Order", HFILL }},
340
14
    { &hf_krb4_m_type,
341
14
      { "M Type", "krb4.m_type",
342
14
        FT_UINT8, BASE_HEX, VALS(m_type_vals), 0xfe,
343
14
        "Message Type", HFILL }},
344
14
    { &hf_krb4_byte_order,
345
14
      { "Byte Order", "krb4.byte_order",
346
14
        FT_UINT8, BASE_HEX, VALS(byte_order_vals), 0x01,
347
14
        NULL, HFILL }},
348
14
    { &hf_krb4_name,
349
14
      { "Name", "krb4.name",
350
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
351
14
        NULL, HFILL }},
352
14
    { &hf_krb4_instance,
353
14
      { "Instance", "krb4.instance",
354
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
355
14
        NULL, HFILL }},
356
14
    { &hf_krb4_realm,
357
14
      { "Realm", "krb4.realm",
358
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
359
14
        NULL, HFILL }},
360
14
    { &hf_krb4_time_sec,
361
14
      { "Time Sec", "krb4.time_sec",
362
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
363
14
        NULL, HFILL }},
364
14
    { &hf_krb4_exp_date,
365
14
      { "Exp Date", "krb4.exp_date",
366
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
367
14
        NULL, HFILL }},
368
14
    { &hf_krb4_req_date,
369
14
      { "Req Date", "krb4.req_date",
370
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
371
14
        NULL, HFILL }},
372
14
    { &hf_krb4_lifetime,
373
14
      { "Lifetime", "krb4.lifetime",
374
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
375
14
        "Lifetime (in 5 min units)", HFILL }},
376
14
    { &hf_krb4_s_name,
377
14
      { "Service Name", "krb4.s_name",
378
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
379
14
        NULL, HFILL }},
380
14
    { &hf_krb4_s_instance,
381
14
      { "Service Instance", "krb4.s_instance",
382
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
383
14
        NULL, HFILL }},
384
14
    { &hf_krb4_kvno,
385
14
      { "Kvno", "krb4.kvno",
386
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
387
14
        "Key Version No", HFILL }},
388
14
    { &hf_krb4_length,
389
14
      { "Length", "krb4.length",
390
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
391
14
        "Length of encrypted blob", HFILL }},
392
14
    { &hf_krb4_ticket_length,
393
14
      { "Ticket Length", "krb4.ticket.length",
394
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
395
14
        "Length of ticket", HFILL }},
396
14
    { &hf_krb4_request_length,
397
14
      { "Request Length", "krb4.request.length",
398
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
399
14
        "Length of request", HFILL }},
400
14
    { &hf_krb4_ticket_blob,
401
14
      { "Ticket Blob", "krb4.ticket.blob",
402
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
403
14
        NULL, HFILL }},
404
14
    { &hf_krb4_request_blob,
405
14
      { "Request Blob", "krb4.request.blob",
406
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
407
14
        NULL, HFILL }},
408
14
    { &hf_krb4_encrypted_blob,
409
14
      { "Encrypted Blob", "krb4.encrypted_blob",
410
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
411
14
        NULL, HFILL }},
412
14
    { &hf_krb4_unknown_transarc_blob,
413
14
      { "Unknown Transarc Blob", "krb4.unknown_transarc_blob",
414
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
415
14
        "Unknown blob only present in Transarc packets", HFILL }},
416
14
  };
417
14
  static int *ett[] = {
418
14
    &ett_krb4,
419
14
    &ett_krb4_auth_msg_type,
420
14
  };
421
422
14
  proto_krb4 = proto_register_protocol("Kerberos v4", "KRB4", "krb4");
423
14
  krb4_handle = register_dissector("krb4", dissect_krb4, proto_krb4);
424
14
  proto_register_field_array(proto_krb4, hf, array_length(hf));
425
14
  proto_register_subtree_array(ett, array_length(ett));
426
14
}
427
428
void
429
proto_reg_handoff_krb4(void)
430
14
{
431
14
  dissector_add_uint_with_preference("udp.port", UDP_PORT_KRB4, krb4_handle);
432
14
}
433
434
/*
435
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
436
 *
437
 * Local variables:
438
 * c-basic-offset: 8
439
 * tab-width: 8
440
 * indent-tabs-mode: t
441
 * End:
442
 *
443
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
444
 * :indentSize=8:tabSize=8:noTabs=false:
445
 */