2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
4 * Copyright 2003, Tim Potter <tpot@samba.org>
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 {
195 rc4_state_struct rc4_state_peer1;
196 rc4_state_struct rc4_state_peer2;
197 guint32 peer1_dest_port;
198 int rc4_state_initialized;
199 ntlmssp_blob ntlm_response;
200 ntlmssp_blob lm_response;
204 * GMemChunk from which ntlmssp_info structures are allocated.
206 static GMemChunk *ntlmssp_info_chunk;
207 static int ntlmssp_info_count = 10;
209 /* If this struct exists in the payload_decrypt, then we have already
211 typedef struct _ntlmssp_packet_info {
213 guint8 *decrypted_payload;
215 gboolean payload_decrypted;
216 gboolean verifier_decrypted;
217 } ntlmssp_packet_info;
220 * GMemChunk from which ntlmssp_packet_info structures are allocated.
222 static GMemChunk *ntlmssp_packet_info_chunk;
223 static int ntlmssp_packet_info_count = 10;
226 * GSlist of decrypted payloads.
228 static GSList *decrypted_payloads;
231 Generate a challenge response, given an eight byte challenge and
232 either the NT or the Lan Manager password hash (16 bytes).
233 Returns output in response, which is expected to be 24 bytes.
235 static int ntlmssp_generate_challenge_response(guint8 *response,
236 const guint8 *passhash,
237 const guint8 *challenge)
239 guint8 pw21[21]; /* Password hash padded to 21 bytes */
241 memset(pw21, 0x0, sizeof(pw21));
242 memcpy(pw21, passhash, 16);
244 memset(response, 0, 24);
246 crypt_des_ecb(response, challenge, pw21, 1);
247 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
248 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
253 /* Create an NTLMSSP version 1 key.
254 * password points to the ANSI password to encrypt, challenge points to
255 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
256 * otherwise it will do a 40 bit key. The result is stored in
257 * sspkey (expected to be 16 octets)
260 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge,
261 int use_key_128, guint8 *sspkey)
263 unsigned char lm_password_upper[16];
264 unsigned char lm_password_hash[16];
265 guint8 lm_challenge_response[24];
267 guint8 pw21[21]; /* Password hash padded to 21 bytes */
270 unsigned char lmhash_key[] =
271 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
273 memset(lm_password_upper, 0, sizeof(lm_password_upper));
275 /* Create a Lan Manager hash of the input password */
276 if (nt_password[0] != '\0') {
277 password_len = strlen(nt_password);
278 /* Truncate password if too long */
279 if (password_len > 16)
281 for (i = 0; i < password_len; i++) {
282 lm_password_upper[i] = toupper(nt_password[i]);
286 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
287 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
289 /* Generate the LanMan Challenge Response */
290 ntlmssp_generate_challenge_response(lm_challenge_response,
291 lm_password_hash, challenge);
293 /* Generate the NTLMSSP-v1 RC4 Key.
294 * The RC4 key is derived from the Lan Manager Hash.
295 * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
297 memset(pw21, 0xBD, sizeof(pw21));
298 memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
300 /* Only the first eight bytes of challenge_response is used */
301 crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
302 crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
303 crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
305 /* Create the SSP Key */
306 memset(sspkey, 0, sizeof(sspkey));
308 /* Create 128 bit key */
309 memcpy(sspkey, rc4key, 16);
312 /* Create 40 bit key */
313 memcpy(sspkey, rc4key, 5);
321 /* dissect a string - header area contains:
324 four byte offset of string in data area
325 The function returns the offset at the end of the string header,
326 but the 'end' parameter returns the offset of the end of the string itself
327 The 'start' parameter returns the offset of the beginning of the string
330 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
331 proto_tree *ntlmssp_tree,
332 gboolean unicode_strings,
333 int string_hf, int *start, int *end)
335 proto_tree *tree = NULL;
336 proto_item *tf = NULL;
337 gint16 string_length = tvb_get_letohs(tvb, offset);
338 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
339 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
340 const char *string_text = NULL;
344 *start = (string_offset > offset+8 ? string_offset : offset+8);
345 if (0 == string_length) {
348 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
353 bc = result_length = string_length;
354 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
355 unicode_strings, &result_length,
359 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
360 string_offset, result_length, string_text);
361 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
363 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
364 tvb, offset, 2, string_length);
366 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
367 tvb, offset, 2, string_maxlen);
369 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
370 tvb, offset, 4, string_offset);
373 *end = string_offset + string_length;
377 /* dissect a generic blob - header area contains:
380 four byte offset of blob in data area
381 The function returns the offset at the end of the blob header,
382 but the 'end' parameter returns the offset of the end of the blob itself
385 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
386 proto_tree *ntlmssp_tree,
387 int blob_hf, int *end, ntlmssp_blob *result)
389 proto_item *tf = NULL;
390 proto_tree *tree = NULL;
391 guint16 blob_length = tvb_get_letohs(tvb, offset);
392 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
393 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
395 if (0 == blob_length) {
396 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
398 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
399 proto_registrar_get_name(blob_hf));
404 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
405 blob_offset, blob_length, FALSE);
406 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
408 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
409 tvb, offset, 2, blob_length);
411 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
412 tvb, offset, 2, blob_maxlen);
414 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
415 tvb, offset, 4, blob_offset);
418 *end = blob_offset + blob_length;
420 if (result != NULL) {
421 result->length = blob_length;
422 memset(result->contents, 0, MAX_BLOB_SIZE);
423 if (blob_length < MAX_BLOB_SIZE)
424 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
427 /* If we are dissecting the NTLM response and it is a NTLMv2
428 response call the appropriate dissector. */
430 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
431 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
437 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
438 proto_tree *ntlmssp_tree,
439 guint32 negotiate_flags)
441 proto_tree *negotiate_flags_tree = NULL;
442 proto_item *tf = NULL;
445 tf = proto_tree_add_uint (ntlmssp_tree,
446 hf_ntlmssp_negotiate_flags,
447 tvb, offset, 4, negotiate_flags);
448 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
451 proto_tree_add_boolean (negotiate_flags_tree,
452 hf_ntlmssp_negotiate_flags_80000000,
453 tvb, offset, 4, negotiate_flags);
454 proto_tree_add_boolean (negotiate_flags_tree,
455 hf_ntlmssp_negotiate_flags_40000000,
456 tvb, offset, 4, negotiate_flags);
457 proto_tree_add_boolean (negotiate_flags_tree,
458 hf_ntlmssp_negotiate_flags_20000000,
459 tvb, offset, 4, negotiate_flags);
460 proto_tree_add_boolean (negotiate_flags_tree,
461 hf_ntlmssp_negotiate_flags_10000000,
462 tvb, offset, 4, negotiate_flags);
463 proto_tree_add_boolean (negotiate_flags_tree,
464 hf_ntlmssp_negotiate_flags_8000000,
465 tvb, offset, 4, negotiate_flags);
466 proto_tree_add_boolean (negotiate_flags_tree,
467 hf_ntlmssp_negotiate_flags_4000000,
468 tvb, offset, 4, negotiate_flags);
469 proto_tree_add_boolean (negotiate_flags_tree,
470 hf_ntlmssp_negotiate_flags_2000000,
471 tvb, offset, 4, negotiate_flags);
472 proto_tree_add_boolean (negotiate_flags_tree,
473 hf_ntlmssp_negotiate_flags_1000000,
474 tvb, offset, 4, negotiate_flags);
475 proto_tree_add_boolean (negotiate_flags_tree,
476 hf_ntlmssp_negotiate_flags_800000,
477 tvb, offset, 4, negotiate_flags);
478 proto_tree_add_boolean (negotiate_flags_tree,
479 hf_ntlmssp_negotiate_flags_400000,
480 tvb, offset, 4, negotiate_flags);
481 proto_tree_add_boolean (negotiate_flags_tree,
482 hf_ntlmssp_negotiate_flags_200000,
483 tvb, offset, 4, negotiate_flags);
484 proto_tree_add_boolean (negotiate_flags_tree,
485 hf_ntlmssp_negotiate_flags_100000,
486 tvb, offset, 4, negotiate_flags);
487 proto_tree_add_boolean (negotiate_flags_tree,
488 hf_ntlmssp_negotiate_flags_80000,
489 tvb, offset, 4, negotiate_flags);
490 proto_tree_add_boolean (negotiate_flags_tree,
491 hf_ntlmssp_negotiate_flags_40000,
492 tvb, offset, 4, negotiate_flags);
493 proto_tree_add_boolean (negotiate_flags_tree,
494 hf_ntlmssp_negotiate_flags_20000,
495 tvb, offset, 4, negotiate_flags);
496 proto_tree_add_boolean (negotiate_flags_tree,
497 hf_ntlmssp_negotiate_flags_10000,
498 tvb, offset, 4, negotiate_flags);
499 proto_tree_add_boolean (negotiate_flags_tree,
500 hf_ntlmssp_negotiate_flags_8000,
501 tvb, offset, 4, negotiate_flags);
502 proto_tree_add_boolean (negotiate_flags_tree,
503 hf_ntlmssp_negotiate_flags_4000,
504 tvb, offset, 4, negotiate_flags);
505 proto_tree_add_boolean (negotiate_flags_tree,
506 hf_ntlmssp_negotiate_flags_2000,
507 tvb, offset, 4, negotiate_flags);
508 proto_tree_add_boolean (negotiate_flags_tree,
509 hf_ntlmssp_negotiate_flags_1000,
510 tvb, offset, 4, negotiate_flags);
511 proto_tree_add_boolean (negotiate_flags_tree,
512 hf_ntlmssp_negotiate_flags_800,
513 tvb, offset, 4, negotiate_flags);
514 proto_tree_add_boolean (negotiate_flags_tree,
515 hf_ntlmssp_negotiate_flags_400,
516 tvb, offset, 4, negotiate_flags);
517 proto_tree_add_boolean (negotiate_flags_tree,
518 hf_ntlmssp_negotiate_flags_200,
519 tvb, offset, 4, negotiate_flags);
520 proto_tree_add_boolean (negotiate_flags_tree,
521 hf_ntlmssp_negotiate_flags_100,
522 tvb, offset, 4, negotiate_flags);
523 proto_tree_add_boolean (negotiate_flags_tree,
524 hf_ntlmssp_negotiate_flags_80,
525 tvb, offset, 4, negotiate_flags);
526 proto_tree_add_boolean (negotiate_flags_tree,
527 hf_ntlmssp_negotiate_flags_40,
528 tvb, offset, 4, negotiate_flags);
529 proto_tree_add_boolean (negotiate_flags_tree,
530 hf_ntlmssp_negotiate_flags_20,
531 tvb, offset, 4, negotiate_flags);
532 proto_tree_add_boolean (negotiate_flags_tree,
533 hf_ntlmssp_negotiate_flags_10,
534 tvb, offset, 4, negotiate_flags);
535 proto_tree_add_boolean (negotiate_flags_tree,
536 hf_ntlmssp_negotiate_flags_08,
537 tvb, offset, 4, negotiate_flags);
538 proto_tree_add_boolean (negotiate_flags_tree,
539 hf_ntlmssp_negotiate_flags_04,
540 tvb, offset, 4, negotiate_flags);
541 proto_tree_add_boolean (negotiate_flags_tree,
542 hf_ntlmssp_negotiate_flags_02,
543 tvb, offset, 4, negotiate_flags);
544 proto_tree_add_boolean (negotiate_flags_tree,
545 hf_ntlmssp_negotiate_flags_01,
546 tvb, offset, 4, negotiate_flags);
553 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
555 guint32 negotiate_flags;
560 /* NTLMSSP Negotiate Flags */
561 negotiate_flags = tvb_get_letohl (tvb, offset);
562 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
565 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
566 hf_ntlmssp_negotiate_domain,
567 &start, &workstation_end);
568 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
569 hf_ntlmssp_negotiate_workstation,
570 &start, &domain_end);
572 /* XXX - two blobs after this one, sometimes? */
574 return MAX(workstation_end, domain_end);
579 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
580 proto_tree *ntlmssp_tree,
583 guint16 list_length = tvb_get_letohs(tvb, offset);
584 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
585 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
586 guint16 item_type, item_length;
588 proto_item *tf = NULL;
589 proto_tree *tree = NULL;
590 proto_item *addr_tf = NULL;
591 proto_tree *addr_tree = NULL;
593 /* the address list is just a blob */
594 if (0 == list_length) {
595 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
597 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
598 "Address List: Empty");
603 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
604 list_offset, list_length, FALSE);
605 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
607 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
608 tvb, offset, 2, list_length);
610 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
611 tvb, offset, 2, list_maxlen);
613 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
614 tvb, offset, 4, list_offset);
617 /* Now enumerate through the individual items in the list */
618 item_offset = list_offset;
620 while (item_offset < (list_offset + list_length)) {
621 const char *text=NULL;
622 guint32 content_offset;
623 guint16 content_length;
628 type_offset = item_offset;
629 item_type = tvb_get_letohs(tvb, type_offset);
632 len_offset = type_offset + 2;
633 content_length = tvb_get_letohs(tvb, len_offset);
636 content_offset = len_offset + 2;
637 item_length = content_length + 4;
639 /* Strings are always in unicode regardless of the negotiated
641 if (content_length > 0) {
646 item_offset_int = content_offset;
648 text = get_unicode_or_ascii_string(tvb, &item_offset_int,
649 TRUE, &result_length,
653 if (!text) text = ""; /* Make sure we don't blow up below */
656 case NTLM_NAME_NB_HOST:
657 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
658 tvb, item_offset, item_length, text);
660 case NTLM_NAME_NB_DOMAIN:
661 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
662 tvb, item_offset, item_length, text);
664 case NTLM_NAME_DNS_HOST:
665 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
666 tvb, item_offset, item_length, text);
668 case NTLM_NAME_DNS_DOMAIN:
669 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
670 tvb, item_offset, item_length, text);
673 addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
674 tvb, item_offset, item_length, TRUE);
677 /* Now show the actual bytes that made up the summary line */
678 addr_tree = proto_item_add_subtree (addr_tf,
679 ett_ntlmssp_address_list_item);
680 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
681 tvb, type_offset, 2, TRUE);
682 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
683 tvb, len_offset, 2, TRUE);
684 if (content_length > 0) {
685 proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
686 tvb, content_offset, content_length, text);
689 item_offset += item_length;
692 *end = list_offset + list_length;
697 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
698 proto_tree *ntlmssp_tree)
700 guint32 negotiate_flags;
701 int item_start, item_end;
702 int data_start, data_end;
703 ntlmssp_info *conv_ntlmssp_info;
704 conversation_t *conversation;
705 gboolean unicode_strings = FALSE;
707 guint8 sspkey[16]; /* NTLMSSP cipher key */
708 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
710 /* need to find unicode flag */
711 negotiate_flags = tvb_get_letohl (tvb, offset+8);
712 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
713 unicode_strings = TRUE;
716 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
717 hf_ntlmssp_challenge_domain,
718 &item_start, &item_end);
719 data_start = item_start;
722 /* NTLMSSP Negotiate Flags */
723 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
726 /* NTLMSSP NT Lan Manager Challenge */
727 proto_tree_add_item (ntlmssp_tree,
728 hf_ntlmssp_ntlm_challenge,
729 tvb, offset, 8, FALSE);
732 * Store the flags and the RC4 state information with the conversation,
733 * as they're needed in order to dissect subsequent messages.
735 conversation = find_conversation(&pinfo->src, &pinfo->dst,
736 pinfo->ptype, pinfo->srcport,
738 if (!conversation) { /* Create one */
739 conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype,
740 pinfo->srcport, pinfo->destport, 0);
743 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
744 conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
745 /* Insert the flags into the conversation */
746 conv_ntlmssp_info->flags = negotiate_flags;
747 /* Insert the RC4 state information into the conversation */
748 tvb_memcpy(tvb, challenge, offset, 8);
750 /* Between the challenge and the user provided password, we can build the
751 NTLMSSP key and initialize the cipher */
752 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
753 create_ntlmssp_v1_key(nt_password, challenge, 1, sspkey);
757 create_ntlmssp_v1_key(nt_password, challenge, 0, sspkey);
760 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
761 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
762 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
763 conv_ntlmssp_info->rc4_state_initialized = 1;
765 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
769 /* Reserved (function not completely known) */
771 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
772 tvb, offset, 8, FALSE);
776 * The presence or absence of this field is not obviously correlated
777 * with any flags in the previous NEGOTIATE message or in this
778 * message (other than the "Workstation Supplied" and "Domain
779 * Supplied" flags in the NEGOTIATE message, at least in the capture
780 * I've seen - but those also correlate with the presence of workstation
781 * and domain name fields, so it doesn't seem to make sense that they
782 * actually *indicate* whether the subsequent CHALLENGE has an
785 if (offset < data_start) {
786 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
787 data_end = MAX(data_end, item_end);
790 return MAX(offset, data_end);
794 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
795 proto_tree *ntlmssp_tree)
797 int item_start, item_end;
798 int data_start, data_end = 0;
799 guint32 negotiate_flags;
800 gboolean unicode_strings = FALSE;
801 ntlmssp_info *conv_ntlmssp_info;
802 conversation_t *conversation;
805 * Get flag info from the original negotiate message, if any.
806 * This is because the flag information is sometimes missing from
807 * the AUTHENTICATE message, so we can't figure out whether
808 * strings are Unicode or not by looking at *our* flags.
810 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
811 if (conv_ntlmssp_info == NULL) {
813 * There isn't any. Is there any from this conversation? If so,
814 * it means this is the first time we've dissected this frame, so
815 * we should give it flag info.
817 conversation = find_conversation(&pinfo->src, &pinfo->dst,
818 pinfo->ptype, pinfo->srcport,
820 if (conversation != NULL) {
821 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
822 if (conv_ntlmssp_info != NULL) {
824 * We have flag info; attach it to the frame.
826 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
830 if (conv_ntlmssp_info != NULL) {
831 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
832 unicode_strings = TRUE;
836 * Sometimes the session key and flags are missing.
837 * Sometimes the session key is present but the flags are missing.
838 * Sometimes they're both present.
840 * This does not correlate with any flags in the previous CHALLENGE
841 * message, and only correlates with "Negotiate Unicode", "Workstation
842 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
843 * those don't make sense as flags to use to determine this.
845 * So we check all of the descriptors to figure out where the data
846 * area begins, and if the session key or the flags would be in the
847 * middle of the data area, we assume the field in question is
851 /* Lan Manager response */
852 data_start = tvb_get_letohl(tvb, offset+4);
853 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
854 hf_ntlmssp_auth_lmresponse,
856 conv_ntlmssp_info == NULL ? NULL :
857 &conv_ntlmssp_info->lm_response);
858 data_end = MAX(data_end, item_end);
861 item_start = tvb_get_letohl(tvb, offset+4);
862 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
863 hf_ntlmssp_auth_ntresponse,
865 conv_ntlmssp_info == NULL ? NULL :
866 &conv_ntlmssp_info->ntlm_response);
867 data_start = MIN(data_start, item_start);
868 data_end = MAX(data_end, item_end);
871 item_start = tvb_get_letohl(tvb, offset+4);
872 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
874 hf_ntlmssp_auth_domain,
875 &item_start, &item_end);
876 data_start = MIN(data_start, item_start);
877 data_end = MAX(data_end, item_end);
880 item_start = tvb_get_letohl(tvb, offset+4);
881 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
883 hf_ntlmssp_auth_username,
884 &item_start, &item_end);
885 data_start = MIN(data_start, item_start);
886 data_end = MAX(data_end, item_end);
889 item_start = tvb_get_letohl(tvb, offset+4);
890 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
892 hf_ntlmssp_auth_hostname,
893 &item_start, &item_end);
894 data_start = MIN(data_start, item_start);
895 data_end = MAX(data_end, item_end);
897 if (offset < data_start) {
899 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
900 hf_ntlmssp_auth_sesskey,
902 data_end = MAX(data_end, item_end);
905 if (offset < data_start) {
906 /* NTLMSSP Negotiate Flags */
907 negotiate_flags = tvb_get_letohl (tvb, offset);
908 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
912 return MAX(offset, data_end);
916 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
918 guint32 ntlmssp_message_type;
919 volatile int offset = 0;
920 proto_tree *volatile ntlmssp_tree = NULL;
921 proto_item *tf = NULL;
923 /* Setup a new tree for the NTLMSSP payload */
925 tf = proto_tree_add_item (tree,
927 tvb, offset, -1, FALSE);
929 ntlmssp_tree = proto_item_add_subtree (tf,
934 * Catch the ReportedBoundsError exception; the stuff we've been
935 * handed doesn't necessarily run to the end of the packet, it's
936 * an item inside a packet, so if it happens to be malformed (or
937 * we, or a dissector we call, has a bug), so that an exception
938 * is thrown, we want to report the error, but return and let
939 * our caller dissect the rest of the packet.
941 * If it gets a BoundsError, we can stop, as there's nothing more
942 * in the packet after our blob to see, so we just re-throw the
946 /* NTLMSSP constant */
947 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
948 tvb, offset, 8, FALSE);
951 /* NTLMSSP Message Type */
952 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
953 tvb, offset, 4, TRUE);
954 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
957 if (check_col(pinfo->cinfo, COL_INFO))
958 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
959 val_to_str(ntlmssp_message_type,
960 ntlmssp_message_types,
961 "Unknown message type"));
963 /* Call the appropriate dissector based on the Message Type */
964 switch (ntlmssp_message_type) {
966 case NTLMSSP_NEGOTIATE:
967 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
970 case NTLMSSP_CHALLENGE:
971 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
975 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
979 /* Unrecognized message type */
980 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
981 "Unrecognized NTLMSSP Message");
984 } CATCH(BoundsError) {
986 } CATCH(ReportedBoundsError) {
987 show_reported_bounds_error(tvb, pinfo, tree);
992 * Get the encryption state tied to this conversation. cryptpeer indicates
993 * whether to retrieve the data for peer1 or peer2.
995 static rc4_state_struct *
996 get_encrypted_state(packet_info *pinfo, int cryptpeer)
998 conversation_t *conversation;
999 ntlmssp_info *conv_ntlmssp_info;
1001 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1002 pinfo->ptype, pinfo->srcport,
1003 pinfo->destport, 0);
1004 if (conversation == NULL) {
1005 /* We don't have a conversation. In this case, stop processing
1006 because we do not have enough info to decrypt the payload */
1010 /* We have a conversation, check for encryption state */
1011 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1013 if (conv_ntlmssp_info == NULL) {
1014 /* No encryption state tied to the conversation. Therefore, we
1015 cannot decrypt the payload */
1019 /* We have the encryption state in the conversation. So return the
1020 crypt state tied to the requested peer
1022 if (cryptpeer == 1) {
1023 return &conv_ntlmssp_info->rc4_state_peer1;
1025 return &conv_ntlmssp_info->rc4_state_peer2;
1033 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1036 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1037 packet_info *pinfo, proto_tree *tree)
1039 proto_tree *decr_tree = NULL;
1040 proto_item *tf = NULL;
1041 conversation_t *conversation;
1042 rc4_state_struct *rc4_state;
1043 rc4_state_struct *rc4_state_peer;
1044 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1046 ntlmssp_info *conv_ntlmssp_info = NULL;
1047 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1048 int decrypted_offset = 0;
1050 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1051 if (packet_ntlmssp_info == NULL) {
1052 /* We don't have data for this packet */
1055 if (!packet_ntlmssp_info->verifier_decrypted) {
1056 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1057 pinfo->ptype, pinfo->srcport,
1058 pinfo->destport, 0);
1059 if (conversation == NULL) {
1060 /* There is no conversation, thus no encryption state */
1064 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1066 if (conv_ntlmssp_info == NULL) {
1067 /* There is no NTLMSSP state tied to the conversation */
1070 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1071 /* The crypto sybsystem is not initialized. This means that either
1072 the conversation did not include a challenge, or we are doing
1073 something other than NTLMSSP v1 */
1077 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1078 rc4_state = get_encrypted_state(pinfo, 1);
1079 rc4_state_peer = get_encrypted_state(pinfo, 0);
1081 rc4_state = get_encrypted_state(pinfo, 0);
1082 rc4_state_peer = get_encrypted_state(pinfo, 1);
1085 if (rc4_state == NULL || rc4_state_peer == NULL) {
1086 /* There is no encryption state, so we cannot decrypt */
1090 /* Setup the buffer to decrypt to */
1091 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1092 offset, encrypted_block_length);
1094 /* Do the actual decryption of the verifier */
1095 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1096 encrypted_block_length);
1098 /* We setup a temporary buffer so we can re-encrypt the payload after
1099 decryption. This is to update the opposite peer's RC4 state */
1100 peer_block = g_malloc(encrypted_block_length);
1101 memcpy(peer_block, packet_ntlmssp_info->verifier,
1102 encrypted_block_length);
1103 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1106 /* Mark the packet as decrypted so that subsequent attempts to dissect
1107 the packet use the already decrypted payload instead of attempting
1109 packet_ntlmssp_info->verifier_decrypted = TRUE;
1112 /* Show the decrypted buffer in a new window */
1113 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1114 encrypted_block_length,
1115 encrypted_block_length);
1116 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1117 add_new_data_source(pinfo, decr_tvb,
1118 "Decrypted NTLMSSP Verifier");
1120 /* Show the decrypted payload in the tree */
1121 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1122 "Decrypted Verifier (%d byte%s)",
1123 encrypted_block_length,
1124 plurality(encrypted_block_length, "", "s"));
1125 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1127 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1128 garbage because it's some sort of nonce, or because there is a problem
1129 with the verifier decryption routine. */
1130 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1131 decr_tvb, decrypted_offset, 4, TRUE);
1132 decrypted_offset += 4;
1134 /* CRC32 of the DCE fragment data */
1135 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1136 decr_tvb, decrypted_offset, 4, TRUE);
1137 decrypted_offset += 4;
1139 /* Incrementing sequence number of DCE conversation */
1140 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1141 decr_tvb, decrypted_offset, 4, TRUE);
1142 decrypted_offset += 4;
1146 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1148 volatile int offset = 0;
1149 proto_tree *volatile ntlmssp_tree = NULL;
1150 proto_item *tf = NULL;
1151 guint32 verifier_length;
1152 guint32 encrypted_block_length;
1154 verifier_length = tvb_length_remaining (tvb, offset);
1155 encrypted_block_length = verifier_length - 4;
1157 if (encrypted_block_length < 12) {
1158 /* Don't know why this would happen, but if it does, don't even bother
1159 attempting decryption/dissection */
1160 return offset + verifier_length;
1163 /* Setup a new tree for the NTLMSSP payload */
1165 tf = proto_tree_add_item (tree,
1167 tvb, offset, -1, FALSE);
1169 ntlmssp_tree = proto_item_add_subtree (tf,
1174 * Catch the ReportedBoundsError exception; the stuff we've been
1175 * handed doesn't necessarily run to the end of the packet, it's
1176 * an item inside a packet, so if it happens to be malformed (or
1177 * we, or a dissector we call, has a bug), so that an exception
1178 * is thrown, we want to report the error, but return and let
1179 * our caller dissect the rest of the packet.
1181 * If it gets a BoundsError, we can stop, as there's nothing more
1182 * in the packet after our blob to see, so we just re-throw the
1186 /* Version number */
1187 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1188 tvb, offset, 4, TRUE);
1191 /* Encrypted body */
1192 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1193 tvb, offset, encrypted_block_length, TRUE);
1195 /* Try to decrypt */
1196 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1198 offset += encrypted_block_length;
1199 } CATCH(BoundsError) {
1201 } CATCH(ReportedBoundsError) {
1202 show_reported_bounds_error(tvb, pinfo, tree);
1209 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, int offset,
1211 dcerpc_auth_info *auth_info _U_)
1213 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1215 conversation_t *conversation;
1216 guint32 encrypted_block_length;
1217 rc4_state_struct *rc4_state;
1218 rc4_state_struct *rc4_state_peer;
1219 ntlmssp_info *conv_ntlmssp_info = NULL;
1220 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1222 encrypted_block_length = tvb_length_remaining (tvb, offset);
1224 /* Check to see if we already have state for this packet */
1225 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1226 if (packet_ntlmssp_info == NULL) {
1227 /* We don't have any packet state, so create one */
1228 packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1229 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1230 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1233 if (!packet_ntlmssp_info->payload_decrypted) {
1234 /* Pull the challenge info from the conversation */
1235 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1236 pinfo->ptype, pinfo->srcport,
1237 pinfo->destport, 0);
1238 if (conversation == NULL) {
1239 /* There is no conversation, thus no encryption state */
1243 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1245 if (conv_ntlmssp_info == NULL) {
1246 /* There is no NTLMSSP state tied to the conversation */
1250 /* Get the pair of RC4 state structures. One is used for to decrypt the
1251 payload. The other is used to re-encrypt the payload to represent
1253 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1254 rc4_state = get_encrypted_state(pinfo, 1);
1255 rc4_state_peer = get_encrypted_state(pinfo, 0);
1257 rc4_state = get_encrypted_state(pinfo, 0);
1258 rc4_state_peer = get_encrypted_state(pinfo, 1);
1261 if (rc4_state == NULL || rc4_state_peer == NULL) {
1262 /* There is no encryption state, so we cannot decrypt */
1266 /* Store the decrypted contents in the packet state struct
1267 (of course at this point, they aren't decrypted yet) */
1268 packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
1269 encrypted_block_length);
1270 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1271 packet_ntlmssp_info->decrypted_payload);
1273 /* Do the decryption of the payload */
1274 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1275 encrypted_block_length);
1277 /* We setup a temporary buffer so we can re-encrypt the payload after
1278 decryption. This is to update the opposite peer's RC4 state */
1279 peer_block = g_malloc(encrypted_block_length);
1280 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1281 encrypted_block_length);
1282 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1285 packet_ntlmssp_info->payload_decrypted = TRUE;
1288 /* Show the decrypted buffer in a new window */
1289 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1290 encrypted_block_length,
1291 encrypted_block_length);
1293 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1295 offset += encrypted_block_length;
1301 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1303 g_free(decrypted_payload);
1307 ntlmssp_init_protocol(void)
1309 if (ntlmssp_info_chunk != NULL)
1310 g_mem_chunk_destroy(ntlmssp_info_chunk);
1311 if (ntlmssp_packet_info_chunk != NULL)
1312 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1315 * Free the decrypted payloads, and then free the list of decrypted
1318 if (decrypted_payloads != NULL) {
1319 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1320 g_slist_free(decrypted_payloads);
1321 decrypted_payloads = NULL;
1324 ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1325 sizeof(ntlmssp_info),
1326 ntlmssp_info_count * sizeof(ntlmssp_info),
1328 ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1329 sizeof(ntlmssp_packet_info),
1330 ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1335 proto_register_ntlmssp(void)
1338 static hf_register_info hf[] = {
1340 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1343 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1345 { &hf_ntlmssp_message_type,
1346 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1348 { &hf_ntlmssp_negotiate_flags,
1349 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1350 { &hf_ntlmssp_negotiate_flags_01,
1352 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1353 { &hf_ntlmssp_negotiate_flags_02,
1354 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1355 { &hf_ntlmssp_negotiate_flags_04,
1356 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1357 { &hf_ntlmssp_negotiate_flags_08,
1358 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1359 { &hf_ntlmssp_negotiate_flags_10,
1360 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1361 { &hf_ntlmssp_negotiate_flags_20,
1362 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1363 { &hf_ntlmssp_negotiate_flags_40,
1364 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1365 { &hf_ntlmssp_negotiate_flags_80,
1366 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1367 { &hf_ntlmssp_negotiate_flags_100,
1368 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1369 { &hf_ntlmssp_negotiate_flags_200,
1370 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1371 { &hf_ntlmssp_negotiate_flags_400,
1372 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1373 { &hf_ntlmssp_negotiate_flags_800,
1374 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1375 { &hf_ntlmssp_negotiate_flags_1000,
1376 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1377 { &hf_ntlmssp_negotiate_flags_2000,
1378 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1379 { &hf_ntlmssp_negotiate_flags_4000,
1380 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1381 { &hf_ntlmssp_negotiate_flags_8000,
1382 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1383 { &hf_ntlmssp_negotiate_flags_10000,
1384 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1385 { &hf_ntlmssp_negotiate_flags_20000,
1386 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1387 { &hf_ntlmssp_negotiate_flags_40000,
1388 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1389 { &hf_ntlmssp_negotiate_flags_80000,
1390 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1391 { &hf_ntlmssp_negotiate_flags_100000,
1392 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1393 { &hf_ntlmssp_negotiate_flags_200000,
1394 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1395 { &hf_ntlmssp_negotiate_flags_400000,
1396 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1397 { &hf_ntlmssp_negotiate_flags_800000,
1398 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1399 { &hf_ntlmssp_negotiate_flags_1000000,
1400 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1401 { &hf_ntlmssp_negotiate_flags_2000000,
1402 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1403 { &hf_ntlmssp_negotiate_flags_4000000,
1404 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1405 { &hf_ntlmssp_negotiate_flags_8000000,
1406 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1407 { &hf_ntlmssp_negotiate_flags_10000000,
1408 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1409 { &hf_ntlmssp_negotiate_flags_20000000,
1410 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
1411 { &hf_ntlmssp_negotiate_flags_40000000,
1412 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1413 { &hf_ntlmssp_negotiate_flags_80000000,
1414 { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
1415 { &hf_ntlmssp_negotiate_workstation_strlen,
1416 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1417 { &hf_ntlmssp_negotiate_workstation_maxlen,
1418 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1419 { &hf_ntlmssp_negotiate_workstation_buffer,
1420 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1421 { &hf_ntlmssp_negotiate_workstation,
1422 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1423 { &hf_ntlmssp_negotiate_domain_strlen,
1424 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1425 { &hf_ntlmssp_negotiate_domain_maxlen,
1426 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1427 { &hf_ntlmssp_negotiate_domain_buffer,
1428 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1429 { &hf_ntlmssp_negotiate_domain,
1430 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1431 { &hf_ntlmssp_ntlm_challenge,
1432 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1433 { &hf_ntlmssp_reserved,
1434 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1435 { &hf_ntlmssp_challenge_domain,
1436 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1437 { &hf_ntlmssp_auth_domain,
1438 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1439 { &hf_ntlmssp_auth_username,
1440 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1441 { &hf_ntlmssp_auth_hostname,
1442 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1443 { &hf_ntlmssp_auth_lmresponse,
1444 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1445 { &hf_ntlmssp_auth_ntresponse,
1446 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1447 { &hf_ntlmssp_auth_sesskey,
1448 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1449 { &hf_ntlmssp_string_len,
1450 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1451 { &hf_ntlmssp_string_maxlen,
1452 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1453 { &hf_ntlmssp_string_offset,
1454 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1455 { &hf_ntlmssp_blob_len,
1456 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1457 { &hf_ntlmssp_blob_maxlen,
1458 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1459 { &hf_ntlmssp_blob_offset,
1460 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1461 { &hf_ntlmssp_address_list,
1462 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1463 { &hf_ntlmssp_address_list_len,
1464 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1465 { &hf_ntlmssp_address_list_maxlen,
1466 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1467 { &hf_ntlmssp_address_list_offset,
1468 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1469 { &hf_ntlmssp_address_list_item_type,
1470 { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, "", HFILL }},
1471 { &hf_ntlmssp_address_list_item_len,
1472 { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1473 { &hf_ntlmssp_address_list_item_content,
1474 { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1475 { &hf_ntlmssp_address_list_server_nb,
1476 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1477 { &hf_ntlmssp_address_list_domain_nb,
1478 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1479 { &hf_ntlmssp_address_list_server_dns,
1480 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1481 { &hf_ntlmssp_address_list_domain_dns,
1482 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1483 { &hf_ntlmssp_address_list_terminator,
1484 { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
1486 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1487 { &hf_ntlmssp_verf_vers,
1488 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1489 { &hf_ntlmssp_verf_body,
1490 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1491 { &hf_ntlmssp_decrypted_payload,
1492 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1493 { &hf_ntlmssp_verf_unknown1,
1494 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1495 { &hf_ntlmssp_verf_crc32,
1496 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1497 { &hf_ntlmssp_verf_sequence,
1498 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1502 static gint *ett[] = {
1504 &ett_ntlmssp_negotiate_flags,
1505 &ett_ntlmssp_string,
1507 &ett_ntlmssp_address_list,
1508 &ett_ntlmssp_address_list_item
1510 module_t *ntlmssp_module;
1512 proto_ntlmssp = proto_register_protocol (
1513 "NTLM Secure Service Provider", /* name */
1514 "NTLMSSP", /* short name */
1515 "ntlmssp" /* abbrev */
1517 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1518 proto_register_subtree_array (ett, array_length (ett));
1519 register_init_routine(&ntlmssp_init_protocol);
1521 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1523 prefs_register_string_preference(ntlmssp_module, "nt_password",
1525 "NT Password (used to decrypt payloads)",
1528 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1529 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1532 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
1533 proto_tree *tree, guint8 *drep _U_)
1537 auth_tvb = tvb_new_subset(
1538 tvb, offset, tvb_length_remaining(tvb, offset),
1539 tvb_length_remaining(tvb, offset));
1541 dissect_ntlmssp(auth_tvb, pinfo, tree);
1543 return tvb_length_remaining(tvb, offset);
1546 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
1547 proto_tree *tree, guint8 *drep _U_)
1551 auth_tvb = tvb_new_subset(
1552 tvb, offset, tvb_length_remaining(tvb, offset),
1553 tvb_length_remaining(tvb, offset));
1555 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
1558 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
1559 wrap_dissect_ntlmssp, /* Bind */
1560 wrap_dissect_ntlmssp, /* Bind ACK */
1561 wrap_dissect_ntlmssp, /* AUTH3 */
1562 wrap_dissect_ntlmssp_verf, /* Request verifier */
1563 wrap_dissect_ntlmssp_verf, /* Response verifier */
1564 NULL, /* Request data */
1565 NULL /* Response data */
1568 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
1569 wrap_dissect_ntlmssp, /* Bind */
1570 wrap_dissect_ntlmssp, /* Bind ACK */
1571 wrap_dissect_ntlmssp, /* AUTH3 */
1572 wrap_dissect_ntlmssp_verf, /* Request verifier */
1573 wrap_dissect_ntlmssp_verf, /* Response verifier */
1574 dissect_ntlmssp_encrypted_payload, /* Request data */
1575 dissect_ntlmssp_encrypted_payload /* Response data */
1579 proto_reg_handoff_ntlmssp(void)
1581 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1583 /* Register protocol with the GSS-API module */
1585 ntlmssp_handle = find_dissector("ntlmssp");
1586 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1587 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1588 ntlmssp_handle, ntlmssp_wrap_handle,
1589 "NTLMSSP - Microsoft NTLM Security Support Provider");
1591 /* Register authenticated pipe dissector */
1594 * XXX - the verifiers here seem to have a version of 1 and a body of all
1597 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
1598 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
1599 * any other levels here?
1601 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
1602 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1605 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1606 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1609 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1610 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,