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