Dissect the last unknown item at the end of the NTLMv2 blob.
[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 "asn1.h"               /* XXX - needed for subid_t */
40 #include "packet-gssapi.h"
41 #include "packet-frame.h"
42 #include "prefs.h"
43 #include "crypt-rc4.h"
44 #include "crypt-md4.h"
45 #include "crypt-des.h"
46 #include "packet-dcerpc.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         proto_tree_add_item(
724                 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
725                 offset, 4, TRUE);
726
727         offset += 4;
728
729         return offset;
730 }
731
732 static int
733 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
734 {
735   guint32 negotiate_flags;
736   int start;
737   int workstation_end;
738   int domain_end;
739
740   /* NTLMSSP Negotiate Flags */
741   negotiate_flags = tvb_get_letohl (tvb, offset);
742   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
743                                             negotiate_flags);
744
745   /*
746    * XXX - the davenport document says that these might not be
747    * sent at all, presumably meaning the length of the message
748    * isn't enough to contain them.
749    */
750   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE, 
751                                   hf_ntlmssp_negotiate_domain,
752                                   &start, &workstation_end);
753   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE, 
754                                   hf_ntlmssp_negotiate_workstation,
755                                   &start, &domain_end);
756
757   /* XXX - two blobs after this one, sometimes? */
758
759   return MAX(workstation_end, domain_end);
760 }
761
762
763 static int
764 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset, 
765                               proto_tree *ntlmssp_tree, 
766                               int *end)
767 {
768   guint16 list_length = tvb_get_letohs(tvb, offset);
769   guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
770   guint32 list_offset = tvb_get_letohl(tvb, offset+4);
771   guint16 item_type, item_length;
772   guint32 item_offset;
773   proto_item *tf = NULL;
774   proto_tree *tree = NULL;
775   proto_item *addr_tf = NULL;
776   proto_tree *addr_tree = NULL;
777
778   /* the address list is just a blob */
779   if (0 == list_length) {
780     *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
781     if (ntlmssp_tree)
782             proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
783                                 "Address List: Empty");
784     return offset+8;
785   }
786
787   if (ntlmssp_tree) {
788     tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb, 
789                               list_offset, list_length, FALSE);
790     tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
791   }
792   proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
793                       tvb, offset, 2, list_length);
794   offset += 2;
795   proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
796                       tvb, offset, 2, list_maxlen);
797   offset += 2;
798   proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
799                       tvb, offset, 4, list_offset);
800   offset += 4;
801
802   /* Now enumerate through the individual items in the list */
803   item_offset = list_offset;
804
805   while (item_offset < (list_offset + list_length)) {
806     const char *text=NULL;
807     guint32 content_offset;
808     guint16 content_length;
809     guint32 type_offset;
810     guint32 len_offset;
811
812     /* Content type */
813     type_offset = item_offset;
814     item_type = tvb_get_letohs(tvb, type_offset);
815
816     /* Content length */
817     len_offset = type_offset + 2;
818     content_length = tvb_get_letohs(tvb, len_offset);
819
820     /* Content value */
821     content_offset = len_offset + 2;
822     item_length = content_length + 4;
823
824     /* Strings are always in Unicode regardless of the negotiated
825        string type. */
826     if (content_length > 0) {
827       guint16 bc;
828       int result_length;
829       int item_offset_int;
830
831       item_offset_int = content_offset;
832       bc = content_length;
833       text = get_unicode_or_ascii_string(tvb, &item_offset_int,
834                                          TRUE, &result_length,
835                                          FALSE, FALSE, &bc);
836     }
837
838     if (!text) text = ""; /* Make sure we don't blow up below */
839
840     switch(item_type) {
841     case NTLM_NAME_NB_HOST:
842       addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
843                                       tvb, item_offset, item_length, text);
844       break;
845     case NTLM_NAME_NB_DOMAIN:
846       addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
847                                       tvb, item_offset, item_length, text);
848       break;
849     case NTLM_NAME_DNS_HOST:
850       addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
851                                       tvb, item_offset, item_length, text);
852       break;
853     case NTLM_NAME_DNS_DOMAIN:
854       addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
855                                       tvb, item_offset, item_length, text);
856       break;
857     case NTLM_NAME_END:
858       addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
859                                     tvb, item_offset, item_length, TRUE);
860     }
861
862     /* Now show the actual bytes that made up the summary line */
863     addr_tree = proto_item_add_subtree (addr_tf, 
864                                         ett_ntlmssp_address_list_item);
865     proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
866                          tvb, type_offset, 2, TRUE);
867     proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
868                          tvb, len_offset, 2, TRUE);
869     if (content_length > 0) {
870       proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
871                             tvb, content_offset, content_length, text);
872     }
873
874     item_offset += item_length;
875   }
876
877   *end = list_offset + list_length;
878   return offset;
879 }
880
881 static int
882 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
883                            proto_tree *ntlmssp_tree)
884 {
885   guint32 negotiate_flags;
886   int item_start, item_end;
887   int data_start, data_end;
888   ntlmssp_info *conv_ntlmssp_info;
889   conversation_t *conversation;
890   gboolean unicode_strings = FALSE;
891   guint8 challenge[8];  
892   guint8 sspkey[16]; /* NTLMSSP cipher key */
893   guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
894
895   /* need to find unicode flag */
896   negotiate_flags = tvb_get_letohl (tvb, offset+8);
897   if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
898     unicode_strings = TRUE;
899
900   /* Domain name */
901   /*
902    * XXX - the davenport document calls this the "Target Name",
903    * presumably because non-domain targets are supported.
904    */
905   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings, 
906                          hf_ntlmssp_challenge_domain,
907                          &item_start, &item_end);
908   data_start = item_start;
909   data_end = item_end;
910
911   /* NTLMSSP Negotiate Flags */
912   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
913                                             negotiate_flags);
914
915   /* NTLMSSP NT Lan Manager Challenge */
916   proto_tree_add_item (ntlmssp_tree,
917                        hf_ntlmssp_ntlm_challenge,
918                        tvb, offset, 8, FALSE);
919
920   /*
921    * Store the flags and the RC4 state information with the conversation,
922    * as they're needed in order to dissect subsequent messages.
923    */
924   conversation = find_conversation(&pinfo->src, &pinfo->dst,
925                                    pinfo->ptype, pinfo->srcport,
926                                    pinfo->destport, 0);
927   if (!conversation) { /* Create one */
928     conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype, 
929                                     pinfo->srcport, pinfo->destport, 0);
930   }
931
932   if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
933     conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
934     /* Insert the flags into the conversation */
935     conv_ntlmssp_info->flags = negotiate_flags;
936     /* Insert the RC4 state information into the conversation */
937     tvb_memcpy(tvb, challenge, offset, 8);
938
939     /* Between the challenge and the user provided password, we can build the
940        NTLMSSP key and initialize the cipher */
941     if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
942       create_ntlmssp_v1_key(nt_password, challenge, 1, sspkey);
943       ssp_key_len = 16;
944     }
945     else {
946       create_ntlmssp_v1_key(nt_password, challenge, 0, sspkey);
947       ssp_key_len = 8;
948     }
949     crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
950     crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
951     conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
952     conv_ntlmssp_info->rc4_state_initialized = 1;
953
954     conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
955   }
956   offset += 8;
957
958   /* Reserved (function not completely known) */
959   /*
960    * XXX - SSP key?  The davenport document says
961    *
962    *    The context field is typically populated when Negotiate Local
963    *    Call is set. It contains an SSPI context handle, which allows
964    *    the client to "short-circuit" authentication and effectively
965    *    circumvent responding to the challenge. Physically, the context
966    *    is two long values. This is covered in greater detail later,
967    *    in the "Local Authentication" section.
968    *
969    * It also says that that information may be omitted.
970    */
971   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
972                        tvb, offset, 8, FALSE);
973   offset += 8;
974
975   /*
976    * The presence or absence of this field is not obviously correlated
977    * with any flags in the previous NEGOTIATE message or in this
978    * message (other than the "Workstation Supplied" and "Domain
979    * Supplied" flags in the NEGOTIATE message, at least in the capture
980    * I've seen - but those also correlate with the presence of workstation
981    * and domain name fields, so it doesn't seem to make sense that they
982    * actually *indicate* whether the subsequent CHALLENGE has an
983    * address list).
984    */
985   if (offset < data_start) {
986     offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
987     data_end = MAX(data_end, item_end);
988   }
989
990   return MAX(offset, data_end);
991 }
992
993 static int
994 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
995                       proto_tree *ntlmssp_tree)
996 {
997   int item_start, item_end;
998   int data_start, data_end = 0;
999   guint32 negotiate_flags;
1000   gboolean unicode_strings = FALSE;
1001   ntlmssp_info *conv_ntlmssp_info;
1002   conversation_t *conversation;
1003
1004   /*
1005    * Get flag info from the original negotiate message, if any.
1006    * This is because the flag information is sometimes missing from
1007    * the AUTHENTICATE message, so we can't figure out whether
1008    * strings are Unicode or not by looking at *our* flags.
1009    */
1010   conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1011   if (conv_ntlmssp_info == NULL) {
1012     /*
1013      * There isn't any.  Is there any from this conversation?  If so,
1014      * it means this is the first time we've dissected this frame, so
1015      * we should give it flag info.
1016      */
1017     conversation = find_conversation(&pinfo->src, &pinfo->dst,
1018                                      pinfo->ptype, pinfo->srcport,
1019                                      pinfo->destport, 0);
1020     if (conversation != NULL) {
1021       conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1022       if (conv_ntlmssp_info != NULL) {
1023         /*
1024          * We have flag info; attach it to the frame.
1025          */
1026         p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1027       }
1028     }
1029   }
1030   if (conv_ntlmssp_info != NULL) {
1031     if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1032       unicode_strings = TRUE;
1033   }
1034
1035   /*
1036    * Sometimes the session key and flags are missing.
1037    * Sometimes the session key is present but the flags are missing.
1038    * Sometimes they're both present.
1039    *
1040    * This does not correlate with any flags in the previous CHALLENGE
1041    * message, and only correlates with "Negotiate Unicode", "Workstation
1042    * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1043    * those don't make sense as flags to use to determine this.
1044    *
1045    * So we check all of the descriptors to figure out where the data
1046    * area begins, and if the session key or the flags would be in the
1047    * middle of the data area, we assume the field in question is
1048    * missing.
1049    */
1050
1051   /* Lan Manager response */
1052   data_start = tvb_get_letohl(tvb, offset+4);
1053   offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1054                                 hf_ntlmssp_auth_lmresponse,
1055                                 &item_end,
1056                                 conv_ntlmssp_info == NULL ? NULL :
1057                                     &conv_ntlmssp_info->lm_response);
1058   data_end = MAX(data_end, item_end);
1059
1060   /* NTLM response */
1061   item_start = tvb_get_letohl(tvb, offset+4);
1062   offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1063                                 hf_ntlmssp_auth_ntresponse,
1064                                 &item_end,
1065                                 conv_ntlmssp_info == NULL ? NULL :
1066                                 &conv_ntlmssp_info->ntlm_response);
1067   data_start = MIN(data_start, item_start);
1068   data_end = MAX(data_end, item_end);
1069
1070   /* domain name */
1071   item_start = tvb_get_letohl(tvb, offset+4);
1072   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
1073                                   unicode_strings, 
1074                                   hf_ntlmssp_auth_domain,
1075                                   &item_start, &item_end);
1076   data_start = MIN(data_start, item_start);
1077   data_end = MAX(data_end, item_end);
1078
1079   /* user name */
1080   item_start = tvb_get_letohl(tvb, offset+4);
1081   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
1082                                   unicode_strings, 
1083                                   hf_ntlmssp_auth_username,
1084                                   &item_start, &item_end);
1085   data_start = MIN(data_start, item_start);
1086   data_end = MAX(data_end, item_end);
1087
1088   /* hostname */
1089   item_start = tvb_get_letohl(tvb, offset+4);
1090   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 
1091                                   unicode_strings, 
1092                                   hf_ntlmssp_auth_hostname,
1093                                   &item_start, &item_end);
1094   data_start = MIN(data_start, item_start);
1095   data_end = MAX(data_end, item_end);
1096
1097   if (offset < data_start) {
1098     /* Session Key */
1099     offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1100                                   hf_ntlmssp_auth_sesskey,
1101                                   &item_end, NULL);
1102     data_end = MAX(data_end, item_end);
1103   }
1104
1105   if (offset < data_start) {
1106     /* NTLMSSP Negotiate Flags */
1107     negotiate_flags = tvb_get_letohl (tvb, offset);
1108     offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1109                                               negotiate_flags);
1110   }
1111
1112   return MAX(offset, data_end);
1113 }
1114
1115 static void
1116 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1117 {
1118   guint32 ntlmssp_message_type;
1119   volatile int offset = 0;
1120   proto_tree *volatile ntlmssp_tree = NULL;
1121   proto_item *tf = NULL;
1122
1123   /* Setup a new tree for the NTLMSSP payload */
1124   if (tree) {
1125     tf = proto_tree_add_item (tree,
1126                               hf_ntlmssp,
1127                               tvb, offset, -1, FALSE);
1128
1129     ntlmssp_tree = proto_item_add_subtree (tf,
1130                                            ett_ntlmssp);
1131   }
1132
1133   /*
1134    * Catch the ReportedBoundsError exception; the stuff we've been
1135    * handed doesn't necessarily run to the end of the packet, it's
1136    * an item inside a packet, so if it happens to be malformed (or
1137    * we, or a dissector we call, has a bug), so that an exception
1138    * is thrown, we want to report the error, but return and let
1139    * our caller dissect the rest of the packet.
1140    *
1141    * If it gets a BoundsError, we can stop, as there's nothing more
1142    * in the packet after our blob to see, so we just re-throw the
1143    * exception.
1144    */
1145   TRY {
1146     /* NTLMSSP constant */
1147     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
1148                          tvb, offset, 8, FALSE);
1149     offset += 8;
1150
1151     /* NTLMSSP Message Type */
1152     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
1153                          tvb, offset, 4, TRUE);
1154     ntlmssp_message_type = tvb_get_letohl (tvb, offset);
1155     offset += 4; 
1156
1157     if (check_col(pinfo->cinfo, COL_INFO))
1158             col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1159                             val_to_str(ntlmssp_message_type, 
1160                                        ntlmssp_message_types,
1161                                        "Unknown message type"));
1162
1163     /* Call the appropriate dissector based on the Message Type */
1164     switch (ntlmssp_message_type) {
1165
1166     case NTLMSSP_NEGOTIATE:
1167       offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
1168       break;
1169
1170     case NTLMSSP_CHALLENGE:
1171       offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
1172       break;
1173
1174     case NTLMSSP_AUTH:
1175       offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
1176       break;
1177
1178     default:
1179       /* Unrecognized message type */
1180       proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
1181                            "Unrecognized NTLMSSP Message");
1182       break;
1183     }
1184   } CATCH(BoundsError) {
1185     RETHROW;
1186   } CATCH(ReportedBoundsError) {
1187     show_reported_bounds_error(tvb, pinfo, tree);
1188   } ENDTRY;
1189 }
1190
1191 /*
1192  * Get the encryption state tied to this conversation.  cryptpeer indicates 
1193  * whether to retrieve the data for peer1 or peer2.
1194  */
1195 static rc4_state_struct *
1196 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1197 {
1198   conversation_t *conversation;
1199   ntlmssp_info *conv_ntlmssp_info;
1200
1201   conversation = find_conversation(&pinfo->src, &pinfo->dst,
1202                                    pinfo->ptype, pinfo->srcport,
1203                                    pinfo->destport, 0);
1204   if (conversation == NULL) {
1205     /* We don't have a conversation.  In this case, stop processing
1206        because we do not have enough info to decrypt the payload */
1207     return NULL;
1208   }
1209   else {
1210     /* We have a conversation, check for encryption state */
1211     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1212                                                     proto_ntlmssp);
1213     if (conv_ntlmssp_info == NULL) {
1214       /* No encryption state tied to the conversation.  Therefore, we
1215          cannot decrypt the payload */
1216       return NULL;
1217     }
1218     else {
1219       /* We have the encryption state in the conversation.  So return the
1220          crypt state tied to the requested peer
1221        */
1222       if (cryptpeer == 1) {
1223         return &conv_ntlmssp_info->rc4_state_peer1;
1224       } else {
1225         return &conv_ntlmssp_info->rc4_state_peer2;
1226       }
1227     }
1228   }
1229   return NULL;
1230 }
1231
1232 /*
1233  * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1234  */
1235 static void
1236 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1237                  packet_info *pinfo, proto_tree *tree)
1238 {
1239   proto_tree *decr_tree = NULL;
1240   proto_item *tf = NULL;
1241   conversation_t *conversation;
1242   rc4_state_struct *rc4_state;
1243   rc4_state_struct *rc4_state_peer;
1244   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1245   guint8 *peer_block;
1246   ntlmssp_info *conv_ntlmssp_info = NULL;
1247   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1248   int decrypted_offset = 0;
1249
1250   packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1251   if (packet_ntlmssp_info == NULL) {
1252     /* We don't have data for this packet */
1253     return;
1254   }
1255   if (!packet_ntlmssp_info->verifier_decrypted) {
1256     conversation = find_conversation(&pinfo->src, &pinfo->dst,
1257                                      pinfo->ptype, pinfo->srcport,
1258                                      pinfo->destport, 0);
1259     if (conversation == NULL) {
1260       /* There is no conversation, thus no encryption state */
1261       return;
1262     }
1263
1264     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1265                                                     proto_ntlmssp);
1266     if (conv_ntlmssp_info == NULL) {
1267       /* There is no NTLMSSP state tied to the conversation */
1268       return;
1269     }
1270     if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1271       /* The crypto sybsystem is not initialized.  This means that either
1272          the conversation did not include a challenge, or we are doing
1273          something other than NTLMSSP v1 */
1274       return;
1275     }
1276
1277     if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1278       rc4_state = get_encrypted_state(pinfo, 1);
1279       rc4_state_peer = get_encrypted_state(pinfo, 0);
1280     } else {
1281       rc4_state = get_encrypted_state(pinfo, 0);
1282       rc4_state_peer = get_encrypted_state(pinfo, 1);
1283     }
1284
1285     if (rc4_state == NULL || rc4_state_peer == NULL) {
1286       /* There is no encryption state, so we cannot decrypt */
1287       return;
1288     }
1289
1290     /* Setup the buffer to decrypt to */
1291     tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1292                offset, encrypted_block_length);
1293     
1294     /* Do the actual decryption of the verifier */
1295     crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1296               encrypted_block_length);
1297
1298     /* We setup a temporary buffer so we can re-encrypt the payload after
1299        decryption.  This is to update the opposite peer's RC4 state */
1300     peer_block = g_malloc(encrypted_block_length);
1301     memcpy(peer_block, packet_ntlmssp_info->verifier,
1302            encrypted_block_length);
1303     crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1304     g_free(peer_block);
1305
1306     /* Mark the packet as decrypted so that subsequent attempts to dissect
1307        the packet use the already decrypted payload instead of attempting
1308        to decrypt again */
1309     packet_ntlmssp_info->verifier_decrypted = TRUE;
1310   }
1311
1312   /* Show the decrypted buffer in a new window */
1313   decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1314                                encrypted_block_length,
1315                                encrypted_block_length);
1316   tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1317   add_new_data_source(pinfo, decr_tvb,
1318                       "Decrypted NTLMSSP Verifier");
1319
1320   /* Show the decrypted payload in the tree */
1321   tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1322                            "Decrypted Verifier (%d byte%s)",
1323                            encrypted_block_length, 
1324                            plurality(encrypted_block_length, "", "s"));
1325   decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1326
1327   /* LKCL page 45 says this is a "reserved" field.  I'm not sure if it's
1328      garbage because it's some sort of nonce, or because there is a problem
1329      with the verifier decryption routine.  */
1330   proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1331                        decr_tvb, decrypted_offset, 4, TRUE);
1332   decrypted_offset += 4;
1333
1334   /* CRC32 of the DCE fragment data */
1335   proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1336                        decr_tvb, decrypted_offset, 4, TRUE);
1337   decrypted_offset += 4;
1338
1339   /* Incrementing sequence number of DCE conversation */
1340   proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1341                        decr_tvb, decrypted_offset, 4, TRUE);
1342   decrypted_offset += 4;
1343 }
1344
1345 static int
1346 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1347 {
1348   volatile int offset = 0;
1349   proto_tree *volatile ntlmssp_tree = NULL;
1350   proto_item *tf = NULL;
1351   guint32 verifier_length;
1352   guint32 encrypted_block_length;
1353
1354   verifier_length = tvb_length_remaining (tvb, offset);
1355   encrypted_block_length = verifier_length - 4;
1356
1357   if (encrypted_block_length < 12) {
1358     /* Don't know why this would happen, but if it does, don't even bother
1359        attempting decryption/dissection */
1360     return offset + verifier_length;
1361   }
1362
1363   /* Setup a new tree for the NTLMSSP payload */
1364   if (tree) {
1365     tf = proto_tree_add_item (tree,
1366                               hf_ntlmssp_verf,
1367                               tvb, offset, -1, FALSE);
1368
1369     ntlmssp_tree = proto_item_add_subtree (tf,
1370                                            ett_ntlmssp);
1371   }
1372
1373   /*
1374    * Catch the ReportedBoundsError exception; the stuff we've been
1375    * handed doesn't necessarily run to the end of the packet, it's
1376    * an item inside a packet, so if it happens to be malformed (or
1377    * we, or a dissector we call, has a bug), so that an exception
1378    * is thrown, we want to report the error, but return and let
1379    * our caller dissect the rest of the packet.
1380    *
1381    * If it gets a BoundsError, we can stop, as there's nothing more
1382    * in the packet after our blob to see, so we just re-throw the
1383    * exception.
1384    */
1385   TRY {
1386     /* Version number */
1387     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1388                          tvb, offset, 4, TRUE);
1389     offset += 4;
1390   
1391     /* Encrypted body */
1392     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1393                          tvb, offset, encrypted_block_length, TRUE);
1394
1395     /* Try to decrypt */
1396     decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1397
1398     offset += encrypted_block_length;
1399   } CATCH(BoundsError) {
1400     RETHROW;
1401   } CATCH(ReportedBoundsError) {
1402     show_reported_bounds_error(tvb, pinfo, tree);
1403   } ENDTRY;
1404
1405   return offset;
1406 }
1407
1408 static tvbuff_t *
1409 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, int offset,
1410                                   packet_info *pinfo, 
1411                                   dcerpc_auth_info *auth_info _U_)
1412 {
1413   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1414   guint8 *peer_block;
1415   conversation_t *conversation;
1416   guint32 encrypted_block_length;
1417   rc4_state_struct *rc4_state;
1418   rc4_state_struct *rc4_state_peer;
1419   ntlmssp_info *conv_ntlmssp_info = NULL;
1420   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1421
1422   encrypted_block_length = tvb_length_remaining (tvb, offset);
1423
1424   /* Check to see if we already have state for this packet */
1425   packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1426   if (packet_ntlmssp_info == NULL) {
1427     /* We don't have any packet state, so create one */
1428     packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1429     memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1430     p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1431   }
1432   
1433   if (!packet_ntlmssp_info->payload_decrypted) {
1434     /* Pull the challenge info from the conversation */
1435     conversation = find_conversation(&pinfo->src, &pinfo->dst,
1436                                      pinfo->ptype, pinfo->srcport,
1437                                      pinfo->destport, 0);
1438     if (conversation == NULL) {
1439       /* There is no conversation, thus no encryption state */
1440       return NULL;
1441     }
1442     
1443     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1444                                                     proto_ntlmssp);
1445     if (conv_ntlmssp_info == NULL) {
1446       /* There is no NTLMSSP state tied to the conversation */
1447             return NULL;
1448     }
1449     
1450     /* Get the pair of RC4 state structures.  One is used for to decrypt the
1451        payload.  The other is used to re-encrypt the payload to represent
1452        the peer */
1453     if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1454       rc4_state = get_encrypted_state(pinfo, 1);
1455       rc4_state_peer = get_encrypted_state(pinfo, 0);
1456     } else {
1457       rc4_state = get_encrypted_state(pinfo, 0);
1458       rc4_state_peer = get_encrypted_state(pinfo, 1);
1459     }
1460     
1461     if (rc4_state == NULL || rc4_state_peer == NULL) {
1462       /* There is no encryption state, so we cannot decrypt */
1463       return NULL;
1464     }
1465
1466     /* Store the decrypted contents in the packet state struct
1467        (of course at this point, they aren't decrypted yet) */
1468     packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
1469                                                         encrypted_block_length);
1470     decrypted_payloads = g_slist_prepend(decrypted_payloads,
1471                                          packet_ntlmssp_info->decrypted_payload);
1472     
1473     /* Do the decryption of the payload */
1474     crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload, 
1475               encrypted_block_length);
1476     
1477     /* We setup a temporary buffer so we can re-encrypt the payload after
1478        decryption.  This is to update the opposite peer's RC4 state */
1479     peer_block = g_malloc(encrypted_block_length);
1480     memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1481            encrypted_block_length);
1482     crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1483     g_free(peer_block);
1484     
1485     packet_ntlmssp_info->payload_decrypted = TRUE;
1486   }
1487
1488   /* Show the decrypted buffer in a new window */
1489   decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1490                                encrypted_block_length,
1491                                encrypted_block_length);
1492
1493   tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1494   
1495   offset += encrypted_block_length;
1496
1497   return decr_tvb;
1498 }
1499
1500 static void
1501 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1502 {
1503         g_free(decrypted_payload);
1504 }
1505
1506 static void
1507 ntlmssp_init_protocol(void)
1508 {
1509         if (ntlmssp_info_chunk != NULL)
1510                 g_mem_chunk_destroy(ntlmssp_info_chunk);
1511         if (ntlmssp_packet_info_chunk != NULL)
1512                 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1513
1514         /*
1515          * Free the decrypted payloads, and then free the list of decrypted
1516          * payloads.
1517          */
1518         if (decrypted_payloads != NULL) {
1519                 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1520                 g_slist_free(decrypted_payloads);
1521                 decrypted_payloads = NULL;
1522         }
1523
1524         ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1525             sizeof(ntlmssp_info),
1526             ntlmssp_info_count * sizeof(ntlmssp_info),
1527             G_ALLOC_ONLY);
1528         ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1529             sizeof(ntlmssp_packet_info),
1530             ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1531             G_ALLOC_ONLY);
1532 }
1533
1534 void
1535 proto_register_ntlmssp(void)
1536 {
1537
1538   static hf_register_info hf[] = {
1539     { &hf_ntlmssp,
1540       { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1541     { &hf_ntlmssp_auth,
1542       { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1543     { &hf_ntlmssp_message_type,
1544       { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1545     { &hf_ntlmssp_negotiate_flags,
1546       { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1547     { &hf_ntlmssp_negotiate_flags_01,
1548       { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1549     { &hf_ntlmssp_negotiate_flags_02,
1550       { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1551     { &hf_ntlmssp_negotiate_flags_04,
1552       { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1553     { &hf_ntlmssp_negotiate_flags_08,
1554       { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1555     { &hf_ntlmssp_negotiate_flags_10,
1556       { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1557     { &hf_ntlmssp_negotiate_flags_20,
1558       { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1559     { &hf_ntlmssp_negotiate_flags_40,
1560       { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1561     { &hf_ntlmssp_negotiate_flags_80,
1562       { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1563     { &hf_ntlmssp_negotiate_flags_100,
1564       { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1565     { &hf_ntlmssp_negotiate_flags_200,
1566       { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1567     { &hf_ntlmssp_negotiate_flags_400,
1568       { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1569     { &hf_ntlmssp_negotiate_flags_800,
1570       { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1571     { &hf_ntlmssp_negotiate_flags_1000,
1572       { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1573     { &hf_ntlmssp_negotiate_flags_2000,
1574       { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1575     { &hf_ntlmssp_negotiate_flags_4000,
1576       { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1577     { &hf_ntlmssp_negotiate_flags_8000,
1578       { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1579     { &hf_ntlmssp_negotiate_flags_10000,
1580       { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1581     { &hf_ntlmssp_negotiate_flags_20000,
1582       { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1583     { &hf_ntlmssp_negotiate_flags_40000,
1584       { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1585     { &hf_ntlmssp_negotiate_flags_80000,
1586       { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1587     { &hf_ntlmssp_negotiate_flags_100000,
1588       { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1589     { &hf_ntlmssp_negotiate_flags_200000,
1590       { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1591     { &hf_ntlmssp_negotiate_flags_400000,
1592       { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1593     { &hf_ntlmssp_negotiate_flags_800000,
1594       { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1595     { &hf_ntlmssp_negotiate_flags_1000000,
1596       { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1597     { &hf_ntlmssp_negotiate_flags_2000000,
1598       { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1599     { &hf_ntlmssp_negotiate_flags_4000000,
1600       { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1601     { &hf_ntlmssp_negotiate_flags_8000000,
1602       { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1603     { &hf_ntlmssp_negotiate_flags_10000000,
1604       { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1605     { &hf_ntlmssp_negotiate_flags_20000000,
1606       { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "128-bit encryption is supported", HFILL }},
1607     { &hf_ntlmssp_negotiate_flags_40000000,
1608       { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1609     { &hf_ntlmssp_negotiate_flags_80000000,
1610       { "Negotiate 56", "ntlmssp.negotiate56", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_56, "56-bit encryption is supported", HFILL }},
1611     { &hf_ntlmssp_negotiate_workstation_strlen,
1612       { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1613     { &hf_ntlmssp_negotiate_workstation_maxlen,
1614       { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1615     { &hf_ntlmssp_negotiate_workstation_buffer,
1616       { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1617     { &hf_ntlmssp_negotiate_workstation,
1618       { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1619     { &hf_ntlmssp_negotiate_domain_strlen,
1620       { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1621     { &hf_ntlmssp_negotiate_domain_maxlen,
1622       { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1623     { &hf_ntlmssp_negotiate_domain_buffer,
1624       { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1625     { &hf_ntlmssp_negotiate_domain,
1626       { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1627     { &hf_ntlmssp_ntlm_challenge,
1628       { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1629     { &hf_ntlmssp_reserved,
1630       { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1631     { &hf_ntlmssp_challenge_domain,
1632       { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1633     { &hf_ntlmssp_auth_domain,
1634       { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1635     { &hf_ntlmssp_auth_username,
1636       { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1637     { &hf_ntlmssp_auth_hostname,
1638       { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1639     { &hf_ntlmssp_auth_lmresponse,
1640       { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1641     { &hf_ntlmssp_auth_ntresponse,
1642       { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1643     { &hf_ntlmssp_auth_sesskey,
1644       { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1645     { &hf_ntlmssp_string_len,
1646       { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1647     { &hf_ntlmssp_string_maxlen,
1648       { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1649     { &hf_ntlmssp_string_offset,
1650       { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1651     { &hf_ntlmssp_blob_len,
1652       { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1653     { &hf_ntlmssp_blob_maxlen,
1654       { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1655     { &hf_ntlmssp_blob_offset,
1656       { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1657     { &hf_ntlmssp_address_list,
1658       { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1659     { &hf_ntlmssp_address_list_len,
1660       { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1661     { &hf_ntlmssp_address_list_maxlen,
1662       { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1663     { &hf_ntlmssp_address_list_offset,
1664       { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1665     { &hf_ntlmssp_address_list_item_type,
1666       { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, "", HFILL }},
1667     { &hf_ntlmssp_address_list_item_len,
1668       { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1669     { &hf_ntlmssp_address_list_item_content,
1670       { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1671     { &hf_ntlmssp_address_list_server_nb,
1672       { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1673     { &hf_ntlmssp_address_list_domain_nb,
1674       { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1675     { &hf_ntlmssp_address_list_server_dns,
1676       { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1677     { &hf_ntlmssp_address_list_domain_dns,
1678       { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1679     { &hf_ntlmssp_address_list_terminator,
1680       { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
1681     { &hf_ntlmssp_verf,
1682       { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1683     { &hf_ntlmssp_verf_vers,
1684       { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1685     { &hf_ntlmssp_verf_body,
1686       { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1687     { &hf_ntlmssp_decrypted_payload,
1688       { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1689     { &hf_ntlmssp_verf_unknown1,
1690       { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1691     { &hf_ntlmssp_verf_crc32,
1692       { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1693     { &hf_ntlmssp_verf_sequence,
1694       { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1695     { &hf_ntlmssp_ntlmv2_response,
1696       { "NTLMv2 Response", "ntlmssp.ntlmv2response", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1697     { &hf_ntlmssp_ntlmv2_response_hmac,
1698       { "HMAC", "ntlmssp.ntlmv2response.hmac", FT_BYTES, BASE_HEX,  NULL, 0x0, "", HFILL }},
1699     { &hf_ntlmssp_ntlmv2_response_header,
1700       { "Header", "ntlmssp.ntlmv2response.header", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1701     { &hf_ntlmssp_ntlmv2_response_reserved,
1702       { "Reserved", "ntlmssp.ntlmv2response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1703     { &hf_ntlmssp_ntlmv2_response_time,
1704       { "Time", "ntlmssp.ntlmv2response.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, "", HFILL }},
1705     { &hf_ntlmssp_ntlmv2_response_chal,
1706       { "Client challenge", "ntlmssp.ntlmv2response.chal", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1707     { &hf_ntlmssp_ntlmv2_response_unknown,
1708       { "Unknown", "ntlmssp.ntlmv2response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1709     { &hf_ntlmssp_ntlmv2_response_name,
1710       { "Name", "ntlmssp.ntlmv2response.name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1711     { &hf_ntlmssp_ntlmv2_response_name_type,
1712       { "Name type", "ntlmssp.ntlmv2response.name.type", FT_UINT32, BASE_DEC, VALS(ntlm_name_types), 0x0, "", HFILL }},
1713     { &hf_ntlmssp_ntlmv2_response_name_len,
1714       { "Name len", "ntlmssp.ntlmv2response.name.len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1715   };
1716
1717
1718   static gint *ett[] = {
1719     &ett_ntlmssp,
1720     &ett_ntlmssp_negotiate_flags,
1721     &ett_ntlmssp_string,
1722     &ett_ntlmssp_blob,
1723     &ett_ntlmssp_address_list,
1724     &ett_ntlmssp_address_list_item,
1725     &ett_ntlmssp_ntlmv2_response,
1726     &ett_ntlmssp_ntlmv2_response_name
1727   };
1728   module_t *ntlmssp_module;
1729   
1730   proto_ntlmssp = proto_register_protocol (
1731                                            "NTLM Secure Service Provider", /* name */
1732                                            "NTLMSSP",   /* short name */
1733                                            "ntlmssp"    /* abbrev */
1734                                            );
1735   proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1736   proto_register_subtree_array (ett, array_length (ett));
1737   register_init_routine(&ntlmssp_init_protocol);
1738
1739   ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1740   
1741   prefs_register_string_preference(ntlmssp_module, "nt_password",
1742                                    "NT Password",
1743                                    "NT Password (used to decrypt payloads)",
1744                                    &nt_password);
1745
1746   register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1747   new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1748 }
1749
1750 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo, 
1751                                 proto_tree *tree, guint8 *drep _U_)
1752 {
1753         tvbuff_t *auth_tvb;
1754
1755         auth_tvb = tvb_new_subset(
1756                 tvb, offset, tvb_length_remaining(tvb, offset),
1757                 tvb_length_remaining(tvb, offset));
1758         
1759         dissect_ntlmssp(auth_tvb, pinfo, tree);
1760
1761         return tvb_length_remaining(tvb, offset);
1762 }
1763
1764 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo, 
1765                                      proto_tree *tree, guint8 *drep _U_)
1766 {
1767         tvbuff_t *auth_tvb;
1768
1769         auth_tvb = tvb_new_subset(
1770                 tvb, offset, tvb_length_remaining(tvb, offset),
1771                 tvb_length_remaining(tvb, offset));
1772         
1773         return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
1774 }
1775
1776 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
1777         wrap_dissect_ntlmssp,                   /* Bind */
1778         wrap_dissect_ntlmssp,                   /* Bind ACK */
1779         wrap_dissect_ntlmssp,                   /* AUTH3 */
1780         wrap_dissect_ntlmssp_verf,              /* Request verifier */
1781         wrap_dissect_ntlmssp_verf,              /* Response verifier */
1782         NULL,                                   /* Request data */
1783         NULL                                    /* Response data */
1784 };
1785
1786 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
1787         wrap_dissect_ntlmssp,                   /* Bind */
1788         wrap_dissect_ntlmssp,                   /* Bind ACK */
1789         wrap_dissect_ntlmssp,                   /* AUTH3 */
1790         wrap_dissect_ntlmssp_verf,              /* Request verifier */
1791         wrap_dissect_ntlmssp_verf,              /* Response verifier */
1792         dissect_ntlmssp_encrypted_payload,      /* Request data */
1793         dissect_ntlmssp_encrypted_payload       /* Response data */
1794 };
1795
1796 void
1797 proto_reg_handoff_ntlmssp(void)
1798 {     
1799   dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1800
1801   /* Register protocol with the GSS-API module */
1802
1803   ntlmssp_handle = find_dissector("ntlmssp");
1804   ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1805   gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp, 
1806                   ntlmssp_handle, ntlmssp_wrap_handle,
1807                   "NTLMSSP - Microsoft NTLM Security Support Provider");
1808
1809   /* Register authenticated pipe dissector */
1810
1811   /*
1812    * XXX - the verifiers here seem to have a version of 1 and a body of all
1813    * zeroes.
1814    *
1815    * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
1816    * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT.  Should we register
1817    * any other levels here?
1818    */
1819   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
1820                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1821                                     &ntlmssp_sign_fns);
1822
1823   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1824                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1825                                     &ntlmssp_sign_fns);
1826
1827   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1828                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1829                                     &ntlmssp_seal_fns);
1830 }