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