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