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