Update Laurent Meyer's e-mail address.
[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  *
5  * $Id: packet-ntlmssp.c,v 1.40 2003/05/09 01:41:28 tpot Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/packet.h>
32
33 #include "packet-smb-common.h"
34 #include "asn1.h"               /* XXX - needed for subid_t */
35 #include "packet-gssapi.h"
36 #include "packet-frame.h"
37 #include "prefs.h"
38 #include "crypt-rc4.h"
39 #include "crypt-md4.h"
40 #include "crypt-des.h"
41 #include "packet-ntlmssp.h"
42
43 /* Message types */
44
45 #define NTLMSSP_NEGOTIATE 1
46 #define NTLMSSP_CHALLENGE 2
47 #define NTLMSSP_AUTH      3
48 #define NTLMSSP_UNKNOWN   4
49
50 static const value_string ntlmssp_message_types[] = {
51   { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
52   { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
53   { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
54   { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
55   { 0, NULL }
56 };
57
58 /*
59  * NTLMSSP negotiation flags
60  * Taken from Samba
61  */
62 #define NTLMSSP_NEGOTIATE_UNICODE          0x00000001
63 #define NTLMSSP_NEGOTIATE_OEM              0x00000002
64 #define NTLMSSP_REQUEST_TARGET             0x00000004
65 #define NTLMSSP_NEGOTIATE_00000008         0x00000008
66 #define NTLMSSP_NEGOTIATE_SIGN             0x00000010
67 #define NTLMSSP_NEGOTIATE_SEAL             0x00000020
68 #define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE   0x00000040
69 #define NTLMSSP_NEGOTIATE_LM_KEY           0x00000080
70 #define NTLMSSP_NEGOTIATE_NETWARE          0x00000100
71 #define NTLMSSP_NEGOTIATE_NTLM             0x00000200
72 #define NTLMSSP_NEGOTIATE_00000400         0x00000400
73 #define NTLMSSP_NEGOTIATE_00000800         0x00000800
74 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED  0x00001000
75 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
76 #define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL  0x00004000
77 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN      0x00008000
78 #define NTLMSSP_CHAL_INIT_RESPONSE         0x00010000
79 #define NTLMSSP_CHAL_ACCEPT_RESPONSE       0x00020000
80 #define NTLMSSP_CHAL_NON_NT_SESSION_KEY    0x00040000
81 #define NTLMSSP_NEGOTIATE_NTLM2            0x00080000
82 #define NTLMSSP_NEGOTIATE_00100000         0x00100000
83 #define NTLMSSP_NEGOTIATE_00200000         0x00200000
84 #define NTLMSSP_NEGOTIATE_00400000         0x00400000
85 #define NTLMSSP_CHAL_TARGET_INFO           0x00800000
86 #define NTLMSSP_NEGOTIATE_01000000         0x01000000
87 #define NTLMSSP_NEGOTIATE_02000000         0x02000000
88 #define NTLMSSP_NEGOTIATE_04000000         0x04000000
89 #define NTLMSSP_NEGOTIATE_08000000         0x08000000
90 #define NTLMSSP_NEGOTIATE_10000000         0x10000000
91 #define NTLMSSP_NEGOTIATE_128              0x20000000
92 #define NTLMSSP_NEGOTIATE_KEY_EXCH         0x40000000
93 #define NTLMSSP_NEGOTIATE_80000000         0x80000000
94
95 static int proto_ntlmssp = -1;
96 static int hf_ntlmssp = -1;
97 static int hf_ntlmssp_auth = -1;
98 static int hf_ntlmssp_message_type = -1;
99 static int hf_ntlmssp_negotiate_flags = -1;
100 static int hf_ntlmssp_negotiate_flags_01 = -1;
101 static int hf_ntlmssp_negotiate_flags_02 = -1;
102 static int hf_ntlmssp_negotiate_flags_04 = -1;
103 static int hf_ntlmssp_negotiate_flags_08 = -1;
104 static int hf_ntlmssp_negotiate_flags_10 = -1;
105 static int hf_ntlmssp_negotiate_flags_20 = -1;
106 static int hf_ntlmssp_negotiate_flags_40 = -1;
107 static int hf_ntlmssp_negotiate_flags_80 = -1;
108 static int hf_ntlmssp_negotiate_flags_100 = -1;
109 static int hf_ntlmssp_negotiate_flags_200 = -1;
110 static int hf_ntlmssp_negotiate_flags_400 = -1;
111 static int hf_ntlmssp_negotiate_flags_800 = -1;
112 static int hf_ntlmssp_negotiate_flags_1000 = -1;
113 static int hf_ntlmssp_negotiate_flags_2000 = -1;
114 static int hf_ntlmssp_negotiate_flags_4000 = -1;
115 static int hf_ntlmssp_negotiate_flags_8000 = -1;
116 static int hf_ntlmssp_negotiate_flags_10000 = -1;
117 static int hf_ntlmssp_negotiate_flags_20000 = -1;
118 static int hf_ntlmssp_negotiate_flags_40000 = -1;
119 static int hf_ntlmssp_negotiate_flags_80000 = -1;
120 static int hf_ntlmssp_negotiate_flags_100000 = -1;
121 static int hf_ntlmssp_negotiate_flags_200000 = -1;
122 static int hf_ntlmssp_negotiate_flags_400000 = -1;
123 static int hf_ntlmssp_negotiate_flags_800000 = -1;
124 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
125 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
126 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
127 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
128 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
129 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
130 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
131 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
132 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
133 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
134 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
135 static int hf_ntlmssp_negotiate_workstation = -1;
136 static int hf_ntlmssp_negotiate_domain_strlen = -1;
137 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
138 static int hf_ntlmssp_negotiate_domain_buffer = -1;
139 static int hf_ntlmssp_negotiate_domain = -1;
140 static int hf_ntlmssp_ntlm_challenge = -1;
141 static int hf_ntlmssp_reserved = -1;
142 static int hf_ntlmssp_challenge_domain = -1;
143 static int hf_ntlmssp_auth_username = -1;
144 static int hf_ntlmssp_auth_domain = -1;
145 static int hf_ntlmssp_auth_hostname = -1;
146 static int hf_ntlmssp_auth_lmresponse = -1;
147 static int hf_ntlmssp_auth_ntresponse = -1;
148 static int hf_ntlmssp_auth_sesskey = -1;
149 static int hf_ntlmssp_string_len = -1;
150 static int hf_ntlmssp_string_maxlen = -1;
151 static int hf_ntlmssp_string_offset = -1;
152 static int hf_ntlmssp_blob_len = -1;
153 static int hf_ntlmssp_blob_maxlen = -1;
154 static int hf_ntlmssp_blob_offset = -1;
155 static int hf_ntlmssp_address_list = -1;
156 static int hf_ntlmssp_address_list_len = -1;
157 static int hf_ntlmssp_address_list_maxlen = -1;
158 static int hf_ntlmssp_address_list_offset = -1;
159 static int hf_ntlmssp_address_list_server_nb = -1;
160 static int hf_ntlmssp_address_list_domain_nb = -1;
161 static int hf_ntlmssp_address_list_server_dns = -1;
162 static int hf_ntlmssp_address_list_domain_dns = -1;
163 static int hf_ntlmssp_verf = -1;
164 static int hf_ntlmssp_verf_vers = -1;
165 static int hf_ntlmssp_verf_body = -1;
166 static int hf_ntlmssp_verf_unknown1 = -1;
167 static int hf_ntlmssp_verf_crc32 = -1;
168 static int hf_ntlmssp_verf_sequence = -1;
169 static int hf_ntlmssp_decrypted_payload = -1;
170
171 static gint ett_ntlmssp = -1;
172 static gint ett_ntlmssp_negotiate_flags = -1;
173 static gint ett_ntlmssp_string = -1;
174 static gint ett_ntlmssp_blob = -1;
175 static gint ett_ntlmssp_address_list = -1;
176 static gint ett_ntlmssp_decrypted_tree = -1;
177
178 /* Configuration variables */
179 static char *nt_password = NULL;
180
181 #define MAX_BLOB_SIZE 256
182 typedef struct _ntlmssp_blob {
183   guint16 length;
184   guint8 contents[MAX_BLOB_SIZE];  
185 } ntlmssp_blob;
186
187 /* Used in the conversation function */
188 typedef struct _ntlmssp_info {
189   guint32 flags;
190   guint8 challenge[8];  
191   rc4_state_struct rc4_state_peer1;
192   rc4_state_struct rc4_state_peer2;
193   guint32 peer1_dest_port;
194   int rc4_state_initialized;
195   ntlmssp_blob ntlm_response;
196   ntlmssp_blob lm_response;
197 } ntlmssp_info;
198
199 /*
200  * GMemChunk from which ntlmssp_info structures are allocated.
201  */
202 static GMemChunk  *ntlmssp_info_chunk;
203 static int ntlmssp_info_count = 10;
204
205 /* If this struct exists in the payload_decrypt, then we have already
206    decrypted it once */
207 typedef struct _ntlmssp_packet_info {
208   guint32 flags;
209   guint8 challenge[8];  
210   guint8 *decrypted_payload;
211   guint8 verifier[16];
212   gboolean payload_decrypted;
213   gboolean verifier_decrypted;
214 } ntlmssp_packet_info;
215
216 /*
217  * GMemChunk from which ntlmssp_packet_info structures are allocated.
218  */
219 static GMemChunk  *ntlmssp_packet_info_chunk;
220 static int ntlmssp_packet_info_count = 10;
221
222 /*
223  * GSlist of decrypted payloads.
224  */
225 static GSList *decrypted_payloads;
226
227 /*
228   Generate a challenge response, given an eight byte challenge and
229   either the NT or the Lan Manager password hash (16 bytes).
230   Returns output in response, which is expected to be 24 bytes.
231 */
232 static int ntlmssp_generate_challenge_response(guint8 *response,
233                                                const guint8 *passhash, 
234                                                const guint8 *challenge)
235 {
236   guint8 pw21[21]; /* Password hash padded to 21 bytes */
237   
238   memset(pw21, 0x0, sizeof(pw21));
239   memcpy(pw21, passhash, 16);
240
241   memset(response, 0, 24);
242
243   crypt_des_ecb(response, challenge, pw21, 1);
244   crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
245   crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
246
247   return 1;
248 }
249
250 /* Create an NTLMSSP version 1 key.  
251  * password points to the ANSI password to encrypt, challenge points to
252  * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
253  * otherwise it will do a 40 bit key.  The result is stored in 
254  * sspkey (expected to be 16 octets)
255  */
256 static void
257 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge, 
258                       int use_key_128, guint8 *sspkey)
259 {
260   unsigned char lm_password_upper[16];
261   unsigned char lm_password_hash[16];
262   guint8 lm_challenge_response[24];
263   guint8 rc4key[24];
264   guint8 pw21[21]; /* Password hash padded to 21 bytes */
265   size_t password_len;
266   unsigned int i;
267   unsigned char lmhash_key[] = 
268     {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
269
270   memset(lm_password_upper, 0, sizeof(lm_password_upper));
271
272   /* Create a Lan Manager hash of the input password */
273   if (nt_password[0] != '\0') {
274     password_len = strlen(nt_password);
275     /* Truncate password if too long */
276     if (password_len > 16)
277       password_len = 16;
278     for (i = 0; i < password_len; i++) {
279       lm_password_upper[i] = toupper(nt_password[i]);
280     }
281   }
282
283   crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
284   crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
285   
286   /* Generate the LanMan Challenge Response */
287   ntlmssp_generate_challenge_response(lm_challenge_response,
288                                       lm_password_hash, challenge);
289   
290   /* Generate the NTLMSSP-v1 RC4 Key.
291    * The RC4 key is derived from the Lan Manager Hash.  
292    * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
293    */
294   memset(pw21, 0xBD, sizeof(pw21));
295   memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
296
297   /* Only the first eight bytes of challenge_response is used */
298   crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
299   crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
300   crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
301   
302   /* Create the SSP Key */
303   memset(sspkey, 0, sizeof(sspkey));
304   if (use_key_128) {
305     /* Create 128 bit key */
306     memcpy(sspkey, rc4key, 16);
307   }
308   else {
309     /* Create 40 bit key */
310     memcpy(sspkey, rc4key, 5);
311     sspkey[5]=0xe5;
312     sspkey[6]=0x38;
313     sspkey[7]=0xb0;
314   }
315   return;
316 }
317
318 /* dissect a string - header area contains:
319      two byte len
320      two byte maxlen
321      four byte offset of string in data area
322   The function returns the offset at the end of the string header,
323   but the 'end' parameter returns the offset of the end of the string itself
324   The 'start' parameter returns the offset of the beginning of the string
325 */
326 static int
327 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
328                         proto_tree *ntlmssp_tree, 
329                         gboolean unicode_strings,
330                         int string_hf, int *start, int *end)
331 {
332   proto_tree *tree = NULL;
333   proto_item *tf = NULL;
334   gint16 string_length = tvb_get_letohs(tvb, offset);
335   gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
336   gint32 string_offset = tvb_get_letohl(tvb, offset+4);
337   const char *string_text = NULL;
338   int result_length;
339   guint16 bc;
340
341   *start = (string_offset > offset+8 ? string_offset : offset+8);
342   if (0 == string_length) {
343     *end = *start;
344     if (ntlmssp_tree)
345             proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
346                                   offset, 8, "NULL");
347     return offset+8;
348   }
349
350   bc = result_length = string_length;
351   string_text = get_unicode_or_ascii_string(tvb, &string_offset,
352                                             unicode_strings, &result_length,
353                                             FALSE, TRUE, &bc);
354
355   if (ntlmssp_tree) {
356     tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
357                                string_offset, result_length, string_text);
358     tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
359   }
360   proto_tree_add_uint(tree, hf_ntlmssp_string_len,
361                       tvb, offset, 2, string_length);
362   offset += 2;
363   proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
364                       tvb, offset, 2, string_maxlen);
365   offset += 2;
366   proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
367                       tvb, offset, 4, string_offset);
368   offset += 4;
369
370   *end = string_offset + string_length;
371   return offset;
372 }
373
374 /* dissect a generic blob - header area contains:
375      two byte len
376      two byte maxlen
377      four byte offset of blob in data area
378   The function returns the offset at the end of the blob header,
379   but the 'end' parameter returns the offset of the end of the blob itself
380 */
381 static int
382 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
383                       proto_tree *ntlmssp_tree, 
384                       int blob_hf, int *end, ntlmssp_blob *result)
385 {
386   proto_item *tf = NULL;
387   proto_tree *tree = NULL;
388   guint16 blob_length = tvb_get_letohs(tvb, offset);
389   guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
390   guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
391
392   if (0 == blob_length) {
393     *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
394     if (ntlmssp_tree)
395             proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
396                                 proto_registrar_get_name(blob_hf));
397     return offset+8;
398   }
399
400   if (ntlmssp_tree) {
401     tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb, 
402                               blob_offset, blob_length, FALSE);
403     tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
404   }
405   proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
406                       tvb, offset, 2, blob_length);
407   offset += 2;
408   proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
409                       tvb, offset, 2, blob_maxlen);
410   offset += 2;
411   proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
412                       tvb, offset, 4, blob_offset);
413   offset += 4;
414
415   *end = blob_offset + blob_length;
416
417   if (result != NULL) {
418     result->length = blob_length;
419     memset(result->contents, 0, MAX_BLOB_SIZE);
420     if (blob_length < MAX_BLOB_SIZE)
421       tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
422   }
423
424   /* If we are dissecting the NTLM response and it is a NTLMv2
425      response call the appropriate dissector. */
426
427   if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
428           dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
429
430   return offset;
431 }
432
433 static int
434 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
435                                  proto_tree *ntlmssp_tree,
436                                  guint32 negotiate_flags)
437 {
438   proto_tree *negotiate_flags_tree = NULL;
439   proto_item *tf = NULL;
440
441   if (ntlmssp_tree) {
442     tf = proto_tree_add_uint (ntlmssp_tree,
443                               hf_ntlmssp_negotiate_flags,
444                               tvb, offset, 4, negotiate_flags);
445     negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
446   }
447
448   proto_tree_add_boolean (negotiate_flags_tree,
449                           hf_ntlmssp_negotiate_flags_80000000,
450                           tvb, offset, 4, negotiate_flags);
451   proto_tree_add_boolean (negotiate_flags_tree,
452                           hf_ntlmssp_negotiate_flags_40000000,
453                           tvb, offset, 4, negotiate_flags);
454   proto_tree_add_boolean (negotiate_flags_tree,
455                           hf_ntlmssp_negotiate_flags_20000000,
456                           tvb, offset, 4, negotiate_flags);
457   proto_tree_add_boolean (negotiate_flags_tree,
458                           hf_ntlmssp_negotiate_flags_10000000,
459                           tvb, offset, 4, negotiate_flags);
460   proto_tree_add_boolean (negotiate_flags_tree,
461                           hf_ntlmssp_negotiate_flags_8000000,
462                           tvb, offset, 4, negotiate_flags);
463   proto_tree_add_boolean (negotiate_flags_tree,
464                           hf_ntlmssp_negotiate_flags_4000000,
465                           tvb, offset, 4, negotiate_flags);
466   proto_tree_add_boolean (negotiate_flags_tree,
467                           hf_ntlmssp_negotiate_flags_2000000,
468                           tvb, offset, 4, negotiate_flags);
469   proto_tree_add_boolean (negotiate_flags_tree,
470                           hf_ntlmssp_negotiate_flags_1000000,
471                           tvb, offset, 4, negotiate_flags);
472   proto_tree_add_boolean (negotiate_flags_tree,
473                           hf_ntlmssp_negotiate_flags_800000,
474                           tvb, offset, 4, negotiate_flags);
475   proto_tree_add_boolean (negotiate_flags_tree,
476                           hf_ntlmssp_negotiate_flags_400000,
477                           tvb, offset, 4, negotiate_flags);
478   proto_tree_add_boolean (negotiate_flags_tree,
479                           hf_ntlmssp_negotiate_flags_200000,
480                           tvb, offset, 4, negotiate_flags);
481   proto_tree_add_boolean (negotiate_flags_tree,
482                           hf_ntlmssp_negotiate_flags_100000,
483                           tvb, offset, 4, negotiate_flags);
484   proto_tree_add_boolean (negotiate_flags_tree,
485                           hf_ntlmssp_negotiate_flags_80000,
486                           tvb, offset, 4, negotiate_flags);
487   proto_tree_add_boolean (negotiate_flags_tree,
488                           hf_ntlmssp_negotiate_flags_40000,
489                           tvb, offset, 4, negotiate_flags);
490   proto_tree_add_boolean (negotiate_flags_tree,
491                           hf_ntlmssp_negotiate_flags_20000,
492                           tvb, offset, 4, negotiate_flags);
493   proto_tree_add_boolean (negotiate_flags_tree,
494                           hf_ntlmssp_negotiate_flags_10000,
495                           tvb, offset, 4, negotiate_flags);
496   proto_tree_add_boolean (negotiate_flags_tree,
497                           hf_ntlmssp_negotiate_flags_8000,
498                           tvb, offset, 4, negotiate_flags);
499   proto_tree_add_boolean (negotiate_flags_tree,
500                           hf_ntlmssp_negotiate_flags_4000,
501                           tvb, offset, 4, negotiate_flags);
502   proto_tree_add_boolean (negotiate_flags_tree,
503                           hf_ntlmssp_negotiate_flags_2000,
504                           tvb, offset, 4, negotiate_flags);
505   proto_tree_add_boolean (negotiate_flags_tree,
506                           hf_ntlmssp_negotiate_flags_1000,
507                           tvb, offset, 4, negotiate_flags);
508   proto_tree_add_boolean (negotiate_flags_tree,
509                           hf_ntlmssp_negotiate_flags_800,
510                           tvb, offset, 4, negotiate_flags);
511   proto_tree_add_boolean (negotiate_flags_tree,
512                           hf_ntlmssp_negotiate_flags_400,
513                           tvb, offset, 4, negotiate_flags);
514   proto_tree_add_boolean (negotiate_flags_tree,
515                           hf_ntlmssp_negotiate_flags_200,
516                           tvb, offset, 4, negotiate_flags);
517   proto_tree_add_boolean (negotiate_flags_tree,
518                           hf_ntlmssp_negotiate_flags_100,
519                           tvb, offset, 4, negotiate_flags);
520   proto_tree_add_boolean (negotiate_flags_tree,
521                           hf_ntlmssp_negotiate_flags_80,
522                           tvb, offset, 4, negotiate_flags);
523   proto_tree_add_boolean (negotiate_flags_tree,
524                           hf_ntlmssp_negotiate_flags_40,
525                           tvb, offset, 4, negotiate_flags);
526   proto_tree_add_boolean (negotiate_flags_tree,
527                           hf_ntlmssp_negotiate_flags_20,
528                           tvb, offset, 4, negotiate_flags);
529   proto_tree_add_boolean (negotiate_flags_tree,
530                           hf_ntlmssp_negotiate_flags_10,
531                           tvb, offset, 4, negotiate_flags);
532   proto_tree_add_boolean (negotiate_flags_tree,
533                           hf_ntlmssp_negotiate_flags_08,
534                           tvb, offset, 4, negotiate_flags);
535   proto_tree_add_boolean (negotiate_flags_tree,
536                           hf_ntlmssp_negotiate_flags_04,
537                           tvb, offset, 4, negotiate_flags);
538   proto_tree_add_boolean (negotiate_flags_tree,
539                           hf_ntlmssp_negotiate_flags_02,
540                           tvb, offset, 4, negotiate_flags);
541   proto_tree_add_boolean (negotiate_flags_tree,
542                           hf_ntlmssp_negotiate_flags_01,
543                           tvb, offset, 4, negotiate_flags);
544
545   return (offset + 4);
546 }
547
548
549 static int
550 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
551 {
552   guint32 negotiate_flags;
553   int start;
554   int workstation_end;
555   int domain_end;
556
557   /* NTLMSSP Negotiate Flags */
558   negotiate_flags = tvb_get_letohl (tvb, offset);
559   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
560                                             negotiate_flags);
561
562   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE, 
563                                   hf_ntlmssp_negotiate_domain,
564                                   &start, &workstation_end);
565   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE, 
566                                   hf_ntlmssp_negotiate_workstation,
567                                   &start, &domain_end);
568
569   /* XXX - two blobs after this one, sometimes? */
570
571   return MAX(workstation_end, domain_end);
572 }
573
574
575 static int
576 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset, 
577                               proto_tree *ntlmssp_tree, 
578                               int *end)
579 {
580   guint16 list_length = tvb_get_letohs(tvb, offset);
581   guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
582   guint32 list_offset = tvb_get_letohl(tvb, offset+4);
583   guint16 item_type, item_length;
584   int item_offset;
585   proto_item *tf = NULL;
586   proto_tree *tree = NULL;
587
588   /* the address list is just a blob */
589   if (0 == list_length) {
590     *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
591     if (ntlmssp_tree)
592             proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
593                                 "Address List: Empty");
594     return offset+8;
595   }
596
597   if (ntlmssp_tree) {
598     tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb, 
599                               list_offset, list_length, FALSE);
600     tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
601   }
602   proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
603                       tvb, offset, 2, list_length);
604   offset += 2;
605   proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
606                       tvb, offset, 2, list_maxlen);
607   offset += 2;
608   proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
609                       tvb, offset, 4, list_offset);
610   offset += 4;
611
612   item_offset = list_offset;
613   item_type = tvb_get_letohs(tvb, item_offset);
614   item_offset += 2;
615   item_length = tvb_get_letohs(tvb, item_offset);
616   item_offset += 2;
617   while (item_type) {
618     guint16 bc;
619     int result_length;
620     const char *text;
621     bc = item_length;
622
623     /* Strings are always in unicode regardless of the negotiated
624        string type. */
625
626     text = get_unicode_or_ascii_string(tvb, &item_offset,
627                                        TRUE, &result_length,
628                                        FALSE, FALSE, &bc);
629
630     if (!text) text = ""; /* Make sure we don't blow up below */
631
632     switch(item_type) {
633     case NTLM_NAME_NB_HOST:
634       proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
635                             tvb, item_offset, item_length, text);
636       break;
637     case NTLM_NAME_NB_DOMAIN:
638       proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
639                             tvb, item_offset, item_length, text);
640       break;
641     case NTLM_NAME_DNS_HOST:
642       proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
643                             tvb, item_offset, item_length, text);
644       break;
645     case NTLM_NAME_DNS_DOMAIN:
646       proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
647                             tvb, item_offset, item_length, text);
648     }
649
650     item_offset += item_length;
651     item_type = tvb_get_letohs(tvb, item_offset);
652     item_offset += 2;
653     item_length = tvb_get_letohs(tvb, item_offset);
654     item_offset += 2;
655   }
656
657   *end = list_offset + list_length;
658   return offset;
659 }
660
661 static int
662 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
663                            proto_tree *ntlmssp_tree)
664 {
665   guint32 negotiate_flags;
666   int item_start, item_end;
667   int data_start, data_end;
668   ntlmssp_info *conv_ntlmssp_info;
669   conversation_t *conversation;
670   gboolean unicode_strings = FALSE;
671   guint8 sspkey[16]; /* NTLMSSP cipher key */
672   guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
673
674   /* need to find unicode flag */
675   negotiate_flags = tvb_get_letohl (tvb, offset+8);
676   if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
677     unicode_strings = TRUE;
678
679   /* Domain name */
680   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings, 
681                          hf_ntlmssp_challenge_domain,
682                          &item_start, &item_end);
683   data_start = item_start;
684   data_end = item_end;
685
686   /* NTLMSSP Negotiate Flags */
687   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
688                                             negotiate_flags);
689
690   /* NTLMSSP NT Lan Manager Challenge */
691   proto_tree_add_item (ntlmssp_tree,
692                        hf_ntlmssp_ntlm_challenge,
693                        tvb, offset, 8, FALSE);
694
695   /*
696    * Store the flags and the challenge with the conversation, as they're
697    * needed in order to dissect subsequent messages.
698    */
699   conversation = find_conversation(&pinfo->src, &pinfo->dst,
700                                    pinfo->ptype, pinfo->srcport,
701                                    pinfo->destport, 0);
702   if (!conversation) { /* Create one */
703     conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype, 
704                                     pinfo->srcport, pinfo->destport, 0);
705   }
706
707   if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
708     conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
709     /* Insert the flags into the conversation */
710     conv_ntlmssp_info->flags = negotiate_flags;
711     /* Insert the challenge into the conversation */
712     tvb_memcpy(tvb, conv_ntlmssp_info->challenge, offset, 8);
713
714     /* Between the challenge and the user provided password, we can build the
715        NTLMSSP key and initialize the cipher */
716     if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
717       create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge, 
718                             1, sspkey);
719       ssp_key_len = 16;
720     }
721     else {
722       create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge, 
723                             0, sspkey);
724       ssp_key_len = 8;
725     }
726     crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
727     crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
728     conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
729     conv_ntlmssp_info->rc4_state_initialized = 1;
730
731     conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
732   }
733   offset += 8;
734
735   /* Reserved (function not completely known) */
736   /* XXX - SSP key? */
737   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
738                        tvb, offset, 8, FALSE);
739   offset += 8;
740
741   /*
742    * The presence or absence of this field is not obviously correlated
743    * with any flags in the previous NEGOTIATE message or in this
744    * message (other than the "Workstation Supplied" and "Domain
745    * Supplied" flags in the NEGOTIATE message, at least in the capture
746    * I've seen - but those also correlate with the presence of workstation
747    * and domain name fields, so it doesn't seem to make sense that they
748    * actually *indicate* whether the subsequent CHALLENGE has an
749    * address list).
750    */
751   if (offset < data_start) {
752     offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
753     data_end = MAX(data_end, item_end);
754   }
755
756   return MAX(offset, data_end);
757 }
758
759 static int
760 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
761                       proto_tree *ntlmssp_tree)
762 {
763   int item_start, item_end;
764   int data_start, data_end = 0;
765   guint32 negotiate_flags;
766   gboolean unicode_strings = FALSE;
767   ntlmssp_info *conv_ntlmssp_info;
768   conversation_t *conversation;
769
770   /*
771    * Get flag info from the original negotiate message, if any.
772    * This is because the flag information is sometimes missing from
773    * the AUTHENTICATE message, so we can't figure out whether
774    * strings are Unicode or not by looking at *our* flags.
775    */
776   conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
777   if (conv_ntlmssp_info == NULL) {
778     /*
779      * There isn't any.  Is there any from this conversation?  If so,
780      * it means this is the first time we've dissected this frame, so
781      * we should give it flag info.
782      */
783     conversation = find_conversation(&pinfo->src, &pinfo->dst,
784                                      pinfo->ptype, pinfo->srcport,
785                                      pinfo->destport, 0);
786     if (conversation != NULL) {
787       conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
788       if (conv_ntlmssp_info != NULL) {
789         /*
790          * We have flag info; attach it to the frame.
791          */
792         p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
793       }
794     }
795   }
796   if (conv_ntlmssp_info != NULL) {
797     if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
798       unicode_strings = TRUE;
799   }
800
801   /*
802    * Sometimes the session key and flags are missing.
803    * Sometimes the session key is present but the flags are missing.
804    * Sometimes they're both present.
805    *
806    * This does not correlate with any flags in the previous CHALLENGE
807    * message, and only correlates with "Negotiate Unicode", "Workstation
808    * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
809    * those don't make sense as flags to use to determine this.
810    *
811    * So we check all of the descriptors to figure out where the data
812    * area begins, and if the session key or the flags would be in the
813    * middle of the data area, we assume the field in question is
814    * missing.
815    */
816
817   /* Lan Manager response */
818   data_start = tvb_get_letohl(tvb, offset+4);
819   offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
820                                 hf_ntlmssp_auth_lmresponse,
821                                 &item_end,
822                                 conv_ntlmssp_info == NULL ? NULL :
823                                     &conv_ntlmssp_info->lm_response);
824   data_end = MAX(data_end, item_end);
825
826   /* NTLM response */
827   item_start = tvb_get_letohl(tvb, offset+4);
828   offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
829                                 hf_ntlmssp_auth_ntresponse,
830                                 &item_end,
831                                 conv_ntlmssp_info == NULL ? NULL :
832                                 &conv_ntlmssp_info->ntlm_response);
833   data_start = MIN(data_start, item_start);
834   data_end = MAX(data_end, item_end);
835
836   /* domain name */
837   item_start = tvb_get_letohl(tvb, offset+4);
838   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
839                                   unicode_strings, 
840                                   hf_ntlmssp_auth_domain,
841                                   &item_start, &item_end);
842   data_start = MIN(data_start, item_start);
843   data_end = MAX(data_end, item_end);
844
845   /* user name */
846   item_start = tvb_get_letohl(tvb, offset+4);
847   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
848                                   unicode_strings, 
849                                   hf_ntlmssp_auth_username,
850                                   &item_start, &item_end);
851   data_start = MIN(data_start, item_start);
852   data_end = MAX(data_end, item_end);
853
854   /* hostname */
855   item_start = tvb_get_letohl(tvb, offset+4);
856   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
857                                   unicode_strings, 
858                                   hf_ntlmssp_auth_hostname,
859                                   &item_start, &item_end);
860   data_start = MIN(data_start, item_start);
861   data_end = MAX(data_end, item_end);
862
863   if (offset < data_start) {
864     /* Session Key */
865     offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
866                                   hf_ntlmssp_auth_sesskey,
867                                   &item_end, NULL);
868     data_end = MAX(data_end, item_end);
869   }
870
871   if (offset < data_start) {
872     /* NTLMSSP Negotiate Flags */
873     negotiate_flags = tvb_get_letohl (tvb, offset);
874     offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
875                                               negotiate_flags);
876   }
877
878   return MAX(offset, data_end);
879 }
880
881 static void
882 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
883 {
884   guint32 ntlmssp_message_type;
885   volatile int offset = 0;
886   proto_tree *volatile ntlmssp_tree = NULL;
887   proto_item *tf = NULL;
888
889   /* Setup a new tree for the NTLMSSP payload */
890   if (tree) {
891     tf = proto_tree_add_item (tree,
892                               hf_ntlmssp,
893                               tvb, offset, -1, FALSE);
894
895     ntlmssp_tree = proto_item_add_subtree (tf,
896                                            ett_ntlmssp);
897   }
898
899   /*
900    * Catch the ReportedBoundsError exception; the stuff we've been
901    * handed doesn't necessarily run to the end of the packet, it's
902    * an item inside a packet, so if it happens to be malformed (or
903    * we, or a dissector we call, has a bug), so that an exception
904    * is thrown, we want to report the error, but return and let
905    * our caller dissect the rest of the packet.
906    *
907    * If it gets a BoundsError, we can stop, as there's nothing more
908    * in the packet after our blob to see, so we just re-throw the
909    * exception.
910    */
911   TRY {
912     /* NTLMSSP constant */
913     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
914                          tvb, offset, 8, FALSE);
915     offset += 8;
916
917     /* NTLMSSP Message Type */
918     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
919                          tvb, offset, 4, TRUE);
920     ntlmssp_message_type = tvb_get_letohl (tvb, offset);
921     offset += 4; 
922
923     if (check_col(pinfo->cinfo, COL_INFO))
924             col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
925                             val_to_str(ntlmssp_message_type, 
926                                        ntlmssp_message_types,
927                                        "Unknown message type"));
928
929     /* Call the appropriate dissector based on the Message Type */
930     switch (ntlmssp_message_type) {
931
932     case NTLMSSP_NEGOTIATE:
933       offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
934       break;
935
936     case NTLMSSP_CHALLENGE:
937       offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
938       break;
939
940     case NTLMSSP_AUTH:
941       offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
942       break;
943
944     default:
945       /* Unrecognized message type */
946       proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
947                            "Unrecognized NTLMSSP Message");
948       break;
949     }
950   } CATCH(BoundsError) {
951     RETHROW;
952   } CATCH(ReportedBoundsError) {
953     show_reported_bounds_error(tvb, pinfo, tree);
954   } ENDTRY;
955 }
956
957 /*
958  * Get the encryption state tied to this conversation.  cryptpeer indicates 
959  * whether to retrieve the data for peer1 or peer2.
960  */
961 static rc4_state_struct *
962 get_encrypted_state(packet_info *pinfo, int cryptpeer)
963 {
964   conversation_t *conversation;
965   ntlmssp_info *conv_ntlmssp_info;
966
967   conversation = find_conversation(&pinfo->src, &pinfo->dst,
968                                    pinfo->ptype, pinfo->srcport,
969                                    pinfo->destport, 0);
970   if (conversation == NULL) {
971     /* We don't have a conversation.  In this case, stop processing
972        because we do not have enough info to decrypt the payload */
973     return NULL;
974   }
975   else {
976     /* We have a conversation, check for encryption state */
977     conv_ntlmssp_info = conversation_get_proto_data(conversation,
978                                                     proto_ntlmssp);
979     if (conv_ntlmssp_info == NULL) {
980       /* No encryption state tied to the conversation.  Therefore, we
981          cannot decrypt the payload */
982       return NULL;
983     }
984     else {
985       /* We have the encryption state in the conversation.  So return the
986          crypt state tied to the requested peer
987        */
988       if (cryptpeer == 1) {
989         return &conv_ntlmssp_info->rc4_state_peer1;
990       } else {
991         return &conv_ntlmssp_info->rc4_state_peer2;
992       }
993     }
994   }
995   return NULL;
996 }
997
998 /*
999  * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1000  */
1001 static void
1002 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1003                  packet_info *pinfo, proto_tree *tree)
1004 {
1005   proto_tree *decr_tree = NULL;
1006   proto_item *tf = NULL;
1007   conversation_t *conversation;
1008   rc4_state_struct *rc4_state;
1009   rc4_state_struct *rc4_state_peer;
1010   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1011   guint8 *peer_block;
1012   ntlmssp_info *conv_ntlmssp_info = NULL;
1013   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1014   int decrypted_offset = 0;
1015
1016   packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1017   if (packet_ntlmssp_info == NULL) {
1018     /* We don't have data for this packet */
1019     return;
1020   }
1021   if (!packet_ntlmssp_info->verifier_decrypted) {
1022     conversation = find_conversation(&pinfo->src, &pinfo->dst,
1023                                      pinfo->ptype, pinfo->srcport,
1024                                      pinfo->destport, 0);
1025     if (conversation == NULL) {
1026       /* There is no conversation, thus no encryption state */
1027       return;
1028     }
1029
1030     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1031                                                     proto_ntlmssp);
1032     if (conv_ntlmssp_info == NULL) {
1033       /* There is no NTLMSSP state tied to the conversation */
1034       return;
1035     }
1036     if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1037       /* The crypto sybsystem is not initialized.  This means that either
1038          the conversation did not include a challenge, or we are doing
1039          something other than NTLMSSP v1 */
1040       return;
1041     }
1042
1043     if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1044       rc4_state = get_encrypted_state(pinfo, 1);
1045       rc4_state_peer = get_encrypted_state(pinfo, 0);
1046     } else {
1047       rc4_state = get_encrypted_state(pinfo, 0);
1048       rc4_state_peer = get_encrypted_state(pinfo, 1);
1049     }
1050
1051     if (rc4_state == NULL || rc4_state_peer == NULL) {
1052       /* There is no encryption state, so we cannot decrypt */
1053       return;
1054     }
1055
1056     /* Setup the buffer to decrypt to */
1057     tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1058                offset, encrypted_block_length);
1059     
1060     /* Do the actual decryption of the verifier */
1061     crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1062               encrypted_block_length);
1063
1064     /* We setup a temporary buffer so we can re-encrypt the payload after
1065        decryption.  This is to update the opposite peer's RC4 state */
1066     peer_block = g_malloc(encrypted_block_length);
1067     memcpy(peer_block, packet_ntlmssp_info->verifier,
1068            encrypted_block_length);
1069     crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1070     g_free(peer_block);
1071
1072     /* Mark the packet as decrypted so that subsequent attempts to dissect
1073        the packet use the already decrypted payload instead of attempting
1074        to decrypt again */
1075     packet_ntlmssp_info->verifier_decrypted = TRUE;
1076   }
1077
1078   /* Show the decrypted buffer in a new window */
1079   decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1080                                encrypted_block_length,
1081                                encrypted_block_length);
1082   tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1083   add_new_data_source(pinfo, decr_tvb,
1084                       "Decrypted NTLMSSP Verifier");
1085
1086   /* Show the decrypted payload in the tree */
1087   tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1088                            "Decrypted Verifier (%d byte%s)",
1089                            encrypted_block_length, 
1090                            plurality(encrypted_block_length, "", "s"));
1091   decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1092
1093   /* LKCL page 45 says this is a "reserved" field.  I'm not sure if it's
1094      garbage because it's some sort of nonce, or because there is a problem
1095      with the verifier decryption routine.  */
1096   proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1097                        decr_tvb, decrypted_offset, 4, TRUE);
1098   decrypted_offset += 4;
1099
1100   /* CRC32 of the DCE fragment data */
1101   proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1102                        decr_tvb, decrypted_offset, 4, TRUE);
1103   decrypted_offset += 4;
1104
1105   /* Incrementing sequence number of DCE conversation */
1106   proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1107                        decr_tvb, decrypted_offset, 4, TRUE);
1108   decrypted_offset += 4;
1109 }
1110
1111 static int
1112 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1113 {
1114   volatile int offset = 0;
1115   proto_tree *volatile ntlmssp_tree = NULL;
1116   proto_item *tf = NULL;
1117   guint32 verifier_length;
1118   guint32 encrypted_block_length;
1119
1120   verifier_length = tvb_length_remaining (tvb, offset);
1121   encrypted_block_length = verifier_length - 4;
1122
1123   if (encrypted_block_length < 12) {
1124     /* Don't know why this would happen, but if it does, don't even bother
1125        attempting decryption/dissection */
1126     return offset + verifier_length;
1127   }
1128
1129   /* Setup a new tree for the NTLMSSP payload */
1130   if (tree) {
1131     tf = proto_tree_add_item (tree,
1132                               hf_ntlmssp_verf,
1133                               tvb, offset, -1, FALSE);
1134
1135     ntlmssp_tree = proto_item_add_subtree (tf,
1136                                            ett_ntlmssp);
1137   }
1138
1139   /*
1140    * Catch the ReportedBoundsError exception; the stuff we've been
1141    * handed doesn't necessarily run to the end of the packet, it's
1142    * an item inside a packet, so if it happens to be malformed (or
1143    * we, or a dissector we call, has a bug), so that an exception
1144    * is thrown, we want to report the error, but return and let
1145    * our caller dissect the rest of the packet.
1146    *
1147    * If it gets a BoundsError, we can stop, as there's nothing more
1148    * in the packet after our blob to see, so we just re-throw the
1149    * exception.
1150    */
1151   TRY {
1152     /* Version number */
1153     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1154                          tvb, offset, 4, TRUE);
1155     offset += 4;
1156   
1157     /* Encrypted body */
1158     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1159                          tvb, offset, encrypted_block_length, TRUE);
1160
1161     /* Try to decrypt */
1162     decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1163
1164     offset += encrypted_block_length;
1165   } CATCH(BoundsError) {
1166     RETHROW;
1167   } CATCH(ReportedBoundsError) {
1168     show_reported_bounds_error(tvb, pinfo, tree);
1169   } ENDTRY;
1170
1171   return offset;
1172 }
1173
1174
1175 static int
1176 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, 
1177                                   packet_info *pinfo, proto_tree *tree)
1178 {
1179   volatile int offset = 0;
1180   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1181   guint8 *peer_block;
1182   conversation_t *conversation;
1183   guint32 encrypted_block_length;
1184   rc4_state_struct *rc4_state;
1185   rc4_state_struct *rc4_state_peer;
1186   ntlmssp_info *conv_ntlmssp_info = NULL;
1187   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1188   proto_item *it;
1189   static ntlmssp_decrypted_info_t ndi;
1190
1191   encrypted_block_length = tvb_length_remaining (tvb, offset);
1192
1193   /* Check to see if we already have state for this packet */
1194   packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1195   if (packet_ntlmssp_info == NULL) {
1196     /* We don't have any packet state, so create one */
1197     packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1198     memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1199     p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1200   }
1201   
1202   if (!packet_ntlmssp_info->payload_decrypted) {
1203     /* Pull the challenge info from the conversation */
1204     conversation = find_conversation(&pinfo->src, &pinfo->dst,
1205                                      pinfo->ptype, pinfo->srcport,
1206                                      pinfo->destport, 0);
1207     if (conversation == NULL) {
1208       /* There is no conversation, thus no encryption state */
1209       return offset + encrypted_block_length;
1210     }
1211     
1212     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1213                                                     proto_ntlmssp);
1214     if (conv_ntlmssp_info == NULL) {
1215       /* There is no NTLMSSP state tied to the conversation */
1216       return offset + encrypted_block_length;
1217     }
1218     
1219     /* Get the pair of RC4 state structures.  One is used for to decrypt the
1220        payload.  The other is used to re-encrypt the payload to represent
1221        the peer */
1222     if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1223       rc4_state = get_encrypted_state(pinfo, 1);
1224       rc4_state_peer = get_encrypted_state(pinfo, 0);
1225     } else {
1226       rc4_state = get_encrypted_state(pinfo, 0);
1227       rc4_state_peer = get_encrypted_state(pinfo, 1);
1228     }
1229     
1230     if (rc4_state == NULL || rc4_state_peer == NULL) {
1231       /* There is no encryption state, so we cannot decrypt */
1232       return offset + encrypted_block_length;
1233     }
1234
1235     /* Store the decrypted contents in the packet state struct
1236        (of course at this point, they aren't decrypted yet) */
1237     packet_ntlmssp_info->decrypted_payload = g_malloc (encrypted_block_length);
1238     decrypted_payloads = g_slist_prepend(decrypted_payloads,
1239                                          packet_ntlmssp_info->decrypted_payload);
1240     tvb_memcpy(tvb, packet_ntlmssp_info->decrypted_payload, 
1241                offset, encrypted_block_length);
1242     
1243     /* Do the decryption of the payload */
1244     crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload, 
1245               encrypted_block_length);
1246     
1247     /* We setup a temporary buffer so we can re-encrypt the payload after
1248        decryption.  This is to update the opposite peer's RC4 state */
1249     peer_block = g_malloc(encrypted_block_length);
1250     memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1251            encrypted_block_length);
1252     crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1253     g_free(peer_block);
1254     
1255     packet_ntlmssp_info->payload_decrypted = TRUE;
1256   }
1257
1258   /* Show the decrypted buffer in a new window */
1259   decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1260                                encrypted_block_length,
1261                                encrypted_block_length);
1262   tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1263   add_new_data_source(pinfo, decr_tvb,
1264                       "Decrypted NTLMSSP block");
1265   
1266   /* Show the decrypted payload in the tree */
1267   it=proto_tree_add_text(tree, decr_tvb, 0, -1,
1268                         "Decrypted stub data (%d byte%s)",
1269                         encrypted_block_length, 
1270                         plurality(encrypted_block_length, "", "s"));
1271   ndi.decr_tree=proto_item_add_subtree(it, ett_ntlmssp_decrypted_tree);
1272   ndi.decr_tvb=decr_tvb;    
1273   pinfo->decrypted_data=&ndi;
1274
1275   offset += encrypted_block_length;
1276   return offset;
1277 }
1278
1279 static void
1280 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1281 {
1282         g_free(decrypted_payload);
1283 }
1284
1285 static void
1286 ntlmssp_init_protocol(void)
1287 {
1288         if (ntlmssp_info_chunk != NULL)
1289                 g_mem_chunk_destroy(ntlmssp_info_chunk);
1290         if (ntlmssp_packet_info_chunk != NULL)
1291                 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1292
1293         /*
1294          * Free the decrypted payloads, and then free the list of decrypted
1295          * payloads.
1296          */
1297         if (decrypted_payloads != NULL) {
1298                 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1299                 g_slist_free(decrypted_payloads);
1300                 decrypted_payloads = NULL;
1301         }
1302
1303         ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1304             sizeof(ntlmssp_info),
1305             ntlmssp_info_count * sizeof(ntlmssp_info),
1306             G_ALLOC_ONLY);
1307         ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1308             sizeof(ntlmssp_packet_info),
1309             ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1310             G_ALLOC_ONLY);
1311 }
1312
1313 void
1314 proto_register_ntlmssp(void)
1315 {
1316
1317   static hf_register_info hf[] = {
1318     { &hf_ntlmssp,
1319       { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1320
1321     { &hf_ntlmssp_auth,
1322       { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1323
1324     { &hf_ntlmssp_message_type,
1325       { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1326
1327     { &hf_ntlmssp_negotiate_flags,
1328       { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1329     { &hf_ntlmssp_negotiate_flags_01,
1330
1331       { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1332     { &hf_ntlmssp_negotiate_flags_02,
1333       { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1334     { &hf_ntlmssp_negotiate_flags_04,
1335       { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1336     { &hf_ntlmssp_negotiate_flags_08,
1337       { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1338     { &hf_ntlmssp_negotiate_flags_10,
1339       { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1340     { &hf_ntlmssp_negotiate_flags_20,
1341       { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1342     { &hf_ntlmssp_negotiate_flags_40,
1343       { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1344     { &hf_ntlmssp_negotiate_flags_80,
1345       { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1346     { &hf_ntlmssp_negotiate_flags_100,
1347       { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1348     { &hf_ntlmssp_negotiate_flags_200,
1349       { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1350     { &hf_ntlmssp_negotiate_flags_400,
1351       { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1352     { &hf_ntlmssp_negotiate_flags_800,
1353       { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1354     { &hf_ntlmssp_negotiate_flags_1000,
1355       { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1356     { &hf_ntlmssp_negotiate_flags_2000,
1357       { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1358     { &hf_ntlmssp_negotiate_flags_4000,
1359       { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1360     { &hf_ntlmssp_negotiate_flags_8000,
1361       { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1362     { &hf_ntlmssp_negotiate_flags_10000,
1363       { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1364     { &hf_ntlmssp_negotiate_flags_20000,
1365       { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1366     { &hf_ntlmssp_negotiate_flags_40000,
1367       { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1368     { &hf_ntlmssp_negotiate_flags_80000,
1369       { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1370     { &hf_ntlmssp_negotiate_flags_100000,
1371       { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1372     { &hf_ntlmssp_negotiate_flags_200000,
1373       { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1374     { &hf_ntlmssp_negotiate_flags_400000,
1375       { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1376     { &hf_ntlmssp_negotiate_flags_800000,
1377       { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1378     { &hf_ntlmssp_negotiate_flags_1000000,
1379       { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1380     { &hf_ntlmssp_negotiate_flags_2000000,
1381       { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1382     { &hf_ntlmssp_negotiate_flags_4000000,
1383       { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1384     { &hf_ntlmssp_negotiate_flags_8000000,
1385       { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1386     { &hf_ntlmssp_negotiate_flags_10000000,
1387       { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1388     { &hf_ntlmssp_negotiate_flags_20000000,
1389       { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
1390     { &hf_ntlmssp_negotiate_flags_40000000,
1391       { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1392     { &hf_ntlmssp_negotiate_flags_80000000,
1393       { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
1394     { &hf_ntlmssp_negotiate_workstation_strlen,
1395       { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1396     { &hf_ntlmssp_negotiate_workstation_maxlen,
1397       { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1398     { &hf_ntlmssp_negotiate_workstation_buffer,
1399       { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1400     { &hf_ntlmssp_negotiate_workstation,
1401       { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1402     { &hf_ntlmssp_negotiate_domain_strlen,
1403       { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1404     { &hf_ntlmssp_negotiate_domain_maxlen,
1405       { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1406     { &hf_ntlmssp_negotiate_domain_buffer,
1407       { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1408     { &hf_ntlmssp_negotiate_domain,
1409       { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1410     { &hf_ntlmssp_ntlm_challenge,
1411       { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1412     { &hf_ntlmssp_reserved,
1413       { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1414     { &hf_ntlmssp_challenge_domain,
1415       { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1416     { &hf_ntlmssp_auth_domain,
1417       { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1418     { &hf_ntlmssp_auth_username,
1419       { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1420     { &hf_ntlmssp_auth_hostname,
1421       { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1422     { &hf_ntlmssp_auth_lmresponse,
1423       { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1424     { &hf_ntlmssp_auth_ntresponse,
1425       { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1426     { &hf_ntlmssp_auth_sesskey,
1427       { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1428     { &hf_ntlmssp_string_len,
1429       { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1430     { &hf_ntlmssp_string_maxlen,
1431       { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1432     { &hf_ntlmssp_string_offset,
1433       { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1434     { &hf_ntlmssp_blob_len,
1435       { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1436     { &hf_ntlmssp_blob_maxlen,
1437       { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1438     { &hf_ntlmssp_blob_offset,
1439       { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1440     { &hf_ntlmssp_address_list,
1441       { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1442     { &hf_ntlmssp_address_list_len,
1443       { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1444     { &hf_ntlmssp_address_list_maxlen,
1445       { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1446     { &hf_ntlmssp_address_list_offset,
1447       { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1448     { &hf_ntlmssp_address_list_server_nb,
1449       { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1450     { &hf_ntlmssp_address_list_domain_nb,
1451       { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1452     { &hf_ntlmssp_address_list_server_dns,
1453       { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1454     { &hf_ntlmssp_address_list_domain_dns,
1455       { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1456
1457     { &hf_ntlmssp_verf,
1458       { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1459     { &hf_ntlmssp_verf_vers,
1460       { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1461     { &hf_ntlmssp_verf_body,
1462       { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1463     { &hf_ntlmssp_decrypted_payload,
1464       { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1465     { &hf_ntlmssp_verf_unknown1,
1466       { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1467     { &hf_ntlmssp_verf_crc32,
1468       { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1469     { &hf_ntlmssp_verf_sequence,
1470       { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1471   };
1472
1473
1474   static gint *ett[] = {
1475     &ett_ntlmssp,
1476     &ett_ntlmssp_negotiate_flags,
1477     &ett_ntlmssp_string,
1478     &ett_ntlmssp_blob,
1479     &ett_ntlmssp_address_list,
1480     &ett_ntlmssp_decrypted_tree
1481   };
1482   module_t *ntlmssp_module;
1483   
1484   proto_ntlmssp = proto_register_protocol (
1485                                            "NTLM Secure Service Provider", /* name */
1486                                            "NTLMSSP",   /* short name */
1487                                            "ntlmssp"    /* abbrev */
1488                                            );
1489   proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1490   proto_register_subtree_array (ett, array_length (ett));
1491   register_init_routine(&ntlmssp_init_protocol);
1492
1493   ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1494   
1495   prefs_register_string_preference(ntlmssp_module, "nt_password",
1496                                    "NT Password",
1497                                    "NT Password (used to decrypt payloads)",
1498                                    &nt_password);
1499
1500   register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1501   new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1502   new_register_dissector("ntlmssp_encrypted_payload", 
1503                          dissect_ntlmssp_encrypted_payload, proto_ntlmssp);
1504 }
1505
1506 void
1507 proto_reg_handoff_ntlmssp(void)
1508 {     
1509   dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1510
1511   /* Register protocol with the GSS-API module */
1512
1513   ntlmssp_handle = find_dissector("ntlmssp");
1514   ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1515   gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp, 
1516                   ntlmssp_handle, ntlmssp_wrap_handle,
1517                   "NTLMSSP - Microsoft NTLM Security Support Provider");
1518 }