Refactor dissection of CHALLENGE target-info & AUTHENTICATE ntlmv2-response attributes:
[obnox/wireshark/wip.git] / epan / dissectors / packet-ntlmssp.c
1 /* packet-ntlmssp.c
2  * Add-on for better NTLM v1/v2 handling
3  * Copyright 2009 Matthieu Patou <matthieu.patou@matws.net>
4  * Routines for NTLM Secure Service Provider
5  * Devin Heitmueller <dheitmueller@netilla.com>
6  * Copyright 2003, Tim Potter <tpot@samba.org>
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #ifdef DEBUG_NTLMSSP
33 #include <stdio.h>
34 #endif
35 #include <string.h>
36 #include <ctype.h>
37
38 #include <glib.h>
39 #include <epan/packet.h>
40
41 #include "packet-windows-common.h"
42 #include "packet-smb-common.h"
43 #include "packet-frame.h"
44 #include <epan/asn1.h>
45 #include "packet-kerberos.h"
46 #include <epan/prefs.h>
47 #include <epan/emem.h>
48 #include <epan/tap.h>
49 #include <epan/expert.h>
50 #include <epan/crypt/crypt-rc4.h>
51 #include <epan/crypt/crypt-md4.h>
52 #include <epan/crypt/crypt-md5.h>
53 #include <epan/crypt/crypt-des.h>
54 #include "packet-dcerpc.h"
55 #include "packet-gssapi.h"
56 #include <epan/crc32.h>
57
58 #include "packet-ntlmssp.h"
59
60 static int ntlmssp_tap = -1;
61
62 /* Message types */
63
64 #define NTLMSSP_NEGOTIATE 1
65 #define NTLMSSP_CHALLENGE 2
66 #define NTLMSSP_AUTH      3
67 #define NTLMSSP_UNKNOWN   4
68 #define CLIENT_SIGN_TEXT "session key to client-to-server signing key magic constant"
69 #define CLIENT_SEAL_TEXT "session key to client-to-server sealing key magic constant"
70 #define SERVER_SIGN_TEXT "session key to server-to-client signing key magic constant"
71 #define SERVER_SEAL_TEXT "session key to server-to-client sealing key magic constant"
72
73 #define NTLMSSP_KEY_LEN 16
74
75 static const value_string ntlmssp_message_types[] = {
76   { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
77   { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
78   { NTLMSSP_AUTH,      "NTLMSSP_AUTH" },
79   { NTLMSSP_UNKNOWN,   "NTLMSSP_UNKNOWN" },
80   { 0, NULL }
81 };
82
83 typedef struct _md4_pass {
84   guint8 md4[NTLMSSP_KEY_LEN];
85 } md4_pass;
86
87 static unsigned char gbl_zeros[24] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
88 static GHashTable* hash_packet = NULL;
89
90 /*
91  * NTLMSSP negotiation flags
92  * Taken from Samba
93  *
94  * See also
95  *
96  *      http://davenport.sourceforge.net/ntlm.html
97  *
98  * although that document says that:
99  *
100  *      0x00010000 is "Target Type Domain";
101  *      0x00020000 is "Target Type Server"
102  *      0x00040000 is "Target Type Share";
103  *
104  * and that 0x00100000, 0x00200000, and 0x00400000 are
105  * "Request Init Response", "Request Accept Response", and
106  * "Request Non-NT Session Key", rather than those values shifted
107  * right one having those interpretations.
108  *
109  * UPDATE: Further information obtained from [MS-NLMP]:
110  * NT LAN Manager (NTLM) Authentication Protocol Specification
111  * http://msdn2.microsoft.com/en-us/library/cc236621.aspx
112  *
113  */
114 #define NTLMSSP_NEGOTIATE_UNICODE          0x00000001
115 #define NTLMSSP_NEGOTIATE_OEM              0x00000002
116 #define NTLMSSP_REQUEST_TARGET             0x00000004
117 #define NTLMSSP_NEGOTIATE_00000008         0x00000008
118 #define NTLMSSP_NEGOTIATE_SIGN             0x00000010
119 #define NTLMSSP_NEGOTIATE_SEAL             0x00000020
120 #define NTLMSSP_NEGOTIATE_DATAGRAM         0x00000040
121 #define NTLMSSP_NEGOTIATE_LM_KEY           0x00000080
122 #define NTLMSSP_NEGOTIATE_00000100         0x00000100
123 #define NTLMSSP_NEGOTIATE_NTLM             0x00000200
124 #define NTLMSSP_NEGOTIATE_NT_ONLY          0x00000400
125 #define NTLMSSP_NEGOTIATE_00000800         0x00000800
126 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
127 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
128 #define NTLMSSP_NEGOTIATE_00004000         0x00004000
129 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN      0x00008000
130 #define NTLMSSP_TARGET_TYPE_DOMAIN         0x00010000
131 #define NTLMSSP_TARGET_TYPE_SERVER         0x00020000
132 #define NTLMSSP_TARGET_TYPE_SHARE          0x00040000
133 #define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
134 #define NTLMSSP_NEGOTIATE_IDENTIFY         0x00100000
135 #define NTLMSSP_NEGOTIATE_00200000         0x00200000
136 #define NTLMSSP_REQUEST_NON_NT_SESSION     0x00400000
137 #define NTLMSSP_NEGOTIATE_TARGET_INFO      0x00800000
138 #define NTLMSSP_NEGOTIATE_01000000         0x01000000
139 #define NTLMSSP_NEGOTIATE_VERSION          0x02000000
140 #define NTLMSSP_NEGOTIATE_04000000         0x04000000
141 #define NTLMSSP_NEGOTIATE_08000000         0x08000000
142 #define NTLMSSP_NEGOTIATE_10000000         0x10000000
143 #define NTLMSSP_NEGOTIATE_128              0x20000000
144 #define NTLMSSP_NEGOTIATE_KEY_EXCH         0x40000000
145 #define NTLMSSP_NEGOTIATE_56               0x80000000
146
147 static int proto_ntlmssp = -1;
148 static int hf_ntlmssp_auth = -1;
149 static int hf_ntlmssp_message_type = -1;
150 static int hf_ntlmssp_negotiate_flags = -1;
151 static int hf_ntlmssp_negotiate_flags_01 = -1;
152 static int hf_ntlmssp_negotiate_flags_02 = -1;
153 static int hf_ntlmssp_negotiate_flags_04 = -1;
154 static int hf_ntlmssp_negotiate_flags_08 = -1;
155 static int hf_ntlmssp_negotiate_flags_10 = -1;
156 static int hf_ntlmssp_negotiate_flags_20 = -1;
157 static int hf_ntlmssp_negotiate_flags_40 = -1;
158 static int hf_ntlmssp_negotiate_flags_80 = -1;
159 static int hf_ntlmssp_negotiate_flags_100 = -1;
160 static int hf_ntlmssp_negotiate_flags_200 = -1;
161 static int hf_ntlmssp_negotiate_flags_400 = -1;
162 static int hf_ntlmssp_negotiate_flags_800 = -1;
163 static int hf_ntlmssp_negotiate_flags_1000 = -1;
164 static int hf_ntlmssp_negotiate_flags_2000 = -1;
165 static int hf_ntlmssp_negotiate_flags_4000 = -1;
166 static int hf_ntlmssp_negotiate_flags_8000 = -1;
167 static int hf_ntlmssp_negotiate_flags_10000 = -1;
168 static int hf_ntlmssp_negotiate_flags_20000 = -1;
169 static int hf_ntlmssp_negotiate_flags_40000 = -1;
170 static int hf_ntlmssp_negotiate_flags_80000 = -1;
171 static int hf_ntlmssp_negotiate_flags_100000 = -1;
172 static int hf_ntlmssp_negotiate_flags_200000 = -1;
173 static int hf_ntlmssp_negotiate_flags_400000 = -1;
174 static int hf_ntlmssp_negotiate_flags_800000 = -1;
175 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
176 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
177 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
178 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
179 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
180 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
181 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
182 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
183 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
184 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
185 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
186 static int hf_ntlmssp_negotiate_workstation = -1;
187 static int hf_ntlmssp_negotiate_domain_strlen = -1;
188 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
189 static int hf_ntlmssp_negotiate_domain_buffer = -1;
190 static int hf_ntlmssp_negotiate_domain = -1;
191 static int hf_ntlmssp_ntlm_server_challenge = -1;
192 static int hf_ntlmssp_ntlm_client_challenge = -1;
193 static int hf_ntlmssp_reserved = -1;
194 static int hf_ntlmssp_challenge_target_name = -1;
195 static int hf_ntlmssp_auth_username = -1;
196 static int hf_ntlmssp_auth_domain = -1;
197 static int hf_ntlmssp_auth_hostname = -1;
198 static int hf_ntlmssp_auth_lmresponse = -1;
199 static int hf_ntlmssp_auth_ntresponse = -1;
200 static int hf_ntlmssp_auth_sesskey = -1;
201 static int hf_ntlmssp_string_len = -1;
202 static int hf_ntlmssp_string_maxlen = -1;
203 static int hf_ntlmssp_string_offset = -1;
204 static int hf_ntlmssp_blob_len = -1;
205 static int hf_ntlmssp_blob_maxlen = -1;
206 static int hf_ntlmssp_blob_offset = -1;
207 static int hf_ntlmssp_version = -1;
208 static int hf_ntlmssp_version_major = -1;
209 static int hf_ntlmssp_version_minor = -1;
210 static int hf_ntlmssp_version_build_number = -1;
211 static int hf_ntlmssp_version_ntlm_current_revision = -1;
212
213 static int hf_ntlmssp_challenge_target_info = -1;
214 static int hf_ntlmssp_challenge_target_info_len = -1;
215 static int hf_ntlmssp_challenge_target_info_maxlen = -1;
216 static int hf_ntlmssp_challenge_target_info_offset = -1;
217
218 static int hf_ntlmssp_challenge_target_info_item_type = -1;
219 static int hf_ntlmssp_challenge_target_info_item_len = -1;
220
221 static int hf_ntlmssp_challenge_target_info_end = -1;
222 static int hf_ntlmssp_challenge_target_info_nb_computer_name = -1;
223 static int hf_ntlmssp_challenge_target_info_nb_domain_name = -1;
224 static int hf_ntlmssp_challenge_target_info_dns_computer_name = -1;
225 static int hf_ntlmssp_challenge_target_info_dns_domain_name = -1;
226 static int hf_ntlmssp_challenge_target_info_dns_tree_name = -1;
227 static int hf_ntlmssp_challenge_target_info_flags = -1;
228 static int hf_ntlmssp_challenge_target_info_timestamp = -1;
229 static int hf_ntlmssp_challenge_target_info_restrictions = -1;
230 static int hf_ntlmssp_challenge_target_info_target_name =-1;
231 static int hf_ntlmssp_challenge_target_info_channel_bindings =-1;
232
233 static int hf_ntlmssp_ntlmv2_response_item_type = -1;
234 static int hf_ntlmssp_ntlmv2_response_item_len = -1;
235
236 static int hf_ntlmssp_ntlmv2_response_end = -1;
237 static int hf_ntlmssp_ntlmv2_response_nb_computer_name = -1;
238 static int hf_ntlmssp_ntlmv2_response_nb_domain_name = -1;
239 static int hf_ntlmssp_ntlmv2_response_dns_computer_name = -1;
240 static int hf_ntlmssp_ntlmv2_response_dns_domain_name = -1;
241 static int hf_ntlmssp_ntlmv2_response_dns_tree_name = -1;
242 static int hf_ntlmssp_ntlmv2_response_flags = -1;
243 static int hf_ntlmssp_ntlmv2_response_timestamp = -1;
244 static int hf_ntlmssp_ntlmv2_response_restrictions = -1;
245 static int hf_ntlmssp_ntlmv2_response_target_name =-1;
246 static int hf_ntlmssp_ntlmv2_response_channel_bindings =-1;
247
248 static int hf_ntlmssp_message_integrity_code = -1;
249 static int hf_ntlmssp_verf = -1;
250 static int hf_ntlmssp_verf_vers = -1;
251 static int hf_ntlmssp_verf_body = -1;
252 static int hf_ntlmssp_verf_randompad = -1;
253 static int hf_ntlmssp_verf_hmacmd5 = -1;
254 static int hf_ntlmssp_verf_crc32 = -1;
255 static int hf_ntlmssp_verf_sequence = -1;
256 static int hf_ntlmssp_decrypted_payload = -1;
257
258 static int hf_ntlmssp_ntlmv2_response = -1;
259 static int hf_ntlmssp_ntlmv2_response_hmac = -1;
260 static int hf_ntlmssp_ntlmv2_response_header = -1;
261 static int hf_ntlmssp_ntlmv2_response_reserved = -1;
262 static int hf_ntlmssp_ntlmv2_response_time = -1;
263 static int hf_ntlmssp_ntlmv2_response_chal = -1;
264 static int hf_ntlmssp_ntlmv2_response_unknown = -1;
265
266 static gint ett_ntlmssp = -1;
267 static gint ett_ntlmssp_negotiate_flags = -1;
268 static gint ett_ntlmssp_string = -1;
269 static gint ett_ntlmssp_blob = -1;
270 static gint ett_ntlmssp_version = -1;
271 static gint ett_ntlmssp_challenge_target_info = -1;
272 static gint ett_ntlmssp_challenge_target_info_item = -1;
273 static gint ett_ntlmssp_ntlmv2_response = -1;
274 static gint ett_ntlmssp_ntlmv2_response_item = -1;
275
276 /* Configuration variables */
277 const char *gbl_nt_password = NULL;
278
279 #define MAX_BLOB_SIZE 256
280 typedef struct _ntlmssp_blob {
281   guint16 length;
282   guint8 contents[MAX_BLOB_SIZE];
283 } ntlmssp_blob;
284
285 /* Used in the conversation function */
286 typedef struct _ntlmssp_info {
287   guint32 flags;
288   int is_auth_ntlm_v2;
289   rc4_state_struct rc4_state_client;
290   rc4_state_struct rc4_state_server;
291   guint8 sign_key_client[NTLMSSP_KEY_LEN];
292   guint8 sign_key_server[NTLMSSP_KEY_LEN];
293   guint32 server_dest_port;
294   unsigned char server_challenge[8];
295   unsigned char client_challenge[8];
296   int rc4_state_initialized;
297   ntlmssp_blob ntlm_response;
298   ntlmssp_blob lm_response;
299 } ntlmssp_info;
300
301 /* If this struct exists in the payload_decrypt, then we have already
302    decrypted it once */
303 typedef struct _ntlmssp_packet_info {
304   guint8 *decrypted_payload;
305   guint8 payload_len;
306   guint8 verifier[NTLMSSP_KEY_LEN];
307   gboolean payload_decrypted;
308   gboolean verifier_decrypted;
309 } ntlmssp_packet_info;
310
311 #ifdef DEBUG_NTLMSSP
312 static void printnbyte(const guint8* tab,int nb,const char* txt,const char* txt2)
313 {
314   int i=0;
315   fprintf(stderr,"%s ",txt);
316   for(i=0;i<nb;i++)
317   {
318     fprintf(stderr,"%02hhX ",*(tab+i));
319   }
320   fprintf(stderr,"%s",txt2);
321 }
322 #if 0
323  static void printnchar(const guint8* tab,int nb,char* txt,char* txt2)
324 {
325   int i=0;
326   fprintf(stderr,"%s ",txt);
327   for(i=0;i<nb;i++)
328   {
329     fprintf(stderr,"%c",*(tab+i));
330   }
331   fprintf(stderr,"%s",txt2);
332 }
333 #endif
334 #else
335 static void printnbyte(const guint8* tab _U_,int nb _U_, const char* txt _U_,const char* txt2 _U_)
336 {
337 }
338 #endif
339 /*
340  * GSlist of decrypted payloads.
341  */
342 static GSList *decrypted_payloads;
343
344 int LEBE_Convert(int value)
345 {
346   char a,b,c,d;
347   /* Get each byte */
348   a=value&0x000000FF;
349   b=(value&0x0000FF00) >> 8;
350   c=(value&0x00FF0000) >> 16;
351   d=(value&0xFF000000) >> 24;
352   return (a << 24) | (b << 16) | (c << 8) | d;
353 }
354 /*
355   Perform a DES encryption with a 16 bit key and 8bit data item.
356   It's in fact 3 susbsequent call to crypt_des_ecb with a 7 bit key.
357   Missing bits for the key are replaced by 0;
358   Returns output in response, which is expected to be 24 bytes.
359 */
360 static int crypt_des_ecb_long(guint8 *response,
361                                                const guint8 *key,
362                                                const guint8 *data)
363 {
364   guint8 pw21[21]; /* 21 bytes place for the needed key */
365
366   memset(pw21, 0, sizeof(pw21));
367   memcpy(pw21, key, 16);
368
369   memset(response, 0, 24);
370   /* crypt_des_ecb(data,key)*/
371   crypt_des_ecb(response, data, pw21, 1);
372   crypt_des_ecb(response + 8, data, pw21 + 7, 1);
373   crypt_des_ecb(response + 16, data, pw21 + 14, 1);
374
375   return 1;
376 }
377 /*
378   Generate a challenge response, given an eight byte challenge and
379   either the NT or the Lan Manager password hash (16 bytes).
380   Returns output in response, which is expected to be 24 bytes.
381 */
382 static int ntlmssp_generate_challenge_response(guint8 *response,
383                                                const guint8 *passhash,
384                                                const guint8 *challenge)
385 {
386   guint8 pw21[21]; /* Password hash padded to 21 bytes */
387
388   memset(pw21, 0x0, sizeof(pw21));
389   memcpy(pw21, passhash, 16);
390
391   memset(response, 0, 24);
392
393   crypt_des_ecb(response, challenge, pw21, 1);
394   crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
395   crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
396
397   return 1;
398 }
399
400
401 /* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/
402 static void str_to_unicode(const char *nt_password, char *nt_password_unicode)
403 {
404   size_t password_len = 0;
405   size_t i;
406
407   password_len = strlen(nt_password);
408   if(nt_password_unicode != NULL)
409   {
410    for(i=0;i<(password_len);i++)
411    {
412      nt_password_unicode[i*2]=nt_password[i];
413      nt_password_unicode[i*2+1]=0;
414    }
415    nt_password_unicode[2*password_len]='\0';
416   }
417 }
418
419 /* This function generate the Key Exchange Key
420  * Depending on the flags this key will either be used to crypt the exported session key
421  * or will be used directly as exported session key.
422  * Exported session key is the key that will be used for sealing and signing communication*/
423
424 static void
425 get_keyexchange_key(unsigned char keyexchangekey[NTLMSSP_KEY_LEN],const unsigned char sessionbasekey[NTLMSSP_KEY_LEN],const unsigned char lm_challenge_response[24],int flags)
426 {
427   guint8 basekey[NTLMSSP_KEY_LEN];
428   guint8 zeros[24];
429
430   memset(keyexchangekey,0,NTLMSSP_KEY_LEN);
431   memset(basekey,0,NTLMSSP_KEY_LEN);
432   /* sessionbasekey is either derived from lm_password_hash or from nt_password_hash depending on the key type negotiated */
433   memcpy(basekey,sessionbasekey,8);
434   memset(basekey,0xBD,8);
435   if(flags&NTLMSSP_NEGOTIATE_LM_KEY)
436   {
437     /*data,key*/
438     crypt_des_ecb(keyexchangekey,lm_challenge_response,basekey,1);
439     crypt_des_ecb(keyexchangekey+8,lm_challenge_response,basekey+7,1);
440   }
441   else
442   {
443     if(flags&NTLMSSP_REQUEST_NON_NT_SESSION)
444     {
445       /*People from samba tends to use the same function in this case than in the previous one but with 0 data
446        * it's not clear that it produce the good result
447        * memcpy(keyexchangekey,lm_hash,8);
448        * Let's trust samba implementation it mights seem weird but they are more often rights than the spec !
449        */
450       memset(zeros,0,24);
451       crypt_des_ecb(keyexchangekey,zeros,basekey,3);
452       crypt_des_ecb(keyexchangekey+8,zeros,basekey+7,1);
453     }
454     else
455     {
456       /* it is stated page 65 of NTLM SSP spec that sessionbasekey should be encrypted with hmac_md5 using the concact of both challenge
457        * when it's NTLM v1 + extended security but it turns out to be wrong !
458        */
459       memcpy(keyexchangekey,sessionbasekey,NTLMSSP_KEY_LEN);
460     }
461   }
462 }
463 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
464 static guint32
465 get_md4pass_list(md4_pass** p_pass_list,const char* nt_password)
466 {
467
468         guint32 nb_pass = 0;
469         enc_key_t *ek;
470         unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
471         int password_len = 0;
472         char nt_password_unicode[256];
473         md4_pass* pass_list;
474         int i = 0;
475         if(!krb_decrypt){
476                 pass_list=NULL;
477                 return 0;
478         }
479         read_keytab_file_from_preferences();
480
481         for(ek=enc_key_list;ek;ek=ek->next){
482                 if( ek->keylength == NTLMSSP_KEY_LEN ) {
483                         nb_pass++;
484                 }
485         }
486         memset(nt_password_hash,0,NTLMSSP_KEY_LEN);
487         if (nt_password[0] != '\0' && ( strlen(nt_password) < 129 )) {
488                 nb_pass++;
489                 password_len = strlen(nt_password);
490                 str_to_unicode(nt_password,nt_password_unicode);
491                 crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
492         }
493         if( nb_pass == 0 ) {
494                 /* Unable to calculate the session key without a password       or if password is more than 128 char ......*/
495                 return 0;
496         }
497         i = 0;
498         *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
499         pass_list=*p_pass_list;
500
501         if( memcmp(nt_password_hash,gbl_zeros,NTLMSSP_KEY_LEN) != 0 ) {
502                 memcpy(pass_list[i].md4,nt_password_hash,NTLMSSP_KEY_LEN);
503                 i = 1;
504         }
505         for(ek=enc_key_list;ek;ek=ek->next){
506                 if( ek->keylength == NTLMSSP_KEY_LEN ) {
507                         memcpy(pass_list[i].md4,ek->keyvalue,NTLMSSP_KEY_LEN);
508                         i++;
509                 }
510         }
511         return nb_pass;
512 }
513 #endif
514 /* Create an NTLMSSP version 2 key
515  */
516 static void
517 create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge , const guint8 *clientchallenge ,
518                       guint8 *sessionkey ,const  guint8 *encryptedsessionkey , int flags , ntlmssp_blob ntlm_response, ntlmssp_blob lm_response _U_, ntlmssp_header_t *ntlmssph ) {
519   char domain_name_unicode[256];
520   char user_uppercase[256];
521   char buf[512];
522   /*guint8 md4[NTLMSSP_KEY_LEN];*/
523   unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
524   unsigned char nt_proof[NTLMSSP_KEY_LEN];
525   unsigned char ntowf[NTLMSSP_KEY_LEN];
526   guint8 sessionbasekey[NTLMSSP_KEY_LEN];
527   guint8 keyexchangekey[NTLMSSP_KEY_LEN];
528   guint8 lm_challenge_response[24];
529   guint32 i;
530   guint32 j;
531   rc4_state_struct rc4state;
532   size_t user_len;
533   size_t domain_len;
534   md4_pass *pass_list = NULL;
535   guint32 nb_pass = 0;
536   int found = 0;
537
538   /* We are going to try password encrypted in keytab as well, it's an idean of Stefan Metzmacher <metze@samba.org>
539    * The idea is to be able to test all the key of domain in once and to be able to decode the NTLM dialogs */
540
541   memset(sessionkey, 0, NTLMSSP_KEY_LEN);
542 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
543   nb_pass = get_md4pass_list(&pass_list,nt_password);
544 #endif
545   i=0;
546   memset(user_uppercase,0,256);
547   user_len = strlen(ntlmssph->acct_name);
548   if( user_len < 129 ) {
549      memset(buf,0,512);
550      str_to_unicode(ntlmssph->acct_name,buf);
551      for (j = 0; j < (2*user_len); j++) {
552        if( buf[j] != '\0' ) {
553          user_uppercase[j] = toupper(buf[j]);
554        }
555      }
556   }
557   else {
558      /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
559      return;
560   }
561   domain_len = strlen(ntlmssph->domain_name);
562   if( domain_len < 129 ) {
563     str_to_unicode(ntlmssph->domain_name,domain_name_unicode);
564   }
565   else {
566     /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
567     return;
568   }
569   while (i < nb_pass ) {
570     /*fprintf(stderr,"Turn %d, ",i);*/
571     memcpy(nt_password_hash,pass_list[i].md4,NTLMSSP_KEY_LEN);
572     /*printnbyte(nt_password_hash,NTLMSSP_KEY_LEN,"Current NT password hash: ","\n");*/
573     i++;
574     /* ntowf computation */
575     memset(buf,0,512);
576     memcpy(buf,user_uppercase,user_len*2);
577     memcpy(buf+user_len*2,domain_name_unicode,domain_len*2);
578     md5_hmac(buf,domain_len*2+user_len*2,nt_password_hash,NTLMSSP_KEY_LEN,ntowf);
579     /* LM response */
580     memset(buf,0,512);
581     memcpy(buf,serverchallenge,8);
582     memcpy(buf+8,clientchallenge,8);
583     md5_hmac(buf,NTLMSSP_KEY_LEN,ntowf,NTLMSSP_KEY_LEN,lm_challenge_response);
584     memcpy(lm_challenge_response+NTLMSSP_KEY_LEN,clientchallenge,8);
585     printnbyte(lm_challenge_response,24,"LM Response: ","\n");
586
587     /* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */
588     memset(buf,0,512);
589     memcpy(buf,serverchallenge,8);
590     memcpy(buf+8,ntlm_response.contents+NTLMSSP_KEY_LEN,ntlm_response.length-NTLMSSP_KEY_LEN);
591     md5_hmac(buf,ntlm_response.length-8,ntowf,NTLMSSP_KEY_LEN,nt_proof);
592     printnbyte(nt_proof,NTLMSSP_KEY_LEN,"NT proof: ","\n");
593     if( !memcmp(nt_proof,ntlm_response.contents,NTLMSSP_KEY_LEN) ) {
594       found = 1;
595       break;
596     }
597
598   }
599   if( found == 0 ) {
600
601     return;
602   }
603
604   md5_hmac(nt_proof,NTLMSSP_KEY_LEN,ntowf,NTLMSSP_KEY_LEN,sessionbasekey);
605   get_keyexchange_key(keyexchangekey,sessionbasekey,lm_challenge_response,flags);
606   /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
607   if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
608   {
609     memcpy(sessionkey,encryptedsessionkey,NTLMSSP_KEY_LEN);
610     crypt_rc4_init(&rc4state,keyexchangekey,NTLMSSP_KEY_LEN);
611     crypt_rc4(&rc4state,sessionkey,NTLMSSP_KEY_LEN);
612   }
613   else
614   {
615     memcpy(sessionkey,keyexchangekey,NTLMSSP_KEY_LEN);
616   }
617
618 }
619  /* Create an NTLMSSP version 1 key
620  * That is more complicated logic and methods and user challenge as well.
621  * password points to the ANSI password to encrypt, challenge points to
622  * the 8 octet challenge string
623  */
624 static void
625 create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, const guint8 *clientchallenge,
626                       guint8 *sessionkey,const  guint8 *encryptedsessionkey, int flags, const guint8 *ref_nt_challenge_response,const guint8 *ref_lm_challenge_response)
627 {
628   unsigned char lm_password_upper[NTLMSSP_KEY_LEN];
629   unsigned char lm_password_hash[NTLMSSP_KEY_LEN];
630   unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
631   unsigned char challenges_hash[NTLMSSP_KEY_LEN];
632   unsigned char challenges_hash_first8[8];
633   unsigned char challenges[NTLMSSP_KEY_LEN];
634   guint8 md4[NTLMSSP_KEY_LEN];
635   guint8 nb_pass = 0;
636   guint8 sessionbasekey[NTLMSSP_KEY_LEN];
637   guint8 keyexchangekey[NTLMSSP_KEY_LEN];
638   guint8 lm_challenge_response[24];
639   guint8 nt_challenge_response[24];
640   rc4_state_struct rc4state;
641   md5_state_t md5state;
642   char nt_password_unicode[256];
643   size_t password_len;
644   unsigned int i;
645   int found = 0;
646   md4_pass *pass_list = NULL;
647   unsigned char lmhash_key[] =
648     {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
649
650   memset(sessionkey, 0, NTLMSSP_KEY_LEN);
651   memset(lm_password_upper, 0, sizeof(lm_password_upper));
652   /* lm auth/lm session == (!NTLM_NEGOTIATE_NT_ONLY && NTLMSSP_NEGOTIATE_LM_KEY) || ! (EXTENDED_SECURITY) || ! NTLMSSP_NEGOTIATE_NTLM*/
653   /* Create a Lan Manager hash of the input password */
654   if (nt_password[0] != '\0') {
655     password_len = strlen(nt_password);
656     /*Do not forget to free nt_password_nt*/
657     str_to_unicode(nt_password,nt_password_unicode);
658     crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
659     /* Truncate password if too long */
660     if (password_len > NTLMSSP_KEY_LEN)
661       password_len = NTLMSSP_KEY_LEN;
662     for (i = 0; i < password_len; i++) {
663       lm_password_upper[i] = toupper(nt_password[i]);
664     }
665   }
666   else
667   {
668     /* Unable to calculate the session key without a password ... and we will not use one for a keytab*/
669     if( !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
670       return;
671     }
672   }
673   if((flags & NTLMSSP_NEGOTIATE_LM_KEY && !(flags & NTLMSSP_NEGOTIATE_NT_ONLY)) || !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)  || !(flags & NTLMSSP_NEGOTIATE_NTLM)) {
674     crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
675     crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
676     ntlmssp_generate_challenge_response(lm_challenge_response,
677                                       lm_password_hash, serverchallenge);
678     memcpy(sessionbasekey,lm_password_hash,NTLMSSP_KEY_LEN);
679   }
680   else {
681
682     memset(lm_challenge_response,0,24);
683     if( flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY ) {
684 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
685       nb_pass = get_md4pass_list(&pass_list,nt_password);
686 #endif
687       i=0;
688       while (i < nb_pass ) {
689         /*fprintf(stderr,"Turn %d, ",i);*/
690         memcpy(nt_password_hash,pass_list[i].md4,NTLMSSP_KEY_LEN);
691         /*printnbyte(nt_password_hash,NTLMSSP_KEY_LEN,"Current NT password hash: ","\n");*/
692         i++;
693         memcpy(lm_challenge_response,clientchallenge,8);
694         md5_init(&md5state);
695         md5_append(&md5state,serverchallenge,8);
696         md5_append(&md5state,clientchallenge,8);
697         md5_finish(&md5state,challenges_hash);
698         memcpy(challenges_hash_first8,challenges_hash,8);
699         crypt_des_ecb_long(nt_challenge_response,nt_password_hash,challenges_hash_first8);
700         if( !memcmp(ref_nt_challenge_response,nt_challenge_response,24) ) {
701           found = 1;
702           break;
703         }
704       }
705     }
706     else {
707       crypt_des_ecb_long(nt_challenge_response,nt_password_hash,serverchallenge);
708       if( flags & NTLMSSP_NEGOTIATE_NT_ONLY ) {
709         memcpy(lm_challenge_response,nt_challenge_response,24);
710       }
711       else {
712         crypt_des_ecb_long(lm_challenge_response,lm_password_hash,serverchallenge);
713       }
714       if( !memcmp(ref_nt_challenge_response,nt_challenge_response,24) && !memcmp(ref_lm_challenge_response,lm_challenge_response,24) ) {
715           found = 1;
716       }
717     }
718     /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident
719      * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth
720      * Otherwise it should be lm_password_hash ...*/
721     crypt_md4(md4,nt_password_hash,NTLMSSP_KEY_LEN);
722     if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
723      memcpy(challenges,serverchallenge,8);
724      memcpy(challenges+8,clientchallenge,8);
725      /*md5_hmac(text,text_len,key,key_len,digest);*/
726      md5_hmac(challenges,NTLMSSP_KEY_LEN,md4,NTLMSSP_KEY_LEN,sessionbasekey);
727     }
728     else {
729      memcpy(sessionbasekey,md4,NTLMSSP_KEY_LEN);
730     }
731   }
732
733   if( found == 0 ) {
734     return;
735   }
736
737
738   get_keyexchange_key(keyexchangekey,sessionbasekey,lm_challenge_response,flags);
739   memset(sessionkey, 0, NTLMSSP_KEY_LEN);
740   /*printnbyte(nt_challenge_response,24,"NT challenge response","\n");
741   printnbyte(lm_challenge_response,24,"LM challenge response","\n");*/
742   /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
743   if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
744   {
745     memcpy(sessionkey,encryptedsessionkey,NTLMSSP_KEY_LEN);
746     crypt_rc4_init(&rc4state,keyexchangekey,NTLMSSP_KEY_LEN);
747     crypt_rc4(&rc4state,sessionkey,NTLMSSP_KEY_LEN);
748   }
749   else
750   {
751     memcpy(sessionkey,keyexchangekey,NTLMSSP_KEY_LEN);
752   }
753 }
754 static void
755 get_siging_key(guint8 *sign_key_server,guint8* sign_key_client,const guint8 key[NTLMSSP_KEY_LEN], int keylen)
756 {
757   md5_state_t md5state;
758   md5_state_t md5state2;
759   memset(sign_key_client,0,NTLMSSP_KEY_LEN);
760   memset(sign_key_server,0,NTLMSSP_KEY_LEN);
761   md5_init(&md5state);
762   md5_append(&md5state,key,keylen);
763   md5_append(&md5state,CLIENT_SIGN_TEXT,strlen(CLIENT_SIGN_TEXT)+1);
764   md5_finish(&md5state,sign_key_client);
765   md5_init(&md5state2);
766   md5_append(&md5state2,key,keylen);
767   md5_append(&md5state2,SERVER_SIGN_TEXT,strlen(SERVER_SIGN_TEXT)+1);
768   md5_finish(&md5state2,sign_key_server);
769
770 }
771
772 /* We return either a 128 or 64 bit key
773  */
774 static void
775 get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] ,const int flags ,int *keylen ,guint8 *clientsealkey ,guint8 *serversealkey)
776 {
777   md5_state_t md5state;
778   md5_state_t md5state2;
779   memset(clientsealkey,0,NTLMSSP_KEY_LEN);
780   memset(serversealkey,0,NTLMSSP_KEY_LEN);
781   memcpy(clientsealkey,exportedsessionkey,NTLMSSP_KEY_LEN);
782   if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)
783   {
784     if (flags & NTLMSSP_NEGOTIATE_128)
785     {
786       /* The exportedsessionkey has already the good length just update the length*/
787       *keylen = 16;
788     }
789     else
790     {
791       if (flags & NTLMSSP_NEGOTIATE_56)
792       {
793         memset(clientsealkey+7,0,9);
794         *keylen = 7;
795       }
796       else
797       {
798         memset(clientsealkey+5,0,11);
799         *keylen = 5;
800       }
801     }
802     memcpy(serversealkey,clientsealkey,NTLMSSP_KEY_LEN);
803     md5_init(&md5state);
804     md5_append(&md5state,clientsealkey,*keylen);
805     md5_append(&md5state,CLIENT_SEAL_TEXT,strlen(CLIENT_SEAL_TEXT)+1);
806     md5_finish(&md5state,clientsealkey);
807     md5_init(&md5state2);
808     md5_append(&md5state2,serversealkey,*keylen);
809     md5_append(&md5state2,SERVER_SEAL_TEXT,strlen(SERVER_SEAL_TEXT)+1);
810     md5_finish(&md5state2,serversealkey);
811   }
812   else
813   {
814     if (flags & NTLMSSP_NEGOTIATE_128)
815     {
816       /* The exportedsessionkey has already the good length just update the length*/
817       *keylen = 16;
818     }
819     else
820     {
821       *keylen = 8;
822       if (flags & NTLMSSP_NEGOTIATE_56)
823       {
824         memset(clientsealkey+7,0,9);
825       }
826       else
827       {
828         memset(clientsealkey+5,0,11);
829         clientsealkey[5]=0xe5;
830         clientsealkey[6]=0x38;
831         clientsealkey[7]=0xb0;
832       }
833     }
834     serversealkey = memcpy(serversealkey,clientsealkey,*keylen);
835   }
836 }
837 /* Create an NTLMSSP version 1 key.
838  * password points to the ANSI password to encrypt, challenge points to
839  * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
840  * otherwise it will do a 40 bit key.  The result is stored in
841  * sspkey (expected to be NTLMSSP_KEY_LEN octets)
842  */
843 /* dissect a string - header area contains:
844      two byte len
845      two byte maxlen
846      four byte offset of string in data area
847   The function returns the offset at the end of the string header,
848   but the 'end' parameter returns the offset of the end of the string itself
849   The 'start' parameter returns the offset of the beginning of the string
850   If there's no string, just use the offset of the end of the tvb as start/end.
851 */
852 static int
853 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
854                         proto_tree *ntlmssp_tree,
855                         gboolean unicode_strings,
856                         int string_hf, int *start, int *end,
857                         const char **stringp)
858 {
859   proto_tree *tree = NULL;
860   proto_item *tf = NULL;
861   gint16 string_length = tvb_get_letohs(tvb, offset);
862   gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
863   gint32 string_offset = tvb_get_letohl(tvb, offset+4);
864   const char *string_text = NULL;
865   int result_length;
866   guint16 bc;
867
868   *start = (string_offset > offset+8 ? string_offset : (signed)tvb_reported_length(tvb));
869   if (0 == string_length) {
870     *end = *start;
871     if (ntlmssp_tree)
872             proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
873                                   offset, 8, "NULL");
874     if (stringp != NULL)
875       *stringp = "";
876     return offset+8;
877   }
878
879   bc = result_length = string_length;
880   string_text = get_unicode_or_ascii_string(tvb, &string_offset,
881                                             unicode_strings, &result_length,
882                                             FALSE, TRUE, &bc);
883
884   if (stringp != NULL) {
885     if (!string_text) string_text = ""; /* Make sure we don't blow up later */
886
887     *stringp = string_text;
888   }
889
890   if (ntlmssp_tree) {
891     tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
892                                string_offset, result_length, string_text);
893     tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
894   }
895   proto_tree_add_uint(tree, hf_ntlmssp_string_len,
896                       tvb, offset, 2, string_length);
897   offset += 2;
898   proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
899                       tvb, offset, 2, string_maxlen);
900   offset += 2;
901   proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
902                       tvb, offset, 4, string_offset);
903   offset += 4;
904
905   *end = string_offset + string_length;
906   return offset;
907 }
908
909 /* dissect a generic blob - header area contains:
910      two byte len
911      two byte maxlen
912      four byte offset of blob in data area
913   The function returns the offset at the end of the blob header,
914   but the 'end' parameter returns the offset of the end of the blob itself
915 */
916 static int
917 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
918                       proto_tree *ntlmssp_tree,
919                       int blob_hf, int *end, ntlmssp_blob *result)
920 {
921   proto_item *tf = NULL;
922   proto_tree *tree = NULL;
923   guint16 blob_length = tvb_get_letohs(tvb, offset);
924   guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
925   guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
926   if (0 == blob_length) {
927     *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
928     if (ntlmssp_tree)
929             proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
930                                 proto_registrar_get_name(blob_hf));
931     return offset+8;
932   }
933
934   if (ntlmssp_tree) {
935     tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
936                               blob_offset, blob_length, FALSE);
937     tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
938   }
939   proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
940                       tvb, offset, 2, blob_length);
941   offset += 2;
942   proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
943                       tvb, offset, 2, blob_maxlen);
944   offset += 2;
945   proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
946                       tvb, offset, 4, blob_offset);
947   offset += 4;
948
949   *end = blob_offset + blob_length;
950
951   if (result != NULL) {
952     result->length = blob_length;
953     memset(result->contents, 0, MAX_BLOB_SIZE);
954     if (blob_length < MAX_BLOB_SIZE)
955     {
956       tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
957       if (blob_hf == hf_ntlmssp_auth_lmresponse && !(memcmp(tvb->real_data+blob_offset+8,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",NTLMSSP_KEY_LEN)))
958       {
959         proto_tree_add_item (ntlmssp_tree,
960                        hf_ntlmssp_ntlm_client_challenge,
961                        tvb, blob_offset, 8, FALSE);
962       }
963     }
964   }
965
966   /* If we are dissecting the NTLM response and it is a NTLMv2
967      response call the appropriate dissector. */
968
969   if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
970   {
971     proto_tree_add_item (ntlmssp_tree,
972             hf_ntlmssp_ntlm_client_challenge,
973             tvb, blob_offset+32, 8, FALSE);
974           dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
975   }
976
977   return offset;
978 }
979
980 static int
981 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
982                                  proto_tree *ntlmssp_tree,
983                                  guint32 negotiate_flags)
984 {
985   proto_tree *negotiate_flags_tree = NULL;
986   proto_item *tf = NULL;
987
988   if (ntlmssp_tree) {
989     tf = proto_tree_add_uint (ntlmssp_tree,
990                               hf_ntlmssp_negotiate_flags,
991                               tvb, offset, 4, negotiate_flags);
992     negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
993   }
994
995   proto_tree_add_boolean (negotiate_flags_tree,
996                           hf_ntlmssp_negotiate_flags_80000000,
997                           tvb, offset, 4, negotiate_flags);
998   proto_tree_add_boolean (negotiate_flags_tree,
999                           hf_ntlmssp_negotiate_flags_40000000,
1000                           tvb, offset, 4, negotiate_flags);
1001   proto_tree_add_boolean (negotiate_flags_tree,
1002                           hf_ntlmssp_negotiate_flags_20000000,
1003                           tvb, offset, 4, negotiate_flags);
1004   proto_tree_add_boolean (negotiate_flags_tree,
1005                           hf_ntlmssp_negotiate_flags_10000000,
1006                           tvb, offset, 4, negotiate_flags);
1007   proto_tree_add_boolean (negotiate_flags_tree,
1008                           hf_ntlmssp_negotiate_flags_8000000,
1009                           tvb, offset, 4, negotiate_flags);
1010   proto_tree_add_boolean (negotiate_flags_tree,
1011                           hf_ntlmssp_negotiate_flags_4000000,
1012                           tvb, offset, 4, negotiate_flags);
1013   proto_tree_add_boolean (negotiate_flags_tree,
1014                           hf_ntlmssp_negotiate_flags_2000000,
1015                           tvb, offset, 4, negotiate_flags);
1016   proto_tree_add_boolean (negotiate_flags_tree,
1017                           hf_ntlmssp_negotiate_flags_1000000,
1018                           tvb, offset, 4, negotiate_flags);
1019   proto_tree_add_boolean (negotiate_flags_tree,
1020                           hf_ntlmssp_negotiate_flags_800000,
1021                           tvb, offset, 4, negotiate_flags);
1022   proto_tree_add_boolean (negotiate_flags_tree,
1023                           hf_ntlmssp_negotiate_flags_400000,
1024                           tvb, offset, 4, negotiate_flags);
1025   proto_tree_add_boolean (negotiate_flags_tree,
1026                           hf_ntlmssp_negotiate_flags_200000,
1027                           tvb, offset, 4, negotiate_flags);
1028   proto_tree_add_boolean (negotiate_flags_tree,
1029                           hf_ntlmssp_negotiate_flags_100000,
1030                           tvb, offset, 4, negotiate_flags);
1031   proto_tree_add_boolean (negotiate_flags_tree,
1032                           hf_ntlmssp_negotiate_flags_80000,
1033                           tvb, offset, 4, negotiate_flags);
1034   proto_tree_add_boolean (negotiate_flags_tree,
1035                           hf_ntlmssp_negotiate_flags_40000,
1036                           tvb, offset, 4, negotiate_flags);
1037   proto_tree_add_boolean (negotiate_flags_tree,
1038                           hf_ntlmssp_negotiate_flags_20000,
1039                           tvb, offset, 4, negotiate_flags);
1040   proto_tree_add_boolean (negotiate_flags_tree,
1041                           hf_ntlmssp_negotiate_flags_10000,
1042                           tvb, offset, 4, negotiate_flags);
1043   proto_tree_add_boolean (negotiate_flags_tree,
1044                           hf_ntlmssp_negotiate_flags_8000,
1045                           tvb, offset, 4, negotiate_flags);
1046   proto_tree_add_boolean (negotiate_flags_tree,
1047                           hf_ntlmssp_negotiate_flags_4000,
1048                           tvb, offset, 4, negotiate_flags);
1049   proto_tree_add_boolean (negotiate_flags_tree,
1050                           hf_ntlmssp_negotiate_flags_2000,
1051                           tvb, offset, 4, negotiate_flags);
1052   proto_tree_add_boolean (negotiate_flags_tree,
1053                           hf_ntlmssp_negotiate_flags_1000,
1054                           tvb, offset, 4, negotiate_flags);
1055   proto_tree_add_boolean (negotiate_flags_tree,
1056                           hf_ntlmssp_negotiate_flags_800,
1057                           tvb, offset, 4, negotiate_flags);
1058   proto_tree_add_boolean (negotiate_flags_tree,
1059                           hf_ntlmssp_negotiate_flags_400,
1060                           tvb, offset, 4, negotiate_flags);
1061   proto_tree_add_boolean (negotiate_flags_tree,
1062                           hf_ntlmssp_negotiate_flags_200,
1063                           tvb, offset, 4, negotiate_flags);
1064   proto_tree_add_boolean (negotiate_flags_tree,
1065                           hf_ntlmssp_negotiate_flags_100,
1066                           tvb, offset, 4, negotiate_flags);
1067   proto_tree_add_boolean (negotiate_flags_tree,
1068                           hf_ntlmssp_negotiate_flags_80,
1069                           tvb, offset, 4, negotiate_flags);
1070   proto_tree_add_boolean (negotiate_flags_tree,
1071                           hf_ntlmssp_negotiate_flags_40,
1072                           tvb, offset, 4, negotiate_flags);
1073   proto_tree_add_boolean (negotiate_flags_tree,
1074                           hf_ntlmssp_negotiate_flags_20,
1075                           tvb, offset, 4, negotiate_flags);
1076   proto_tree_add_boolean (negotiate_flags_tree,
1077                           hf_ntlmssp_negotiate_flags_10,
1078                           tvb, offset, 4, negotiate_flags);
1079   proto_tree_add_boolean (negotiate_flags_tree,
1080                           hf_ntlmssp_negotiate_flags_08,
1081                           tvb, offset, 4, negotiate_flags);
1082   proto_tree_add_boolean (negotiate_flags_tree,
1083                           hf_ntlmssp_negotiate_flags_04,
1084                           tvb, offset, 4, negotiate_flags);
1085   proto_tree_add_boolean (negotiate_flags_tree,
1086                           hf_ntlmssp_negotiate_flags_02,
1087                           tvb, offset, 4, negotiate_flags);
1088   proto_tree_add_boolean (negotiate_flags_tree,
1089                           hf_ntlmssp_negotiate_flags_01,
1090                           tvb, offset, 4, negotiate_flags);
1091
1092   return (offset + 4);
1093 }
1094
1095 /* Dissect "version" */
1096
1097 /* From MS-NLMP:
1098     0   Major Version Number    1 byte
1099     1   Minor Version Number    1 byte
1100     2   Build Number            short(LE)
1101     3   (Reserved)              3 bytes
1102     4   NTLM Current Revision   1 byte
1103 */
1104
1105 static int
1106 dissect_ntlmssp_version(tvbuff_t *tvb, int offset,
1107                         proto_tree *ntlmssp_tree)
1108 {
1109   if (ntlmssp_tree) {
1110     proto_item *tf;
1111     proto_tree *version_tree;
1112     tf = proto_tree_add_none_format(ntlmssp_tree, hf_ntlmssp_version, tvb, offset, 8,
1113                                     "Version %u.%u (Build %u); NTLM Current Revision %u",
1114                                     tvb_get_guint8(tvb, offset),
1115                                     tvb_get_guint8(tvb, offset+1),
1116                                     tvb_get_letohs(tvb, offset+2),
1117                                     tvb_get_guint8(tvb, offset+7));
1118     version_tree = proto_item_add_subtree (tf, ett_ntlmssp_version);
1119     proto_tree_add_item(version_tree, hf_ntlmssp_version_major                , tvb, offset  , 1, ENC_NA);
1120     proto_tree_add_item(version_tree, hf_ntlmssp_version_minor                , tvb, offset+1, 1, ENC_NA);
1121     proto_tree_add_item(version_tree, hf_ntlmssp_version_build_number         , tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1122     proto_tree_add_item(version_tree, hf_ntlmssp_version_ntlm_current_revision, tvb, offset+7, 1, ENC_NA);
1123   }
1124   return offset+8;
1125 }
1126
1127 /* Dissect a NTLM response. This is documented at
1128    http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
1129
1130 /* Attribute types */
1131 /*
1132  * XXX - the davenport document says that a type of 5 has been seen,
1133  * "apparently containing the 'parent' DNS domain for servers in
1134  * subdomains".
1135  * XXX: MS-NLMP info is newer than Davenport info;
1136  *      The attribute type list and the attribute names below are
1137  *      based upon MS-NLMP.
1138  */
1139
1140 #define NTLM_TARGET_INFO_END               0x0000
1141 #define NTLM_TARGET_INFO_NB_COMPUTER_NAME  0x0001
1142 #define NTLM_TARGET_INFO_NB_DOMAIN_NAME    0x0002
1143 #define NTLM_TARGET_INFO_DNS_COMPUTER_NAME 0x0003
1144 #define NTLM_TARGET_INFO_DNS_DOMAIN_NAME   0x0004
1145 #define NTLM_TARGET_INFO_DNS_TREE_NAME     0x0005
1146 #define NTLM_TARGET_INFO_FLAGS             0x0006
1147 #define NTLM_TARGET_INFO_TIMESTAMP         0x0007
1148 #define NTLM_TARGET_INFO_RESTRICTIONS      0x0008
1149 #define NTLM_TARGET_INFO_TARGET_NAME       0x0009
1150 #define NTLM_TARGET_INFO_CHANNEL_BINDINGS  0x000A
1151
1152 static const value_string ntlm_name_types[] = {
1153         { NTLM_TARGET_INFO_END,               "End of list" },
1154         { NTLM_TARGET_INFO_NB_COMPUTER_NAME,  "NetBIOS computer name" },
1155         { NTLM_TARGET_INFO_NB_DOMAIN_NAME,    "NetBIOS domain name" },
1156         { NTLM_TARGET_INFO_DNS_COMPUTER_NAME, "DNS computer name" },
1157         { NTLM_TARGET_INFO_DNS_DOMAIN_NAME,   "DNS domain name" },
1158         { NTLM_TARGET_INFO_DNS_TREE_NAME,     "DNS tree name" },
1159         { NTLM_TARGET_INFO_FLAGS,             "Flags" },
1160         { NTLM_TARGET_INFO_TIMESTAMP,         "Timestamp" },
1161         { NTLM_TARGET_INFO_RESTRICTIONS,      "Restrictions" },
1162         { NTLM_TARGET_INFO_TARGET_NAME,       "Target Name"},
1163         { NTLM_TARGET_INFO_CHANNEL_BINDINGS,  "Channel Bindings"},
1164         { 0, NULL }
1165 };
1166
1167 /* The following *must* match the order of the list of attribute types   */
1168 /*  Assumption: values in the list are a sequence starting with 0 and    */
1169 /*  with no gaps allowing a direct access of the array by attribute type */
1170 static int *ntlmssp_hf_challenge_target_info_hf_ptr_array[] = {
1171   &hf_ntlmssp_challenge_target_info_end,
1172   &hf_ntlmssp_challenge_target_info_nb_computer_name,
1173   &hf_ntlmssp_challenge_target_info_nb_domain_name,
1174   &hf_ntlmssp_challenge_target_info_dns_computer_name,
1175   &hf_ntlmssp_challenge_target_info_dns_domain_name,
1176   &hf_ntlmssp_challenge_target_info_dns_tree_name,
1177   &hf_ntlmssp_challenge_target_info_flags,
1178   &hf_ntlmssp_challenge_target_info_timestamp,
1179   &hf_ntlmssp_challenge_target_info_restrictions,
1180   &hf_ntlmssp_challenge_target_info_target_name,
1181   &hf_ntlmssp_challenge_target_info_channel_bindings
1182 };
1183
1184 static int *ntlmssp_hf_ntlmv2_response_hf_ptr_array[] = {
1185   &hf_ntlmssp_ntlmv2_response_end,
1186   &hf_ntlmssp_ntlmv2_response_nb_computer_name,
1187   &hf_ntlmssp_ntlmv2_response_nb_domain_name,
1188   &hf_ntlmssp_ntlmv2_response_dns_computer_name,
1189   &hf_ntlmssp_ntlmv2_response_dns_domain_name,
1190   &hf_ntlmssp_ntlmv2_response_dns_tree_name,
1191   &hf_ntlmssp_ntlmv2_response_flags,
1192   &hf_ntlmssp_ntlmv2_response_timestamp,
1193   &hf_ntlmssp_ntlmv2_response_restrictions,
1194   &hf_ntlmssp_ntlmv2_response_target_name,
1195   &hf_ntlmssp_ntlmv2_response_channel_bindings
1196 };
1197
1198 typedef struct _tif {
1199   gint  *ett;
1200   int   *hf_item_type;
1201   int   *hf_item_length;
1202   int  **hf_attr_array_p;
1203 } tif_t;
1204
1205 static tif_t ntlmssp_challenge_target_info_tif = {
1206   &ett_ntlmssp_challenge_target_info_item,
1207   &hf_ntlmssp_challenge_target_info_item_type,
1208   &hf_ntlmssp_challenge_target_info_item_len,
1209   ntlmssp_hf_challenge_target_info_hf_ptr_array
1210 };
1211
1212 static tif_t ntlmssp_ntlmv2_response_tif = {
1213   &ett_ntlmssp_ntlmv2_response_item,
1214   &hf_ntlmssp_ntlmv2_response_item_type,
1215   &hf_ntlmssp_ntlmv2_response_item_len,
1216   ntlmssp_hf_ntlmv2_response_hf_ptr_array
1217 };
1218
1219 static void
1220 dissect_ntlmssp_target_info_list(tvbuff_t *tvb, proto_tree *tree,
1221                                  guint32 target_info_offset, guint16 target_info_length,
1222                                  tif_t *tif_p)
1223 {
1224   guint32 item_offset;
1225   guint16 item_type;
1226   guint16 item_length;
1227
1228
1229   /* Now enumerate through the individual items in the list */
1230   item_offset = target_info_offset;
1231
1232   while (item_offset < (target_info_offset + target_info_length)) {
1233     proto_item *target_info_tf;
1234     proto_tree *target_info_tree;
1235     guint32     content_offset;
1236     guint16     content_length;
1237     guint32     type_offset;
1238     guint32     len_offset;
1239
1240     int **hf_array_p = tif_p->hf_attr_array_p;
1241
1242     /* Content type */
1243     type_offset = item_offset;
1244     item_type = tvb_get_letohs(tvb, type_offset);
1245
1246     /* Content length */
1247     len_offset = type_offset + 2;
1248     content_length = tvb_get_letohs(tvb, len_offset);
1249
1250     /* Content value */
1251     content_offset = len_offset + 2;
1252     item_length    = content_length + 4;
1253
1254     target_info_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Attribute: %s",
1255                                   val_to_str(item_type, ntlm_name_types, "Unknown (%d)"));
1256
1257     target_info_tree = proto_item_add_subtree (target_info_tf, *tif_p->ett);
1258     proto_tree_add_item (target_info_tree, *tif_p->hf_item_type,    tvb, type_offset, 2, ENC_LITTLE_ENDIAN);
1259     proto_tree_add_item (target_info_tree, *tif_p->hf_item_length,  tvb, len_offset,  2, ENC_LITTLE_ENDIAN);
1260
1261     switch(item_type) {
1262     case NTLM_TARGET_INFO_NB_COMPUTER_NAME:
1263     case NTLM_TARGET_INFO_NB_DOMAIN_NAME:
1264     case NTLM_TARGET_INFO_DNS_COMPUTER_NAME:
1265     case NTLM_TARGET_INFO_DNS_DOMAIN_NAME:
1266     case NTLM_TARGET_INFO_DNS_TREE_NAME:
1267     case NTLM_TARGET_INFO_TARGET_NAME:
1268       if (content_length > 0) {
1269         const gchar *text;
1270
1271         text = tvb_get_ephemeral_faked_unicode(tvb, content_offset, content_length / 2, TRUE);
1272         proto_tree_add_string(target_info_tree, *hf_array_p[item_type],
1273                               tvb, content_offset, content_length, text);
1274         proto_item_append_text(target_info_tf, ": %s", text);
1275       }
1276       break;
1277
1278     case NTLM_TARGET_INFO_FLAGS:
1279       proto_tree_add_item(target_info_tree, *hf_array_p[item_type],
1280                           tvb, content_offset, content_length, ENC_LITTLE_ENDIAN);
1281       break;
1282
1283     case NTLM_TARGET_INFO_TIMESTAMP:
1284       dissect_nt_64bit_time(tvb, target_info_tree, content_offset, *hf_array_p[item_type]);
1285       break;
1286
1287     case NTLM_TARGET_INFO_RESTRICTIONS:
1288     case NTLM_TARGET_INFO_CHANNEL_BINDINGS:
1289       proto_tree_add_item(target_info_tree, *hf_array_p[item_type],
1290                           tvb, content_offset, content_length, ENC_NA);
1291       break;
1292
1293     default:
1294       break;
1295     }
1296
1297     item_offset += item_length;
1298   }
1299 }
1300
1301 int
1302 dissect_ntlmv2_response(tvbuff_t *tvb, proto_tree *tree, int offset, int len)
1303 {
1304         proto_item *ntlmv2_item = NULL;
1305         proto_tree *ntlmv2_tree = NULL;
1306         int         orig_offset;
1307
1308         /* Dissect NTLMv2 bits&pieces */
1309         orig_offset = offset;
1310
1311         if (tree) {
1312                 ntlmv2_item = proto_tree_add_item(
1313                         tree, hf_ntlmssp_ntlmv2_response, tvb,
1314                         offset, len, TRUE);
1315                 ntlmv2_tree = proto_item_add_subtree(
1316                         ntlmv2_item, ett_ntlmssp_ntlmv2_response);
1317         }
1318
1319         proto_tree_add_item(
1320                 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
1321                 offset, 16, TRUE);
1322
1323         offset += 16;
1324
1325         proto_tree_add_item(
1326                 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
1327                 offset, 4, TRUE);
1328
1329         offset += 4;
1330
1331         proto_tree_add_item(
1332                 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
1333                 offset, 4, TRUE);
1334
1335         offset += 4;
1336
1337         offset = dissect_nt_64bit_time(
1338                 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
1339
1340         proto_tree_add_item(
1341                 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
1342                 offset, 8, TRUE);
1343
1344         offset += 8;
1345
1346         proto_tree_add_item(
1347                 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
1348                 offset, 4, TRUE);
1349
1350         offset += 4;
1351
1352         /* Variable length list of attributes */
1353         /*
1354          * XXX - Windows puts one or more sets of 4 bytes of additional stuff (all zeros ?)
1355          *        at the end of the attributes.
1356          * Samba's smbclient doesn't.
1357          * Both of them appear to be able to connect to W2K SMB
1358          * servers.
1359          * The additional stuff will be dissected as extra "end" attributes.
1360          *
1361          */
1362         dissect_ntlmssp_target_info_list(tvb, ntlmv2_tree,
1363                                          offset, len - (offset - orig_offset),
1364                                          &ntlmssp_ntlmv2_response_tif);
1365
1366         return offset+len;
1367 }
1368
1369 /* tapping into ntlmssph not yet implemented */
1370 static int
1371 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1372 {
1373   guint32 negotiate_flags;
1374   int data_start;
1375   int data_end;
1376   int item_start;
1377   int item_end;
1378
1379   /* NTLMSSP Negotiate Flags */
1380   negotiate_flags = tvb_get_letohl (tvb, offset);
1381   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1382                                             negotiate_flags);
1383
1384   /*
1385    * XXX - the davenport document says that these might not be
1386    * sent at all, presumably meaning the length of the message
1387    * isn't enough to contain them.
1388    */
1389   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1390                                   hf_ntlmssp_negotiate_domain,
1391                                   &data_start, &data_end, NULL);
1392
1393   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1394                                   hf_ntlmssp_negotiate_workstation,
1395                                   &item_start, &item_end, NULL);
1396   data_start = MIN(data_start, item_start);
1397   data_end   = MAX(data_end,   item_end);
1398
1399   /* If there are more bytes before the data block dissect a version field */
1400   if (offset < data_start) {
1401     offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1402   }
1403   return data_end;
1404 }
1405
1406
1407 static int
1408 dissect_ntlmssp_challenge_target_info_blob (tvbuff_t *tvb, int offset,
1409                                             proto_tree *ntlmssp_tree,
1410                                             int *end)
1411 {
1412   guint16 challenge_target_info_length = tvb_get_letohs(tvb, offset);
1413   guint16 challenge_target_info_maxlen = tvb_get_letohs(tvb, offset+2);
1414   guint32 challenge_target_info_offset = tvb_get_letohl(tvb, offset+4);
1415   proto_item *tf = NULL;
1416   proto_tree *challenge_target_info_tree = NULL;
1417
1418   /* the target info list is just a blob */
1419   if (0 == challenge_target_info_length) {
1420     *end = (challenge_target_info_offset > ((guint)offset)+8 ? challenge_target_info_offset : ((guint)offset)+8);
1421     if (ntlmssp_tree)
1422             proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
1423                                 "Target Info List: Empty");
1424     return offset+8;
1425   }
1426
1427   if (ntlmssp_tree) {
1428     tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_target_info, tvb,
1429                               challenge_target_info_offset, challenge_target_info_length, FALSE);
1430     challenge_target_info_tree = proto_item_add_subtree(tf, ett_ntlmssp_challenge_target_info);
1431   }
1432   proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_len,
1433                       tvb, offset, 2, challenge_target_info_length);
1434   offset += 2;
1435   proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_maxlen,
1436                       tvb, offset, 2, challenge_target_info_maxlen);
1437   offset += 2;
1438   proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_offset,
1439                       tvb, offset, 4, challenge_target_info_offset);
1440   offset += 4;
1441
1442   dissect_ntlmssp_target_info_list(tvb, challenge_target_info_tree,
1443                                    challenge_target_info_offset, challenge_target_info_length,
1444                                    &ntlmssp_challenge_target_info_tif);
1445
1446   *end = challenge_target_info_offset + challenge_target_info_length;
1447   return offset;
1448 }
1449
1450 /* tapping into ntlmssph not yet implemented */
1451 static int
1452 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
1453                            proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1454 {
1455   guint32 negotiate_flags;
1456   int item_start, item_end;
1457   int data_start, data_end; /* MIN and MAX seen */
1458   guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1459   guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1460   ntlmssp_info *conv_ntlmssp_info = NULL;
1461   conversation_t *conversation;
1462   gboolean unicode_strings = FALSE;
1463   guint8 challenge[8];
1464   guint8 tmp[8];
1465   guint8 sspkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key */
1466   int ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
1467
1468   /* need to find unicode flag */
1469   negotiate_flags = tvb_get_letohl (tvb, offset+8);
1470   if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
1471     unicode_strings = TRUE;
1472
1473   /* Target name */
1474   /*
1475    * XXX - the davenport document (and MS-NLMP) calls this "Target Name",
1476    * presumably because non-domain targets are supported.
1477    * XXX - Original name "domain" changed to "target_name" to match MS-NLMP
1478    */
1479   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
1480                          hf_ntlmssp_challenge_target_name,
1481                          &item_start, &item_end, NULL);
1482   data_start = item_start;
1483   data_end = item_end;
1484
1485   /* NTLMSSP Negotiate Flags */
1486   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1487                                             negotiate_flags);
1488
1489   /* NTLMSSP NT Lan Manager Challenge */
1490   proto_tree_add_item (ntlmssp_tree,
1491                        hf_ntlmssp_ntlm_server_challenge,
1492                        tvb, offset, 8, FALSE);
1493
1494   /*
1495    * Store the flags and the RC4 state information with the conversation,
1496    * as they're needed in order to dissect subsequent messages.
1497    */
1498   conversation = find_or_create_conversation(pinfo);
1499
1500   tvb_memcpy(tvb, tmp, offset, 8); /* challenge */
1501   /* We can face more than one NTLM exchange over the same couple of IP and ports ...*/
1502   conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1503   /* XXX: The following code is (re)executed every time a particular frame is dissected
1504    *      (in whatever order). Thus it seems to me that "multiple exchanges" might not be
1505    *      handled well depending on the order that frames are visited after the initial dissection.
1506    */
1507   if (!conv_ntlmssp_info || memcmp(tmp,conv_ntlmssp_info->server_challenge,8) != 0) {
1508     conv_ntlmssp_info = se_alloc(sizeof(ntlmssp_info));
1509     /* Insert the flags into the conversation */
1510     conv_ntlmssp_info->flags = negotiate_flags;
1511     /* Insert the RC4 state information into the conversation */
1512     tvb_memcpy(tvb, challenge, offset, 8);
1513     tvb_memcpy(tvb, conv_ntlmssp_info->server_challenge, offset, 8);
1514     conv_ntlmssp_info->is_auth_ntlm_v2=0;
1515     /* Between the challenge and the user provided password, we can build the
1516        NTLMSSP key and initialize the cipher if we are not in EXTENDED SECURITY
1517        in this case we need the client challenge as well*/
1518     /* BTW this is true just if we are in LM Authentification if not the logic is a bit different.
1519      * Right now it's not very clear what is LM Authentification it __seems__ to be when
1520      * NEGOTIATE NT ONLY is not set and NEGOSIATE EXTENDED SECURITY is not set as well*/
1521     if (!(conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1522     {
1523       conv_ntlmssp_info->rc4_state_initialized = 0;
1524       create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,NULL, sspkey,NULL,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response.contents,conv_ntlmssp_info->lm_response.contents);
1525       if( memcmp(sspkey,gbl_zeros,NTLMSSP_KEY_LEN) != 0 ) {
1526         get_sealing_rc4key(sspkey,conv_ntlmssp_info->flags,&ssp_key_len,clientkey,serverkey);
1527         crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, sspkey, ssp_key_len);
1528         crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, sspkey, ssp_key_len);
1529         conv_ntlmssp_info->server_dest_port = pinfo->destport;
1530         conv_ntlmssp_info->rc4_state_initialized = 1;
1531       }
1532
1533     }
1534     conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1535   }
1536   offset += 8;
1537
1538   /* If no more bytes (ie: no "reserved", ...) before start of data block, then return */
1539   /* XXX: According to Davenport "This form is seen in older Win9x-based systems"      */
1540   /*      Also: I've seen a capture with an HTTP CONNECT proxy-authentication          */
1541   /*            message wherein the challenge from the proxy has this form.            */
1542   if (offset >= data_start) {
1543     return data_end;
1544   }
1545
1546   /* Reserved (function not completely known) */
1547   /*
1548    * XXX - SSP key?  The davenport document says
1549    *
1550    *    The context field is typically populated when Negotiate Local
1551    *    Call is set. It contains an SSPI context handle, which allows
1552    *    the client to "short-circuit" authentication and effectively
1553    *    circumvent responding to the challenge. Physically, the context
1554    *    is two long values. This is covered in greater detail later,
1555    *    in the "Local Authentication" section.
1556    *
1557    * It also says that that information may be omitted.
1558    */
1559   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
1560                        tvb, offset, 8, FALSE);
1561   offset += 8;
1562
1563   /*
1564    * The presence or absence of this field is not obviously correlated
1565    * with any flags in the previous NEGOTIATE message or in this
1566    * message (other than the "Workstation Supplied" and "Domain
1567    * Supplied" flags in the NEGOTIATE message, at least in the capture
1568    * I've seen - but those also correlate with the presence of workstation
1569    * and domain name fields, so it doesn't seem to make sense that they
1570    * actually *indicate* whether the subsequent CHALLENGE has an
1571    * address list).
1572    */
1573   if (offset < data_start) {
1574     offset = dissect_ntlmssp_challenge_target_info_blob(tvb, offset, ntlmssp_tree, &item_end);
1575     /* XXX: This code assumes that the address list in the data block */
1576     /*      is always after the target name. Is this OK ?             */
1577     data_end = MAX(data_end, item_end);
1578   }
1579
1580   /* If there are more bytes before the data block dissect a version field */
1581   if (offset < data_start) {
1582     offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1583   }
1584
1585   return MAX(offset, data_end);
1586 }
1587
1588 static int
1589 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
1590                       proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
1591 {
1592   int item_start, item_end;
1593   int data_start, data_end = 0;
1594   guint32 negotiate_flags;
1595   guint8 sspkey[NTLMSSP_KEY_LEN]; /* exported session key */
1596   guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1597   guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1598   guint8 encryptedsessionkey[NTLMSSP_KEY_LEN];
1599   ntlmssp_blob sessionblob;
1600   gboolean unicode_strings = FALSE;
1601   ntlmssp_info *conv_ntlmssp_info = NULL;
1602   conversation_t *conversation;
1603   int ssp_key_len;
1604   /*
1605    * Get flag info from the original negotiate message, if any.
1606    * This is because the flag information is sometimes missing from
1607    * the AUTHENTICATE message, so we can't figure out whether
1608    * strings are Unicode or not by looking at *our* flags.
1609    * XXX it seems it's more from the CHALLENGE message, which is more clever in fact
1610    * because the server can change some flags.
1611    * But according to MS NTLMSSP doc it's not that simple.
1612    * In case of Conection less mode AUTHENTICATE flags should be used because they
1613    * reprensent the choice of the client after having been informed of options of the
1614    * server in the CHALLENGE message.
1615    * In Connection mode then the CHALLENGE flags should (must ?) be used
1616    * XXX: MS-NLMP says the flag field in the AUTHENTICATE message "contains the set of bit
1617    *   flags (section 2.2.2.5) negotiated in the previous messages."
1618    *   I read that to mean that the flags for in connection-mode AUTHENTICATE also represent
1619    *   the choice of the client (for the flags which are negotiated).
1620    * XXX: In the absence of CHALLENGE flags, as a last resort we'll use the flags
1621    *      (if available) from this AUTHENTICATE message.
1622    *      I've seen a capture which does an HTTP CONNECT which:
1623    *      - has the NEGOTIATE & CHALLENGE messages in one TCP connection;
1624    *      - has the AUTHENTICATE message in a second TCP connection;
1625    *        (The authentication aparently succeeded).
1626    */
1627   conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1628   if (conv_ntlmssp_info == NULL) {
1629     /*
1630      * There isn't any.  Is there any from this conversation?  If so,
1631      * it means this is the first time we've dissected this frame, so
1632      * we should give it flag info.
1633      */
1634     /* XXX: Create conv_ntlmssp_info & etc if no previous CHALLENGE seen */
1635     /*      so we'll have a place to store flags.                        */
1636     /*      This is a bit brute-force but looks like it will be OK.      */
1637     conversation = find_or_create_conversation(pinfo);
1638     conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1639     if (conv_ntlmssp_info == NULL) {
1640       conv_ntlmssp_info = se_alloc0(sizeof(ntlmssp_info));
1641       conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1642     }
1643     /* XXX: The *conv_ntlmssp_info struct attached to the frame is the
1644             same as the one attached to the conversation. That is: *both* point to
1645             the exact same struct in memory.  Is this what is indended ?  */
1646     p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1647   }
1648
1649   if (conv_ntlmssp_info != NULL) {
1650     if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1651       unicode_strings = TRUE;
1652   }
1653
1654   /*
1655    * Sometimes the session key and flags are missing.
1656    * Sometimes the session key is present but the flags are missing.
1657    * XXX Who stay so ? Reading spec I would rather say the opposite: flags are
1658    * always present, session information are always there as well but sometime
1659    * session information could be null (in case of no session)
1660    * Sometimes they're both present.
1661    *
1662    * This does not correlate with any flags in the previous CHALLENGE
1663    * message, and only correlates with "Negotiate Unicode", "Workstation
1664    * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1665    * those don't make sense as flags to use to determine this.
1666    *
1667    * So we check all of the descriptors to figure out where the data
1668    * area begins, and if the session key or the flags would be in the
1669    * middle of the data area, we assume the field in question is
1670    * missing.
1671    *
1672    * XXX - Reading Davenport and MS-NLMP: as I see it the possibilities are:
1673    *       a. No session-key; no flags; no version ("Win9x")
1674    *       b. Session-key & flags.
1675    *       c. Session-key, flags & version.
1676    *    In cases b and c the session key may be "null".
1677    *
1678    */
1679
1680   /* Lan Manager response */
1681   data_start = tvb_get_letohl(tvb, offset+4);
1682   offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1683                                 hf_ntlmssp_auth_lmresponse,
1684                                 &item_end,
1685                                 conv_ntlmssp_info == NULL ? NULL :
1686                                     &conv_ntlmssp_info->lm_response);
1687   data_end = MAX(data_end, item_end);
1688
1689   /* NTLM response */
1690   item_start = tvb_get_letohl(tvb, offset+4);
1691   offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1692                                 hf_ntlmssp_auth_ntresponse,
1693                                 &item_end,
1694                                 conv_ntlmssp_info == NULL ? NULL :
1695                                 &conv_ntlmssp_info->ntlm_response);
1696   if( conv_ntlmssp_info != NULL && conv_ntlmssp_info->ntlm_response.length > 24 ) {
1697     memcpy(conv_ntlmssp_info->client_challenge,conv_ntlmssp_info->ntlm_response.contents+32,8);
1698   }
1699   data_start = MIN(data_start, item_start);
1700   data_end = MAX(data_end, item_end);
1701   if( conv_ntlmssp_info != NULL )
1702   {
1703     if( conv_ntlmssp_info->ntlm_response.length > 24 )
1704     {
1705       conv_ntlmssp_info->is_auth_ntlm_v2=1;
1706     }
1707     else
1708     {
1709       conv_ntlmssp_info->is_auth_ntlm_v2=0;
1710     }
1711   }
1712
1713   /* domain name */
1714   item_start = tvb_get_letohl(tvb, offset+4);
1715   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1716                                   unicode_strings,
1717                                   hf_ntlmssp_auth_domain,
1718                                   &item_start, &item_end, &(ntlmssph->domain_name));
1719   /*ntlmssph->domain_name_len=item_end-item_start;*/
1720   data_start = MIN(data_start, item_start);
1721   data_end = MAX(data_end, item_end);
1722
1723   /* user name */
1724   item_start = tvb_get_letohl(tvb, offset+4);
1725   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1726                                   unicode_strings,
1727                                   hf_ntlmssp_auth_username,
1728                                   &item_start, &item_end, &(ntlmssph->acct_name));
1729   /*ntlmssph->acct_name_len=item_end-item_start;*/
1730   data_start = MIN(data_start, item_start);
1731   data_end = MAX(data_end, item_end);
1732
1733   if (check_col(pinfo->cinfo, COL_INFO))
1734     col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s\\%s",
1735                     ntlmssph->domain_name, ntlmssph->acct_name);
1736
1737   /* hostname */
1738   item_start = tvb_get_letohl(tvb, offset+4);
1739   offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1740                                   unicode_strings,
1741                                   hf_ntlmssp_auth_hostname,
1742                                   &item_start, &item_end, &(ntlmssph->host_name));
1743   data_start = MIN(data_start, item_start);
1744   data_end = MAX(data_end, item_end);
1745
1746   memset(sessionblob.contents, 0, MAX_BLOB_SIZE);
1747   sessionblob.length = 0;
1748   if (offset < data_start) {
1749     /* Session Key */
1750     offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1751                                   hf_ntlmssp_auth_sesskey,
1752                                   &item_end, &sessionblob);
1753     data_end = MAX(data_end, item_end);
1754   }
1755
1756   if (offset < data_start) {
1757     /* NTLMSSP Negotiate Flags */
1758     negotiate_flags = tvb_get_letohl (tvb, offset);
1759     offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1760                                               negotiate_flags);
1761     /* If no previous flags seen (ie: no previous CHALLENGE) use flags
1762        from the AUTHENTICATE message).
1763        Assumption: (flags == 0) means flags not previously seen  */
1764     if ((conv_ntlmssp_info != NULL) && (conv_ntlmssp_info->flags == 0)) {
1765       conv_ntlmssp_info->flags = negotiate_flags;
1766     }
1767   }
1768
1769   /* If there are more bytes before the data block dissect a version field */
1770   if (offset < data_start) {
1771     offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1772   }
1773
1774   /* If there are still more bytes before the data block dissect an MIC (message integrity_code) field */
1775   /*  (See MS-NLMP)                                                                    */
1776   if (offset < data_start) {
1777     proto_tree_add_item(ntlmssp_tree, hf_ntlmssp_message_integrity_code, tvb, offset, 16, ENC_NA);
1778     offset += 16;
1779   }
1780
1781   if ( sessionblob.length > NTLMSSP_KEY_LEN ) {
1782     expert_add_info_format(pinfo, NULL, PI_WARN, PI_UNDECODED, "Session blob length too long: %u", sessionblob.length);
1783   } else if( sessionblob.length != 0 ) {
1784     memcpy(encryptedsessionkey,sessionblob.contents,sessionblob.length);
1785     /* Try to attach to an existing conversation if not then it's useless to try to do so
1786      * because we are missing important information (ie. server challenge)
1787      */
1788     if (conv_ntlmssp_info) {
1789       /* If we are in EXTENDED SECURITY then we can now initialize cipher */
1790       if ((conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1791       {
1792         conv_ntlmssp_info->rc4_state_initialized = 0;
1793         if( conv_ntlmssp_info->is_auth_ntlm_v2 ) {
1794           create_ntlmssp_v2_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response,conv_ntlmssp_info->lm_response,ntlmssph);
1795         }
1796         else
1797         {
1798           memcpy(conv_ntlmssp_info->client_challenge,conv_ntlmssp_info->lm_response.contents,8);
1799           create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response.contents,conv_ntlmssp_info->lm_response.contents);
1800         }
1801         /* ssp is the exported session key */
1802         if( memcmp(sspkey,gbl_zeros,NTLMSSP_KEY_LEN) != 0) {
1803           get_sealing_rc4key(sspkey,conv_ntlmssp_info->flags,&ssp_key_len,clientkey,serverkey);
1804           get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server,(guint8*)&conv_ntlmssp_info->sign_key_client,sspkey,ssp_key_len);
1805           crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, serverkey, ssp_key_len);
1806           crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, clientkey, ssp_key_len);
1807           conv_ntlmssp_info->server_dest_port = pinfo->destport;
1808           conv_ntlmssp_info->rc4_state_initialized = 1;
1809         }
1810       }
1811      }
1812   }
1813   return MAX(offset, data_end);
1814 }
1815 static guint8*
1816 get_sign_key(packet_info *pinfo, int cryptpeer)
1817 {
1818   conversation_t *conversation;
1819   ntlmssp_info *conv_ntlmssp_info;
1820
1821   conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1822                                    pinfo->ptype, pinfo->srcport,
1823                                    pinfo->destport, 0);
1824   if (conversation == NULL) {
1825     /* We don't have a conversation.  In this case, stop processing
1826        because we do not have enough info to decrypt the payload */
1827     return NULL;
1828   }
1829   else {
1830     /* We have a conversation, check for encryption state */
1831     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1832                                                     proto_ntlmssp);
1833     if (conv_ntlmssp_info == NULL) {
1834       /* No encryption state tied to the conversation.  Therefore, we
1835          cannot decrypt the payload */
1836       return NULL;
1837     }
1838     else {
1839       /* We have the encryption state in the conversation.  So return the
1840          crypt state tied to the requested peer
1841        */
1842       if (cryptpeer == 1) {
1843               return (guint8*)&conv_ntlmssp_info->sign_key_client;
1844       } else {
1845               return (guint8*)&conv_ntlmssp_info->sign_key_server;
1846       }
1847     }
1848   }
1849 }
1850 /*
1851  * Get the encryption state tied to this conversation.  cryptpeer indicates
1852  * whether to retrieve the client key (1) or the server key (0)
1853  */
1854 static rc4_state_struct *
1855 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1856 {
1857   conversation_t *conversation;
1858   ntlmssp_info *conv_ntlmssp_info;
1859
1860   conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1861                                    pinfo->ptype, pinfo->srcport,
1862                                    pinfo->destport, 0);
1863   if (conversation == NULL) {
1864     /* We don't have a conversation.  In this case, stop processing
1865        because we do not have enough info to decrypt the payload */
1866     return NULL;
1867   }
1868   else {
1869     /* We have a conversation, check for encryption state */
1870     conv_ntlmssp_info = conversation_get_proto_data(conversation,
1871                                                     proto_ntlmssp);
1872     if (conv_ntlmssp_info == NULL) {
1873       /* No encryption state tied to the conversation.  Therefore, we
1874          cannot decrypt the payload */
1875       return NULL;
1876     }
1877     else {
1878       /* We have the encryption state in the conversation.  So return the
1879          crypt state tied to the requested peer
1880        */
1881       if (cryptpeer == 1) {
1882               return &conv_ntlmssp_info->rc4_state_client;
1883       } else {
1884               return &conv_ntlmssp_info->rc4_state_server;
1885       }
1886     }
1887   }
1888 }
1889 void
1890 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1891                  packet_info *pinfo, proto_tree *tree _U_,gpointer key);
1892 static void
1893 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1894                  packet_info *pinfo, proto_tree *tree,gpointer key);
1895 /*
1896 tvbuff_t *
1897 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
1898                                   tvbuff_t *auth_tvb _U_,
1899                                   int offset,
1900                                   packet_info *pinfo,
1901                                   dcerpc_auth_info *auth_info _U_)*/
1902
1903 int
1904 dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
1905 {
1906   volatile int offset = 0;
1907   proto_tree *volatile ntlmssp_tree = NULL;
1908   proto_item *tf = NULL;
1909   guint32 length;
1910   guint32 encrypted_block_length;
1911   guint8 key[NTLMSSP_KEY_LEN];
1912   /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
1913    */
1914   guint32 ntlm_magic_size = 4;
1915   guint32 ntlm_signature_size = 8;
1916   guint32 ntlm_seq_size = 4;
1917   length = tvb_length (tvb);
1918   /* signature + seq + real payload */
1919   encrypted_block_length = length - ntlm_magic_size;
1920
1921   if (encrypted_block_length < (ntlm_signature_size + ntlm_seq_size)) {
1922     /* Don't know why this would happen, but if it does, don't even bother
1923        attempting decryption/dissection */
1924     return offset + length;
1925   }
1926
1927   /* Setup a new tree for the NTLMSSP payload */
1928   if (tree) {
1929     tf = proto_tree_add_item (tree,
1930                               hf_ntlmssp_verf,
1931                               tvb, offset, -1, FALSE);
1932
1933     ntlmssp_tree = proto_item_add_subtree (tf,
1934                                            ett_ntlmssp);
1935   }
1936
1937   /*
1938    * Catch the ReportedBoundsError exception; the stuff we've been
1939    * handed doesn't necessarily run to the end of the packet, it's
1940    * an item inside a packet, so if it happens to be malformed (or
1941    * we, or a dissector we call, has a bug), so that an exception
1942    * is thrown, we want to report the error, but return and let
1943    * our caller dissect the rest of the packet.
1944    *
1945    * If it gets a BoundsError, we can stop, as there's nothing more
1946    * in the packet after our blob to see, so we just re-throw the
1947    * exception.
1948    */
1949   TRY {
1950     /* Version number */
1951     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1952                          tvb, offset, 4, TRUE);
1953     offset += 4;
1954
1955     /* Encrypted body */
1956     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1957                          tvb, offset, ntlm_signature_size + ntlm_seq_size, TRUE);
1958     tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size);
1959     /* Try to decrypt */
1960     decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree,key);
1961     decrypt_verifier (tvb, offset, ntlm_signature_size + ntlm_seq_size, pinfo, ntlmssp_tree,key);
1962     /* let's try to hook ourselves here */
1963
1964     offset += 12;
1965   } CATCH(BoundsError) {
1966     RETHROW;
1967   } CATCH(ReportedBoundsError) {
1968     show_reported_bounds_error(tvb, pinfo, tree);
1969   } ENDTRY;
1970
1971   return offset;
1972 }
1973 void
1974 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1975                  packet_info *pinfo, proto_tree *tree _U_,gpointer key)
1976 {
1977   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1978   guint8 *peer_block;
1979   conversation_t *conversation;
1980   rc4_state_struct *rc4_state;
1981   rc4_state_struct *rc4_state_peer;
1982   ntlmssp_info *conv_ntlmssp_info = NULL;
1983   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1984   ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
1985
1986   /* Check to see if we already have state for this packet */
1987   packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1988   if (packet_ntlmssp_info == NULL) {
1989     /* We don't have any packet state, so create one */
1990     packet_ntlmssp_info = se_alloc0(sizeof(ntlmssp_packet_info));
1991     p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1992   }
1993   if (!packet_ntlmssp_info->payload_decrypted) {
1994     /* Pull the challenge info from the conversation */
1995     conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1996                                      pinfo->ptype, pinfo->srcport,
1997                                      pinfo->destport, 0);
1998     if (conversation == NULL) {
1999       /* There is no conversation, thus no encryption state */
2000       return ;
2001     }
2002
2003     conv_ntlmssp_info = conversation_get_proto_data(conversation,
2004                                                     proto_ntlmssp);
2005     if (conv_ntlmssp_info == NULL) {
2006       /* There is no NTLMSSP state tied to the conversation */
2007             return ;
2008     }
2009     if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
2010        /* The crypto sybsystem is not initialized.  This means that either
2011                  the conversation did not include a challenge, or that we do not have the right password */
2012        return;
2013     }
2014     if( key != NULL ){
2015       stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet,key);
2016     }
2017     if( stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->payload_decrypted == TRUE)
2018     {
2019       /* Mat TBD (stderr,"Found a already decrypted packet\n");*/
2020       memcpy(packet_ntlmssp_info,stored_packet_ntlmssp_info,sizeof(ntlmssp_packet_info));
2021       /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload,encrypted_block_length,"Data: ","\n");*/
2022     }
2023     else
2024     {
2025       /* Get the pair of RC4 state structures.  One is used for to decrypt the
2026          payload.  The other is used to re-encrypt the payload to represent
2027          the peer */
2028       if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2029         /* client */
2030         rc4_state = get_encrypted_state(pinfo, 1);
2031         rc4_state_peer = get_encrypted_state(pinfo, 0);
2032       } else {
2033         /* server */
2034         rc4_state = get_encrypted_state(pinfo, 0);
2035         rc4_state_peer = get_encrypted_state(pinfo, 1);
2036       }
2037
2038       if (rc4_state == NULL ) {
2039         /* There is no encryption state, so we cannot decrypt */
2040         return ;
2041       }
2042
2043       /* Store the decrypted contents in the packet state struct
2044          (of course at this point, they aren't decrypted yet) */
2045       packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
2046                                                           encrypted_block_length);
2047       packet_ntlmssp_info->payload_len = encrypted_block_length;
2048       decrypted_payloads = g_slist_prepend(decrypted_payloads,
2049                                            packet_ntlmssp_info->decrypted_payload);
2050       if( key != NULL ) {
2051         g_hash_table_insert(hash_packet,key,packet_ntlmssp_info);
2052       }
2053
2054       /* Do the decryption of the payload */
2055       crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2056               encrypted_block_length);
2057       /* decrypt the verifier */
2058       /*printnchar(packet_ntlmssp_info->decrypted_payload,encrypted_block_length,"data: ","\n");*/
2059       /* We setup a temporary buffer so we can re-encrypt the payload after
2060          decryption.  This is to update the opposite peer's RC4 state
2061          it's usefull when we have only one key for both conversation
2062          in case of KEY_EXCH we have independant key so this is not needed*/
2063       if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2064         peer_block = ep_memdup(packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
2065         crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2066       }
2067
2068       packet_ntlmssp_info->payload_decrypted = TRUE;
2069     }
2070   }
2071
2072  /* Show the decrypted buffer in a new window */
2073   decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
2074                                encrypted_block_length,
2075                                encrypted_block_length);
2076
2077   tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
2078   pinfo->gssapi_decrypted_tvb =  decr_tvb;
2079 }
2080 static void
2081 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2082 {
2083   volatile int offset = 0;
2084   proto_tree *volatile ntlmssp_tree = NULL;
2085   proto_item *tf = NULL;
2086   ntlmssp_header_t *ntlmssph;
2087
2088   ntlmssph=ep_alloc(sizeof(ntlmssp_header_t));
2089   ntlmssph->type=0;
2090   ntlmssph->domain_name=NULL;
2091   ntlmssph->acct_name=NULL;
2092   ntlmssph->host_name=NULL;
2093
2094   /* Setup a new tree for the NTLMSSP payload */
2095   if (tree) {
2096     tf = proto_tree_add_item (tree,
2097                               proto_ntlmssp,
2098                               tvb, offset, -1, FALSE);
2099
2100     ntlmssp_tree = proto_item_add_subtree (tf,
2101                                            ett_ntlmssp);
2102   }
2103
2104   /*
2105    * Catch the ReportedBoundsError exception; the stuff we've been
2106    * handed doesn't necessarily run to the end of the packet, it's
2107    * an item inside a packet, so if it happens to be malformed (or
2108    * we, or a dissector we call, has a bug), so that an exception
2109    * is thrown, we want to report the error, but return and let
2110    * our caller dissect the rest of the packet.
2111    *
2112    * If it gets a BoundsError, we can stop, as there's nothing more
2113    * in the packet after our blob to see, so we just re-throw the
2114    * exception.
2115    */
2116   TRY {
2117     /* NTLMSSP constant */
2118     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
2119                          tvb, offset, 8, FALSE);
2120     offset += 8;
2121
2122     /* NTLMSSP Message Type */
2123     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
2124                          tvb, offset, 4, TRUE);
2125     ntlmssph->type = tvb_get_letohl (tvb, offset);
2126     offset += 4;
2127
2128     if (check_col(pinfo->cinfo, COL_INFO))
2129             col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
2130                             val_to_str(ntlmssph->type,
2131                                        ntlmssp_message_types,
2132                                        "Unknown message type"));
2133
2134     /* Call the appropriate dissector based on the Message Type */
2135     switch (ntlmssph->type) {
2136
2137     case NTLMSSP_NEGOTIATE:
2138       offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree, ntlmssph);
2139       break;
2140
2141     case NTLMSSP_CHALLENGE:
2142       offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2143       break;
2144
2145     case NTLMSSP_AUTH:
2146       offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2147       break;
2148
2149     default:
2150       /* Unrecognized message type */
2151       proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
2152                            "Unrecognized NTLMSSP Message");
2153       break;
2154     }
2155   } CATCH(BoundsError) {
2156     RETHROW;
2157   } CATCH(ReportedBoundsError) {
2158     show_reported_bounds_error(tvb, pinfo, tree);
2159   } ENDTRY;
2160
2161   /*tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);*/
2162 }
2163
2164
2165
2166 /*
2167  * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
2168  */
2169 static void
2170 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
2171                  packet_info *pinfo, proto_tree *tree,gpointer key)
2172 {
2173   proto_tree *decr_tree = NULL;
2174   proto_item *tf = NULL;
2175   conversation_t *conversation;
2176   guint8* sign_key;
2177   rc4_state_struct *rc4_state;
2178   rc4_state_struct *rc4_state_peer;
2179   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2180   guint8 *peer_block;
2181   guint8 *check_buf;
2182   guint8 calculated_md5[NTLMSSP_KEY_LEN];
2183   ntlmssp_info *conv_ntlmssp_info = NULL;
2184   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
2185   int decrypted_offset = 0;
2186   int sequence = 0;
2187
2188   ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
2189   packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2190   if (packet_ntlmssp_info == NULL) {
2191     /* We don't have data for this packet */
2192     return;
2193   }
2194   conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2195                      pinfo->ptype, pinfo->srcport,
2196                      pinfo->destport, 0);
2197   if (conversation == NULL) {
2198     /* There is no conversation, thus no encryption state */
2199     return;
2200   }
2201   conv_ntlmssp_info = conversation_get_proto_data(conversation,
2202                                                     proto_ntlmssp);
2203   if (conv_ntlmssp_info == NULL) {
2204   /* There is no NTLMSSP state tied to the conversation */
2205     return;
2206   }
2207
2208   if( key != NULL ){
2209     stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet,key);
2210   }
2211   if( stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->verifier_decrypted == TRUE) {
2212       /* Mat TBD fprintf(stderr,"Found a already decrypted packet\n");*/
2213       /* In Theory it's aleady the case, and we should be more clever ... like just copying buffers ...*/
2214       packet_ntlmssp_info = stored_packet_ntlmssp_info;
2215   }
2216   else {
2217     if (!packet_ntlmssp_info->verifier_decrypted) {
2218       if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
2219         /* The crypto sybsystem is not initialized.  This means that either
2220          the conversation did not include a challenge, or we are doing
2221          something other than NTLMSSP v1 */
2222         return;
2223       }
2224       if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2225         /* client talk to server */
2226         rc4_state = get_encrypted_state(pinfo, 1);
2227         sign_key = get_sign_key(pinfo,1);
2228         rc4_state_peer = get_encrypted_state(pinfo, 0);
2229       } else {
2230         rc4_state = get_encrypted_state(pinfo, 0);
2231         sign_key = get_sign_key(pinfo,0);
2232         rc4_state_peer = get_encrypted_state(pinfo, 1);
2233       }
2234
2235       if (rc4_state == NULL || rc4_state_peer == NULL) {
2236         /* There is no encryption state, so we cannot decrypt */
2237         return;
2238       }
2239
2240       /* Setup the buffer to decrypt to */
2241       tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
2242                offset, encrypted_block_length);
2243
2244       /*if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/
2245       if( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY ) {
2246         if( (NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2247           /* The spec says that if we have have a key exchange then we have a the signature that is crypted
2248            * otherwise it's just a hmac_md5(keysign,concat(message,sequence))[0..7]
2249            */
2250           crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2251                 8);
2252         }
2253         /*
2254          * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but
2255          * don't with DCE/RPC calls.
2256          * Some analysis need to be done ...
2257          */
2258         if( sign_key != NULL ) {
2259           check_buf = ep_alloc(packet_ntlmssp_info->payload_len+4);
2260           tvb_memcpy(tvb, &sequence,offset+8,4);
2261           memcpy(check_buf,&sequence,4);
2262           memcpy(check_buf+4,packet_ntlmssp_info->decrypted_payload,packet_ntlmssp_info->payload_len);
2263           md5_hmac(check_buf,(int)(packet_ntlmssp_info->payload_len+4),sign_key,NTLMSSP_KEY_LEN,calculated_md5);
2264           /*
2265           printnbyte(packet_ntlmssp_info->verifier,8,"HMAC from packet: ","\n");
2266           printnbyte(calculated_md5,8,"HMAC            : ","\n");
2267           */
2268         }
2269       }
2270       else {
2271         /* The packet has a PAD then a checksum then a sequence and they are encoded in this order so we can decrypt all at once */
2272         /* Do the actual decryption of the verifier */
2273         crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2274                 encrypted_block_length);
2275       }
2276
2277
2278
2279       /* We setup a temporary buffer so we can re-encrypt the payload after
2280          decryption.  This is to update the opposite peer's RC4 state
2281          This is not needed when we just have EXTENDED SECURITY because the signature is not crypted
2282          and it's also not needed when we have key exchange because server and client have independant keys */
2283       if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) {
2284         peer_block = ep_memdup(packet_ntlmssp_info->verifier, encrypted_block_length);
2285         crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2286       }
2287
2288       /* Mark the packet as decrypted so that subsequent attempts to dissect
2289          the packet use the already decrypted payload instead of attempting
2290          to decrypt again */
2291       packet_ntlmssp_info->verifier_decrypted = TRUE;
2292     }
2293   }
2294   /* Show the decrypted buffer in a new window */
2295   decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->verifier,
2296                                encrypted_block_length,
2297                                encrypted_block_length);
2298   add_new_data_source(pinfo, decr_tvb,
2299                       "Decrypted NTLMSSP Verifier");
2300
2301   /* Show the decrypted payload in the tree */
2302   tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
2303                            "Decrypted Verifier (%d byte%s)",
2304                            encrypted_block_length,
2305                            plurality(encrypted_block_length, "", "s"));
2306   decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
2307
2308   if(( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
2309     proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5,
2310                        decr_tvb, decrypted_offset, 8,TRUE);
2311     decrypted_offset += 8;
2312
2313
2314
2315     /* Incrementing sequence number of DCE conversation */
2316    proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2317                          decr_tvb, decrypted_offset, 4, TRUE);
2318     decrypted_offset += 4;
2319   }
2320   else {
2321
2322     /* RANDOM PAD usually it's 0 */
2323     proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad,
2324                        decr_tvb, decrypted_offset, 4, TRUE);
2325     decrypted_offset += 4;
2326
2327     /* CRC32 of the DCE fragment data */
2328     proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
2329                        decr_tvb, decrypted_offset, 4, TRUE);
2330     decrypted_offset += 4;
2331
2332     /* Incrementing sequence number of DCE conversation */
2333    proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2334                          decr_tvb, decrypted_offset, 4, TRUE);
2335     decrypted_offset += 4;
2336   }
2337 }
2338
2339 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious*/
2340 static int
2341 dissect_ntlmssp_payload_only(tvbuff_t *tvb, packet_info *pinfo, _U_ proto_tree *tree)
2342 {
2343   volatile int offset = 0;
2344   proto_tree *volatile ntlmssp_tree = NULL;
2345   guint32 encrypted_block_length;
2346   /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
2347    */
2348   encrypted_block_length = tvb_length (tvb);
2349   /* signature + seq + real payload */
2350
2351   /* Setup a new tree for the NTLMSSP payload */
2352   /*
2353   if (tree) {
2354     tf = proto_tree_add_item (tree,
2355                               hf_ntlmssp_verf,
2356                               tvb, offset, -1, FALSE);
2357
2358     ntlmssp_tree = proto_item_add_subtree (tf,
2359                                            ett_ntlmssp);
2360   }
2361   */
2362   /*
2363    * Catch the ReportedBoundsError exception; the stuff we've been
2364    * handed doesn't necessarily run to the end of the packet, it's
2365    * an item inside a packet, so if it happens to be malformed (or
2366    * we, or a dissector we call, has a bug), so that an exception
2367    * is thrown, we want to report the error, but return and let
2368    * our caller dissect the rest of the packet.
2369    *
2370    * If it gets a BoundsError, we can stop, as there's nothing more
2371    * in the packet after our blob to see, so we just re-throw the
2372    * exception.
2373    */
2374   TRY {
2375     /* Version number */
2376
2377     /* Try to decrypt */
2378     decrypt_data_payload (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
2379     /* let's try to hook ourselves here */
2380
2381   } CATCH(BoundsError) {
2382     RETHROW;
2383   } CATCH(ReportedBoundsError) {
2384     show_reported_bounds_error(tvb, pinfo, tree);
2385   } ENDTRY;
2386
2387   return offset;
2388 }
2389 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious
2390  * But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there
2391  */
2392 static int
2393 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2394 {
2395   volatile int offset = 0;
2396   proto_tree *volatile ntlmssp_tree = NULL;
2397   proto_item *tf = NULL;
2398   guint32 verifier_length;
2399   guint32 encrypted_block_length;
2400
2401   verifier_length = tvb_length (tvb);
2402   encrypted_block_length = verifier_length - 4;
2403
2404   if (encrypted_block_length < 12) {
2405     /* Don't know why this would happen, but if it does, don't even bother
2406        attempting decryption/dissection */
2407     return offset + verifier_length;
2408   }
2409
2410   /* Setup a new tree for the NTLMSSP payload */
2411   if (tree) {
2412     tf = proto_tree_add_item (tree,
2413                               hf_ntlmssp_verf,
2414                               tvb, offset, -1, FALSE);
2415
2416     ntlmssp_tree = proto_item_add_subtree (tf,
2417                                            ett_ntlmssp);
2418   }
2419
2420   /*
2421    * Catch the ReportedBoundsError exception; the stuff we've been
2422    * handed doesn't necessarily run to the end of the packet, it's
2423    * an item inside a packet, so if it happens to be malformed (or
2424    * we, or a dissector we call, has a bug), so that an exception
2425    * is thrown, we want to report the error, but return and let
2426    * our caller dissect the rest of the packet.
2427    *
2428    * If it gets a BoundsError, we can stop, as there's nothing more
2429    * in the packet after our blob to see, so we just re-throw the
2430    * exception.
2431    */
2432   TRY {
2433     /* Version number */
2434     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
2435                          tvb, offset, 4, TRUE);
2436     offset += 4;
2437
2438     /* Encrypted body */
2439     proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
2440                          tvb, offset, encrypted_block_length, TRUE);
2441
2442     /* Try to decrypt */
2443     decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
2444     /* let's try to hook ourselves here */
2445
2446     offset += 12;
2447     offset += encrypted_block_length;
2448   } CATCH(BoundsError) {
2449     RETHROW;
2450   } CATCH(ReportedBoundsError) {
2451     show_reported_bounds_error(tvb, pinfo, tree);
2452   } ENDTRY;
2453
2454   return offset;
2455 }
2456
2457 static tvbuff_t *
2458 wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb,tvbuff_t *auth_tvb _U_,
2459  int offset, packet_info *pinfo,dcerpc_auth_info *auth_info _U_)
2460 {
2461         tvbuff_t *data_tvb;
2462
2463         data_tvb = tvb_new_subset(
2464                 tvb, offset, tvb_length_remaining(tvb, offset),
2465                 tvb_length_remaining(tvb, offset));
2466         dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL);
2467   return pinfo->gssapi_decrypted_tvb;
2468 }
2469
2470 #if 0
2471 tvbuff_t *
2472 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
2473                                   tvbuff_t *auth_tvb _U_,
2474                                   int offset,
2475                                   packet_info *pinfo,
2476                                   dcerpc_auth_info *auth_info _U_)
2477 {
2478   /* gssapi_decrypted_tvb=NULL */
2479   tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2480   guint8 *peer_block;
2481   conversation_t *conversation;
2482   guint32 encrypted_block_length;
2483   rc4_state_struct *rc4_state;
2484   rc4_state_struct *rc4_state_peer;
2485   ntlmssp_info *conv_ntlmssp_info = NULL;
2486   ntlmssp_packet_info *packet_ntlmssp_info = NULL;
2487   encrypted_block_length = tvb_length_remaining (data_tvb, offset);
2488
2489   fprintf(stderr,"Called dissect_ntlmssp_encrypted_payload\n");
2490   /* Check to see if we already have state for this packet */
2491   packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2492   if (packet_ntlmssp_info == NULL) {
2493     /* We don't have any packet state, so create one */
2494     packet_ntlmssp_info = se_alloc0(sizeof(ntlmssp_packet_info));
2495     p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
2496   }
2497
2498   if (!packet_ntlmssp_info->payload_decrypted) {
2499     /* Pull the challenge info from the conversation */
2500     conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2501                                      pinfo->ptype, pinfo->srcport,
2502                                      pinfo->destport, 0);
2503     if (conversation == NULL) {
2504       /* There is no conversation, thus no encryption state */
2505       return NULL;
2506
2507     }
2508     conv_ntlmssp_info = conversation_get_proto_data(conversation,
2509                                                     proto_ntlmssp);
2510     if (conv_ntlmssp_info == NULL) {
2511     /* There is no NTLMSSP state tied to the conversation */
2512     return NULL;
2513     }
2514     /* Get the pair of RC4 state structures.  One is used for to decrypt the
2515        payload.  The other is used to re-encrypt the payload to represent
2516        the peer */
2517     if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2518       rc4_state = get_encrypted_state(pinfo, 1);
2519       rc4_state_peer = get_encrypted_state(pinfo, 0);
2520     } else {
2521       rc4_state = get_encrypted_state(pinfo, 0);
2522       rc4_state_peer = get_encrypted_state(pinfo, 1);
2523     }
2524
2525     if (rc4_state == NULL || rc4_state_peer == NULL) {
2526       /* There is no encryption state, so we cannot decrypt */
2527       return NULL;
2528     }
2529
2530     /* Store the decrypted contents in the packet state struct
2531        (of course at this point, they aren't decrypted yet) */
2532     packet_ntlmssp_info->decrypted_payload = tvb_memdup(data_tvb, offset,
2533                                                         encrypted_block_length);
2534     decrypted_payloads = g_slist_prepend(decrypted_payloads,
2535                                          packet_ntlmssp_info->decrypted_payload);
2536
2537     /* Do the decryption of the payload */
2538     crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2539               encrypted_block_length);
2540
2541     /* We setup a temporary buffer so we can re-encrypt the payload after
2542        decryption.  This is to update the opposite peer's RC4 state */
2543     peer_block = ep_memdup(packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
2544     crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2545
2546     packet_ntlmssp_info->payload_decrypted = TRUE;
2547   }
2548
2549   /* Show the decrypted buffer in a new window */
2550   decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload,
2551                                encrypted_block_length,
2552                                encrypted_block_length);
2553
2554   offset += encrypted_block_length;
2555
2556   return decr_tvb;
2557 }
2558 #endif
2559
2560 static void
2561 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
2562 {
2563         g_free(decrypted_payload);
2564 }
2565
2566 guint g_header_hash(gconstpointer pointer) {
2567   guint32 crc =  ~crc32c_calculate(pointer,NTLMSSP_KEY_LEN,CRC32C_PRELOAD);
2568   /* Mat TBD fprintf(stderr,"Val: %u\n",crc);*/
2569   return crc;
2570 }
2571
2572 gboolean g_header_equal(gconstpointer pointer1, gconstpointer pointer2) {
2573   if(!memcmp(pointer1,pointer2,16)) {
2574     return TRUE;
2575   }
2576   else {
2577     return FALSE;
2578   }
2579 }
2580
2581 static void
2582 ntlmssp_init_protocol(void)
2583 {
2584         /*
2585          * Free the decrypted payloads, and then free the list of decrypted
2586          * payloads.
2587          */
2588         if (decrypted_payloads != NULL) {
2589                 g_slist_foreach(decrypted_payloads, free_payload, NULL);
2590                 g_slist_free(decrypted_payloads);
2591                 decrypted_payloads = NULL;
2592         }
2593
2594   if(hash_packet == NULL) {
2595     hash_packet = g_hash_table_new(g_header_hash,g_header_equal);
2596   }
2597
2598 }
2599
2600
2601
2602 void
2603 proto_register_ntlmssp(void)
2604 {
2605
2606   static hf_register_info hf[] = {
2607     { &hf_ntlmssp_auth,
2608       { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2609     { &hf_ntlmssp_message_type,
2610       { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, NULL, HFILL }},
2611     { &hf_ntlmssp_negotiate_flags,
2612       { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2613     { &hf_ntlmssp_negotiate_flags_01,
2614       { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_UNICODE, NULL, HFILL }},
2615     { &hf_ntlmssp_negotiate_flags_02,
2616       { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM, NULL, HFILL }},
2617     { &hf_ntlmssp_negotiate_flags_04,
2618       { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_TARGET, NULL, HFILL }},
2619     { &hf_ntlmssp_negotiate_flags_08,
2620       { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000008, NULL, HFILL }},
2621     { &hf_ntlmssp_negotiate_flags_10,
2622       { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SIGN, NULL, HFILL }},
2623     { &hf_ntlmssp_negotiate_flags_20,
2624       { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SEAL, NULL, HFILL }},
2625     { &hf_ntlmssp_negotiate_flags_40,
2626       { "Negotiate Datagram", "ntlmssp.negotiatedatagram", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_DATAGRAM, NULL, HFILL }},
2627     { &hf_ntlmssp_negotiate_flags_80,
2628       { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_LM_KEY, NULL, HFILL }},
2629     { &hf_ntlmssp_negotiate_flags_100,
2630       { "Negotiate 0x00000100", "ntlmssp.negotiate00000100", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000100, NULL, HFILL }},
2631     { &hf_ntlmssp_negotiate_flags_200,
2632       { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NTLM, NULL, HFILL }},
2633     { &hf_ntlmssp_negotiate_flags_400,
2634       { "Negotiate NT Only", "ntlmssp.negotiatentonly", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NT_ONLY, NULL, HFILL }},
2635     { &hf_ntlmssp_negotiate_flags_800,
2636       { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000800, NULL, HFILL }},
2637     { &hf_ntlmssp_negotiate_flags_1000,
2638       { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED, NULL, HFILL }},
2639     { &hf_ntlmssp_negotiate_flags_2000,
2640       { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, NULL, HFILL }},
2641     { &hf_ntlmssp_negotiate_flags_4000,
2642       { "Negotiate 0x00004000", "ntlmssp.negotiate00004000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00004000, NULL, HFILL }},
2643     { &hf_ntlmssp_negotiate_flags_8000,
2644       { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, NULL, HFILL }},
2645     { &hf_ntlmssp_negotiate_flags_10000,
2646       { "Target Type Domain", "ntlmssp.targettypedomain", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_DOMAIN, NULL, HFILL }},
2647     { &hf_ntlmssp_negotiate_flags_20000,
2648       { "Target Type Server", "ntlmssp.targettypeserver", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SERVER, NULL, HFILL }},
2649     { &hf_ntlmssp_negotiate_flags_40000,
2650       { "Target Type Share", "ntlmssp.targettypeshare", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SHARE, NULL, HFILL }},
2651
2652 /* Negotiate Flags */
2653     { &hf_ntlmssp_negotiate_flags_80000,
2654       { "Negotiate Extended Security", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY, NULL, HFILL }},
2655     { &hf_ntlmssp_negotiate_flags_100000,
2656       { "Negotiate Identify", "ntlmssp.negotiateidentify", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_IDENTIFY, NULL, HFILL }},
2657     { &hf_ntlmssp_negotiate_flags_200000,
2658       { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00200000, NULL, HFILL }},
2659     { &hf_ntlmssp_negotiate_flags_400000,
2660       { "Request Non-NT Session", "ntlmssp.requestnonntsession", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_NON_NT_SESSION, NULL, HFILL }},
2661     { &hf_ntlmssp_negotiate_flags_800000,
2662       { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_TARGET_INFO, NULL, HFILL }},
2663     { &hf_ntlmssp_negotiate_flags_1000000,
2664       { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_01000000, NULL, HFILL }},
2665     { &hf_ntlmssp_negotiate_flags_2000000,
2666       { "Negotiate Version", "ntlmssp.negotiateversion", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_VERSION, NULL, HFILL }},
2667     { &hf_ntlmssp_negotiate_flags_4000000,
2668       { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_04000000, NULL, HFILL }},
2669     { &hf_ntlmssp_negotiate_flags_8000000,
2670       { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_08000000, NULL, HFILL }},
2671     { &hf_ntlmssp_negotiate_flags_10000000,
2672       { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_10000000, NULL, HFILL }},
2673     { &hf_ntlmssp_negotiate_flags_20000000,
2674       { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_128, "128-bit encryption is supported", HFILL }},
2675     { &hf_ntlmssp_negotiate_flags_40000000,
2676       { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_KEY_EXCH, NULL, HFILL }},
2677     { &hf_ntlmssp_negotiate_flags_80000000,
2678       { "Negotiate 56", "ntlmssp.negotiate56", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_56, "56-bit encryption is supported", HFILL }},
2679     { &hf_ntlmssp_negotiate_workstation_strlen,
2680       { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2681     { &hf_ntlmssp_negotiate_workstation_maxlen,
2682       { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2683     { &hf_ntlmssp_negotiate_workstation_buffer,
2684       { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2685     { &hf_ntlmssp_negotiate_workstation,
2686       { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2687     { &hf_ntlmssp_negotiate_domain_strlen,
2688       { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2689     { &hf_ntlmssp_negotiate_domain_maxlen,
2690       { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2691     { &hf_ntlmssp_negotiate_domain_buffer,
2692       { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2693     { &hf_ntlmssp_negotiate_domain,
2694       { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2695     { &hf_ntlmssp_ntlm_client_challenge,
2696       { "NTLM Client Challenge", "ntlmssp.ntlmclientchallenge", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2697     { &hf_ntlmssp_ntlm_server_challenge,
2698       { "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2699     { &hf_ntlmssp_reserved,
2700       { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2701
2702     { &hf_ntlmssp_challenge_target_name,
2703       { "Target Name", "ntlmssp.challenge.target_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2704     { &hf_ntlmssp_auth_domain,
2705       { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2706     { &hf_ntlmssp_auth_username,
2707       { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2708     { &hf_ntlmssp_auth_hostname,
2709       { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2710     { &hf_ntlmssp_auth_lmresponse,
2711       { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2712     { &hf_ntlmssp_auth_ntresponse,
2713       { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2714     { &hf_ntlmssp_auth_sesskey,
2715       { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2716     { &hf_ntlmssp_string_len,
2717       { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2718     { &hf_ntlmssp_string_maxlen,
2719       { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2720     { &hf_ntlmssp_string_offset,
2721       { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2722     { &hf_ntlmssp_blob_len,
2723       { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2724     { &hf_ntlmssp_blob_maxlen,
2725       { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2726     { &hf_ntlmssp_blob_offset,
2727       { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2728     { &hf_ntlmssp_version,
2729       { "Version", "ntlmssp.version", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2730     { &hf_ntlmssp_version_major,
2731       { "Major Version", "ntlmssp.version.major", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2732     { &hf_ntlmssp_version_minor,
2733       { "Minor Version", "ntlmssp.version.minor", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2734     { &hf_ntlmssp_version_build_number,
2735       { "Major Version", "ntlmssp.version.build_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2736     { &hf_ntlmssp_version_ntlm_current_revision,
2737       { "NTLM Current Revision", "ntlmssp.version.ntlm_current_revision", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2738
2739 /* Target Info */
2740     { &hf_ntlmssp_challenge_target_info,
2741       { "Target Info", "ntlmssp.challenge.target_info", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2742     { &hf_ntlmssp_challenge_target_info_len,
2743       { "Length", "ntlmssp.challenge.target_info.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2744     { &hf_ntlmssp_challenge_target_info_maxlen,
2745       { "Maxlen", "ntlmssp.challenge.target_info.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2746     { &hf_ntlmssp_challenge_target_info_offset,
2747       { "Offset", "ntlmssp.challenge.target_info.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2748
2749     { &hf_ntlmssp_challenge_target_info_item_type,
2750       { "Target Info Item Type", "ntlmssp.challenge.target_info.item.type", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
2751     { &hf_ntlmssp_challenge_target_info_item_len,
2752       { "Target Info Item Length", "ntlmssp.challenge.target_info.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2753
2754     { &hf_ntlmssp_challenge_target_info_end,
2755       { "List End", "ntlmssp.challenge.target_info.end", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2756     { &hf_ntlmssp_challenge_target_info_nb_computer_name,
2757       { "NetBIOS Computer Name", "ntlmssp.challenge.target_info.nb_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Computer Name", HFILL }},
2758     { &hf_ntlmssp_challenge_target_info_nb_domain_name,
2759       { "NetBIOS Domain Name", "ntlmssp.challenge.target_info.nb_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Domain Name", HFILL }},
2760     { &hf_ntlmssp_challenge_target_info_dns_computer_name,
2761       { "DNS Computer Name", "ntlmssp.challenge.target_info.dns_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2762     { &hf_ntlmssp_challenge_target_info_dns_domain_name,
2763       { "DNS Domain Name", "ntlmssp.challenge.target_info.dns_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2764     { &hf_ntlmssp_challenge_target_info_dns_tree_name,
2765       { "DNS Tree Name", "ntlmssp.challenge.target_info.dns_tree_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2766     { &hf_ntlmssp_challenge_target_info_flags,
2767       { "Flags", "ntlmssp.challenge.target_info.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2768     { &hf_ntlmssp_challenge_target_info_timestamp,
2769       { "Timestamp", "ntlmssp.challenge.target_info.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
2770     { &hf_ntlmssp_challenge_target_info_restrictions,
2771       { "Restrictions", "ntlmssp.challenge.target_info.restrictions", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
2772     { &hf_ntlmssp_challenge_target_info_target_name,
2773       { "Target Name", "ntlmssp.challenge.target_info.target_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2774     { &hf_ntlmssp_challenge_target_info_channel_bindings,
2775       { "Channel Bindings", "ntlmssp.challenge.target_info.channel_bindings", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2776
2777     { &hf_ntlmssp_ntlmv2_response_item_type,
2778       { "NTLMV2 Response Item Type", "ntlmssp.ntlmv2_response.item.type", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
2779     { &hf_ntlmssp_ntlmv2_response_item_len,
2780       { "NTLMV2 Response Item Length", "ntlmssp.ntlmv2_response.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2781
2782     { &hf_ntlmssp_ntlmv2_response_end,
2783       { "List End", "ntlmssp.ntlmv2_response.end", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2784     { &hf_ntlmssp_ntlmv2_response_nb_computer_name,
2785       { "NetBIOS Computer Name", "ntlmssp.ntlmv2_response.nb_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Computer Name", HFILL }},
2786     { &hf_ntlmssp_ntlmv2_response_nb_domain_name,
2787       { "NetBIOS Domain Name", "ntlmssp.ntlmv2_response.nb_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, "Server NetBIOS Domain Name", HFILL }},
2788     { &hf_ntlmssp_ntlmv2_response_dns_computer_name,
2789       { "DNS Computer Name", "ntlmssp.ntlmv2_response.dns_computer_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2790     { &hf_ntlmssp_ntlmv2_response_dns_domain_name,
2791       { "DNS Domain Name", "ntlmssp.ntlmv2_response.dns_domain_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2792     { &hf_ntlmssp_ntlmv2_response_dns_tree_name,
2793       { "DNS Tree Name", "ntlmssp.ntlmv2_response.dns_tree_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2794     { &hf_ntlmssp_ntlmv2_response_flags,
2795       { "Flags", "ntlmssp.ntlmv2_response.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2796     { &hf_ntlmssp_ntlmv2_response_timestamp,
2797       { "Timestamp", "ntlmssp.ntlmv2_response.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
2798     { &hf_ntlmssp_ntlmv2_response_restrictions,
2799       { "Restrictions", "ntlmssp.ntlmv2_response.restrictions", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
2800     { &hf_ntlmssp_ntlmv2_response_target_name,
2801       { "Target Name", "ntlmssp.ntlmv2_response.target_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2802     { &hf_ntlmssp_ntlmv2_response_channel_bindings,
2803       { "Channel Bindings", "ntlmssp.ntlmv2_response.channel_bindings", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2804
2805     { &hf_ntlmssp_message_integrity_code,
2806       { "MIC", "ntlmssp.authenticate.mic", FT_BYTES, BASE_NONE, NULL, 0x0, "Message Integrity Code", HFILL}},
2807     { &hf_ntlmssp_verf,
2808       { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2809     { &hf_ntlmssp_verf_vers,
2810       { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2811     { &hf_ntlmssp_verf_body,
2812       { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2813     { &hf_ntlmssp_decrypted_payload,
2814       { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2815     { &hf_ntlmssp_verf_randompad,
2816       { "Random Pad", "ntlmssp.verf.randompad", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2817     { &hf_ntlmssp_verf_crc32,
2818       { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2819     { &hf_ntlmssp_verf_hmacmd5,
2820       { "HMAC MD5", "ntlmssp.verf.hmacmd5", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2821     { &hf_ntlmssp_verf_sequence,
2822       { "Sequence", "ntlmssp.verf.sequence", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2823
2824     { &hf_ntlmssp_ntlmv2_response,
2825       { "NTLMv2 Response", "ntlmssp.ntlmv2_response", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2826     { &hf_ntlmssp_ntlmv2_response_hmac,
2827       { "HMAC", "ntlmssp.ntlmv2_response.hmac", FT_BYTES, BASE_NONE,  NULL, 0x0, NULL, HFILL }},
2828     { &hf_ntlmssp_ntlmv2_response_header,
2829       { "Header", "ntlmssp.ntlmv2_response.header", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2830     { &hf_ntlmssp_ntlmv2_response_reserved,
2831       { "Reserved", "ntlmssp.ntlmv2_response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2832     { &hf_ntlmssp_ntlmv2_response_time,
2833       { "Time", "ntlmssp.ntlmv2_response.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
2834     { &hf_ntlmssp_ntlmv2_response_chal,
2835       { "Client challenge", "ntlmssp.ntlmv2_response.chal", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2836     { &hf_ntlmssp_ntlmv2_response_unknown,
2837       { "Unknown", "ntlmssp.ntlmv2_response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}
2838   };
2839
2840
2841   static gint *ett[] = {
2842     &ett_ntlmssp,
2843     &ett_ntlmssp_negotiate_flags,
2844     &ett_ntlmssp_string,
2845     &ett_ntlmssp_blob,
2846     &ett_ntlmssp_version,
2847     &ett_ntlmssp_challenge_target_info,
2848     &ett_ntlmssp_challenge_target_info_item,
2849     &ett_ntlmssp_ntlmv2_response,
2850     &ett_ntlmssp_ntlmv2_response_item,
2851   };
2852   module_t *ntlmssp_module;
2853
2854   proto_ntlmssp = proto_register_protocol (
2855                                            "NTLM Secure Service Provider", /* name */
2856                                            "NTLMSSP",   /* short name */
2857                                            "ntlmssp"    /* abbrev */
2858                                            );
2859   proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
2860   proto_register_subtree_array (ett, array_length (ett));
2861   register_init_routine(&ntlmssp_init_protocol);
2862
2863   ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
2864
2865   prefs_register_string_preference(ntlmssp_module, "nt_password",
2866                                    "NT Password",
2867                                    "NT Password (used to decrypt payloads)",
2868                                    &gbl_nt_password);
2869
2870   register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
2871   new_register_dissector("ntlmssp_payload", dissect_ntlmssp_payload, proto_ntlmssp);
2872   new_register_dissector("ntlmssp_data_only", dissect_ntlmssp_payload_only, proto_ntlmssp);
2873   new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
2874 }
2875
2876 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
2877                                 proto_tree *tree, guint8 *drep _U_)
2878 {
2879         tvbuff_t *auth_tvb;
2880
2881         auth_tvb = tvb_new_subset(
2882                 tvb, offset, tvb_length_remaining(tvb, offset),
2883                 tvb_length_remaining(tvb, offset));
2884
2885         dissect_ntlmssp(auth_tvb, pinfo, tree);
2886
2887         return tvb_length_remaining(tvb, offset);
2888 }
2889
2890 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
2891                                      proto_tree *tree, guint8 *drep _U_)
2892 {
2893         tvbuff_t *auth_tvb;
2894
2895         auth_tvb = tvb_new_subset(
2896                 tvb, offset, tvb_length_remaining(tvb, offset),
2897                 tvb_length_remaining(tvb, offset));
2898         return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
2899 }
2900
2901 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
2902         wrap_dissect_ntlmssp,                   /* Bind */
2903         wrap_dissect_ntlmssp,                   /* Bind ACK */
2904         wrap_dissect_ntlmssp,                   /* AUTH3 */
2905         wrap_dissect_ntlmssp_verf,              /* Request verifier */
2906         wrap_dissect_ntlmssp_verf,              /* Response verifier */
2907         NULL,                                   /* Request data */
2908         NULL                                    /* Response data */
2909 };
2910
2911 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
2912         wrap_dissect_ntlmssp,                   /* Bind */
2913         wrap_dissect_ntlmssp,                   /* Bind ACK */
2914         wrap_dissect_ntlmssp,                   /* AUTH3 */
2915         wrap_dissect_ntlmssp_verf,              /* Request verifier */
2916         wrap_dissect_ntlmssp_verf,              /* Response verifier */
2917         wrap_dissect_ntlmssp_payload_only,      /* Request data */
2918         wrap_dissect_ntlmssp_payload_only       /* Response data */
2919 };
2920
2921 void
2922 proto_reg_handoff_ntlmssp(void)
2923 {
2924   dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
2925
2926   /* Register protocol with the GSS-API module */
2927
2928   ntlmssp_handle = find_dissector("ntlmssp");
2929   ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
2930   gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
2931                   ntlmssp_handle, ntlmssp_wrap_handle,
2932                   "NTLMSSP - Microsoft NTLM Security Support Provider");
2933
2934   /* Register authenticated pipe dissector */
2935
2936   /*
2937    * XXX - the verifiers here seem to have a version of 1 and a body of all
2938    * zeroes.
2939    *
2940    * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
2941    * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT.  Should we register
2942    * any other levels here?
2943    */
2944   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2945                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2946                                     &ntlmssp_sign_fns);
2947
2948   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT,
2949                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2950                                     &ntlmssp_sign_fns);
2951
2952   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2953                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2954                                     &ntlmssp_sign_fns);
2955
2956   register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2957                                     DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2958                                     &ntlmssp_seal_fns);
2959   ntlmssp_tap = register_tap("ntlmssp");
2960 }
2961
2962 /*
2963  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2964  *
2965  * Local variables:
2966  * c-basic-offset: 2
2967  * tab-width: 8
2968  * indent-tabs-mode: nil
2969  * End:
2970  *
2971  * vi: set shiftwidth=2 tabstop=8 expandtab
2972  * :indentSize=2:tabSize=8:noTabs=true:
2973  */