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