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