From Chris Wilson:
[obnox/wireshark/wip.git] / packet-ntlmssp.c
1 /* packet-ntlmssp.c
2  * Routines for NTLM Secure Service Provider
3  * Devin Heitmueller <dheitmueller@netilla.com>
4  * Copyright 2003, Tim Potter <tpot@samba.org>
5  *
6  * $Id: packet-ntlmssp.c,v 1.46 2004/01/19 20:10:36 jmayer Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
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.
16  *
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.
21  *
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.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <glib.h>
32 #include <epan/packet.h>
33
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"
38 #include "prefs.h"
39 #include "crypt-rc4.h"
40 #include "crypt-md4.h"
41 #include "crypt-des.h"
42 #include "packet-dcerpc.h"
43
44 /* Message types */
45
46 #define NTLMSSP_NEGOTIATE 1
47 #define NTLMSSP_CHALLENGE 2
48 #define NTLMSSP_AUTH      3
49 #define NTLMSSP_UNKNOWN   4
50
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" },
56   { 0, NULL }
57 };
58
59 /*
60  * NTLMSSP negotiation flags
61  * Taken from Samba
62  */
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
95
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;
175
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;
182
183 /* Configuration variables */
184 static char *nt_password = NULL;
185
186 #define MAX_BLOB_SIZE 256
187 typedef struct _ntlmssp_blob {
188   guint16 length;
189   guint8 contents[MAX_BLOB_SIZE];  
190 } ntlmssp_blob;
191
192 /* Used in the conversation function */
193 typedef struct _ntlmssp_info {
194   guint32 flags;
195   guint8 challenge[8];  
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;
202 } ntlmssp_info;
203
204 /*
205  * GMemChunk from which ntlmssp_info structures are allocated.
206  */
207 static GMemChunk  *ntlmssp_info_chunk;
208 static int ntlmssp_info_count = 10;
209
210 /* If this struct exists in the payload_decrypt, then we have already
211    decrypted it once */
212 typedef struct _ntlmssp_packet_info {
213   guint32 flags;
214   guint8 challenge[8];  
215   guint8 *decrypted_payload;
216   guint8 verifier[16];
217   gboolean payload_decrypted;
218   gboolean verifier_decrypted;
219 } ntlmssp_packet_info;
220
221 /*
222  * GMemChunk from which ntlmssp_packet_info structures are allocated.
223  */
224 static GMemChunk  *ntlmssp_packet_info_chunk;
225 static int ntlmssp_packet_info_count = 10;
226
227 /*
228  * GSlist of decrypted payloads.
229  */
230 static GSList *decrypted_payloads;
231
232 /*
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.
236 */
237 static int ntlmssp_generate_challenge_response(guint8 *response,
238                                                const guint8 *passhash, 
239                                                const guint8 *challenge)
240 {
241   guint8 pw21[21]; /* Password hash padded to 21 bytes */
242   
243   memset(pw21, 0x0, sizeof(pw21));
244   memcpy(pw21, passhash, 16);
245
246   memset(response, 0, 24);
247
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);
251
252   return 1;
253 }
254
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)
260  */
261 static void
262 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge, 
263                       int use_key_128, guint8 *sspkey)
264 {
265   unsigned char lm_password_upper[16];
266   unsigned char lm_password_hash[16];
267   guint8 lm_challenge_response[24];
268   guint8 rc4key[24];
269   guint8 pw21[21]; /* Password hash padded to 21 bytes */
270   size_t password_len;
271   unsigned int i;
272   unsigned char lmhash_key[] = 
273     {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
274
275   memset(lm_password_upper, 0, sizeof(lm_password_upper));
276
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)
282       password_len = 16;
283     for (i = 0; i < password_len; i++) {
284       lm_password_upper[i] = toupper(nt_password[i]);
285     }
286   }
287
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);
290   
291   /* Generate the LanMan Challenge Response */
292   ntlmssp_generate_challenge_response(lm_challenge_response,
293                                       lm_password_hash, challenge);
294   
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.
298    */
299   memset(pw21, 0xBD, sizeof(pw21));
300   memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
301
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);
306   
307   /* Create the SSP Key */
308   memset(sspkey, 0, sizeof(sspkey));
309   if (use_key_128) {
310     /* Create 128 bit key */
311     memcpy(sspkey, rc4key, 16);
312   }
313   else {
314     /* Create 40 bit key */
315     memcpy(sspkey, rc4key, 5);
316     sspkey[5]=0xe5;
317     sspkey[6]=0x38;
318     sspkey[7]=0xb0;
319   }
320   return;
321 }
322
323 /* dissect a string - header area contains:
324      two byte len
325      two byte maxlen
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
330 */
331 static int
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)
336 {
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;
343   int result_length;
344   guint16 bc;
345
346   *start = (string_offset > offset+8 ? string_offset : offset+8);
347   if (0 == string_length) {
348     *end = *start;
349     if (ntlmssp_tree)
350             proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
351                                   offset, 8, "NULL");
352     return offset+8;
353   }
354
355   bc = result_length = string_length;
356   string_text = get_unicode_or_ascii_string(tvb, &string_offset,
357                                             unicode_strings, &result_length,
358                                             FALSE, TRUE, &bc);
359
360   if (ntlmssp_tree) {
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);
364   }
365   proto_tree_add_uint(tree, hf_ntlmssp_string_len,
366                       tvb, offset, 2, string_length);
367   offset += 2;
368   proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
369                       tvb, offset, 2, string_maxlen);
370   offset += 2;
371   proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
372                       tvb, offset, 4, string_offset);
373   offset += 4;
374
375   *end = string_offset + string_length;
376   return offset;
377 }
378
379 /* dissect a generic blob - header area contains:
380      two byte len
381      two byte maxlen
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
385 */
386 static int
387 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
388                       proto_tree *ntlmssp_tree, 
389                       int blob_hf, int *end, ntlmssp_blob *result)
390 {
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);
396
397   if (0 == blob_length) {
398     *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
399     if (ntlmssp_tree)
400             proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
401                                 proto_registrar_get_name(blob_hf));
402     return offset+8;
403   }
404
405   if (ntlmssp_tree) {
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);
409   }
410   proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
411                       tvb, offset, 2, blob_length);
412   offset += 2;
413   proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
414                       tvb, offset, 2, blob_maxlen);
415   offset += 2;
416   proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
417                       tvb, offset, 4, blob_offset);
418   offset += 4;
419
420   *end = blob_offset + blob_length;
421
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);
427   }
428
429   /* If we are dissecting the NTLM response and it is a NTLMv2
430      response call the appropriate dissector. */
431
432   if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
433           dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
434
435   return offset;
436 }
437
438 static int
439 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
440                                  proto_tree *ntlmssp_tree,
441                                  guint32 negotiate_flags)
442 {
443   proto_tree *negotiate_flags_tree = NULL;
444   proto_item *tf = NULL;
445
446   if (ntlmssp_tree) {
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);
451   }
452
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);
549
550   return (offset + 4);
551 }
552
553
554 static int
555 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
556 {
557   guint32 negotiate_flags;
558   int start;
559   int workstation_end;
560   int domain_end;
561
562   /* NTLMSSP Negotiate Flags */
563   negotiate_flags = tvb_get_letohl (tvb, offset);
564   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
565                                             negotiate_flags);
566
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);
573
574   /* XXX - two blobs after this one, sometimes? */
575
576   return MAX(workstation_end, domain_end);
577 }
578
579
580 static int
581 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset, 
582                               proto_tree *ntlmssp_tree, 
583                               int *end)
584 {
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;
589   guint32 item_offset;
590   proto_item *tf = NULL;
591   proto_tree *tree = NULL;
592   proto_item *addr_tf = NULL;
593   proto_tree *addr_tree = NULL;
594
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);
598     if (ntlmssp_tree)
599             proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
600                                 "Address List: Empty");
601     return offset+8;
602   }
603
604   if (ntlmssp_tree) {
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);
608   }
609   proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
610                       tvb, offset, 2, list_length);
611   offset += 2;
612   proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
613                       tvb, offset, 2, list_maxlen);
614   offset += 2;
615   proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
616                       tvb, offset, 4, list_offset);
617   offset += 4;
618
619   /* Now enumerate through the individual items in the list */
620   item_offset = list_offset;
621
622   while (item_offset < (list_offset + list_length)) {
623     const char *text=NULL;
624     guint32 content_offset;
625     guint16 content_length;
626     guint32 type_offset;
627     guint32 len_offset;
628
629     /* Content type */
630     type_offset = item_offset;
631     item_type = tvb_get_letohs(tvb, type_offset);
632
633     /* Content length */
634     len_offset = type_offset + 2;
635     content_length = tvb_get_letohs(tvb, len_offset);
636
637     /* Content value */
638     content_offset = len_offset + 2;
639     item_length = content_length + 4;
640
641     /* Strings are always in unicode regardless of the negotiated
642        string type. */
643     if (content_length > 0) {
644       guint16 bc;
645       int result_length;
646       int item_offset_int;
647
648       item_offset_int = content_offset;
649       bc = content_length;
650       text = get_unicode_or_ascii_string(tvb, &item_offset_int,
651                                          TRUE, &result_length,
652                                          FALSE, FALSE, &bc);
653     }
654
655     if (!text) text = ""; /* Make sure we don't blow up below */
656
657     switch(item_type) {
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);
661       break;
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);
665       break;
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);
669       break;
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);
673       break;
674     case NTLM_NAME_END:
675       addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
676                                     tvb, item_offset, item_length, TRUE);
677     }
678
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);
689     }
690
691     item_offset += item_length;
692   }
693
694   *end = list_offset + list_length;
695   return offset;
696 }
697
698 static int
699 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
700                            proto_tree *ntlmssp_tree)
701 {
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) */
710
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;
715
716   /* Domain name */
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;
721   data_end = item_end;
722
723   /* NTLMSSP Negotiate Flags */
724   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
725                                             negotiate_flags);
726
727   /* NTLMSSP NT Lan Manager Challenge */
728   proto_tree_add_item (ntlmssp_tree,
729                        hf_ntlmssp_ntlm_challenge,
730                        tvb, offset, 8, FALSE);
731
732   /*
733    * Store the flags and the challenge with the conversation, as they're
734    * needed in order to dissect subsequent messages.
735    */
736   conversation = find_conversation(&pinfo->src, &pinfo->dst,
737                                    pinfo->ptype, pinfo->srcport,
738                                    pinfo->destport, 0);
739   if (!conversation) { /* Create one */
740     conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype, 
741                                     pinfo->srcport, pinfo->destport, 0);
742   }
743
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);
750
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, 
755                             1, sspkey);
756       ssp_key_len = 16;
757     }
758     else {
759       create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge, 
760                             0, sspkey);
761       ssp_key_len = 8;
762     }
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;
767
768     conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
769   }
770   offset += 8;
771
772   /* Reserved (function not completely known) */
773   /* XXX - SSP key? */
774   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
775                        tvb, offset, 8, FALSE);
776   offset += 8;
777
778   /*
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
786    * address list).
787    */
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);
791   }
792
793   return MAX(offset, data_end);
794 }
795
796 static int
797 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
798                       proto_tree *ntlmssp_tree)
799 {
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;
806
807   /*
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.
812    */
813   conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
814   if (conv_ntlmssp_info == NULL) {
815     /*
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.
819      */
820     conversation = find_conversation(&pinfo->src, &pinfo->dst,
821                                      pinfo->ptype, pinfo->srcport,
822                                      pinfo->destport, 0);
823     if (conversation != NULL) {
824       conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
825       if (conv_ntlmssp_info != NULL) {
826         /*
827          * We have flag info; attach it to the frame.
828          */
829         p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
830       }
831     }
832   }
833   if (conv_ntlmssp_info != NULL) {
834     if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
835       unicode_strings = TRUE;
836   }
837
838   /*
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.
842    *
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.
847    *
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
851    * missing.
852    */
853
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,
858                                 &item_end,
859                                 conv_ntlmssp_info == NULL ? NULL :
860                                     &conv_ntlmssp_info->lm_response);
861   data_end = MAX(data_end, item_end);
862
863   /* NTLM response */
864   item_start = tvb_get_letohl(tvb, offset+4);
865   offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
866                                 hf_ntlmssp_auth_ntresponse,
867                                 &item_end,
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);
872
873   /* domain name */
874   item_start = tvb_get_letohl(tvb, offset+4);
875   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
876                                   unicode_strings, 
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);
881
882   /* user name */
883   item_start = tvb_get_letohl(tvb, offset+4);
884   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
885                                   unicode_strings, 
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);
890
891   /* hostname */
892   item_start = tvb_get_letohl(tvb, offset+4);
893   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
894                                   unicode_strings, 
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);
899
900   if (offset < data_start) {
901     /* Session Key */
902     offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
903                                   hf_ntlmssp_auth_sesskey,
904                                   &item_end, NULL);
905     data_end = MAX(data_end, item_end);
906   }
907
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,
912                                               negotiate_flags);
913   }
914
915   return MAX(offset, data_end);
916 }
917
918 static void
919 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
920 {
921   guint32 ntlmssp_message_type;
922   volatile int offset = 0;
923   proto_tree *volatile ntlmssp_tree = NULL;
924   proto_item *tf = NULL;
925
926   /* Setup a new tree for the NTLMSSP payload */
927   if (tree) {
928     tf = proto_tree_add_item (tree,
929                               hf_ntlmssp,
930                               tvb, offset, -1, FALSE);
931
932     ntlmssp_tree = proto_item_add_subtree (tf,
933                                            ett_ntlmssp);
934   }
935
936   /*
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.
943    *
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
946    * exception.
947    */
948   TRY {
949     /* NTLMSSP constant */
950     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
951                          tvb, offset, 8, FALSE);
952     offset += 8;
953
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);
958     offset += 4; 
959
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"));
965
966     /* Call the appropriate dissector based on the Message Type */
967     switch (ntlmssp_message_type) {
968
969     case NTLMSSP_NEGOTIATE:
970       offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
971       break;
972
973     case NTLMSSP_CHALLENGE:
974       offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
975       break;
976
977     case NTLMSSP_AUTH:
978       offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
979       break;
980
981     default:
982       /* Unrecognized message type */
983       proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
984                            "Unrecognized NTLMSSP Message");
985       break;
986     }
987   } CATCH(BoundsError) {
988     RETHROW;
989   } CATCH(ReportedBoundsError) {
990     show_reported_bounds_error(tvb, pinfo, tree);
991   } ENDTRY;
992 }
993
994 /*
995  * Get the encryption state tied to this conversation.  cryptpeer indicates 
996  * whether to retrieve the data for peer1 or peer2.
997  */
998 static rc4_state_struct *
999 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1000 {
1001   conversation_t *conversation;
1002   ntlmssp_info *conv_ntlmssp_info;
1003
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 */
1010     return NULL;
1011   }
1012   else {
1013     /* We have a conversation, check for encryption state */
1014     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1015                                                     proto_ntlmssp);
1016     if (conv_ntlmssp_info == NULL) {
1017       /* No encryption state tied to the conversation.  Therefore, we
1018          cannot decrypt the payload */
1019       return NULL;
1020     }
1021     else {
1022       /* We have the encryption state in the conversation.  So return the
1023          crypt state tied to the requested peer
1024        */
1025       if (cryptpeer == 1) {
1026         return &conv_ntlmssp_info->rc4_state_peer1;
1027       } else {
1028         return &conv_ntlmssp_info->rc4_state_peer2;
1029       }
1030     }
1031   }
1032   return NULL;
1033 }
1034
1035 /*
1036  * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1037  */
1038 static void
1039 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1040                  packet_info *pinfo, proto_tree *tree)
1041 {
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 */
1048   guint8 *peer_block;
1049   ntlmssp_info *conv_ntlmssp_info = NULL;
1050   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1051   int decrypted_offset = 0;
1052
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 */
1056     return;
1057   }
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 */
1064       return;
1065     }
1066
1067     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1068                                                     proto_ntlmssp);
1069     if (conv_ntlmssp_info == NULL) {
1070       /* There is no NTLMSSP state tied to the conversation */
1071       return;
1072     }
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 */
1077       return;
1078     }
1079
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);
1083     } else {
1084       rc4_state = get_encrypted_state(pinfo, 0);
1085       rc4_state_peer = get_encrypted_state(pinfo, 1);
1086     }
1087
1088     if (rc4_state == NULL || rc4_state_peer == NULL) {
1089       /* There is no encryption state, so we cannot decrypt */
1090       return;
1091     }
1092
1093     /* Setup the buffer to decrypt to */
1094     tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1095                offset, encrypted_block_length);
1096     
1097     /* Do the actual decryption of the verifier */
1098     crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1099               encrypted_block_length);
1100
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);
1107     g_free(peer_block);
1108
1109     /* Mark the packet as decrypted so that subsequent attempts to dissect
1110        the packet use the already decrypted payload instead of attempting
1111        to decrypt again */
1112     packet_ntlmssp_info->verifier_decrypted = TRUE;
1113   }
1114
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");
1122
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);
1129
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;
1136
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;
1141
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;
1146 }
1147
1148 static int
1149 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1150 {
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;
1156
1157   verifier_length = tvb_length_remaining (tvb, offset);
1158   encrypted_block_length = verifier_length - 4;
1159
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;
1164   }
1165
1166   /* Setup a new tree for the NTLMSSP payload */
1167   if (tree) {
1168     tf = proto_tree_add_item (tree,
1169                               hf_ntlmssp_verf,
1170                               tvb, offset, -1, FALSE);
1171
1172     ntlmssp_tree = proto_item_add_subtree (tf,
1173                                            ett_ntlmssp);
1174   }
1175
1176   /*
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.
1183    *
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
1186    * exception.
1187    */
1188   TRY {
1189     /* Version number */
1190     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1191                          tvb, offset, 4, TRUE);
1192     offset += 4;
1193   
1194     /* Encrypted body */
1195     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1196                          tvb, offset, encrypted_block_length, TRUE);
1197
1198     /* Try to decrypt */
1199     decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1200
1201     offset += encrypted_block_length;
1202   } CATCH(BoundsError) {
1203     RETHROW;
1204   } CATCH(ReportedBoundsError) {
1205     show_reported_bounds_error(tvb, pinfo, tree);
1206   } ENDTRY;
1207
1208   return offset;
1209 }
1210
1211 static tvbuff_t *
1212 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, int offset,
1213                                   packet_info *pinfo, 
1214                                   dcerpc_auth_info *auth_info _U_)
1215 {
1216   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1217   guint8 *peer_block;
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;
1224
1225   encrypted_block_length = tvb_length_remaining (tvb, offset);
1226
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);
1234   }
1235   
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 */
1243       return NULL;
1244     }
1245     
1246     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1247                                                     proto_ntlmssp);
1248     if (conv_ntlmssp_info == NULL) {
1249       /* There is no NTLMSSP state tied to the conversation */
1250             return NULL;
1251     }
1252     
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
1255        the peer */
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);
1259     } else {
1260       rc4_state = get_encrypted_state(pinfo, 0);
1261       rc4_state_peer = get_encrypted_state(pinfo, 1);
1262     }
1263     
1264     if (rc4_state == NULL || rc4_state_peer == NULL) {
1265       /* There is no encryption state, so we cannot decrypt */
1266       return NULL;
1267     }
1268
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 = g_malloc (encrypted_block_length);
1272     decrypted_payloads = g_slist_prepend(decrypted_payloads,
1273                                          packet_ntlmssp_info->decrypted_payload);
1274     tvb_memcpy(tvb, packet_ntlmssp_info->decrypted_payload, 
1275                offset, encrypted_block_length);
1276     
1277     /* Do the decryption of the payload */
1278     crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload, 
1279               encrypted_block_length);
1280     
1281     /* We setup a temporary buffer so we can re-encrypt the payload after
1282        decryption.  This is to update the opposite peer's RC4 state */
1283     peer_block = g_malloc(encrypted_block_length);
1284     memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1285            encrypted_block_length);
1286     crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1287     g_free(peer_block);
1288     
1289     packet_ntlmssp_info->payload_decrypted = TRUE;
1290   }
1291
1292   /* Show the decrypted buffer in a new window */
1293   decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1294                                encrypted_block_length,
1295                                encrypted_block_length);
1296
1297   tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1298   
1299   offset += encrypted_block_length;
1300
1301   return decr_tvb;
1302 }
1303
1304 static void
1305 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1306 {
1307         g_free(decrypted_payload);
1308 }
1309
1310 static void
1311 ntlmssp_init_protocol(void)
1312 {
1313         if (ntlmssp_info_chunk != NULL)
1314                 g_mem_chunk_destroy(ntlmssp_info_chunk);
1315         if (ntlmssp_packet_info_chunk != NULL)
1316                 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1317
1318         /*
1319          * Free the decrypted payloads, and then free the list of decrypted
1320          * payloads.
1321          */
1322         if (decrypted_payloads != NULL) {
1323                 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1324                 g_slist_free(decrypted_payloads);
1325                 decrypted_payloads = NULL;
1326         }
1327
1328         ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1329             sizeof(ntlmssp_info),
1330             ntlmssp_info_count * sizeof(ntlmssp_info),
1331             G_ALLOC_ONLY);
1332         ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1333             sizeof(ntlmssp_packet_info),
1334             ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1335             G_ALLOC_ONLY);
1336 }
1337
1338 void
1339 proto_register_ntlmssp(void)
1340 {
1341
1342   static hf_register_info hf[] = {
1343     { &hf_ntlmssp,
1344       { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1345
1346     { &hf_ntlmssp_auth,
1347       { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1348
1349     { &hf_ntlmssp_message_type,
1350       { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1351
1352     { &hf_ntlmssp_negotiate_flags,
1353       { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1354     { &hf_ntlmssp_negotiate_flags_01,
1355
1356       { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1357     { &hf_ntlmssp_negotiate_flags_02,
1358       { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1359     { &hf_ntlmssp_negotiate_flags_04,
1360       { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1361     { &hf_ntlmssp_negotiate_flags_08,
1362       { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1363     { &hf_ntlmssp_negotiate_flags_10,
1364       { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1365     { &hf_ntlmssp_negotiate_flags_20,
1366       { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1367     { &hf_ntlmssp_negotiate_flags_40,
1368       { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1369     { &hf_ntlmssp_negotiate_flags_80,
1370       { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1371     { &hf_ntlmssp_negotiate_flags_100,
1372       { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1373     { &hf_ntlmssp_negotiate_flags_200,
1374       { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1375     { &hf_ntlmssp_negotiate_flags_400,
1376       { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1377     { &hf_ntlmssp_negotiate_flags_800,
1378       { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1379     { &hf_ntlmssp_negotiate_flags_1000,
1380       { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1381     { &hf_ntlmssp_negotiate_flags_2000,
1382       { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1383     { &hf_ntlmssp_negotiate_flags_4000,
1384       { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1385     { &hf_ntlmssp_negotiate_flags_8000,
1386       { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1387     { &hf_ntlmssp_negotiate_flags_10000,
1388       { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1389     { &hf_ntlmssp_negotiate_flags_20000,
1390       { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1391     { &hf_ntlmssp_negotiate_flags_40000,
1392       { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1393     { &hf_ntlmssp_negotiate_flags_80000,
1394       { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1395     { &hf_ntlmssp_negotiate_flags_100000,
1396       { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1397     { &hf_ntlmssp_negotiate_flags_200000,
1398       { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1399     { &hf_ntlmssp_negotiate_flags_400000,
1400       { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1401     { &hf_ntlmssp_negotiate_flags_800000,
1402       { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1403     { &hf_ntlmssp_negotiate_flags_1000000,
1404       { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1405     { &hf_ntlmssp_negotiate_flags_2000000,
1406       { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1407     { &hf_ntlmssp_negotiate_flags_4000000,
1408       { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1409     { &hf_ntlmssp_negotiate_flags_8000000,
1410       { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1411     { &hf_ntlmssp_negotiate_flags_10000000,
1412       { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1413     { &hf_ntlmssp_negotiate_flags_20000000,
1414       { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
1415     { &hf_ntlmssp_negotiate_flags_40000000,
1416       { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1417     { &hf_ntlmssp_negotiate_flags_80000000,
1418       { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
1419     { &hf_ntlmssp_negotiate_workstation_strlen,
1420       { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1421     { &hf_ntlmssp_negotiate_workstation_maxlen,
1422       { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1423     { &hf_ntlmssp_negotiate_workstation_buffer,
1424       { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1425     { &hf_ntlmssp_negotiate_workstation,
1426       { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1427     { &hf_ntlmssp_negotiate_domain_strlen,
1428       { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1429     { &hf_ntlmssp_negotiate_domain_maxlen,
1430       { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1431     { &hf_ntlmssp_negotiate_domain_buffer,
1432       { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1433     { &hf_ntlmssp_negotiate_domain,
1434       { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1435     { &hf_ntlmssp_ntlm_challenge,
1436       { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1437     { &hf_ntlmssp_reserved,
1438       { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1439     { &hf_ntlmssp_challenge_domain,
1440       { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1441     { &hf_ntlmssp_auth_domain,
1442       { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1443     { &hf_ntlmssp_auth_username,
1444       { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1445     { &hf_ntlmssp_auth_hostname,
1446       { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1447     { &hf_ntlmssp_auth_lmresponse,
1448       { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1449     { &hf_ntlmssp_auth_ntresponse,
1450       { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1451     { &hf_ntlmssp_auth_sesskey,
1452       { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1453     { &hf_ntlmssp_string_len,
1454       { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1455     { &hf_ntlmssp_string_maxlen,
1456       { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1457     { &hf_ntlmssp_string_offset,
1458       { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1459     { &hf_ntlmssp_blob_len,
1460       { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1461     { &hf_ntlmssp_blob_maxlen,
1462       { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1463     { &hf_ntlmssp_blob_offset,
1464       { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1465     { &hf_ntlmssp_address_list,
1466       { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1467     { &hf_ntlmssp_address_list_len,
1468       { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1469     { &hf_ntlmssp_address_list_maxlen,
1470       { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1471     { &hf_ntlmssp_address_list_offset,
1472       { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1473     { &hf_ntlmssp_address_list_item_type,
1474       { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, "", HFILL }},
1475     { &hf_ntlmssp_address_list_item_len,
1476       { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1477     { &hf_ntlmssp_address_list_item_content,
1478       { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1479     { &hf_ntlmssp_address_list_server_nb,
1480       { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1481     { &hf_ntlmssp_address_list_domain_nb,
1482       { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1483     { &hf_ntlmssp_address_list_server_dns,
1484       { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1485     { &hf_ntlmssp_address_list_domain_dns,
1486       { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1487     { &hf_ntlmssp_address_list_terminator,
1488       { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
1489     { &hf_ntlmssp_verf,
1490       { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1491     { &hf_ntlmssp_verf_vers,
1492       { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1493     { &hf_ntlmssp_verf_body,
1494       { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1495     { &hf_ntlmssp_decrypted_payload,
1496       { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1497     { &hf_ntlmssp_verf_unknown1,
1498       { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1499     { &hf_ntlmssp_verf_crc32,
1500       { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1501     { &hf_ntlmssp_verf_sequence,
1502       { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1503   };
1504
1505
1506   static gint *ett[] = {
1507     &ett_ntlmssp,
1508     &ett_ntlmssp_negotiate_flags,
1509     &ett_ntlmssp_string,
1510     &ett_ntlmssp_blob,
1511     &ett_ntlmssp_address_list,
1512     &ett_ntlmssp_address_list_item
1513   };
1514   module_t *ntlmssp_module;
1515   
1516   proto_ntlmssp = proto_register_protocol (
1517                                            "NTLM Secure Service Provider", /* name */
1518                                            "NTLMSSP",   /* short name */
1519                                            "ntlmssp"    /* abbrev */
1520                                            );
1521   proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1522   proto_register_subtree_array (ett, array_length (ett));
1523   register_init_routine(&ntlmssp_init_protocol);
1524
1525   ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1526   
1527   prefs_register_string_preference(ntlmssp_module, "nt_password",
1528                                    "NT Password",
1529                                    "NT Password (used to decrypt payloads)",
1530                                    &nt_password);
1531
1532   register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1533   new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1534 }
1535
1536 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo, 
1537                                 proto_tree *tree, guint8 *drep _U_)
1538 {
1539         tvbuff_t *auth_tvb;
1540
1541         auth_tvb = tvb_new_subset(
1542                 tvb, offset, tvb_length_remaining(tvb, offset),
1543                 tvb_length_remaining(tvb, offset));
1544         
1545         dissect_ntlmssp(auth_tvb, pinfo, tree);
1546
1547         return tvb_length_remaining(tvb, offset);
1548 }
1549
1550 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo, 
1551                                      proto_tree *tree, guint8 *drep _U_)
1552 {
1553         tvbuff_t *auth_tvb;
1554
1555         auth_tvb = tvb_new_subset(
1556                 tvb, offset, tvb_length_remaining(tvb, offset),
1557                 tvb_length_remaining(tvb, offset));
1558         
1559         return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
1560 }
1561
1562 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
1563         wrap_dissect_ntlmssp,                   /* Bind */
1564         wrap_dissect_ntlmssp,                   /* Bind ACK */
1565         wrap_dissect_ntlmssp,                   /* AUTH3 */
1566         wrap_dissect_ntlmssp_verf,              /* Request verifier */
1567         wrap_dissect_ntlmssp_verf,              /* Response verifier */
1568         NULL,                                   /* Request data */
1569         NULL                                    /* Response data */
1570 };
1571
1572 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
1573         wrap_dissect_ntlmssp,                   /* Bind */
1574         wrap_dissect_ntlmssp,                   /* Bind ACK */
1575         wrap_dissect_ntlmssp,                   /* AUTH3 */
1576         wrap_dissect_ntlmssp_verf,              /* Request verifier */
1577         wrap_dissect_ntlmssp_verf,              /* Response verifier */
1578         dissect_ntlmssp_encrypted_payload,      /* Request data */
1579         dissect_ntlmssp_encrypted_payload       /* Response data */
1580 };
1581
1582 void
1583 proto_reg_handoff_ntlmssp(void)
1584 {     
1585   dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1586
1587   /* Register protocol with the GSS-API module */
1588
1589   ntlmssp_handle = find_dissector("ntlmssp");
1590   ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1591   gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp, 
1592                   ntlmssp_handle, ntlmssp_wrap_handle,
1593                   "NTLMSSP - Microsoft NTLM Security Support Provider");
1594
1595   /* Register authenticated pipe dissector */
1596
1597   /*
1598    * XXX - the verifiers here seem to have a version of 1 and a body of all
1599    * zeroes.
1600    *
1601    * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
1602    * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT.  Should we register
1603    * any other levels here?
1604    */
1605   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
1606                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1607                                     &ntlmssp_sign_fns);
1608
1609   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1610                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1611                                     &ntlmssp_sign_fns);
1612
1613   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1614                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1615                                     &ntlmssp_seal_fns);
1616 }