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