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