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