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