2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
5 * $Id: packet-ntlmssp.c,v 1.6 2002/08/10 23:16:37 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
33 #include "packet-smb-common.h"
37 #define NTLMSSP_NEGOTIATE 1
38 #define NTLMSSP_CHALLENGE 2
39 #define NTLMSSP_AUTH 3
40 #define NTLMSSP_UNKNOWN 4
42 static const value_string ntlmssp_message_types[] = {
43 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
44 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
45 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
46 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
50 static const true_false_string flags_set_truth = {
56 * NTLMSSP negotiation flags
59 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
60 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
61 #define NTLMSSP_REQUEST_TARGET 0x00000004
62 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
63 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
64 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
65 #define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040
66 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
67 #define NTLMSSP_NEGOTIATE_NETWARE 0x00000100
68 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
69 #define NTLMSSP_NEGOTIATE_00000400 0x00000400
70 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
71 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000
72 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
73 #define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000
74 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
75 #define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000
76 #define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000
77 #define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000
78 #define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
79 #define NTLMSSP_NEGOTIATE_00100000 0x00100000
80 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
81 #define NTLMSSP_NEGOTIATE_00400000 0x00400000
82 #define NTLMSSP_CHAL_TARGET_INFO 0x00800000
83 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
84 #define NTLMSSP_NEGOTIATE_02000000 0x02000000
85 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
86 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
87 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
88 #define NTLMSSP_NEGOTIATE_128 0x20000000
89 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
90 #define NTLMSSP_NEGOTIATE_80000000 0x80000000
93 static int proto_ntlmssp = -1;
94 static int hf_ntlmssp = -1;
95 static int hf_ntlmssp_auth = -1;
96 static int hf_ntlmssp_message_type = -1;
97 static int hf_ntlmssp_negotiate_flags = -1;
98 static int hf_ntlmssp_negotiate_flags_01 = -1;
99 static int hf_ntlmssp_negotiate_flags_02 = -1;
100 static int hf_ntlmssp_negotiate_flags_04 = -1;
101 static int hf_ntlmssp_negotiate_flags_08 = -1;
102 static int hf_ntlmssp_negotiate_flags_10 = -1;
103 static int hf_ntlmssp_negotiate_flags_20 = -1;
104 static int hf_ntlmssp_negotiate_flags_40 = -1;
105 static int hf_ntlmssp_negotiate_flags_80 = -1;
106 static int hf_ntlmssp_negotiate_flags_100 = -1;
107 static int hf_ntlmssp_negotiate_flags_200 = -1;
108 static int hf_ntlmssp_negotiate_flags_400 = -1;
109 static int hf_ntlmssp_negotiate_flags_800 = -1;
110 static int hf_ntlmssp_negotiate_flags_1000 = -1;
111 static int hf_ntlmssp_negotiate_flags_2000 = -1;
112 static int hf_ntlmssp_negotiate_flags_4000 = -1;
113 static int hf_ntlmssp_negotiate_flags_8000 = -1;
114 static int hf_ntlmssp_negotiate_flags_10000 = -1;
115 static int hf_ntlmssp_negotiate_flags_20000 = -1;
116 static int hf_ntlmssp_negotiate_flags_40000 = -1;
117 static int hf_ntlmssp_negotiate_flags_80000 = -1;
118 static int hf_ntlmssp_negotiate_flags_100000 = -1;
119 static int hf_ntlmssp_negotiate_flags_200000 = -1;
120 static int hf_ntlmssp_negotiate_flags_400000 = -1;
121 static int hf_ntlmssp_negotiate_flags_800000 = -1;
122 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
123 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
124 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
125 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
126 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
127 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
128 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
129 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
130 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
131 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
132 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
133 static int hf_ntlmssp_negotiate_workstation = -1;
134 static int hf_ntlmssp_negotiate_domain_strlen = -1;
135 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
136 static int hf_ntlmssp_negotiate_domain_buffer = -1;
137 static int hf_ntlmssp_negotiate_domain = -1;
138 static int hf_ntlmssp_ntlm_challenge = -1;
139 static int hf_ntlmssp_reserved = -1;
140 static int hf_ntlmssp_challenge_unknown1 = -1;
141 static int hf_ntlmssp_challenge_unknown2 = -1;
142 static int hf_ntlmssp_auth_lmresponse_strlen = -1;
143 static int hf_ntlmssp_auth_lmresponse_maxlen = -1;
144 static int hf_ntlmssp_auth_lmresponse_offset = -1;
145 static int hf_ntlmssp_auth_ntresponse_strlen = -1;
146 static int hf_ntlmssp_auth_ntresponse_maxlen = -1;
147 static int hf_ntlmssp_auth_ntresponse_offset = -1;
148 static int hf_ntlmssp_auth_domain_strlen = -1;
149 static int hf_ntlmssp_auth_domain_maxlen = -1;
150 static int hf_ntlmssp_auth_domain_offset = -1;
151 static int hf_ntlmssp_auth_username_strlen = -1;
152 static int hf_ntlmssp_auth_username_maxlen = -1;
153 static int hf_ntlmssp_auth_username_offset = -1;
154 static int hf_ntlmssp_auth_hostname_strlen = -1;
155 static int hf_ntlmssp_auth_hostname_maxlen = -1;
156 static int hf_ntlmssp_auth_hostname_offset = -1;
157 static int hf_ntlmssp_auth_unknown1_strlen = -1;
158 static int hf_ntlmssp_auth_unknown1_maxlen = -1;
159 static int hf_ntlmssp_auth_unknown1_offset = -1;
160 static int hf_ntlmssp_auth_username = -1;
161 static int hf_ntlmssp_auth_domain = -1;
162 static int hf_ntlmssp_auth_hostname = -1;
163 static int hf_ntlmssp_auth_lmresponse = -1;
164 static int hf_ntlmssp_auth_ntresponse = -1;
165 static int hf_ntlmssp_auth_unknown1 = -1;
166 static gint ett_ntlmssp = -1;
167 static gint ett_ntlmssp_negotiate_flags = -1;
170 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
171 proto_tree *ntlmssp_tree,
172 guint32 negotiate_flags)
174 proto_tree *negotiate_flags_tree = NULL;
175 proto_item *tf = NULL;
178 tf = proto_tree_add_uint (ntlmssp_tree,
179 hf_ntlmssp_negotiate_flags,
180 tvb, offset, 4, negotiate_flags);
181 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
184 proto_tree_add_boolean (negotiate_flags_tree,
185 hf_ntlmssp_negotiate_flags_80000000,
186 tvb, offset, 4, negotiate_flags);
187 proto_tree_add_boolean (negotiate_flags_tree,
188 hf_ntlmssp_negotiate_flags_40000000,
189 tvb, offset, 4, negotiate_flags);
190 proto_tree_add_boolean (negotiate_flags_tree,
191 hf_ntlmssp_negotiate_flags_20000000,
192 tvb, offset, 4, negotiate_flags);
193 proto_tree_add_boolean (negotiate_flags_tree,
194 hf_ntlmssp_negotiate_flags_10000000,
195 tvb, offset, 4, negotiate_flags);
196 proto_tree_add_boolean (negotiate_flags_tree,
197 hf_ntlmssp_negotiate_flags_8000000,
198 tvb, offset, 4, negotiate_flags);
199 proto_tree_add_boolean (negotiate_flags_tree,
200 hf_ntlmssp_negotiate_flags_4000000,
201 tvb, offset, 4, negotiate_flags);
202 proto_tree_add_boolean (negotiate_flags_tree,
203 hf_ntlmssp_negotiate_flags_2000000,
204 tvb, offset, 4, negotiate_flags);
205 proto_tree_add_boolean (negotiate_flags_tree,
206 hf_ntlmssp_negotiate_flags_1000000,
207 tvb, offset, 4, negotiate_flags);
208 proto_tree_add_boolean (negotiate_flags_tree,
209 hf_ntlmssp_negotiate_flags_800000,
210 tvb, offset, 4, negotiate_flags);
211 proto_tree_add_boolean (negotiate_flags_tree,
212 hf_ntlmssp_negotiate_flags_400000,
213 tvb, offset, 4, negotiate_flags);
214 proto_tree_add_boolean (negotiate_flags_tree,
215 hf_ntlmssp_negotiate_flags_200000,
216 tvb, offset, 4, negotiate_flags);
217 proto_tree_add_boolean (negotiate_flags_tree,
218 hf_ntlmssp_negotiate_flags_100000,
219 tvb, offset, 4, negotiate_flags);
220 proto_tree_add_boolean (negotiate_flags_tree,
221 hf_ntlmssp_negotiate_flags_80000,
222 tvb, offset, 4, negotiate_flags);
223 proto_tree_add_boolean (negotiate_flags_tree,
224 hf_ntlmssp_negotiate_flags_40000,
225 tvb, offset, 4, negotiate_flags);
226 proto_tree_add_boolean (negotiate_flags_tree,
227 hf_ntlmssp_negotiate_flags_20000,
228 tvb, offset, 4, negotiate_flags);
229 proto_tree_add_boolean (negotiate_flags_tree,
230 hf_ntlmssp_negotiate_flags_10000,
231 tvb, offset, 4, negotiate_flags);
232 proto_tree_add_boolean (negotiate_flags_tree,
233 hf_ntlmssp_negotiate_flags_8000,
234 tvb, offset, 4, negotiate_flags);
235 proto_tree_add_boolean (negotiate_flags_tree,
236 hf_ntlmssp_negotiate_flags_4000,
237 tvb, offset, 4, negotiate_flags);
238 proto_tree_add_boolean (negotiate_flags_tree,
239 hf_ntlmssp_negotiate_flags_2000,
240 tvb, offset, 4, negotiate_flags);
241 proto_tree_add_boolean (negotiate_flags_tree,
242 hf_ntlmssp_negotiate_flags_1000,
243 tvb, offset, 4, negotiate_flags);
244 proto_tree_add_boolean (negotiate_flags_tree,
245 hf_ntlmssp_negotiate_flags_800,
246 tvb, offset, 4, negotiate_flags);
247 proto_tree_add_boolean (negotiate_flags_tree,
248 hf_ntlmssp_negotiate_flags_400,
249 tvb, offset, 4, negotiate_flags);
250 proto_tree_add_boolean (negotiate_flags_tree,
251 hf_ntlmssp_negotiate_flags_200,
252 tvb, offset, 4, negotiate_flags);
253 proto_tree_add_boolean (negotiate_flags_tree,
254 hf_ntlmssp_negotiate_flags_100,
255 tvb, offset, 4, negotiate_flags);
256 proto_tree_add_boolean (negotiate_flags_tree,
257 hf_ntlmssp_negotiate_flags_80,
258 tvb, offset, 4, negotiate_flags);
259 proto_tree_add_boolean (negotiate_flags_tree,
260 hf_ntlmssp_negotiate_flags_40,
261 tvb, offset, 4, negotiate_flags);
262 proto_tree_add_boolean (negotiate_flags_tree,
263 hf_ntlmssp_negotiate_flags_20,
264 tvb, offset, 4, negotiate_flags);
265 proto_tree_add_boolean (negotiate_flags_tree,
266 hf_ntlmssp_negotiate_flags_10,
267 tvb, offset, 4, negotiate_flags);
268 proto_tree_add_boolean (negotiate_flags_tree,
269 hf_ntlmssp_negotiate_flags_08,
270 tvb, offset, 4, negotiate_flags);
271 proto_tree_add_boolean (negotiate_flags_tree,
272 hf_ntlmssp_negotiate_flags_04,
273 tvb, offset, 4, negotiate_flags);
274 proto_tree_add_boolean (negotiate_flags_tree,
275 hf_ntlmssp_negotiate_flags_02,
276 tvb, offset, 4, negotiate_flags);
277 proto_tree_add_boolean (negotiate_flags_tree,
278 hf_ntlmssp_negotiate_flags_01,
279 tvb, offset, 4, negotiate_flags);
286 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset,
287 proto_tree *ntlmssp_tree)
289 guint32 negotiate_flags;
290 guint16 workstation_length;
291 guint16 domain_length;
293 /* NTLMSSP Negotiate Flags */
294 negotiate_flags = tvb_get_letohl (tvb, offset);
295 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
298 /* Calling workstation domain name length */
299 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain_strlen,
300 tvb, offset, 2, TRUE);
301 domain_length = tvb_get_letohs (tvb, offset);
304 /* Calling workstation domain name max length */
305 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain_maxlen,
306 tvb, offset, 2, TRUE);
310 /* Calling workstation domain name buffer? */
311 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain_buffer,
312 tvb, offset, 4, TRUE);
315 /* Calling workstation name length */
316 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_workstation_strlen,
317 tvb, offset, 2, TRUE);
318 workstation_length = tvb_get_letohs (tvb, offset);
321 /* Calling workstation name max length */
322 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_workstation_maxlen,
323 tvb, offset, 2, TRUE);
326 /* Calling workstation name buffer? */
327 proto_tree_add_uint(ntlmssp_tree, hf_ntlmssp_negotiate_workstation_buffer,
328 tvb, offset, 4, TRUE);
331 /* Calling workstation name */
332 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_workstation,
333 tvb, offset, workstation_length, FALSE);
334 offset += workstation_length;
336 /* Calling domain name */
337 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain,
338 tvb, offset, domain_length, FALSE);
339 offset += domain_length;
346 dissect_ntlmssp_challenge (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
348 guint32 negotiate_flags;
350 /* Skip over the two unknown fields */
351 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_unknown1,
352 tvb, offset, 4, TRUE);
355 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_unknown2,
356 tvb, offset, 4, TRUE);
359 /* NTLMSSP Negotiate Flags */
360 negotiate_flags = tvb_get_letohl (tvb, offset);
361 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
364 /* NTLMSSP NT Lan Manager Challenge */
365 proto_tree_add_item (ntlmssp_tree,
366 hf_ntlmssp_ntlm_challenge,
367 tvb, offset, 8, FALSE);
370 /* Reserved (function not completely known) */
371 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
372 tvb, offset, 8, FALSE);
379 dissect_ntlmssp_auth (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
381 guint16 lmresponse_length;
382 guint16 ntresponse_length;
383 guint16 domain_length;
384 guint16 username_length;
385 guint16 hostname_length;
386 guint16 unknown1_length;
387 guint32 negotiate_flags;
388 const gchar *username;
390 const gchar *hostname;
393 gboolean unicode_strings = FALSE;
395 /* Lan Manager response length */
396 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_lmresponse_strlen,
397 tvb, offset, 2, TRUE);
398 lmresponse_length = tvb_get_letohs (tvb, offset);
401 /* Lan Manager response max length */
402 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_lmresponse_maxlen,
403 tvb, offset, 2, TRUE);
406 /* Lan Manager response offset */
407 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_lmresponse_offset,
408 tvb, offset, 4, TRUE);
411 /* NTLM response length */
412 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_ntresponse_strlen,
413 tvb, offset, 2, TRUE);
414 ntresponse_length = tvb_get_letohs (tvb, offset);
417 /* NTLM response max length */
418 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_ntresponse_maxlen,
419 tvb, offset, 2, TRUE);
422 /* NTLM response offset */
423 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_ntresponse_offset,
424 tvb, offset, 4, TRUE);
427 /* Domain name length */
428 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_domain_strlen,
429 tvb, offset, 2, TRUE);
430 domain_length = tvb_get_letohs (tvb, offset);
433 /* Domain name max length */
434 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_domain_maxlen,
435 tvb, offset, 2, TRUE);
438 /* Domain name offset */
439 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_domain_offset,
440 tvb, offset, 4, TRUE);
443 /* Username length */
444 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_username_strlen,
445 tvb, offset, 2, TRUE);
446 username_length = tvb_get_letohs (tvb, offset);
449 /* Username max length */
450 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_username_maxlen,
451 tvb, offset, 2, TRUE);
454 /* Username offset */
455 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_username_offset,
456 tvb, offset, 4, TRUE);
459 /* Hostname length */
460 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_hostname_strlen,
461 tvb, offset, 2, TRUE);
462 hostname_length = tvb_get_letohs (tvb, offset);
465 /* Hostname max length */
466 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_hostname_maxlen,
467 tvb, offset, 2, TRUE);
470 /* Hostname offset */
471 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_hostname_offset,
472 tvb, offset, 4, TRUE);
475 /* Unknown1 length */
476 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_unknown1_strlen,
477 tvb, offset, 2, TRUE);
478 unknown1_length = tvb_get_letohs (tvb, offset);
481 /* Unknown1 max length */
482 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_unknown1_maxlen,
483 tvb, offset, 2, TRUE);
486 /* Unknown1 offset */
487 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_unknown1_offset,
488 tvb, offset, 4, TRUE);
491 /* NTLMSSP Negotiate Flags */
492 negotiate_flags = tvb_get_letohl (tvb, offset);
493 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
496 if (negotiate_flags && NTLMSSP_NEGOTIATE_UNICODE)
497 unicode_strings = TRUE;
501 domain = get_unicode_or_ascii_string(tvb, &offset,
502 unicode_strings, &result_length,
505 proto_tree_add_string(ntlmssp_tree, hf_ntlmssp_auth_domain, tvb,
506 offset, result_length, domain);
507 offset += domain_length;
510 bc = username_length;
511 username = get_unicode_or_ascii_string(tvb, &offset,
512 unicode_strings, &result_length,
515 proto_tree_add_string(ntlmssp_tree, hf_ntlmssp_auth_username, tvb,
516 offset, result_length, username);
517 offset += username_length;
520 bc = hostname_length;
521 hostname = get_unicode_or_ascii_string(tvb, &offset,
522 unicode_strings, &result_length,
525 proto_tree_add_string(ntlmssp_tree, hf_ntlmssp_auth_hostname, tvb,
526 offset, result_length, hostname);
527 offset += hostname_length;
529 /* Lan Manager Response */
530 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_lmresponse,
531 tvb, offset, lmresponse_length, FALSE);
532 offset += lmresponse_length;
535 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_ntresponse,
536 tvb, offset, ntresponse_length, FALSE);
537 offset += ntresponse_length;
540 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth_unknown1,
541 tvb, offset, unknown1_length, FALSE);
542 offset += unknown1_length;
548 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
550 guint32 ntlmssp_message_type;
553 proto_tree *ntlmssp_tree = NULL;
554 proto_item *tf = NULL;
556 /* Compute the total size of the data to be parsed */
557 payloadsize = tvb_length_remaining(tvb, 0);
559 /* Setup a new tree for the NTLMSSP payload */
561 tf = proto_tree_add_item (tree,
563 tvb, offset, payloadsize, FALSE);
565 ntlmssp_tree = proto_item_add_subtree (tf,
569 /* NTLMSSP constant */
570 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
571 tvb, offset, 8, FALSE);
574 /* NTLMSSP Message Type */
575 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
576 tvb, offset, 4, TRUE);
577 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
580 /* Call the appropriate dissector based on the Message Type */
581 switch (ntlmssp_message_type) {
583 case NTLMSSP_NEGOTIATE:
584 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
587 case NTLMSSP_CHALLENGE:
588 offset = dissect_ntlmssp_challenge (tvb, offset, ntlmssp_tree);
592 offset = dissect_ntlmssp_auth (tvb, offset, ntlmssp_tree);
596 /* Unrecognized message type */
597 proto_tree_add_text (ntlmssp_tree, tvb, offset,
599 "Unrecognized NTLMSSP Message");
605 proto_register_ntlmssp(void)
608 static hf_register_info hf[] = {
610 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
613 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
615 { &hf_ntlmssp_message_type,
616 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
618 { &hf_ntlmssp_negotiate_flags,
619 { "Flags", "dcerpc.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
620 { &hf_ntlmssp_negotiate_flags_01,
622 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
623 { &hf_ntlmssp_negotiate_flags_02,
624 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
625 { &hf_ntlmssp_negotiate_flags_04,
626 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
627 { &hf_ntlmssp_negotiate_flags_08,
628 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
629 { &hf_ntlmssp_negotiate_flags_10,
630 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
631 { &hf_ntlmssp_negotiate_flags_20,
632 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
633 { &hf_ntlmssp_negotiate_flags_40,
634 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
635 { &hf_ntlmssp_negotiate_flags_80,
636 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
637 { &hf_ntlmssp_negotiate_flags_100,
638 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
639 { &hf_ntlmssp_negotiate_flags_200,
640 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
641 { &hf_ntlmssp_negotiate_flags_400,
642 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
643 { &hf_ntlmssp_negotiate_flags_800,
644 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
645 { &hf_ntlmssp_negotiate_flags_1000,
646 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
647 { &hf_ntlmssp_negotiate_flags_2000,
648 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
649 { &hf_ntlmssp_negotiate_flags_4000,
650 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
651 { &hf_ntlmssp_negotiate_flags_8000,
652 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
653 { &hf_ntlmssp_negotiate_flags_10000,
654 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
655 { &hf_ntlmssp_negotiate_flags_20000,
656 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
657 { &hf_ntlmssp_negotiate_flags_40000,
658 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
659 { &hf_ntlmssp_negotiate_flags_80000,
660 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
661 { &hf_ntlmssp_negotiate_flags_100000,
662 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
663 { &hf_ntlmssp_negotiate_flags_200000,
664 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
665 { &hf_ntlmssp_negotiate_flags_400000,
666 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
667 { &hf_ntlmssp_negotiate_flags_800000,
668 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
669 { &hf_ntlmssp_negotiate_flags_1000000,
670 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
671 { &hf_ntlmssp_negotiate_flags_2000000,
672 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
673 { &hf_ntlmssp_negotiate_flags_4000000,
674 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
675 { &hf_ntlmssp_negotiate_flags_8000000,
676 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
677 { &hf_ntlmssp_negotiate_flags_10000000,
678 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
679 { &hf_ntlmssp_negotiate_flags_20000000,
680 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
681 { &hf_ntlmssp_negotiate_flags_40000000,
682 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
683 { &hf_ntlmssp_negotiate_flags_80000000,
684 { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
685 { &hf_ntlmssp_negotiate_workstation_strlen,
686 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
687 { &hf_ntlmssp_negotiate_workstation_maxlen,
688 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
689 { &hf_ntlmssp_negotiate_workstation_buffer,
690 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
691 { &hf_ntlmssp_negotiate_workstation,
692 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
693 { &hf_ntlmssp_negotiate_domain_strlen,
694 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
695 { &hf_ntlmssp_negotiate_domain_maxlen,
696 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
697 { &hf_ntlmssp_negotiate_domain_buffer,
698 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
699 { &hf_ntlmssp_negotiate_domain,
700 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
701 { &hf_ntlmssp_ntlm_challenge,
702 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
703 { &hf_ntlmssp_reserved,
704 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
705 { &hf_ntlmssp_challenge_unknown1,
706 { "Unknown1", "ntlmssp.challenge.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
707 { &hf_ntlmssp_challenge_unknown2,
708 { "Unknown2", "ntlmssp.challenge.unknown2", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
709 { &hf_ntlmssp_auth_lmresponse_strlen,
710 { "Lan Manager response length", "ntlmssp.auth.lmresponse.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
711 { &hf_ntlmssp_auth_lmresponse_maxlen,
712 { "Lan Manager response max length", "ntlmssp.auth.lmresponse.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
713 { &hf_ntlmssp_auth_lmresponse_offset,
714 { "Lan Manager response offset", "ntlmssp.auth.lmresponse.offset", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
715 { &hf_ntlmssp_auth_ntresponse_strlen,
716 { "NTLM response length", "ntlmssp.auth.ntresponse.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
717 { &hf_ntlmssp_auth_ntresponse_maxlen,
718 { "NTLM response max length", "ntlmssp.auth.ntresponse.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
719 { &hf_ntlmssp_auth_ntresponse_offset,
720 { "NTLM response offset", "ntlmssp.auth.ntresponse.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
721 { &hf_ntlmssp_auth_domain_strlen,
722 { "Domain name length", "ntlmssp.auth.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
723 { &hf_ntlmssp_auth_domain_maxlen,
724 { "Domain name max length", "ntlmssp.auth.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
725 { &hf_ntlmssp_auth_domain_offset,
726 { "Domain name offset", "ntlmssp.auth.domain.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
727 { &hf_ntlmssp_auth_username_strlen,
728 { "Username length", "ntlmssp.auth.username.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
729 { &hf_ntlmssp_auth_username_maxlen,
730 { "Username max length", "ntlmssp.auth.username.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
731 { &hf_ntlmssp_auth_username_offset,
732 { "Username offset", "ntlmssp.auth.username.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
733 { &hf_ntlmssp_auth_hostname_strlen,
734 { "Hostname length", "ntlmssp.auth.hostname.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
735 { &hf_ntlmssp_auth_hostname_maxlen,
736 { "Hostname max length", "ntlmssp.auth.hostname.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
737 { &hf_ntlmssp_auth_hostname_offset,
738 { "Hostname offset", "ntlmssp.auth.hostname.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
739 { &hf_ntlmssp_auth_unknown1_strlen,
740 { "Unknown1 length", "ntlmssp.auth.unknown1.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
741 { &hf_ntlmssp_auth_unknown1_maxlen,
742 { "Unknown1 max length", "ntlmssp.auth.unknown1.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
743 { &hf_ntlmssp_auth_unknown1_offset,
744 { "Unknown1 offset", "ntlmssp.auth.unknown1.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
745 { &hf_ntlmssp_auth_domain,
746 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
747 { &hf_ntlmssp_auth_username,
748 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
749 { &hf_ntlmssp_auth_hostname,
750 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
751 { &hf_ntlmssp_auth_lmresponse,
752 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
753 { &hf_ntlmssp_auth_ntresponse,
754 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
755 { &hf_ntlmssp_auth_unknown1,
756 { "Unknown1", "ntlmssp.auth.unknown1", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}
760 static gint *ett[] = {
762 &ett_ntlmssp_negotiate_flags,
765 proto_ntlmssp = proto_register_protocol (
766 "NTLM Secure Service Provider", /* name */
767 "NTLMSSP", /* short name */
768 "ntlmssp" /* abbrev */
770 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
771 proto_register_subtree_array (ett, array_length (ett));
773 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);