2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
4 * Copyright 2003, Tim Potter <tpot@samba.org>
6 * $Id: packet-ntlmssp.c,v 1.47 2004/02/25 09:31:06 guy Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
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.
32 #include <epan/packet.h>
34 #include "packet-smb-common.h"
35 #include "asn1.h" /* XXX - needed for subid_t */
36 #include "packet-gssapi.h"
37 #include "packet-frame.h"
39 #include "crypt-rc4.h"
40 #include "crypt-md4.h"
41 #include "crypt-des.h"
42 #include "packet-dcerpc.h"
46 #define NTLMSSP_NEGOTIATE 1
47 #define NTLMSSP_CHALLENGE 2
48 #define NTLMSSP_AUTH 3
49 #define NTLMSSP_UNKNOWN 4
51 static const value_string ntlmssp_message_types[] = {
52 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
53 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
54 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
55 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
60 * NTLMSSP negotiation flags
63 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
64 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
65 #define NTLMSSP_REQUEST_TARGET 0x00000004
66 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
67 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
68 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
69 #define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040
70 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
71 #define NTLMSSP_NEGOTIATE_NETWARE 0x00000100
72 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
73 #define NTLMSSP_NEGOTIATE_00000400 0x00000400
74 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
75 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000
76 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
77 #define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000
78 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
79 #define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000
80 #define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000
81 #define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000
82 #define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
83 #define NTLMSSP_NEGOTIATE_00100000 0x00100000
84 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
85 #define NTLMSSP_NEGOTIATE_00400000 0x00400000
86 #define NTLMSSP_CHAL_TARGET_INFO 0x00800000
87 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
88 #define NTLMSSP_NEGOTIATE_02000000 0x02000000
89 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
90 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
91 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
92 #define NTLMSSP_NEGOTIATE_128 0x20000000
93 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
94 #define NTLMSSP_NEGOTIATE_80000000 0x80000000
96 static int proto_ntlmssp = -1;
97 static int hf_ntlmssp = -1;
98 static int hf_ntlmssp_auth = -1;
99 static int hf_ntlmssp_message_type = -1;
100 static int hf_ntlmssp_negotiate_flags = -1;
101 static int hf_ntlmssp_negotiate_flags_01 = -1;
102 static int hf_ntlmssp_negotiate_flags_02 = -1;
103 static int hf_ntlmssp_negotiate_flags_04 = -1;
104 static int hf_ntlmssp_negotiate_flags_08 = -1;
105 static int hf_ntlmssp_negotiate_flags_10 = -1;
106 static int hf_ntlmssp_negotiate_flags_20 = -1;
107 static int hf_ntlmssp_negotiate_flags_40 = -1;
108 static int hf_ntlmssp_negotiate_flags_80 = -1;
109 static int hf_ntlmssp_negotiate_flags_100 = -1;
110 static int hf_ntlmssp_negotiate_flags_200 = -1;
111 static int hf_ntlmssp_negotiate_flags_400 = -1;
112 static int hf_ntlmssp_negotiate_flags_800 = -1;
113 static int hf_ntlmssp_negotiate_flags_1000 = -1;
114 static int hf_ntlmssp_negotiate_flags_2000 = -1;
115 static int hf_ntlmssp_negotiate_flags_4000 = -1;
116 static int hf_ntlmssp_negotiate_flags_8000 = -1;
117 static int hf_ntlmssp_negotiate_flags_10000 = -1;
118 static int hf_ntlmssp_negotiate_flags_20000 = -1;
119 static int hf_ntlmssp_negotiate_flags_40000 = -1;
120 static int hf_ntlmssp_negotiate_flags_80000 = -1;
121 static int hf_ntlmssp_negotiate_flags_100000 = -1;
122 static int hf_ntlmssp_negotiate_flags_200000 = -1;
123 static int hf_ntlmssp_negotiate_flags_400000 = -1;
124 static int hf_ntlmssp_negotiate_flags_800000 = -1;
125 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
126 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
127 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
128 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
129 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
130 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
131 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
132 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
133 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
134 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
135 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
136 static int hf_ntlmssp_negotiate_workstation = -1;
137 static int hf_ntlmssp_negotiate_domain_strlen = -1;
138 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
139 static int hf_ntlmssp_negotiate_domain_buffer = -1;
140 static int hf_ntlmssp_negotiate_domain = -1;
141 static int hf_ntlmssp_ntlm_challenge = -1;
142 static int hf_ntlmssp_reserved = -1;
143 static int hf_ntlmssp_challenge_domain = -1;
144 static int hf_ntlmssp_auth_username = -1;
145 static int hf_ntlmssp_auth_domain = -1;
146 static int hf_ntlmssp_auth_hostname = -1;
147 static int hf_ntlmssp_auth_lmresponse = -1;
148 static int hf_ntlmssp_auth_ntresponse = -1;
149 static int hf_ntlmssp_auth_sesskey = -1;
150 static int hf_ntlmssp_string_len = -1;
151 static int hf_ntlmssp_string_maxlen = -1;
152 static int hf_ntlmssp_string_offset = -1;
153 static int hf_ntlmssp_blob_len = -1;
154 static int hf_ntlmssp_blob_maxlen = -1;
155 static int hf_ntlmssp_blob_offset = -1;
156 static int hf_ntlmssp_address_list = -1;
157 static int hf_ntlmssp_address_list_len = -1;
158 static int hf_ntlmssp_address_list_maxlen = -1;
159 static int hf_ntlmssp_address_list_offset = -1;
160 static int hf_ntlmssp_address_list_server_nb = -1;
161 static int hf_ntlmssp_address_list_domain_nb = -1;
162 static int hf_ntlmssp_address_list_server_dns = -1;
163 static int hf_ntlmssp_address_list_domain_dns = -1;
164 static int hf_ntlmssp_address_list_terminator = -1;
165 static int hf_ntlmssp_address_list_item_type = -1;
166 static int hf_ntlmssp_address_list_item_len = -1;
167 static int hf_ntlmssp_address_list_item_content = -1;
168 static int hf_ntlmssp_verf = -1;
169 static int hf_ntlmssp_verf_vers = -1;
170 static int hf_ntlmssp_verf_body = -1;
171 static int hf_ntlmssp_verf_unknown1 = -1;
172 static int hf_ntlmssp_verf_crc32 = -1;
173 static int hf_ntlmssp_verf_sequence = -1;
174 static int hf_ntlmssp_decrypted_payload = -1;
176 static gint ett_ntlmssp = -1;
177 static gint ett_ntlmssp_negotiate_flags = -1;
178 static gint ett_ntlmssp_string = -1;
179 static gint ett_ntlmssp_blob = -1;
180 static gint ett_ntlmssp_address_list = -1;
181 static gint ett_ntlmssp_address_list_item = -1;
183 /* Configuration variables */
184 static char *nt_password = NULL;
186 #define MAX_BLOB_SIZE 256
187 typedef struct _ntlmssp_blob {
189 guint8 contents[MAX_BLOB_SIZE];
192 /* Used in the conversation function */
193 typedef struct _ntlmssp_info {
196 rc4_state_struct rc4_state_peer1;
197 rc4_state_struct rc4_state_peer2;
198 guint32 peer1_dest_port;
199 int rc4_state_initialized;
200 ntlmssp_blob ntlm_response;
201 ntlmssp_blob lm_response;
205 * GMemChunk from which ntlmssp_info structures are allocated.
207 static GMemChunk *ntlmssp_info_chunk;
208 static int ntlmssp_info_count = 10;
210 /* If this struct exists in the payload_decrypt, then we have already
212 typedef struct _ntlmssp_packet_info {
215 guint8 *decrypted_payload;
217 gboolean payload_decrypted;
218 gboolean verifier_decrypted;
219 } ntlmssp_packet_info;
222 * GMemChunk from which ntlmssp_packet_info structures are allocated.
224 static GMemChunk *ntlmssp_packet_info_chunk;
225 static int ntlmssp_packet_info_count = 10;
228 * GSlist of decrypted payloads.
230 static GSList *decrypted_payloads;
233 Generate a challenge response, given an eight byte challenge and
234 either the NT or the Lan Manager password hash (16 bytes).
235 Returns output in response, which is expected to be 24 bytes.
237 static int ntlmssp_generate_challenge_response(guint8 *response,
238 const guint8 *passhash,
239 const guint8 *challenge)
241 guint8 pw21[21]; /* Password hash padded to 21 bytes */
243 memset(pw21, 0x0, sizeof(pw21));
244 memcpy(pw21, passhash, 16);
246 memset(response, 0, 24);
248 crypt_des_ecb(response, challenge, pw21, 1);
249 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
250 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
255 /* Create an NTLMSSP version 1 key.
256 * password points to the ANSI password to encrypt, challenge points to
257 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
258 * otherwise it will do a 40 bit key. The result is stored in
259 * sspkey (expected to be 16 octets)
262 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge,
263 int use_key_128, guint8 *sspkey)
265 unsigned char lm_password_upper[16];
266 unsigned char lm_password_hash[16];
267 guint8 lm_challenge_response[24];
269 guint8 pw21[21]; /* Password hash padded to 21 bytes */
272 unsigned char lmhash_key[] =
273 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
275 memset(lm_password_upper, 0, sizeof(lm_password_upper));
277 /* Create a Lan Manager hash of the input password */
278 if (nt_password[0] != '\0') {
279 password_len = strlen(nt_password);
280 /* Truncate password if too long */
281 if (password_len > 16)
283 for (i = 0; i < password_len; i++) {
284 lm_password_upper[i] = toupper(nt_password[i]);
288 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
289 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
291 /* Generate the LanMan Challenge Response */
292 ntlmssp_generate_challenge_response(lm_challenge_response,
293 lm_password_hash, challenge);
295 /* Generate the NTLMSSP-v1 RC4 Key.
296 * The RC4 key is derived from the Lan Manager Hash.
297 * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
299 memset(pw21, 0xBD, sizeof(pw21));
300 memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
302 /* Only the first eight bytes of challenge_response is used */
303 crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
304 crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
305 crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
307 /* Create the SSP Key */
308 memset(sspkey, 0, sizeof(sspkey));
310 /* Create 128 bit key */
311 memcpy(sspkey, rc4key, 16);
314 /* Create 40 bit key */
315 memcpy(sspkey, rc4key, 5);
323 /* dissect a string - header area contains:
326 four byte offset of string in data area
327 The function returns the offset at the end of the string header,
328 but the 'end' parameter returns the offset of the end of the string itself
329 The 'start' parameter returns the offset of the beginning of the string
332 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
333 proto_tree *ntlmssp_tree,
334 gboolean unicode_strings,
335 int string_hf, int *start, int *end)
337 proto_tree *tree = NULL;
338 proto_item *tf = NULL;
339 gint16 string_length = tvb_get_letohs(tvb, offset);
340 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
341 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
342 const char *string_text = NULL;
346 *start = (string_offset > offset+8 ? string_offset : offset+8);
347 if (0 == string_length) {
350 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
355 bc = result_length = string_length;
356 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
357 unicode_strings, &result_length,
361 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
362 string_offset, result_length, string_text);
363 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
365 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
366 tvb, offset, 2, string_length);
368 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
369 tvb, offset, 2, string_maxlen);
371 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
372 tvb, offset, 4, string_offset);
375 *end = string_offset + string_length;
379 /* dissect a generic blob - header area contains:
382 four byte offset of blob in data area
383 The function returns the offset at the end of the blob header,
384 but the 'end' parameter returns the offset of the end of the blob itself
387 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
388 proto_tree *ntlmssp_tree,
389 int blob_hf, int *end, ntlmssp_blob *result)
391 proto_item *tf = NULL;
392 proto_tree *tree = NULL;
393 guint16 blob_length = tvb_get_letohs(tvb, offset);
394 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
395 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
397 if (0 == blob_length) {
398 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
400 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
401 proto_registrar_get_name(blob_hf));
406 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
407 blob_offset, blob_length, FALSE);
408 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
410 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
411 tvb, offset, 2, blob_length);
413 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
414 tvb, offset, 2, blob_maxlen);
416 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
417 tvb, offset, 4, blob_offset);
420 *end = blob_offset + blob_length;
422 if (result != NULL) {
423 result->length = blob_length;
424 memset(result->contents, 0, MAX_BLOB_SIZE);
425 if (blob_length < MAX_BLOB_SIZE)
426 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
429 /* If we are dissecting the NTLM response and it is a NTLMv2
430 response call the appropriate dissector. */
432 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
433 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
439 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
440 proto_tree *ntlmssp_tree,
441 guint32 negotiate_flags)
443 proto_tree *negotiate_flags_tree = NULL;
444 proto_item *tf = NULL;
447 tf = proto_tree_add_uint (ntlmssp_tree,
448 hf_ntlmssp_negotiate_flags,
449 tvb, offset, 4, negotiate_flags);
450 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
453 proto_tree_add_boolean (negotiate_flags_tree,
454 hf_ntlmssp_negotiate_flags_80000000,
455 tvb, offset, 4, negotiate_flags);
456 proto_tree_add_boolean (negotiate_flags_tree,
457 hf_ntlmssp_negotiate_flags_40000000,
458 tvb, offset, 4, negotiate_flags);
459 proto_tree_add_boolean (negotiate_flags_tree,
460 hf_ntlmssp_negotiate_flags_20000000,
461 tvb, offset, 4, negotiate_flags);
462 proto_tree_add_boolean (negotiate_flags_tree,
463 hf_ntlmssp_negotiate_flags_10000000,
464 tvb, offset, 4, negotiate_flags);
465 proto_tree_add_boolean (negotiate_flags_tree,
466 hf_ntlmssp_negotiate_flags_8000000,
467 tvb, offset, 4, negotiate_flags);
468 proto_tree_add_boolean (negotiate_flags_tree,
469 hf_ntlmssp_negotiate_flags_4000000,
470 tvb, offset, 4, negotiate_flags);
471 proto_tree_add_boolean (negotiate_flags_tree,
472 hf_ntlmssp_negotiate_flags_2000000,
473 tvb, offset, 4, negotiate_flags);
474 proto_tree_add_boolean (negotiate_flags_tree,
475 hf_ntlmssp_negotiate_flags_1000000,
476 tvb, offset, 4, negotiate_flags);
477 proto_tree_add_boolean (negotiate_flags_tree,
478 hf_ntlmssp_negotiate_flags_800000,
479 tvb, offset, 4, negotiate_flags);
480 proto_tree_add_boolean (negotiate_flags_tree,
481 hf_ntlmssp_negotiate_flags_400000,
482 tvb, offset, 4, negotiate_flags);
483 proto_tree_add_boolean (negotiate_flags_tree,
484 hf_ntlmssp_negotiate_flags_200000,
485 tvb, offset, 4, negotiate_flags);
486 proto_tree_add_boolean (negotiate_flags_tree,
487 hf_ntlmssp_negotiate_flags_100000,
488 tvb, offset, 4, negotiate_flags);
489 proto_tree_add_boolean (negotiate_flags_tree,
490 hf_ntlmssp_negotiate_flags_80000,
491 tvb, offset, 4, negotiate_flags);
492 proto_tree_add_boolean (negotiate_flags_tree,
493 hf_ntlmssp_negotiate_flags_40000,
494 tvb, offset, 4, negotiate_flags);
495 proto_tree_add_boolean (negotiate_flags_tree,
496 hf_ntlmssp_negotiate_flags_20000,
497 tvb, offset, 4, negotiate_flags);
498 proto_tree_add_boolean (negotiate_flags_tree,
499 hf_ntlmssp_negotiate_flags_10000,
500 tvb, offset, 4, negotiate_flags);
501 proto_tree_add_boolean (negotiate_flags_tree,
502 hf_ntlmssp_negotiate_flags_8000,
503 tvb, offset, 4, negotiate_flags);
504 proto_tree_add_boolean (negotiate_flags_tree,
505 hf_ntlmssp_negotiate_flags_4000,
506 tvb, offset, 4, negotiate_flags);
507 proto_tree_add_boolean (negotiate_flags_tree,
508 hf_ntlmssp_negotiate_flags_2000,
509 tvb, offset, 4, negotiate_flags);
510 proto_tree_add_boolean (negotiate_flags_tree,
511 hf_ntlmssp_negotiate_flags_1000,
512 tvb, offset, 4, negotiate_flags);
513 proto_tree_add_boolean (negotiate_flags_tree,
514 hf_ntlmssp_negotiate_flags_800,
515 tvb, offset, 4, negotiate_flags);
516 proto_tree_add_boolean (negotiate_flags_tree,
517 hf_ntlmssp_negotiate_flags_400,
518 tvb, offset, 4, negotiate_flags);
519 proto_tree_add_boolean (negotiate_flags_tree,
520 hf_ntlmssp_negotiate_flags_200,
521 tvb, offset, 4, negotiate_flags);
522 proto_tree_add_boolean (negotiate_flags_tree,
523 hf_ntlmssp_negotiate_flags_100,
524 tvb, offset, 4, negotiate_flags);
525 proto_tree_add_boolean (negotiate_flags_tree,
526 hf_ntlmssp_negotiate_flags_80,
527 tvb, offset, 4, negotiate_flags);
528 proto_tree_add_boolean (negotiate_flags_tree,
529 hf_ntlmssp_negotiate_flags_40,
530 tvb, offset, 4, negotiate_flags);
531 proto_tree_add_boolean (negotiate_flags_tree,
532 hf_ntlmssp_negotiate_flags_20,
533 tvb, offset, 4, negotiate_flags);
534 proto_tree_add_boolean (negotiate_flags_tree,
535 hf_ntlmssp_negotiate_flags_10,
536 tvb, offset, 4, negotiate_flags);
537 proto_tree_add_boolean (negotiate_flags_tree,
538 hf_ntlmssp_negotiate_flags_08,
539 tvb, offset, 4, negotiate_flags);
540 proto_tree_add_boolean (negotiate_flags_tree,
541 hf_ntlmssp_negotiate_flags_04,
542 tvb, offset, 4, negotiate_flags);
543 proto_tree_add_boolean (negotiate_flags_tree,
544 hf_ntlmssp_negotiate_flags_02,
545 tvb, offset, 4, negotiate_flags);
546 proto_tree_add_boolean (negotiate_flags_tree,
547 hf_ntlmssp_negotiate_flags_01,
548 tvb, offset, 4, negotiate_flags);
555 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
557 guint32 negotiate_flags;
562 /* NTLMSSP Negotiate Flags */
563 negotiate_flags = tvb_get_letohl (tvb, offset);
564 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
567 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
568 hf_ntlmssp_negotiate_domain,
569 &start, &workstation_end);
570 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
571 hf_ntlmssp_negotiate_workstation,
572 &start, &domain_end);
574 /* XXX - two blobs after this one, sometimes? */
576 return MAX(workstation_end, domain_end);
581 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
582 proto_tree *ntlmssp_tree,
585 guint16 list_length = tvb_get_letohs(tvb, offset);
586 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
587 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
588 guint16 item_type, item_length;
590 proto_item *tf = NULL;
591 proto_tree *tree = NULL;
592 proto_item *addr_tf = NULL;
593 proto_tree *addr_tree = NULL;
595 /* the address list is just a blob */
596 if (0 == list_length) {
597 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
599 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
600 "Address List: Empty");
605 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
606 list_offset, list_length, FALSE);
607 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
609 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
610 tvb, offset, 2, list_length);
612 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
613 tvb, offset, 2, list_maxlen);
615 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
616 tvb, offset, 4, list_offset);
619 /* Now enumerate through the individual items in the list */
620 item_offset = list_offset;
622 while (item_offset < (list_offset + list_length)) {
623 const char *text=NULL;
624 guint32 content_offset;
625 guint16 content_length;
630 type_offset = item_offset;
631 item_type = tvb_get_letohs(tvb, type_offset);
634 len_offset = type_offset + 2;
635 content_length = tvb_get_letohs(tvb, len_offset);
638 content_offset = len_offset + 2;
639 item_length = content_length + 4;
641 /* Strings are always in unicode regardless of the negotiated
643 if (content_length > 0) {
648 item_offset_int = content_offset;
650 text = get_unicode_or_ascii_string(tvb, &item_offset_int,
651 TRUE, &result_length,
655 if (!text) text = ""; /* Make sure we don't blow up below */
658 case NTLM_NAME_NB_HOST:
659 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
660 tvb, item_offset, item_length, text);
662 case NTLM_NAME_NB_DOMAIN:
663 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
664 tvb, item_offset, item_length, text);
666 case NTLM_NAME_DNS_HOST:
667 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
668 tvb, item_offset, item_length, text);
670 case NTLM_NAME_DNS_DOMAIN:
671 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
672 tvb, item_offset, item_length, text);
675 addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
676 tvb, item_offset, item_length, TRUE);
679 /* Now show the actual bytes that made up the summary line */
680 addr_tree = proto_item_add_subtree (addr_tf,
681 ett_ntlmssp_address_list_item);
682 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
683 tvb, type_offset, 2, TRUE);
684 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
685 tvb, len_offset, 2, TRUE);
686 if (content_length > 0) {
687 proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
688 tvb, content_offset, content_length, text);
691 item_offset += item_length;
694 *end = list_offset + list_length;
699 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
700 proto_tree *ntlmssp_tree)
702 guint32 negotiate_flags;
703 int item_start, item_end;
704 int data_start, data_end;
705 ntlmssp_info *conv_ntlmssp_info;
706 conversation_t *conversation;
707 gboolean unicode_strings = FALSE;
708 guint8 sspkey[16]; /* NTLMSSP cipher key */
709 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
711 /* need to find unicode flag */
712 negotiate_flags = tvb_get_letohl (tvb, offset+8);
713 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
714 unicode_strings = TRUE;
717 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
718 hf_ntlmssp_challenge_domain,
719 &item_start, &item_end);
720 data_start = item_start;
723 /* NTLMSSP Negotiate Flags */
724 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
727 /* NTLMSSP NT Lan Manager Challenge */
728 proto_tree_add_item (ntlmssp_tree,
729 hf_ntlmssp_ntlm_challenge,
730 tvb, offset, 8, FALSE);
733 * Store the flags and the challenge with the conversation, as they're
734 * needed in order to dissect subsequent messages.
736 conversation = find_conversation(&pinfo->src, &pinfo->dst,
737 pinfo->ptype, pinfo->srcport,
739 if (!conversation) { /* Create one */
740 conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype,
741 pinfo->srcport, pinfo->destport, 0);
744 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
745 conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
746 /* Insert the flags into the conversation */
747 conv_ntlmssp_info->flags = negotiate_flags;
748 /* Insert the challenge into the conversation */
749 tvb_memcpy(tvb, conv_ntlmssp_info->challenge, offset, 8);
751 /* Between the challenge and the user provided password, we can build the
752 NTLMSSP key and initialize the cipher */
753 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
754 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
759 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
763 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
764 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
765 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
766 conv_ntlmssp_info->rc4_state_initialized = 1;
768 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
772 /* Reserved (function not completely known) */
774 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
775 tvb, offset, 8, FALSE);
779 * The presence or absence of this field is not obviously correlated
780 * with any flags in the previous NEGOTIATE message or in this
781 * message (other than the "Workstation Supplied" and "Domain
782 * Supplied" flags in the NEGOTIATE message, at least in the capture
783 * I've seen - but those also correlate with the presence of workstation
784 * and domain name fields, so it doesn't seem to make sense that they
785 * actually *indicate* whether the subsequent CHALLENGE has an
788 if (offset < data_start) {
789 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
790 data_end = MAX(data_end, item_end);
793 return MAX(offset, data_end);
797 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
798 proto_tree *ntlmssp_tree)
800 int item_start, item_end;
801 int data_start, data_end = 0;
802 guint32 negotiate_flags;
803 gboolean unicode_strings = FALSE;
804 ntlmssp_info *conv_ntlmssp_info;
805 conversation_t *conversation;
808 * Get flag info from the original negotiate message, if any.
809 * This is because the flag information is sometimes missing from
810 * the AUTHENTICATE message, so we can't figure out whether
811 * strings are Unicode or not by looking at *our* flags.
813 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
814 if (conv_ntlmssp_info == NULL) {
816 * There isn't any. Is there any from this conversation? If so,
817 * it means this is the first time we've dissected this frame, so
818 * we should give it flag info.
820 conversation = find_conversation(&pinfo->src, &pinfo->dst,
821 pinfo->ptype, pinfo->srcport,
823 if (conversation != NULL) {
824 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
825 if (conv_ntlmssp_info != NULL) {
827 * We have flag info; attach it to the frame.
829 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
833 if (conv_ntlmssp_info != NULL) {
834 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
835 unicode_strings = TRUE;
839 * Sometimes the session key and flags are missing.
840 * Sometimes the session key is present but the flags are missing.
841 * Sometimes they're both present.
843 * This does not correlate with any flags in the previous CHALLENGE
844 * message, and only correlates with "Negotiate Unicode", "Workstation
845 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
846 * those don't make sense as flags to use to determine this.
848 * So we check all of the descriptors to figure out where the data
849 * area begins, and if the session key or the flags would be in the
850 * middle of the data area, we assume the field in question is
854 /* Lan Manager response */
855 data_start = tvb_get_letohl(tvb, offset+4);
856 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
857 hf_ntlmssp_auth_lmresponse,
859 conv_ntlmssp_info == NULL ? NULL :
860 &conv_ntlmssp_info->lm_response);
861 data_end = MAX(data_end, item_end);
864 item_start = tvb_get_letohl(tvb, offset+4);
865 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
866 hf_ntlmssp_auth_ntresponse,
868 conv_ntlmssp_info == NULL ? NULL :
869 &conv_ntlmssp_info->ntlm_response);
870 data_start = MIN(data_start, item_start);
871 data_end = MAX(data_end, item_end);
874 item_start = tvb_get_letohl(tvb, offset+4);
875 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
877 hf_ntlmssp_auth_domain,
878 &item_start, &item_end);
879 data_start = MIN(data_start, item_start);
880 data_end = MAX(data_end, item_end);
883 item_start = tvb_get_letohl(tvb, offset+4);
884 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
886 hf_ntlmssp_auth_username,
887 &item_start, &item_end);
888 data_start = MIN(data_start, item_start);
889 data_end = MAX(data_end, item_end);
892 item_start = tvb_get_letohl(tvb, offset+4);
893 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
895 hf_ntlmssp_auth_hostname,
896 &item_start, &item_end);
897 data_start = MIN(data_start, item_start);
898 data_end = MAX(data_end, item_end);
900 if (offset < data_start) {
902 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
903 hf_ntlmssp_auth_sesskey,
905 data_end = MAX(data_end, item_end);
908 if (offset < data_start) {
909 /* NTLMSSP Negotiate Flags */
910 negotiate_flags = tvb_get_letohl (tvb, offset);
911 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
915 return MAX(offset, data_end);
919 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
921 guint32 ntlmssp_message_type;
922 volatile int offset = 0;
923 proto_tree *volatile ntlmssp_tree = NULL;
924 proto_item *tf = NULL;
926 /* Setup a new tree for the NTLMSSP payload */
928 tf = proto_tree_add_item (tree,
930 tvb, offset, -1, FALSE);
932 ntlmssp_tree = proto_item_add_subtree (tf,
937 * Catch the ReportedBoundsError exception; the stuff we've been
938 * handed doesn't necessarily run to the end of the packet, it's
939 * an item inside a packet, so if it happens to be malformed (or
940 * we, or a dissector we call, has a bug), so that an exception
941 * is thrown, we want to report the error, but return and let
942 * our caller dissect the rest of the packet.
944 * If it gets a BoundsError, we can stop, as there's nothing more
945 * in the packet after our blob to see, so we just re-throw the
949 /* NTLMSSP constant */
950 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
951 tvb, offset, 8, FALSE);
954 /* NTLMSSP Message Type */
955 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
956 tvb, offset, 4, TRUE);
957 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
960 if (check_col(pinfo->cinfo, COL_INFO))
961 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
962 val_to_str(ntlmssp_message_type,
963 ntlmssp_message_types,
964 "Unknown message type"));
966 /* Call the appropriate dissector based on the Message Type */
967 switch (ntlmssp_message_type) {
969 case NTLMSSP_NEGOTIATE:
970 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
973 case NTLMSSP_CHALLENGE:
974 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
978 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
982 /* Unrecognized message type */
983 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
984 "Unrecognized NTLMSSP Message");
987 } CATCH(BoundsError) {
989 } CATCH(ReportedBoundsError) {
990 show_reported_bounds_error(tvb, pinfo, tree);
995 * Get the encryption state tied to this conversation. cryptpeer indicates
996 * whether to retrieve the data for peer1 or peer2.
998 static rc4_state_struct *
999 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1001 conversation_t *conversation;
1002 ntlmssp_info *conv_ntlmssp_info;
1004 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1005 pinfo->ptype, pinfo->srcport,
1006 pinfo->destport, 0);
1007 if (conversation == NULL) {
1008 /* We don't have a conversation. In this case, stop processing
1009 because we do not have enough info to decrypt the payload */
1013 /* We have a conversation, check for encryption state */
1014 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1016 if (conv_ntlmssp_info == NULL) {
1017 /* No encryption state tied to the conversation. Therefore, we
1018 cannot decrypt the payload */
1022 /* We have the encryption state in the conversation. So return the
1023 crypt state tied to the requested peer
1025 if (cryptpeer == 1) {
1026 return &conv_ntlmssp_info->rc4_state_peer1;
1028 return &conv_ntlmssp_info->rc4_state_peer2;
1036 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1039 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1040 packet_info *pinfo, proto_tree *tree)
1042 proto_tree *decr_tree = NULL;
1043 proto_item *tf = NULL;
1044 conversation_t *conversation;
1045 rc4_state_struct *rc4_state;
1046 rc4_state_struct *rc4_state_peer;
1047 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1049 ntlmssp_info *conv_ntlmssp_info = NULL;
1050 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1051 int decrypted_offset = 0;
1053 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1054 if (packet_ntlmssp_info == NULL) {
1055 /* We don't have data for this packet */
1058 if (!packet_ntlmssp_info->verifier_decrypted) {
1059 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1060 pinfo->ptype, pinfo->srcport,
1061 pinfo->destport, 0);
1062 if (conversation == NULL) {
1063 /* There is no conversation, thus no encryption state */
1067 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1069 if (conv_ntlmssp_info == NULL) {
1070 /* There is no NTLMSSP state tied to the conversation */
1073 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1074 /* The crypto sybsystem is not initialized. This means that either
1075 the conversation did not include a challenge, or we are doing
1076 something other than NTLMSSP v1 */
1080 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1081 rc4_state = get_encrypted_state(pinfo, 1);
1082 rc4_state_peer = get_encrypted_state(pinfo, 0);
1084 rc4_state = get_encrypted_state(pinfo, 0);
1085 rc4_state_peer = get_encrypted_state(pinfo, 1);
1088 if (rc4_state == NULL || rc4_state_peer == NULL) {
1089 /* There is no encryption state, so we cannot decrypt */
1093 /* Setup the buffer to decrypt to */
1094 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1095 offset, encrypted_block_length);
1097 /* Do the actual decryption of the verifier */
1098 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1099 encrypted_block_length);
1101 /* We setup a temporary buffer so we can re-encrypt the payload after
1102 decryption. This is to update the opposite peer's RC4 state */
1103 peer_block = g_malloc(encrypted_block_length);
1104 memcpy(peer_block, packet_ntlmssp_info->verifier,
1105 encrypted_block_length);
1106 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1109 /* Mark the packet as decrypted so that subsequent attempts to dissect
1110 the packet use the already decrypted payload instead of attempting
1112 packet_ntlmssp_info->verifier_decrypted = TRUE;
1115 /* Show the decrypted buffer in a new window */
1116 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1117 encrypted_block_length,
1118 encrypted_block_length);
1119 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1120 add_new_data_source(pinfo, decr_tvb,
1121 "Decrypted NTLMSSP Verifier");
1123 /* Show the decrypted payload in the tree */
1124 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1125 "Decrypted Verifier (%d byte%s)",
1126 encrypted_block_length,
1127 plurality(encrypted_block_length, "", "s"));
1128 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1130 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1131 garbage because it's some sort of nonce, or because there is a problem
1132 with the verifier decryption routine. */
1133 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1134 decr_tvb, decrypted_offset, 4, TRUE);
1135 decrypted_offset += 4;
1137 /* CRC32 of the DCE fragment data */
1138 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1139 decr_tvb, decrypted_offset, 4, TRUE);
1140 decrypted_offset += 4;
1142 /* Incrementing sequence number of DCE conversation */
1143 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1144 decr_tvb, decrypted_offset, 4, TRUE);
1145 decrypted_offset += 4;
1149 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1151 volatile int offset = 0;
1152 proto_tree *volatile ntlmssp_tree = NULL;
1153 proto_item *tf = NULL;
1154 guint32 verifier_length;
1155 guint32 encrypted_block_length;
1157 verifier_length = tvb_length_remaining (tvb, offset);
1158 encrypted_block_length = verifier_length - 4;
1160 if (encrypted_block_length < 12) {
1161 /* Don't know why this would happen, but if it does, don't even bother
1162 attempting decryption/dissection */
1163 return offset + verifier_length;
1166 /* Setup a new tree for the NTLMSSP payload */
1168 tf = proto_tree_add_item (tree,
1170 tvb, offset, -1, FALSE);
1172 ntlmssp_tree = proto_item_add_subtree (tf,
1177 * Catch the ReportedBoundsError exception; the stuff we've been
1178 * handed doesn't necessarily run to the end of the packet, it's
1179 * an item inside a packet, so if it happens to be malformed (or
1180 * we, or a dissector we call, has a bug), so that an exception
1181 * is thrown, we want to report the error, but return and let
1182 * our caller dissect the rest of the packet.
1184 * If it gets a BoundsError, we can stop, as there's nothing more
1185 * in the packet after our blob to see, so we just re-throw the
1189 /* Version number */
1190 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1191 tvb, offset, 4, TRUE);
1194 /* Encrypted body */
1195 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1196 tvb, offset, encrypted_block_length, TRUE);
1198 /* Try to decrypt */
1199 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1201 offset += encrypted_block_length;
1202 } CATCH(BoundsError) {
1204 } CATCH(ReportedBoundsError) {
1205 show_reported_bounds_error(tvb, pinfo, tree);
1212 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, int offset,
1214 dcerpc_auth_info *auth_info _U_)
1216 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1218 conversation_t *conversation;
1219 guint32 encrypted_block_length;
1220 rc4_state_struct *rc4_state;
1221 rc4_state_struct *rc4_state_peer;
1222 ntlmssp_info *conv_ntlmssp_info = NULL;
1223 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1225 encrypted_block_length = tvb_length_remaining (tvb, offset);
1227 /* Check to see if we already have state for this packet */
1228 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1229 if (packet_ntlmssp_info == NULL) {
1230 /* We don't have any packet state, so create one */
1231 packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1232 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1233 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1236 if (!packet_ntlmssp_info->payload_decrypted) {
1237 /* Pull the challenge info from the conversation */
1238 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1239 pinfo->ptype, pinfo->srcport,
1240 pinfo->destport, 0);
1241 if (conversation == NULL) {
1242 /* There is no conversation, thus no encryption state */
1246 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1248 if (conv_ntlmssp_info == NULL) {
1249 /* There is no NTLMSSP state tied to the conversation */
1253 /* Get the pair of RC4 state structures. One is used for to decrypt the
1254 payload. The other is used to re-encrypt the payload to represent
1256 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1257 rc4_state = get_encrypted_state(pinfo, 1);
1258 rc4_state_peer = get_encrypted_state(pinfo, 0);
1260 rc4_state = get_encrypted_state(pinfo, 0);
1261 rc4_state_peer = get_encrypted_state(pinfo, 1);
1264 if (rc4_state == NULL || rc4_state_peer == NULL) {
1265 /* There is no encryption state, so we cannot decrypt */
1269 /* Store the decrypted contents in the packet state struct
1270 (of course at this point, they aren't decrypted yet) */
1271 packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
1272 encrypted_block_length);
1273 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1274 packet_ntlmssp_info->decrypted_payload);
1276 /* Do the decryption of the payload */
1277 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1278 encrypted_block_length);
1280 /* We setup a temporary buffer so we can re-encrypt the payload after
1281 decryption. This is to update the opposite peer's RC4 state */
1282 peer_block = g_malloc(encrypted_block_length);
1283 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1284 encrypted_block_length);
1285 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1288 packet_ntlmssp_info->payload_decrypted = TRUE;
1291 /* Show the decrypted buffer in a new window */
1292 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1293 encrypted_block_length,
1294 encrypted_block_length);
1296 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1298 offset += encrypted_block_length;
1304 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1306 g_free(decrypted_payload);
1310 ntlmssp_init_protocol(void)
1312 if (ntlmssp_info_chunk != NULL)
1313 g_mem_chunk_destroy(ntlmssp_info_chunk);
1314 if (ntlmssp_packet_info_chunk != NULL)
1315 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1318 * Free the decrypted payloads, and then free the list of decrypted
1321 if (decrypted_payloads != NULL) {
1322 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1323 g_slist_free(decrypted_payloads);
1324 decrypted_payloads = NULL;
1327 ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1328 sizeof(ntlmssp_info),
1329 ntlmssp_info_count * sizeof(ntlmssp_info),
1331 ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1332 sizeof(ntlmssp_packet_info),
1333 ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1338 proto_register_ntlmssp(void)
1341 static hf_register_info hf[] = {
1343 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1346 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1348 { &hf_ntlmssp_message_type,
1349 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1351 { &hf_ntlmssp_negotiate_flags,
1352 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1353 { &hf_ntlmssp_negotiate_flags_01,
1355 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1356 { &hf_ntlmssp_negotiate_flags_02,
1357 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1358 { &hf_ntlmssp_negotiate_flags_04,
1359 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1360 { &hf_ntlmssp_negotiate_flags_08,
1361 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1362 { &hf_ntlmssp_negotiate_flags_10,
1363 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1364 { &hf_ntlmssp_negotiate_flags_20,
1365 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1366 { &hf_ntlmssp_negotiate_flags_40,
1367 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1368 { &hf_ntlmssp_negotiate_flags_80,
1369 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1370 { &hf_ntlmssp_negotiate_flags_100,
1371 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1372 { &hf_ntlmssp_negotiate_flags_200,
1373 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1374 { &hf_ntlmssp_negotiate_flags_400,
1375 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1376 { &hf_ntlmssp_negotiate_flags_800,
1377 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1378 { &hf_ntlmssp_negotiate_flags_1000,
1379 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1380 { &hf_ntlmssp_negotiate_flags_2000,
1381 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1382 { &hf_ntlmssp_negotiate_flags_4000,
1383 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1384 { &hf_ntlmssp_negotiate_flags_8000,
1385 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1386 { &hf_ntlmssp_negotiate_flags_10000,
1387 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1388 { &hf_ntlmssp_negotiate_flags_20000,
1389 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1390 { &hf_ntlmssp_negotiate_flags_40000,
1391 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1392 { &hf_ntlmssp_negotiate_flags_80000,
1393 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1394 { &hf_ntlmssp_negotiate_flags_100000,
1395 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1396 { &hf_ntlmssp_negotiate_flags_200000,
1397 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1398 { &hf_ntlmssp_negotiate_flags_400000,
1399 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1400 { &hf_ntlmssp_negotiate_flags_800000,
1401 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1402 { &hf_ntlmssp_negotiate_flags_1000000,
1403 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1404 { &hf_ntlmssp_negotiate_flags_2000000,
1405 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1406 { &hf_ntlmssp_negotiate_flags_4000000,
1407 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1408 { &hf_ntlmssp_negotiate_flags_8000000,
1409 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1410 { &hf_ntlmssp_negotiate_flags_10000000,
1411 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1412 { &hf_ntlmssp_negotiate_flags_20000000,
1413 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
1414 { &hf_ntlmssp_negotiate_flags_40000000,
1415 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1416 { &hf_ntlmssp_negotiate_flags_80000000,
1417 { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
1418 { &hf_ntlmssp_negotiate_workstation_strlen,
1419 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1420 { &hf_ntlmssp_negotiate_workstation_maxlen,
1421 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1422 { &hf_ntlmssp_negotiate_workstation_buffer,
1423 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1424 { &hf_ntlmssp_negotiate_workstation,
1425 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1426 { &hf_ntlmssp_negotiate_domain_strlen,
1427 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1428 { &hf_ntlmssp_negotiate_domain_maxlen,
1429 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1430 { &hf_ntlmssp_negotiate_domain_buffer,
1431 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1432 { &hf_ntlmssp_negotiate_domain,
1433 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1434 { &hf_ntlmssp_ntlm_challenge,
1435 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1436 { &hf_ntlmssp_reserved,
1437 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1438 { &hf_ntlmssp_challenge_domain,
1439 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1440 { &hf_ntlmssp_auth_domain,
1441 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1442 { &hf_ntlmssp_auth_username,
1443 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1444 { &hf_ntlmssp_auth_hostname,
1445 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1446 { &hf_ntlmssp_auth_lmresponse,
1447 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1448 { &hf_ntlmssp_auth_ntresponse,
1449 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1450 { &hf_ntlmssp_auth_sesskey,
1451 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1452 { &hf_ntlmssp_string_len,
1453 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1454 { &hf_ntlmssp_string_maxlen,
1455 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1456 { &hf_ntlmssp_string_offset,
1457 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1458 { &hf_ntlmssp_blob_len,
1459 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1460 { &hf_ntlmssp_blob_maxlen,
1461 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1462 { &hf_ntlmssp_blob_offset,
1463 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1464 { &hf_ntlmssp_address_list,
1465 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1466 { &hf_ntlmssp_address_list_len,
1467 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1468 { &hf_ntlmssp_address_list_maxlen,
1469 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1470 { &hf_ntlmssp_address_list_offset,
1471 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1472 { &hf_ntlmssp_address_list_item_type,
1473 { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, "", HFILL }},
1474 { &hf_ntlmssp_address_list_item_len,
1475 { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1476 { &hf_ntlmssp_address_list_item_content,
1477 { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1478 { &hf_ntlmssp_address_list_server_nb,
1479 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1480 { &hf_ntlmssp_address_list_domain_nb,
1481 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1482 { &hf_ntlmssp_address_list_server_dns,
1483 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1484 { &hf_ntlmssp_address_list_domain_dns,
1485 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1486 { &hf_ntlmssp_address_list_terminator,
1487 { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
1489 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1490 { &hf_ntlmssp_verf_vers,
1491 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1492 { &hf_ntlmssp_verf_body,
1493 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1494 { &hf_ntlmssp_decrypted_payload,
1495 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1496 { &hf_ntlmssp_verf_unknown1,
1497 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1498 { &hf_ntlmssp_verf_crc32,
1499 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1500 { &hf_ntlmssp_verf_sequence,
1501 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1505 static gint *ett[] = {
1507 &ett_ntlmssp_negotiate_flags,
1508 &ett_ntlmssp_string,
1510 &ett_ntlmssp_address_list,
1511 &ett_ntlmssp_address_list_item
1513 module_t *ntlmssp_module;
1515 proto_ntlmssp = proto_register_protocol (
1516 "NTLM Secure Service Provider", /* name */
1517 "NTLMSSP", /* short name */
1518 "ntlmssp" /* abbrev */
1520 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1521 proto_register_subtree_array (ett, array_length (ett));
1522 register_init_routine(&ntlmssp_init_protocol);
1524 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1526 prefs_register_string_preference(ntlmssp_module, "nt_password",
1528 "NT Password (used to decrypt payloads)",
1531 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1532 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1535 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
1536 proto_tree *tree, guint8 *drep _U_)
1540 auth_tvb = tvb_new_subset(
1541 tvb, offset, tvb_length_remaining(tvb, offset),
1542 tvb_length_remaining(tvb, offset));
1544 dissect_ntlmssp(auth_tvb, pinfo, tree);
1546 return tvb_length_remaining(tvb, offset);
1549 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
1550 proto_tree *tree, guint8 *drep _U_)
1554 auth_tvb = tvb_new_subset(
1555 tvb, offset, tvb_length_remaining(tvb, offset),
1556 tvb_length_remaining(tvb, offset));
1558 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
1561 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
1562 wrap_dissect_ntlmssp, /* Bind */
1563 wrap_dissect_ntlmssp, /* Bind ACK */
1564 wrap_dissect_ntlmssp, /* AUTH3 */
1565 wrap_dissect_ntlmssp_verf, /* Request verifier */
1566 wrap_dissect_ntlmssp_verf, /* Response verifier */
1567 NULL, /* Request data */
1568 NULL /* Response data */
1571 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
1572 wrap_dissect_ntlmssp, /* Bind */
1573 wrap_dissect_ntlmssp, /* Bind ACK */
1574 wrap_dissect_ntlmssp, /* AUTH3 */
1575 wrap_dissect_ntlmssp_verf, /* Request verifier */
1576 wrap_dissect_ntlmssp_verf, /* Response verifier */
1577 dissect_ntlmssp_encrypted_payload, /* Request data */
1578 dissect_ntlmssp_encrypted_payload /* Response data */
1582 proto_reg_handoff_ntlmssp(void)
1584 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1586 /* Register protocol with the GSS-API module */
1588 ntlmssp_handle = find_dissector("ntlmssp");
1589 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1590 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1591 ntlmssp_handle, ntlmssp_wrap_handle,
1592 "NTLMSSP - Microsoft NTLM Security Support Provider");
1594 /* Register authenticated pipe dissector */
1597 * XXX - the verifiers here seem to have a version of 1 and a body of all
1600 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
1601 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
1602 * any other levels here?
1604 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
1605 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1608 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1609 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1612 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1613 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,