/src/wireshark/epan/dissectors/packet-negoex.c
Line | Count | Source |
1 | | /* packet-negoex.c |
2 | | * Dissect the NEGOEX security protocol |
3 | | * as described here: https://tools.ietf.org/html/draft-zhu-negoex-04 |
4 | | * Copyright 2012 Richard Sharpe <realrichardsharpe@gmail.com> |
5 | | * Routines for SPNEGO Extended Negotiation Security Mechanism |
6 | | * |
7 | | * Wireshark - Network traffic analyzer |
8 | | * By Gerald Combs <gerald@wireshark.org> |
9 | | * Copyright 1998 Gerald Combs |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | |
14 | | #include "config.h" |
15 | | |
16 | | #include <epan/packet.h> |
17 | | #include <epan/exceptions.h> |
18 | | #include <epan/show_exception.h> |
19 | | |
20 | | #include "packet-gssapi.h" |
21 | | |
22 | | void proto_register_negoex(void); |
23 | | void proto_reg_handoff_negoex(void); |
24 | | |
25 | | static int proto_negoex; |
26 | | static int hf_negoex_sig; |
27 | | static int hf_negoex_message_type; |
28 | | static int hf_negoex_sequence_num; |
29 | | static int hf_negoex_header_len; |
30 | | static int hf_negoex_message_len; |
31 | | static int hf_negoex_conversation_id; |
32 | | static int hf_negoex_random; |
33 | | static int hf_negoex_proto_version; |
34 | | static int hf_negoex_authscheme; |
35 | | static int hf_negoex_authscheme_vector_offset; |
36 | | static int hf_negoex_authscheme_vector_count; |
37 | | static int hf_negoex_authscheme_vector_pad; |
38 | | static int hf_negoex_extension; |
39 | | static int hf_negoex_extension_vector_offset; |
40 | | static int hf_negoex_extension_vector_count; |
41 | | static int hf_negoex_extension_vector_pad; |
42 | | static int hf_negoex_exchange_vector_offset; |
43 | | static int hf_negoex_exchange_vector_count; |
44 | | static int hf_negoex_exchange_vector_pad; |
45 | | static int hf_negoex_exchange; |
46 | | static int hf_negoex_checksum_scheme; |
47 | | static int hf_negoex_checksum_type; |
48 | | static int hf_negoex_checksum_vector_offset; |
49 | | static int hf_negoex_checksum_vector_count; |
50 | | static int hf_negoex_checksum_vector_pad; |
51 | | static int hf_negoex_checksum; |
52 | | static int hf_negoex_errorcode; |
53 | | static int hf_negoex_data; |
54 | | |
55 | | static int ett_negoex; |
56 | | static int ett_negoex_msg; |
57 | | static int ett_negoex_hdr; |
58 | | static int ett_negoex_authscheme_vector; |
59 | | static int ett_negoex_extension_vector; |
60 | | static int ett_negoex_exchange; |
61 | | static int ett_negoex_checksum; |
62 | | static int ett_negoex_checksum_vector; |
63 | | static int ett_negoex_byte_vector; |
64 | | |
65 | | static dissector_handle_t negoex_handle; |
66 | | |
67 | | /* If you add more message types, add them in sequence and update MAX_MSG */ |
68 | 0 | #define MESSAGE_TYPE_INITIATOR_NEGO 0 |
69 | 0 | #define MESSAGE_TYPE_ACCEPTOR_NEGO 1 |
70 | 0 | #define MESSAGE_TYPE_INITIATOR_META_DATA 2 |
71 | 0 | #define MESSAGE_TYPE_ACCEPTOR_META_DATA 3 |
72 | 0 | #define MESSAGE_TYPE_CHALLENGE 4 |
73 | 0 | #define MESSAGE_TYPE_AP_REQUEST 5 |
74 | 0 | #define MESSAGE_TYPE_VERIFY 6 |
75 | 0 | #define MESSAGE_TYPE_ALERT 7 |
76 | 0 | #define MESSAGE_TYPE_MAX_MSG MESSAGE_TYPE_ALERT |
77 | | |
78 | | static const value_string negoex_message_types[] = { |
79 | | {MESSAGE_TYPE_INITIATOR_NEGO, "INITATOR_NEGO"}, |
80 | | {MESSAGE_TYPE_ACCEPTOR_NEGO, "ACCEPTOR_NEGO"}, |
81 | | {MESSAGE_TYPE_INITIATOR_META_DATA, "INITIATOR_META_DATA"}, |
82 | | {MESSAGE_TYPE_ACCEPTOR_META_DATA, "ACCEPTOR_META_DATA"}, |
83 | | {MESSAGE_TYPE_CHALLENGE, "CHALLENGE"}, |
84 | | {MESSAGE_TYPE_AP_REQUEST, "AP_REQUEST"}, |
85 | | {MESSAGE_TYPE_VERIFY, "VERIFY"}, |
86 | | {MESSAGE_TYPE_ALERT, "ALERT"}, |
87 | | {0, NULL} |
88 | | }; |
89 | | |
90 | | static const value_string checksum_schemes[] = { |
91 | | {1, "rfc3961"}, |
92 | | {0, NULL} |
93 | | }; |
94 | | |
95 | | #if 0 |
96 | | static const value_string alert_types[] = { |
97 | | {1, "ALERT_TYPE_PULSE"}, |
98 | | {0, NULL} |
99 | | }; |
100 | | |
101 | | static const value_string alert_reasons[] = { |
102 | | {1, "ALERT_VERIFY_NO_KEY"}, |
103 | | {0, NULL} |
104 | | }; |
105 | | #endif |
106 | | |
107 | | static void |
108 | | dissect_negoex_alert_message(tvbuff_t *tvb, |
109 | | packet_info *pinfo _U_, |
110 | | proto_tree *tree, |
111 | | uint32_t start_off) |
112 | 0 | { |
113 | 0 | uint32_t offset; |
114 | |
|
115 | 0 | offset = start_off; |
116 | | |
117 | | /* AuthScheme */ |
118 | 0 | proto_tree_add_item(tree, hf_negoex_authscheme, tvb, offset, 16, ENC_LITTLE_ENDIAN); |
119 | 0 | offset += 16; |
120 | | |
121 | | /* ErrorCode, an NTSTATUS :-) */ |
122 | 0 | proto_tree_add_item(tree, hf_negoex_errorcode, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
123 | 0 | offset += 4; |
124 | | |
125 | | /* The rest */ |
126 | 0 | proto_tree_add_bytes_format(tree, hf_negoex_data, tvb, offset, -1, NULL, |
127 | 0 | "The rest of the alert message"); |
128 | |
|
129 | 0 | } |
130 | | |
131 | | static void |
132 | | dissect_negoex_verify_message(tvbuff_t *tvb, |
133 | | packet_info *pinfo _U_, |
134 | | proto_tree *tree, |
135 | | uint32_t start_off) |
136 | 0 | { |
137 | 0 | uint32_t offset; |
138 | 0 | uint32_t checksum_vector_offset; |
139 | 0 | uint32_t checksum_vector_count; |
140 | 0 | proto_tree *checksum; |
141 | 0 | proto_tree *checksum_vector; |
142 | |
|
143 | 0 | offset = start_off; |
144 | | |
145 | | /* AuthScheme */ |
146 | 0 | proto_tree_add_item(tree, hf_negoex_authscheme, tvb, offset, 16, ENC_LITTLE_ENDIAN); |
147 | 0 | offset += 16; |
148 | | |
149 | | /* Checksum */ |
150 | 0 | checksum = proto_tree_add_subtree(tree, tvb, offset, 20, ett_negoex_checksum, NULL, "Checksum"); |
151 | | |
152 | | /* cbHeaderLength */ |
153 | 0 | proto_tree_add_item(checksum, hf_negoex_header_len, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
154 | 0 | offset += 4; |
155 | | |
156 | | /* ChecksumScheme */ |
157 | 0 | proto_tree_add_item(checksum, hf_negoex_checksum_scheme, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
158 | 0 | offset += 4; |
159 | | |
160 | | /* ChecksumType */ |
161 | 0 | proto_tree_add_item(checksum, hf_negoex_checksum_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
162 | 0 | offset += 4; |
163 | | |
164 | | /* Checksum Byte Vector */ |
165 | 0 | checksum_vector_offset = tvb_get_letohl(tvb, offset); |
166 | 0 | checksum_vector_count = tvb_get_letohs(tvb, offset + 4); |
167 | |
|
168 | 0 | checksum_vector = proto_tree_add_subtree_format(checksum, tvb, offset, 8, |
169 | 0 | ett_negoex_checksum_vector, NULL, "Checksum Vector: %u at %u", |
170 | 0 | checksum_vector_count, |
171 | 0 | checksum_vector_offset); |
172 | |
|
173 | 0 | proto_tree_add_item(checksum_vector, hf_negoex_checksum_vector_offset, tvb, |
174 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
175 | 0 | offset += 4; |
176 | |
|
177 | 0 | proto_tree_add_item(checksum_vector, hf_negoex_checksum_vector_count, tvb, |
178 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
179 | 0 | offset += 2; |
180 | |
|
181 | 0 | proto_tree_add_item(checksum_vector, hf_negoex_checksum_vector_pad, tvb, |
182 | 0 | offset, 2, ENC_NA); |
183 | | /*offset += 2;*/ |
184 | |
|
185 | 0 | proto_tree_add_item(checksum_vector, hf_negoex_checksum, tvb, |
186 | 0 | checksum_vector_offset, checksum_vector_count, ENC_NA); |
187 | |
|
188 | 0 | } |
189 | | |
190 | | static void |
191 | | dissect_negoex_exchange_message(tvbuff_t *tvb, |
192 | | packet_info *pinfo _U_, |
193 | | proto_tree *tree, |
194 | | uint32_t start_off) |
195 | 0 | { |
196 | 0 | uint32_t offset; |
197 | 0 | uint32_t exchange_vector_offset; |
198 | 0 | uint32_t exchange_vector_count; |
199 | 0 | proto_tree *exchange_vector; |
200 | |
|
201 | 0 | offset = start_off; |
202 | | |
203 | | /* AuthScheme */ |
204 | 0 | proto_tree_add_item(tree, hf_negoex_authscheme, tvb, offset, 16, ENC_LITTLE_ENDIAN); |
205 | 0 | offset += 16; |
206 | | |
207 | | /* Exchange Byte Vector */ |
208 | 0 | exchange_vector_offset = tvb_get_letohl(tvb, offset); |
209 | 0 | exchange_vector_count = tvb_get_letohs(tvb, offset + 4); |
210 | |
|
211 | 0 | exchange_vector = proto_tree_add_subtree_format(tree, tvb, offset, 8, |
212 | 0 | ett_negoex_exchange, NULL, "Exchange: %u bytes at %u", |
213 | 0 | exchange_vector_count, exchange_vector_offset); |
214 | |
|
215 | 0 | proto_tree_add_item(exchange_vector, hf_negoex_exchange_vector_offset, tvb, |
216 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
217 | 0 | offset += 4; |
218 | |
|
219 | 0 | proto_tree_add_item(exchange_vector, hf_negoex_exchange_vector_count, tvb, |
220 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
221 | 0 | offset += 2; |
222 | |
|
223 | 0 | proto_tree_add_item(exchange_vector, hf_negoex_exchange_vector_pad, tvb, |
224 | 0 | offset, 2, ENC_NA); |
225 | | /*offset += 2;*/ |
226 | |
|
227 | 0 | proto_tree_add_item(exchange_vector, hf_negoex_exchange, tvb, |
228 | 0 | exchange_vector_offset, exchange_vector_count, ENC_NA); |
229 | 0 | } |
230 | | |
231 | | /* |
232 | | * In each of the subdissectors we are handed the whole message, but the |
233 | | * header is already dissected. The offset tells us where in the buffer the |
234 | | * actual data starts. This is a bit redundant, but it allows for changes |
235 | | * to the header structure ... |
236 | | * |
237 | | * Eventually we want to treat the header and body differently perhaps. |
238 | | */ |
239 | | static void |
240 | | dissect_negoex_nego_message(tvbuff_t *tvb, |
241 | | packet_info *pinfo _U_, |
242 | | proto_tree *tree, |
243 | | uint32_t start_off) |
244 | 0 | { |
245 | 0 | volatile uint32_t offset; |
246 | 0 | uint32_t authscheme_vector_offset; |
247 | 0 | uint16_t authscheme_vector_count; |
248 | 0 | uint32_t extension_vector_offset; |
249 | 0 | uint32_t extension_vector_count; |
250 | 0 | proto_tree *authscheme_vector; |
251 | 0 | proto_tree *extension_vector; |
252 | 0 | uint32_t i; |
253 | |
|
254 | 0 | offset = start_off; |
255 | |
|
256 | 0 | TRY { |
257 | | /* The Random field */ |
258 | 0 | proto_tree_add_item(tree, hf_negoex_random, tvb, offset, 32, ENC_NA); |
259 | 0 | offset += 32; |
260 | | |
261 | | /* Protocol version */ |
262 | 0 | proto_tree_add_item(tree, hf_negoex_proto_version, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
263 | 0 | offset += 8; |
264 | | |
265 | | /* AuthScheme offset and count */ |
266 | 0 | authscheme_vector_offset = tvb_get_letohl(tvb, offset); |
267 | 0 | authscheme_vector_count = tvb_get_letohs(tvb, offset + 4); |
268 | |
|
269 | 0 | authscheme_vector = proto_tree_add_subtree_format(tree, tvb, offset, 8, |
270 | 0 | ett_negoex_authscheme_vector, NULL, "AuthSchemes: %u at %u", |
271 | 0 | authscheme_vector_count, authscheme_vector_offset); |
272 | 0 | proto_tree_add_item(authscheme_vector, hf_negoex_authscheme_vector_offset, |
273 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN); |
274 | 0 | offset += 4; |
275 | |
|
276 | 0 | proto_tree_add_item(authscheme_vector, hf_negoex_authscheme_vector_count, |
277 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
278 | 0 | offset += 2; |
279 | |
|
280 | 0 | proto_tree_add_item(authscheme_vector, hf_negoex_authscheme_vector_pad, |
281 | 0 | tvb, offset, 2, ENC_NA); |
282 | 0 | offset += 2; |
283 | | |
284 | | /* Now, add the various items */ |
285 | 0 | for (i = 0; i < authscheme_vector_count; i++) { |
286 | 0 | proto_tree_add_item(authscheme_vector, hf_negoex_authscheme, tvb, |
287 | 0 | authscheme_vector_offset + i * 16, 16, ENC_LITTLE_ENDIAN); |
288 | 0 | } |
289 | |
|
290 | 0 | extension_vector_offset = tvb_get_letohl(tvb, offset); |
291 | 0 | extension_vector_count = tvb_get_letohs(tvb, offset + 4); |
292 | |
|
293 | 0 | extension_vector = proto_tree_add_subtree_format(tree, tvb, offset, 8, |
294 | 0 | ett_negoex_extension_vector, NULL, "Extensions: %u at %u", |
295 | 0 | extension_vector_count, extension_vector_count); |
296 | |
|
297 | 0 | proto_tree_add_item(extension_vector, hf_negoex_extension_vector_offset, |
298 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN); |
299 | 0 | offset += 4; |
300 | |
|
301 | 0 | proto_tree_add_item(extension_vector, hf_negoex_extension_vector_count, |
302 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
303 | 0 | offset += 2; |
304 | |
|
305 | 0 | proto_tree_add_item(extension_vector, hf_negoex_extension_vector_pad, |
306 | 0 | tvb, offset, 2, ENC_NA); |
307 | 0 | offset += 2; |
308 | |
|
309 | 0 | for (i = 0; i < extension_vector_count; i++) { |
310 | 0 | uint32_t byte_vector_offset, byte_vector_count; |
311 | 0 | proto_tree *bv_tree; |
312 | | |
313 | | /* |
314 | | * Dissect these things ... they consist of a byte vector, so we |
315 | | * add a subtree and point to the relevant bytes |
316 | | */ |
317 | 0 | byte_vector_offset = tvb_get_letohl(tvb, offset); |
318 | 0 | byte_vector_count = tvb_get_letohs(tvb, offset + 4); |
319 | |
|
320 | 0 | bv_tree = proto_tree_add_subtree_format(extension_vector, tvb, |
321 | 0 | extension_vector_offset + i * 8, 8, |
322 | 0 | ett_negoex_byte_vector, NULL, "Extension: %u bytes at %u", |
323 | 0 | byte_vector_count, byte_vector_offset); |
324 | |
|
325 | 0 | proto_tree_add_item(bv_tree, hf_negoex_extension, tvb, |
326 | 0 | byte_vector_offset, byte_vector_count, ENC_NA); |
327 | 0 | } |
328 | | |
329 | |
|
330 | 0 | } ENDTRY; |
331 | |
|
332 | 0 | } |
333 | | |
334 | | static int |
335 | | dissect_negoex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
336 | 0 | { |
337 | 0 | volatile uint32_t offset; |
338 | 0 | proto_tree * volatile negoex_tree; |
339 | 0 | proto_item *tf; |
340 | 0 | volatile bool done; |
341 | 0 | uint32_t payload_len; |
342 | 0 | uint32_t message_len; |
343 | 0 | uint32_t message_type; |
344 | 0 | uint32_t header_len; |
345 | |
|
346 | 0 | offset = 0; |
347 | 0 | negoex_tree = NULL; |
348 | 0 | tf = NULL; |
349 | 0 | done = false; |
350 | 0 | payload_len = tvb_reported_length(tvb); |
351 | | |
352 | | /* Set up the initial NEGOEX payload */ |
353 | 0 | if (tree) { |
354 | 0 | tf = proto_tree_add_item(tree, proto_negoex, tvb, offset, -1, ENC_NA); |
355 | 0 | negoex_tree = proto_item_add_subtree(tf, ett_negoex); |
356 | 0 | } |
357 | | |
358 | | /* |
359 | | * There can be multiple negoex messages, each with a header with a length. |
360 | | * However, the payload might not have been reassembled ... |
361 | | */ |
362 | |
|
363 | 0 | while (offset < payload_len && !done) { |
364 | 0 | proto_tree *negoex_msg_tree; |
365 | 0 | proto_tree *negoex_hdr_tree; |
366 | 0 | proto_item *msg; |
367 | 0 | tvbuff_t *msg_tvb; |
368 | 0 | uint32_t start_offset; |
369 | |
|
370 | 0 | start_offset = offset; |
371 | |
|
372 | 0 | TRY { |
373 | | /* Message type, it is after the signature */ |
374 | 0 | message_type = tvb_get_letohl(tvb, offset + 8); |
375 | | |
376 | | /* Add the message type tree ... set its length below */ |
377 | 0 | negoex_msg_tree = proto_tree_add_subtree_format(negoex_tree, tvb, offset, -1, |
378 | 0 | ett_negoex_msg, &msg, "NEGOEX %s", |
379 | 0 | val_to_str_const(message_type, |
380 | 0 | negoex_message_types, |
381 | 0 | "Unknown NEGOEX message type")); |
382 | | |
383 | | /* Add a subtree for the header */ |
384 | 0 | negoex_hdr_tree = proto_tree_add_subtree(negoex_msg_tree, tvb, offset, 40, ett_negoex_hdr, NULL, "Header"); |
385 | | |
386 | | /* Signature, NEGOEXTS */ |
387 | 0 | proto_tree_add_item(negoex_hdr_tree, hf_negoex_sig, |
388 | 0 | tvb, offset, 8, ENC_ASCII); |
389 | 0 | offset += 8; |
390 | |
|
391 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", |
392 | 0 | val_to_str_const(message_type, |
393 | 0 | negoex_message_types, |
394 | 0 | "Unknown NEGOEX message type")); |
395 | 0 | proto_tree_add_uint(negoex_hdr_tree, hf_negoex_message_type, |
396 | 0 | tvb, offset, 4, message_type); |
397 | | |
398 | | /* |
399 | | * If this is an unknown message type, we have to punt because anything |
400 | | * following cannot be handled |
401 | | */ |
402 | 0 | if (message_type > MESSAGE_TYPE_MAX_MSG) { |
403 | 0 | offset = payload_len; /* Can't do any more */ |
404 | 0 | goto bad_message; |
405 | 0 | } else { |
406 | 0 | offset += 4; |
407 | 0 | } |
408 | | |
409 | | /* Sequence Number */ |
410 | 0 | proto_tree_add_item(negoex_hdr_tree, hf_negoex_sequence_num, |
411 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN); |
412 | 0 | offset += 4; |
413 | | |
414 | | /* Header Length */ |
415 | 0 | header_len = tvb_get_letohl(tvb, offset); |
416 | 0 | proto_tree_add_uint(negoex_hdr_tree, hf_negoex_header_len, |
417 | 0 | tvb, offset, 4, header_len); |
418 | 0 | offset += 4; |
419 | | |
420 | | /* Message Length */ |
421 | 0 | message_len = tvb_get_letohl(tvb, offset); |
422 | 0 | proto_tree_add_uint(negoex_hdr_tree, hf_negoex_message_len, |
423 | 0 | tvb, offset, 4, message_len); |
424 | 0 | offset += 4; |
425 | | |
426 | | /* Set the message len so the tree item has correct len */ |
427 | 0 | proto_item_set_len(msg, message_len); |
428 | | |
429 | | /* Conversation ID */ |
430 | 0 | proto_tree_add_item(negoex_hdr_tree, hf_negoex_conversation_id, |
431 | 0 | tvb, offset, 16, ENC_LITTLE_ENDIAN); |
432 | 0 | offset += 16; |
433 | | |
434 | | /* |
435 | | * Construct a new TVB covering just this message and pass to the |
436 | | * sub-dissector |
437 | | */ |
438 | 0 | msg_tvb = tvb_new_subset_length(tvb, |
439 | 0 | start_offset, |
440 | 0 | message_len); |
441 | |
|
442 | 0 | switch (message_type) { |
443 | 0 | case MESSAGE_TYPE_INITIATOR_NEGO: |
444 | 0 | case MESSAGE_TYPE_ACCEPTOR_NEGO: |
445 | 0 | dissect_negoex_nego_message(msg_tvb, |
446 | 0 | pinfo, |
447 | 0 | negoex_msg_tree, |
448 | 0 | offset - start_offset); |
449 | 0 | break; |
450 | | |
451 | 0 | case MESSAGE_TYPE_INITIATOR_META_DATA: |
452 | 0 | case MESSAGE_TYPE_ACCEPTOR_META_DATA: |
453 | 0 | case MESSAGE_TYPE_CHALLENGE: |
454 | 0 | case MESSAGE_TYPE_AP_REQUEST: |
455 | 0 | dissect_negoex_exchange_message(msg_tvb, |
456 | 0 | pinfo, |
457 | 0 | negoex_msg_tree, |
458 | 0 | offset - start_offset); |
459 | 0 | break; |
460 | | |
461 | 0 | case MESSAGE_TYPE_VERIFY: |
462 | 0 | dissect_negoex_verify_message(msg_tvb, |
463 | 0 | pinfo, |
464 | 0 | negoex_msg_tree, |
465 | 0 | offset - start_offset); |
466 | 0 | break; |
467 | | |
468 | 0 | case MESSAGE_TYPE_ALERT: |
469 | 0 | dissect_negoex_alert_message(msg_tvb, |
470 | 0 | pinfo, |
471 | 0 | negoex_msg_tree, |
472 | 0 | offset - start_offset); |
473 | 0 | break; |
474 | | |
475 | 0 | default: |
476 | 0 | proto_tree_add_bytes_format(negoex_msg_tree, hf_negoex_data, tvb, offset, message_len - 40, NULL, |
477 | 0 | "The rest of the message"); |
478 | 0 | } |
479 | | |
480 | 0 | offset = start_offset + message_len; |
481 | | |
482 | | /* We cannot branch out of the TRY block, but we can branch here */ |
483 | 0 | bad_message: |
484 | 0 | ; |
485 | |
|
486 | 0 | } CATCH_NONFATAL_ERRORS { |
487 | 0 | done = true; |
488 | 0 | show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); |
489 | 0 | } ENDTRY; |
490 | 0 | } |
491 | | |
492 | 0 | return tvb_captured_length(tvb); |
493 | 0 | } |
494 | | |
495 | | void |
496 | | proto_register_negoex(void) |
497 | 16 | { |
498 | | |
499 | 16 | static hf_register_info hf[] = { |
500 | 16 | { &hf_negoex_sig, |
501 | 16 | { "Signature", "negoex.message.sig", FT_STRING, BASE_NONE, |
502 | 16 | NULL, 0x0, NULL, HFILL }}, |
503 | 16 | { &hf_negoex_message_type, |
504 | 16 | { "MessageType", "negoex.message.type", FT_UINT32, BASE_HEX, |
505 | 16 | VALS(negoex_message_types), 0x00, NULL, HFILL }}, |
506 | 16 | { &hf_negoex_sequence_num, |
507 | 16 | { "SequenceNum", "negoex.message.seq_num", FT_UINT32, BASE_DEC, |
508 | 16 | NULL, 0x0, NULL, HFILL }}, |
509 | 16 | { &hf_negoex_header_len, |
510 | 16 | { "cbHeaderLength", "negoex.header.len", FT_UINT32, BASE_DEC, |
511 | 16 | NULL, 0x0, NULL, HFILL }}, |
512 | 16 | { &hf_negoex_message_len, |
513 | 16 | { "cbMessageLength", "negoex.message.len", FT_UINT32, BASE_DEC, |
514 | 16 | NULL, 0x0, NULL, HFILL }}, |
515 | 16 | { &hf_negoex_conversation_id, |
516 | 16 | { "ConversationID", "negoex.message.conv_id", FT_GUID, BASE_NONE, |
517 | 16 | NULL, 0x0, NULL, HFILL}}, |
518 | 16 | { &hf_negoex_random, |
519 | 16 | { "Random", "negoex.message.random", FT_BYTES, BASE_NONE, |
520 | 16 | NULL, 0x0, "Random data", HFILL }}, |
521 | 16 | { &hf_negoex_proto_version, |
522 | 16 | { "ProtocolVersion", "negoex.proto_version", FT_UINT64, BASE_DEC, |
523 | 16 | NULL, 0x0, NULL, HFILL}}, |
524 | 16 | { &hf_negoex_authscheme, |
525 | 16 | { "AuthScheme", "negoex.auth_scheme", FT_GUID, BASE_NONE, |
526 | 16 | NULL, 0x0, NULL, HFILL}}, |
527 | 16 | { &hf_negoex_authscheme_vector_offset, |
528 | 16 | { "AuthSchemeArrayOffset", "negoex.auth_scheme_array_offset", FT_UINT32, |
529 | 16 | BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
530 | 16 | { &hf_negoex_authscheme_vector_count, |
531 | 16 | { "AuthSchemeCount", "negoex.auth_scheme_array_count", FT_UINT16, |
532 | 16 | BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
533 | 16 | { &hf_negoex_authscheme_vector_pad, |
534 | 16 | { "AuthSchemePad", "negoex.auth_scheme_array_pad", FT_BYTES, |
535 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
536 | 16 | { &hf_negoex_extension, |
537 | 16 | { "Extension", "negoex.extension", FT_BYTES, BASE_NONE, |
538 | 16 | NULL, 0x0, "Extension data", HFILL }}, |
539 | 16 | { &hf_negoex_extension_vector_offset, |
540 | 16 | { "ExtensionArrayOffset", "negoex.extension_array_offset", FT_UINT32, |
541 | 16 | BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
542 | 16 | { &hf_negoex_extension_vector_count, |
543 | 16 | { "ExtensionCount", "negoex.extension_array_count", FT_UINT16, |
544 | 16 | BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
545 | 16 | { &hf_negoex_extension_vector_pad, |
546 | 16 | { "ExtensionPad", "negoex.extension_pad", FT_BYTES, |
547 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
548 | 16 | { &hf_negoex_exchange_vector_offset, |
549 | 16 | { "ExchangeOffset", "negoex.exchange_vec_offset", FT_UINT32, BASE_DEC, |
550 | 16 | NULL, 0x0, NULL, HFILL}}, |
551 | 16 | { &hf_negoex_exchange_vector_count, |
552 | 16 | { "ExchangeByteCount", "negoex.exchange_vec_byte_count", FT_UINT16, |
553 | 16 | BASE_DEC, NULL, 0x0, NULL, HFILL}}, |
554 | 16 | { &hf_negoex_exchange_vector_pad, |
555 | 16 | { "ExchangePad", "negoex.exchange_vec_pad", FT_BYTES, BASE_NONE, |
556 | 16 | NULL, 0x0, NULL, HFILL}}, |
557 | 16 | { &hf_negoex_exchange, |
558 | 16 | { "Exchange Bytes", "negoex.exchange", FT_BYTES, BASE_NONE, |
559 | 16 | NULL, 0x0, NULL, HFILL}}, |
560 | 16 | { &hf_negoex_checksum_scheme, |
561 | 16 | { "ChecksumScheme", "negoex.checksum_scheme", FT_UINT32, BASE_DEC, |
562 | 16 | VALS(checksum_schemes), 0x0, NULL, HFILL}}, |
563 | 16 | { &hf_negoex_checksum_vector_offset, |
564 | 16 | { "ChecksumOffset", "negoex.checksum_vec_offset", FT_UINT32, BASE_DEC, |
565 | 16 | NULL, 0x0, NULL, HFILL}}, |
566 | 16 | { &hf_negoex_checksum_vector_count, |
567 | 16 | { "ChecksumCount", "negoex.checksum_vec_count", FT_UINT16, BASE_DEC, |
568 | 16 | NULL, 0x0, NULL, HFILL}}, |
569 | 16 | { &hf_negoex_checksum_vector_pad, |
570 | 16 | { "ChecksumPad", "negoex.checksum_pad", FT_BYTES, BASE_NONE, |
571 | 16 | NULL, 0x0, NULL, HFILL}}, |
572 | 16 | { &hf_negoex_checksum_type, |
573 | 16 | { "ChecksumType", "negoex.checksum_type", FT_UINT32, BASE_DEC, |
574 | 16 | NULL, 0x0, NULL, HFILL}}, |
575 | 16 | { &hf_negoex_checksum, |
576 | 16 | { "Checksum", "negoex.checksum", FT_BYTES, BASE_NONE, |
577 | 16 | NULL, 0x0, NULL, HFILL}}, |
578 | 16 | { &hf_negoex_errorcode, |
579 | 16 | { "ErrorCode", "negoex.errorcode", FT_UINT32, BASE_HEX, |
580 | 16 | NULL, 0x0, NULL, HFILL}}, |
581 | 16 | { &hf_negoex_data, |
582 | 16 | { "Data", "negoex.data", FT_BYTES, BASE_NONE, |
583 | 16 | NULL, 0x0, NULL, HFILL}}, |
584 | 16 | }; |
585 | | |
586 | 16 | static int *ett[] = { |
587 | 16 | &ett_negoex, |
588 | 16 | &ett_negoex_msg, |
589 | 16 | &ett_negoex_hdr, |
590 | 16 | &ett_negoex_authscheme_vector, |
591 | 16 | &ett_negoex_extension_vector, |
592 | 16 | &ett_negoex_exchange, |
593 | 16 | &ett_negoex_checksum, |
594 | 16 | &ett_negoex_checksum_vector, |
595 | 16 | &ett_negoex_byte_vector, |
596 | 16 | }; |
597 | | /*module_t *negoex_module = NULL; */ |
598 | | |
599 | 16 | proto_negoex = proto_register_protocol ("SPNEGO Extended Negotiation Security Mechanism", "NEGOEX", "negoex"); |
600 | 16 | proto_register_field_array(proto_negoex, hf, array_length(hf)); |
601 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
602 | | |
603 | | /* negoex_module = prefs_register_protocol(proto_negoex, NULL);*/ |
604 | | |
605 | 16 | negoex_handle = register_dissector("negoex", dissect_negoex, proto_negoex); |
606 | 16 | } |
607 | | |
608 | | void |
609 | | proto_reg_handoff_negoex(void) |
610 | 16 | { |
611 | | |
612 | | /* Register protocol with the GSS-API module */ |
613 | 16 | gssapi_init_oid("1.3.6.1.4.1.311.2.2.30", proto_negoex, ett_negoex, |
614 | 16 | negoex_handle, NULL, |
615 | 16 | "NEGOEX - SPNEGO Extended Negotiation Security Mechanism"); |
616 | | |
617 | 16 | } |
618 | | |
619 | | /* |
620 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
621 | | * |
622 | | * Local variables: |
623 | | * c-basic-offset: 2 |
624 | | * tab-width: 8 |
625 | | * indent-tabs-mode: nil |
626 | | * End: |
627 | | * |
628 | | * vi: set shiftwidth=2 tabstop=8 expandtab: |
629 | | * :indentSize=2:tabSize=8:noTabs=true: |
630 | | */ |