~paulliu/ubuntu/quantal/freerdp/fixext

« back to all changes in this revision

Viewing changes to libfreerdp-core/ntlmssp.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt, Jeremy Bicha, Jean-Louis Dupond, Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120131100214-jaok3uwvni7sqxth
Tags: 1.0.0-0git1
Upload current Debian packaging git to get this rolling for precise.

[ Jeremy Bicha ]
* New upstream release. Closes: #647498.
* Updated symbols and bumped soname
* debian/control:
  - Added new build dependencies
  - Bump Standards-Version to 3.9.2
* debian/source/format: Set to 3.0 (quilt)
* debian/rules: Turn on strict symbols checking
* debian/watch: Watch github

[ Jean-Louis Dupond ]
* debian/control: Updated homepage
* debian/copyright: Reflect upstream switch to the Apache license

[ Martin Pitt ]
* debian/libfreerdp0.symbols: Fix version number, should
  be 1.0~beta5, not 1.0-beta5.
* debian/control: Add libavcodec-dev build dependency, upstream build system
  checks for that. Thanks Jean-Louis Dupond!

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Client
 
3
 * NT LAN Manager Security Support Provider (NTLMSSP)
 
4
 *
 
5
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 *
 
7
 * Licensed under the Apache License, Version 2.0 (the "License");
 
8
 * you may not use this file except in compliance with the License.
 
9
 * You may obtain a copy of the License at
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
13
 * Unless required by applicable law or agreed to in writing, software
 
14
 * distributed under the License is distributed on an "AS IS" BASIS,
 
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
16
 * See the License for the specific language governing permissions and
 
17
 * limitations under the License.
 
18
 */
 
19
 
 
20
#include <time.h>
 
21
#include <openssl/des.h>
 
22
#include <openssl/md4.h>
 
23
#include <openssl/hmac.h>
 
24
#include <openssl/rand.h>
 
25
#include <openssl/engine.h>
 
26
#include <freerdp/utils/memory.h>
 
27
 
 
28
#include "ntlmssp.h"
 
29
 
 
30
#define NTLMSSP_NEGOTIATE_56                                    0x80000000 /* W   (0) */
 
31
#define NTLMSSP_NEGOTIATE_KEY_EXCH                              0x40000000 /* V   (1) */
 
32
#define NTLMSSP_NEGOTIATE_128                                   0x20000000 /* U   (2) */
 
33
#define NTLMSSP_RESERVED1                                       0x10000000 /* r1  (3) */
 
34
#define NTLMSSP_RESERVED2                                       0x08000000 /* r2  (4) */
 
35
#define NTLMSSP_RESERVED3                                       0x04000000 /* r3  (5) */
 
36
#define NTLMSSP_NEGOTIATE_VERSION                               0x02000000 /* T   (6) */
 
37
#define NTLMSSP_RESERVED4                                       0x01000000 /* r4  (7) */
 
38
#define NTLMSSP_NEGOTIATE_TARGET_INFO                           0x00800000 /* S   (8) */
 
39
#define NTLMSSP_RESERVEDEQUEST_NON_NT_SESSION_KEY               0x00400000 /* R   (9) */
 
40
#define NTLMSSP_RESERVED5                                       0x00200000 /* r5  (10) */
 
41
#define NTLMSSP_NEGOTIATE_IDENTIFY                              0x00100000 /* Q   (11) */
 
42
#define NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY             0x00080000 /* P   (12) */
 
43
#define NTLMSSP_RESERVED6                                       0x00040000 /* r6  (13) */
 
44
#define NTLMSSP_TARGET_TYPE_SERVER                              0x00020000 /* O   (14) */
 
45
#define NTLMSSP_TARGET_TYPE_DOMAIN                              0x00010000 /* N   (15) */
 
46
#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN                           0x00008000 /* M   (16) */
 
47
#define NTLMSSP_RESERVED7                                       0x00004000 /* r7  (17) */
 
48
#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED                  0x00002000 /* L   (18) */
 
49
#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED                       0x00001000 /* K   (19) */
 
50
#define NTLMSSP_NEGOTIATE_ANONYMOUS                             0x00000800 /* J   (20) */
 
51
#define NTLMSSP_RESERVED8                                       0x00000400 /* r8  (21) */
 
52
#define NTLMSSP_NEGOTIATE_NTLM                                  0x00000200 /* H   (22) */
 
53
#define NTLMSSP_RESERVED9                                       0x00000100 /* r9  (23) */
 
54
#define NTLMSSP_NEGOTIATE_LM_KEY                                0x00000080 /* G   (24) */
 
55
#define NTLMSSP_NEGOTIATE_DATAGRAM                              0x00000040 /* F   (25) */
 
56
#define NTLMSSP_NEGOTIATE_SEAL                                  0x00000020 /* E   (26) */
 
57
#define NTLMSSP_NEGOTIATE_SIGN                                  0x00000010 /* D   (27) */
 
58
#define NTLMSSP_RESERVED10                                      0x00000008 /* r10 (28) */
 
59
#define NTLMSSP_REQUEST_TARGET                                  0x00000004 /* C   (29) */
 
60
#define NTLMSSP_NEGOTIATE_OEM                                   0x00000002 /* B   (30) */
 
61
#define NTLMSSP_NEGOTIATE_UNICODE                               0x00000001 /* A   (31) */
 
62
 
 
63
#define WINDOWS_MAJOR_VERSION_5         0x05
 
64
#define WINDOWS_MAJOR_VERSION_6         0x06
 
65
#define WINDOWS_MINOR_VERSION_0         0x00
 
66
#define WINDOWS_MINOR_VERSION_1         0x01
 
67
#define WINDOWS_MINOR_VERSION_2         0x02
 
68
#define NTLMSSP_REVISION_W2K3           0x0F
 
69
 
 
70
static const char ntlm_signature[] = "NTLMSSP";
 
71
static const char lm_magic[] = "KGS!@#$%";
 
72
 
 
73
static const char client_sign_magic[] = "session key to client-to-server signing key magic constant";
 
74
static const char server_sign_magic[] = "session key to server-to-client signing key magic constant";
 
75
static const char client_seal_magic[] = "session key to client-to-server sealing key magic constant";
 
76
static const char server_seal_magic[] = "session key to server-to-client sealing key magic constant";
 
77
 
 
78
static const char* const NTLMSSP_NEGOTIATE_STRINGS[] =
 
79
{
 
80
        "NTLMSSP_NEGOTIATE_56",
 
81
        "NTLMSSP_NEGOTIATE_KEY_EXCH",
 
82
        "NTLMSSP_NEGOTIATE_128",
 
83
        "NTLMSSP_RESERVED1",
 
84
        "NTLMSSP_RESERVED2",
 
85
        "NTLMSSP_RESERVED3",
 
86
        "NTLMSSP_NEGOTIATE_VERSION",
 
87
        "NTLMSSP_RESERVED4",
 
88
        "NTLMSSP_NEGOTIATE_TARGET_INFO",
 
89
        "NTLMSSP_REQUEST_NON_NT_SESSION_KEY",
 
90
        "NTLMSSP_RESERVED5",
 
91
        "NTLMSSP_NEGOTIATE_IDENTIFY",
 
92
        "NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY",
 
93
        "NTLMSSP_RESERVED6",
 
94
        "NTLMSSP_TARGET_TYPE_SERVER",
 
95
        "NTLMSSP_TARGET_TYPE_DOMAIN",
 
96
        "NTLMSSP_NEGOTIATE_ALWAYS_SIGN",
 
97
        "NTLMSSP_RESERVED7",
 
98
        "NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED",
 
99
        "NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED",
 
100
        "NTLMSSP_NEGOTIATE_ANONYMOUS",
 
101
        "NTLMSSP_RESERVED8",
 
102
        "NTLMSSP_NEGOTIATE_NTLM",
 
103
        "NTLMSSP_RESERVED9",
 
104
        "NTLMSSP_NEGOTIATE_LM_KEY",
 
105
        "NTLMSSP_NEGOTIATE_DATAGRAM",
 
106
        "NTLMSSP_NEGOTIATE_SEAL",
 
107
        "NTLMSSP_NEGOTIATE_SIGN",
 
108
        "NTLMSSP_RESERVED10",
 
109
        "NTLMSSP_REQUEST_TARGET",
 
110
        "NTLMSSP_NEGOTIATE_OEM",
 
111
        "NTLMSSP_NEGOTIATE_UNICODE"
 
112
};
 
113
 
 
114
static const char* const AV_PAIRS_STRINGS[] =
 
115
{
 
116
        "MsvAvEOL",
 
117
        "MsvAvNbComputerName",
 
118
        "MsvAvNbDomainName",
 
119
        "MsvAvDnsComputerName",
 
120
        "MsvAvDnsDomainName",
 
121
        "MsvAvDnsTreeName",
 
122
        "MsvAvFlags",
 
123
        "MsvAvTimestamp",
 
124
        "MsvAvRestrictions",
 
125
        "MsvAvTargetName",
 
126
        "MsvChannelBindings"
 
127
};
 
128
 
 
129
/**
 
130
 * Set NTLMSSP username.
 
131
 * @param ntlmssp
 
132
 * @param username username
 
133
 */
 
134
 
 
135
void ntlmssp_set_username(NTLMSSP* ntlmssp, char* username)
 
136
{
 
137
        freerdp_blob_free(&ntlmssp->username);
 
138
 
 
139
        if (username != NULL)
 
140
        {
 
141
                ntlmssp->username.data = freerdp_uniconv_out(ntlmssp->uniconv, username, (size_t*) &(ntlmssp->username.length));
 
142
        }
 
143
}
 
144
 
 
145
/**
 
146
 * Set NTLMSSP domain name.
 
147
 * @param ntlmssp
 
148
 * @param domain domain name
 
149
 */
 
150
 
 
151
void ntlmssp_set_domain(NTLMSSP* ntlmssp, char* domain)
 
152
{
 
153
        freerdp_blob_free(&ntlmssp->domain);
 
154
 
 
155
        if (domain != NULL)
 
156
        {
 
157
                ntlmssp->domain.data = freerdp_uniconv_out(ntlmssp->uniconv, domain, (size_t*) &(ntlmssp->domain.length));
 
158
        }
 
159
}
 
160
 
 
161
/**
 
162
 * Set NTLMSSP password.
 
163
 * @param ntlmssp
 
164
 * @param password password
 
165
 */
 
166
 
 
167
void ntlmssp_set_password(NTLMSSP* ntlmssp, char* password)
 
168
{
 
169
        freerdp_blob_free(&ntlmssp->password);
 
170
 
 
171
        if (password != NULL)
 
172
        {
 
173
                ntlmssp->password.data = freerdp_uniconv_out(ntlmssp->uniconv, password, (size_t*) &(ntlmssp->password.length));
 
174
        }
 
175
}
 
176
 
 
177
/**
 
178
 * Set NTLMSSP workstation.
 
179
 * @param ntlmssp
 
180
 * @param workstation workstation
 
181
 */
 
182
 
 
183
void ntlmssp_set_workstation(NTLMSSP* ntlmssp, char* workstation)
 
184
{
 
185
        freerdp_blob_free(&ntlmssp->workstation);
 
186
 
 
187
        if (workstation != NULL)
 
188
        {
 
189
                ntlmssp->workstation.data = freerdp_uniconv_out(ntlmssp->uniconv, workstation, (size_t*) &(ntlmssp->workstation.length));
 
190
        }
 
191
}
 
192
 
 
193
/**
 
194
 * Generate client challenge (8-byte nonce).
 
195
 * @param ntlmssp
 
196
 */
 
197
 
 
198
void ntlmssp_generate_client_challenge(NTLMSSP* ntlmssp)
 
199
{
 
200
        /* ClientChallenge in computation of LMv2 and NTLMv2 responses */
 
201
        crypto_nonce(ntlmssp->client_challenge, 8);
 
202
}
 
203
 
 
204
/**
 
205
 * Generate KeyExchangeKey (the 128-bit SessionBaseKey).\n
 
206
 * @msdn{cc236710}
 
207
 * @param ntlmssp
 
208
 */
 
209
 
 
210
void ntlmssp_generate_key_exchange_key(NTLMSSP* ntlmssp)
 
211
{
 
212
        /* In NTLMv2, KeyExchangeKey is the 128-bit SessionBaseKey */
 
213
        memcpy(ntlmssp->key_exchange_key, ntlmssp->session_base_key, 16);
 
214
}
 
215
 
 
216
/**
 
217
 * Generate RandomSessionKey (16-byte nonce).
 
218
 * @param ntlmssp
 
219
 */
 
220
 
 
221
void ntlmssp_generate_random_session_key(NTLMSSP* ntlmssp)
 
222
{
 
223
        crypto_nonce(ntlmssp->random_session_key, 16);
 
224
}
 
225
 
 
226
/**
 
227
 * Generate ExportedSessionKey (the RandomSessionKey, exported)
 
228
 * @param ntlmssp
 
229
 */
 
230
 
 
231
void ntlmssp_generate_exported_session_key(NTLMSSP* ntlmssp)
 
232
{
 
233
        memcpy(ntlmssp->exported_session_key, ntlmssp->random_session_key, 16);
 
234
}
 
235
 
 
236
/**
 
237
 * Encrypt RandomSessionKey (RC4-encrypted RandomSessionKey, using KeyExchangeKey as the key).
 
238
 * @param ntlmssp
 
239
 */
 
240
 
 
241
void ntlmssp_encrypt_random_session_key(NTLMSSP* ntlmssp)
 
242
{
 
243
        /* In NTLMv2, EncryptedRandomSessionKey is the ExportedSessionKey RC4-encrypted with the KeyExchangeKey */
 
244
        credssp_rc4k(ntlmssp->key_exchange_key, 16, ntlmssp->random_session_key, ntlmssp->encrypted_random_session_key);
 
245
}
 
246
 
 
247
/**
 
248
 * Generate timestamp for AUTHENTICATE_MESSAGE.
 
249
 * @param ntlmssp
 
250
 */
 
251
 
 
252
void ntlmssp_generate_timestamp(NTLMSSP* ntlmssp)
 
253
{
 
254
        credssp_current_time(ntlmssp->timestamp);
 
255
 
 
256
        if (ntlmssp->ntlm_v2)
 
257
        {
 
258
                if (ntlmssp->av_pairs->Timestamp.length == 8)
 
259
                {
 
260
                        memcpy(ntlmssp->av_pairs->Timestamp.value, ntlmssp->timestamp, 8);
 
261
                        return;
 
262
                }
 
263
        }
 
264
        else
 
265
        {
 
266
                if (ntlmssp->av_pairs->Timestamp.length != 8)
 
267
                {
 
268
                        ntlmssp->av_pairs->Timestamp.length = 8;
 
269
                        ntlmssp->av_pairs->Timestamp.value = xmalloc(ntlmssp->av_pairs->Timestamp.length);
 
270
                }
 
271
                memcpy(ntlmssp->av_pairs->Timestamp.value, ntlmssp->timestamp, 8);
 
272
        }
 
273
}
 
274
 
 
275
/**
 
276
 * Generate signing key.\n
 
277
 * @msdn{cc236711}
 
278
 * @param exported_session_key ExportedSessionKey
 
279
 * @param sign_magic Sign magic string
 
280
 * @param signing_key Destination signing key
 
281
 */
 
282
 
 
283
void ntlmssp_generate_signing_key(uint8* exported_session_key, rdpBlob* sign_magic, uint8* signing_key)
 
284
{
 
285
        int length;
 
286
        uint8* value;
 
287
        CryptoMd5 md5;
 
288
 
 
289
        length = 16 + sign_magic->length;
 
290
        value = (uint8*) xmalloc(length);
 
291
 
 
292
        /* Concatenate ExportedSessionKey with sign magic */
 
293
        memcpy(value, exported_session_key, 16);
 
294
        memcpy(&value[16], sign_magic->data, sign_magic->length);
 
295
 
 
296
        md5 = crypto_md5_init();
 
297
        crypto_md5_update(md5, value, length);
 
298
        crypto_md5_final(md5, signing_key);
 
299
 
 
300
        xfree(value);
 
301
}
 
302
 
 
303
/**
 
304
 * Generate client signing key (ClientSigningKey).\n
 
305
 * @msdn{cc236711}
 
306
 * @param ntlmssp
 
307
 */
 
308
 
 
309
void ntlmssp_generate_client_signing_key(NTLMSSP* ntlmssp)
 
310
{
 
311
        rdpBlob sign_magic;
 
312
        sign_magic.data = (void*) client_sign_magic;
 
313
        sign_magic.length = sizeof(client_sign_magic);
 
314
        ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &sign_magic, ntlmssp->client_signing_key);
 
315
}
 
316
 
 
317
/**
 
318
 * Generate server signing key (ServerSigningKey).\n
 
319
 * @msdn{cc236711}
 
320
 * @param ntlmssp
 
321
 */
 
322
 
 
323
void ntlmssp_generate_server_signing_key(NTLMSSP* ntlmssp)
 
324
{
 
325
        rdpBlob sign_magic;
 
326
        sign_magic.data = (void*) server_sign_magic;
 
327
        sign_magic.length = sizeof(server_sign_magic);
 
328
        ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &sign_magic, ntlmssp->server_signing_key);
 
329
}
 
330
 
 
331
/**
 
332
 * Generate sealing key.\n
 
333
 * @msdn{cc236712}
 
334
 * @param exported_session_key ExportedSessionKey
 
335
 * @param seal_magic Seal magic string
 
336
 * @param sealing_key Destination sealing key
 
337
 */
 
338
 
 
339
void ntlmssp_generate_sealing_key(uint8* exported_session_key, rdpBlob* seal_magic, uint8* sealing_key)
 
340
{
 
341
        uint8* p;
 
342
        CryptoMd5 md5;
 
343
        rdpBlob blob;
 
344
 
 
345
        freerdp_blob_alloc(&blob, 16 + seal_magic->length);
 
346
        p = (uint8*) blob.data;
 
347
 
 
348
        /* Concatenate ExportedSessionKey with seal magic */
 
349
        memcpy(p, exported_session_key, 16);
 
350
        memcpy(&p[16], seal_magic->data, seal_magic->length);
 
351
 
 
352
        md5 = crypto_md5_init();
 
353
        crypto_md5_update(md5, blob.data, blob.length);
 
354
        crypto_md5_final(md5, sealing_key);
 
355
 
 
356
        freerdp_blob_free(&blob);
 
357
}
 
358
 
 
359
/**
 
360
 * Generate client sealing key (ClientSealingKey).\n
 
361
 * @msdn{cc236712}
 
362
 * @param ntlmssp
 
363
 */
 
364
 
 
365
void ntlmssp_generate_client_sealing_key(NTLMSSP* ntlmssp)
 
366
{
 
367
        rdpBlob seal_magic;
 
368
        seal_magic.data = (void*) client_seal_magic;
 
369
        seal_magic.length = sizeof(client_seal_magic);
 
370
        ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &seal_magic, ntlmssp->client_sealing_key);
 
371
}
 
372
 
 
373
/**
 
374
 * Generate server sealing key (ServerSealingKey).\n
 
375
 * @msdn{cc236712}
 
376
 * @param ntlmssp
 
377
 */
 
378
 
 
379
void ntlmssp_generate_server_sealing_key(NTLMSSP* ntlmssp)
 
380
{
 
381
        rdpBlob seal_magic;
 
382
        seal_magic.data = (void*) server_seal_magic;
 
383
        seal_magic.length = sizeof(server_seal_magic);
 
384
        ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &seal_magic, ntlmssp->server_sealing_key);
 
385
}
 
386
 
 
387
/**
 
388
 * Initialize RC4 stream cipher states for sealing.
 
389
 * @param ntlmssp
 
390
 */
 
391
 
 
392
void ntlmssp_init_rc4_seal_states(NTLMSSP* ntlmssp)
 
393
{
 
394
        ntlmssp->send_rc4_seal = crypto_rc4_init(ntlmssp->client_sealing_key, 16);
 
395
        ntlmssp->recv_rc4_seal = crypto_rc4_init(ntlmssp->server_sealing_key, 16);
 
396
}
 
397
 
 
398
/**
 
399
 * Get bit from a byte buffer using a bit offset.
 
400
 * @param buffer byte buffer
 
401
 * @param bit bit offset
 
402
 * @return bit value
 
403
 */
 
404
 
 
405
static int get_bit(char* buffer, int bit)
 
406
{
 
407
        return (buffer[(bit - (bit % 8)) / 8] >> (7 - bit % 8) & 1);
 
408
}
 
409
 
 
410
/**
 
411
 * Set bit in a byte buffer using a bit offset.
 
412
 * @param buffer byte buffer
 
413
 * @param bit bit offset
 
414
 * @param value bit value
 
415
 */
 
416
 
 
417
static void set_bit(char* buffer, int bit, int value)
 
418
{
 
419
        buffer[(bit - (bit % 8)) / 8] |= value << (7 - bit % 8);
 
420
}
 
421
 
 
422
static void ntlmssp_compute_des_key(char* text, char* des_key)
 
423
{
 
424
        int i, j;
 
425
        int bit;
 
426
        int nbits;
 
427
 
 
428
        /* Convert the 7 bytes into a bit stream, and insert a parity-bit (odd parity) after every seven bits. */
 
429
 
 
430
        memset(des_key, '\0', 8);
 
431
 
 
432
        for (i = 0; i < 8; i++)
 
433
        {
 
434
                nbits = 0;
 
435
 
 
436
                for (j = 0; j < 7; j++)
 
437
                {
 
438
                        /* copy 7 bits, and count the number of bits that are set */
 
439
 
 
440
                        bit = get_bit(text, i*7 + j);
 
441
                        set_bit(des_key, i*7 + i + j, bit);
 
442
                        nbits += bit;
 
443
                }
 
444
 
 
445
                /* insert parity bit (odd parity) */
 
446
 
 
447
                if (nbits % 2 == 0)
 
448
                        set_bit(des_key, i*7 + i + j, 1);
 
449
        }
 
450
}
 
451
 
 
452
void ntlmssp_compute_lm_hash(char* password, char* hash)
 
453
{
 
454
        int i;
 
455
        int maxlen;
 
456
        char text[14];
 
457
        char des_key1[8];
 
458
        char des_key2[8];
 
459
        des_key_schedule ks;
 
460
 
 
461
        /* LM("password") = E52CAC67419A9A224A3B108F3FA6CB6D */
 
462
 
 
463
        maxlen = (strlen(password) < 14) ? strlen(password) : 14;
 
464
 
 
465
        /* convert to uppercase */
 
466
        for (i = 0; i < maxlen; i++)
 
467
        {
 
468
                if ((password[i] >= 'a') && (password[i] <= 'z'))
 
469
                        text[i] = password[i] - 32;
 
470
                else
 
471
                        text[i] = password[i];
 
472
        }
 
473
 
 
474
        /* pad with nulls up to 14 bytes */
 
475
        for (i = maxlen; i < 14; i++)
 
476
                text[i] = '\0';
 
477
 
 
478
        ntlmssp_compute_des_key(text, des_key1);
 
479
        ntlmssp_compute_des_key(&text[7], des_key2);
 
480
 
 
481
        DES_set_key((const_DES_cblock*)des_key1, &ks);
 
482
        DES_ecb_encrypt((const_DES_cblock*) lm_magic, (DES_cblock*)hash, &ks, DES_ENCRYPT);
 
483
 
 
484
        DES_set_key((const_DES_cblock*)des_key2, &ks);
 
485
        DES_ecb_encrypt((const_DES_cblock*) lm_magic, (DES_cblock*)&hash[8], &ks, DES_ENCRYPT);
 
486
}
 
487
 
 
488
void ntlmssp_compute_ntlm_hash(rdpBlob* password, char* hash)
 
489
{
 
490
        /* NTLMv1("password") = 8846F7EAEE8FB117AD06BDD830B7586C */
 
491
 
 
492
        MD4_CTX md4_ctx;
 
493
 
 
494
        /* Password needs to be in unicode */
 
495
 
 
496
        /* Apply the MD4 digest algorithm on the password in unicode, the result is the NTLM hash */
 
497
 
 
498
        MD4_Init(&md4_ctx);
 
499
        MD4_Update(&md4_ctx, password->data, password->length);
 
500
        MD4_Final((void*) hash, &md4_ctx);
 
501
}
 
502
 
 
503
void ntlmssp_compute_ntlm_v2_hash(NTLMSSP* ntlmssp, char* hash)
 
504
{
 
505
        char* p;
 
506
        rdpBlob blob;
 
507
        char ntlm_hash[16];
 
508
 
 
509
        freerdp_blob_alloc(&blob, ntlmssp->username.length + ntlmssp->domain.length);
 
510
        p = (char*) blob.data;
 
511
 
 
512
        /* First, compute the NTLMv1 hash of the password */
 
513
        ntlmssp_compute_ntlm_hash(&ntlmssp->password, ntlm_hash);
 
514
 
 
515
        /* Concatenate(Uppercase(username),domain)*/
 
516
        memcpy(p, ntlmssp->username.data, ntlmssp->username.length);
 
517
        freerdp_uniconv_uppercase(ntlmssp->uniconv, p, ntlmssp->username.length / 2);
 
518
 
 
519
        memcpy(&p[ntlmssp->username.length], ntlmssp->domain.data, ntlmssp->domain.length);
 
520
 
 
521
        /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */
 
522
        HMAC(EVP_md5(), (void*) ntlm_hash, 16, blob.data, blob.length, (void*) hash, NULL);
 
523
 
 
524
        freerdp_blob_free(&blob);
 
525
}
 
526
 
 
527
void ntlmssp_compute_lm_response(char* password, char* challenge, char* response)
 
528
{
 
529
        char hash[21];
 
530
        char des_key1[8];
 
531
        char des_key2[8];
 
532
        char des_key3[8];
 
533
        des_key_schedule ks;
 
534
 
 
535
        /* A LM hash is 16-bytes long, but the LM response uses a LM hash null-padded to 21 bytes */
 
536
        memset(hash, '\0', 21);
 
537
        ntlmssp_compute_lm_hash(password, hash);
 
538
 
 
539
        /* Each 7-byte third of the 21-byte null-padded LM hash is used to create a DES key */
 
540
        ntlmssp_compute_des_key(hash, des_key1);
 
541
        ntlmssp_compute_des_key(&hash[7], des_key2);
 
542
        ntlmssp_compute_des_key(&hash[14], des_key3);
 
543
 
 
544
        /* Encrypt the LM challenge with each key, and concatenate the result. This is the LM response (24 bytes) */
 
545
        DES_set_key((const_DES_cblock*)des_key1, &ks);
 
546
        DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)response, &ks, DES_ENCRYPT);
 
547
 
 
548
        DES_set_key((const_DES_cblock*)des_key2, &ks);
 
549
        DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)&response[8], &ks, DES_ENCRYPT);
 
550
 
 
551
        DES_set_key((const_DES_cblock*)des_key3, &ks);
 
552
        DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)&response[16], &ks, DES_ENCRYPT);
 
553
}
 
554
 
 
555
void ntlmssp_compute_lm_v2_response(NTLMSSP* ntlmssp)
 
556
{
 
557
        char *response;
 
558
        char value[16];
 
559
        char ntlm_v2_hash[16];
 
560
 
 
561
        /* Compute the NTLMv2 hash */
 
562
        ntlmssp_compute_ntlm_v2_hash(ntlmssp, ntlm_v2_hash);
 
563
 
 
564
        /* Concatenate the server and client challenges */
 
565
        memcpy(value, ntlmssp->server_challenge, 8);
 
566
        memcpy(&value[8], ntlmssp->client_challenge, 8);
 
567
 
 
568
        freerdp_blob_alloc(&ntlmssp->lm_challenge_response, 24);
 
569
        response = (char*) ntlmssp->lm_challenge_response.data;
 
570
 
 
571
        /* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */
 
572
        HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16, (void*) value, 16, (void*) response, NULL);
 
573
 
 
574
        /* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */
 
575
        memcpy(&response[16], ntlmssp->client_challenge, 8);
 
576
}
 
577
 
 
578
/**
 
579
 * Compute NTLMv2 Response.\n
 
580
 * NTLMv2_RESPONSE @msdn{cc236653}\n
 
581
 * NTLMv2 Authentication @msdn{cc236700}
 
582
 * @param ntlmssp
 
583
 */
 
584
 
 
585
void ntlmssp_compute_ntlm_v2_response(NTLMSSP* ntlmssp)
 
586
{
 
587
        uint8* blob;
 
588
        uint8 ntlm_v2_hash[16];
 
589
        uint8 nt_proof_str[16];
 
590
        rdpBlob ntlm_v2_temp;
 
591
        rdpBlob ntlm_v2_temp_chal;
 
592
 
 
593
        freerdp_blob_alloc(&ntlm_v2_temp, ntlmssp->target_info.length + 28);
 
594
 
 
595
        memset(ntlm_v2_temp.data, '\0', ntlm_v2_temp.length);
 
596
        blob = (uint8*) ntlm_v2_temp.data;
 
597
 
 
598
        /* Compute the NTLMv2 hash */
 
599
        ntlmssp_compute_ntlm_v2_hash(ntlmssp, (char*) ntlm_v2_hash);
 
600
 
 
601
#ifdef WITH_DEBUG_NLA
 
602
        printf("Password (length = %d)\n", ntlmssp->password.length);
 
603
        freerdp_hexdump(ntlmssp->password.data, ntlmssp->password.length);
 
604
        printf("\n");
 
605
 
 
606
        printf("Username (length = %d)\n", ntlmssp->username.length);
 
607
        freerdp_hexdump(ntlmssp->username.data, ntlmssp->username.length);
 
608
        printf("\n");
 
609
 
 
610
        printf("Domain (length = %d)\n", ntlmssp->domain.length);
 
611
        freerdp_hexdump(ntlmssp->domain.data, ntlmssp->domain.length);
 
612
        printf("\n");
 
613
 
 
614
        printf("Workstation (length = %d)\n", ntlmssp->workstation.length);
 
615
        freerdp_hexdump(ntlmssp->workstation.data, ntlmssp->workstation.length);
 
616
        printf("\n");
 
617
 
 
618
        printf("NTOWFv2, NTLMv2 Hash\n");
 
619
        freerdp_hexdump(ntlm_v2_hash, 16);
 
620
        printf("\n");
 
621
#endif
 
622
 
 
623
        /* Construct temp */
 
624
        blob[0] = 1; /* RespType (1 byte) */
 
625
        blob[1] = 1; /* HighRespType (1 byte) */
 
626
        /* Reserved1 (2 bytes) */
 
627
        /* Reserved2 (4 bytes) */
 
628
        memcpy(&blob[8], ntlmssp->av_pairs->Timestamp.value, 8); /* Timestamp (8 bytes) */
 
629
        memcpy(&blob[16], ntlmssp->client_challenge, 8); /* ClientChallenge (8 bytes) */
 
630
        /* Reserved3 (4 bytes) */
 
631
        memcpy(&blob[28], ntlmssp->target_info.data, ntlmssp->target_info.length);
 
632
 
 
633
#ifdef WITH_DEBUG_NLA
 
634
        printf("NTLMv2 Response Temp Blob\n");
 
635
        freerdp_hexdump(ntlm_v2_temp.data, ntlm_v2_temp.length);
 
636
        printf("\n");
 
637
#endif
 
638
 
 
639
        /* Concatenate server challenge with temp */
 
640
        freerdp_blob_alloc(&ntlm_v2_temp_chal, ntlm_v2_temp.length + 8);
 
641
        blob = (uint8*) ntlm_v2_temp_chal.data;
 
642
        memcpy(blob, ntlmssp->server_challenge, 8);
 
643
        memcpy(&blob[8], ntlm_v2_temp.data, ntlm_v2_temp.length);
 
644
 
 
645
        HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16, (void*) ntlm_v2_temp_chal.data,
 
646
                ntlm_v2_temp_chal.length, (void*) nt_proof_str, NULL);
 
647
 
 
648
        /* NtChallengeResponse, Concatenate NTProofStr with temp */
 
649
        freerdp_blob_alloc(&ntlmssp->nt_challenge_response, ntlm_v2_temp.length + 16);
 
650
        blob = (uint8*) ntlmssp->nt_challenge_response.data;
 
651
        memcpy(blob, nt_proof_str, 16);
 
652
        memcpy(&blob[16], ntlm_v2_temp.data, ntlm_v2_temp.length);
 
653
 
 
654
        /* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */
 
655
        HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16,
 
656
                (void*) nt_proof_str, 16, (void*) ntlmssp->session_base_key, NULL);
 
657
 
 
658
        freerdp_blob_free(&ntlm_v2_temp);
 
659
        freerdp_blob_free(&ntlm_v2_temp_chal);
 
660
}
 
661
 
 
662
/**
 
663
 * Input NegotiateFlags, a 4-byte bit map.
 
664
 * @param s
 
665
 * @param flags
 
666
 */
 
667
 
 
668
void ntlmssp_input_negotiate_flags(STREAM* s, uint32* flags)
 
669
{
 
670
        *flags = 0;
 
671
        stream_read_uint32(s, *flags);
 
672
}
 
673
 
 
674
/**
 
675
 * Output NegotiateFlags, a 4-byte bit map.
 
676
 * @param s
 
677
 * @param flags
 
678
 */
 
679
 
 
680
void ntlmssp_output_negotiate_flags(STREAM* s, uint32 flags)
 
681
{
 
682
        stream_write_uint32(s, flags);
 
683
}
 
684
 
 
685
void ntlmssp_print_negotiate_flags(uint32 flags)
 
686
{
 
687
        int i;
 
688
        const char* str;
 
689
 
 
690
        printf("negotiateFlags \"0x%08X\"{\n", flags);
 
691
 
 
692
        for (i = 31; i >= 0; i--)
 
693
        {
 
694
                if ((flags >> i) & 1)
 
695
                {
 
696
                        str = NTLMSSP_NEGOTIATE_STRINGS[(31 - i)];
 
697
                        printf("\t%s (%d),\n", str, (31 - i));
 
698
                }
 
699
        }
 
700
 
 
701
        printf("}\n");
 
702
}
 
703
 
 
704
/**
 
705
 * Output Restriction_Encoding.\n
 
706
 * Restriction_Encoding @msdn{cc236647}
 
707
 * @param ntlmssp
 
708
 */
 
709
 
 
710
static void ntlmssp_output_restriction_encoding(NTLMSSP* ntlmssp)
 
711
{
 
712
        AV_PAIR *restrictions = &ntlmssp->av_pairs->Restrictions;
 
713
        STREAM* s = stream_new(0);
 
714
 
 
715
        uint8 machineID[32] =
 
716
                "\x3A\x15\x8E\xA6\x75\x82\xD8\xF7\x3E\x06\xFA\x7A\xB4\xDF\xFD\x43"
 
717
                "\x84\x6C\x02\x3A\xFD\x5A\x94\xFE\xCF\x97\x0F\x3D\x19\x2C\x38\x20";
 
718
 
 
719
        restrictions->value = xmalloc(48);
 
720
        restrictions->length = 48;
 
721
 
 
722
        s->data = restrictions->value;
 
723
        s->size = restrictions->length;
 
724
        s->p = s->data;
 
725
 
 
726
        stream_write_uint32(s, 48); /* Size */
 
727
        stream_write_zero(s, 4); /* Z4 (set to zero) */
 
728
 
 
729
        /* IntegrityLevel (bit 31 set to 1) */
 
730
        stream_write_uint8(s, 1);
 
731
        stream_write_zero(s, 3);
 
732
 
 
733
        stream_write_uint32(s, 0x00002000); /* SubjectIntegrityLevel */
 
734
        stream_write(s, machineID, 32); /* MachineID */
 
735
 
 
736
        xfree(s);
 
737
}
 
738
 
 
739
/**
 
740
 * Output TargetName.\n
 
741
 * @param ntlmssp
 
742
 */
 
743
 
 
744
void ntlmssp_output_target_name(NTLMSSP* ntlmssp)
 
745
{
 
746
        STREAM* s = stream_new(0);
 
747
        AV_PAIR* target_name = &ntlmssp->av_pairs->TargetName;
 
748
 
 
749
        /*
 
750
         * TODO: No idea what should be set here (observed MsvAvTargetName = MsvAvDnsComputerName or
 
751
         * MsvAvTargetName should be the name of the service be accessed after authentication)
 
752
         * here used: "TERMSRV/192.168.0.123" in unicode (Dmitrij Jasnov)
 
753
         */
 
754
        uint8 name[42] =
 
755
                        "\x54\x00\x45\x00\x52\x00\x4d\x00\x53\x00\x52\x00\x56\x00\x2f\x00\x31\x00\x39\x00\x32"
 
756
                        "\x00\x2e\x00\x31\x00\x36\x00\x38\x00\x2e\x00\x30\x00\x2e\x00\x31\x00\x32\x00\x33\x00";
 
757
 
 
758
        target_name->length = 42;
 
759
        target_name->value = (uint8*) xmalloc(target_name->length);
 
760
 
 
761
        s->data = target_name->value;
 
762
        s->size = target_name->length;
 
763
        s->p = s->data;
 
764
 
 
765
        stream_write(s, name, target_name->length);
 
766
 
 
767
        xfree(s);
 
768
}
 
769
 
 
770
/**
 
771
 * Output ChannelBindings.\n
 
772
 * @param ntlmssp
 
773
 */
 
774
 
 
775
void ntlmssp_output_channel_bindings(NTLMSSP* ntlmssp)
 
776
{
 
777
        STREAM* s = stream_new(0);
 
778
        AV_PAIR* channel_bindings = &ntlmssp->av_pairs->ChannelBindings;
 
779
 
 
780
        channel_bindings->value = (uint8*) xmalloc(48);
 
781
        channel_bindings->length = 16;
 
782
 
 
783
        s->data = channel_bindings->value;
 
784
        s->size = channel_bindings->length;
 
785
        s->p = s->data;
 
786
 
 
787
        stream_write_zero(s, 16); /* an all-zero value of the hash is used to indicate absence of channel bindings */
 
788
 
 
789
        xfree(s);
 
790
}
 
791
 
 
792
/**
 
793
 * Populate array of AV_PAIRs.\n
 
794
 * AV_PAIR @msdn{cc236646}
 
795
 * @param ntlmssp
 
796
 */
 
797
 
 
798
void ntlmssp_populate_av_pairs(NTLMSSP* ntlmssp)
 
799
{
 
800
        STREAM* s;
 
801
        rdpBlob target_info;
 
802
        AV_PAIRS *av_pairs = ntlmssp->av_pairs;
 
803
 
 
804
        /* MsvAvFlags */
 
805
        av_pairs->Flags = 0x00000002; /* Indicates the present of a Message Integrity Check (MIC) */
 
806
 
 
807
        /* Restriction_Encoding */
 
808
        ntlmssp_output_restriction_encoding(ntlmssp);
 
809
 
 
810
        /* TargetName */
 
811
        ntlmssp_output_target_name(ntlmssp);
 
812
 
 
813
        /* ChannelBindings */
 
814
        ntlmssp_output_channel_bindings(ntlmssp);
 
815
 
 
816
        s = stream_new(0);
 
817
        s->data = xmalloc(ntlmssp->target_info.length + 512);
 
818
        s->p = s->data;
 
819
 
 
820
        ntlmssp_output_av_pairs(ntlmssp, s);
 
821
        freerdp_blob_alloc(&target_info, s->p - s->data);
 
822
        memcpy(target_info.data, s->data, target_info.length);
 
823
 
 
824
        ntlmssp->target_info.data = target_info.data;
 
825
        ntlmssp->target_info.length = target_info.length;
 
826
}
 
827
 
 
828
/**
 
829
 * Input array of AV_PAIRs.\n
 
830
 * AV_PAIR @msdn{cc236646}
 
831
 * @param ntlmssp
 
832
 * @param s
 
833
 */
 
834
 
 
835
void ntlmssp_input_av_pairs(NTLMSSP* ntlmssp, STREAM* s)
 
836
{
 
837
        AV_ID AvId;
 
838
        uint16 AvLen;
 
839
        uint8* value;
 
840
        AV_PAIRS* av_pairs = ntlmssp->av_pairs;
 
841
 
 
842
#ifdef WITH_DEBUG_NLA
 
843
        printf("AV_PAIRS = {\n");
 
844
#endif
 
845
 
 
846
        do
 
847
        {
 
848
                value = NULL;
 
849
                stream_read_uint16(s, AvId);
 
850
                stream_read_uint16(s, AvLen);
 
851
 
 
852
                if (AvLen > 0)
 
853
                {
 
854
                        if (AvId != MsvAvFlags)
 
855
                        {
 
856
                                value = xmalloc(AvLen);
 
857
                                stream_read(s, value, AvLen);
 
858
                        }
 
859
                        else
 
860
                        {
 
861
                                stream_read_uint32(s, av_pairs->Flags);
 
862
                        }
 
863
                }
 
864
 
 
865
                switch (AvId)
 
866
                {
 
867
                        case MsvAvNbComputerName:
 
868
                                av_pairs->NbComputerName.length = AvLen;
 
869
                                av_pairs->NbComputerName.value = value;
 
870
                                break;
 
871
 
 
872
                        case MsvAvNbDomainName:
 
873
                                av_pairs->NbDomainName.length = AvLen;
 
874
                                av_pairs->NbDomainName.value = value;
 
875
                                break;
 
876
 
 
877
                        case MsvAvDnsComputerName:
 
878
                                av_pairs->DnsComputerName.length = AvLen;
 
879
                                av_pairs->DnsComputerName.value = value;
 
880
                                break;
 
881
 
 
882
                        case MsvAvDnsDomainName:
 
883
                                av_pairs->DnsDomainName.length = AvLen;
 
884
                                av_pairs->DnsDomainName.value = value;
 
885
                                break;
 
886
 
 
887
                        case MsvAvDnsTreeName:
 
888
                                av_pairs->DnsTreeName.length = AvLen;
 
889
                                av_pairs->DnsTreeName.value = value;
 
890
                                break;
 
891
 
 
892
                        case MsvAvTimestamp:
 
893
                                av_pairs->Timestamp.length = AvLen;
 
894
                                av_pairs->Timestamp.value = value;
 
895
                                break;
 
896
 
 
897
                        case MsvAvRestrictions:
 
898
                                av_pairs->Restrictions.length = AvLen;
 
899
                                av_pairs->Restrictions.value = value;
 
900
                                break;
 
901
 
 
902
                        case MsvAvTargetName:
 
903
                                av_pairs->TargetName.length = AvLen;
 
904
                                av_pairs->TargetName.value = value;
 
905
                                break;
 
906
 
 
907
                        case MsvChannelBindings:
 
908
                                av_pairs->ChannelBindings.length = AvLen;
 
909
                                av_pairs->ChannelBindings.value = value;
 
910
                                break;
 
911
 
 
912
                        default:
 
913
                                if (value != NULL)
 
914
                                        xfree(value);
 
915
                                break;
 
916
                }
 
917
 
 
918
#ifdef WITH_DEBUG_NLA
 
919
                if (AvId < 10)
 
920
                        printf("\tAvId: %s, AvLen: %d\n", AV_PAIRS_STRINGS[AvId], AvLen);
 
921
                else
 
922
                        printf("\tAvId: %s, AvLen: %d\n", "Unknown", AvLen);
 
923
 
 
924
                freerdp_hexdump(value, AvLen);
 
925
#endif
 
926
        }
 
927
        while (AvId != MsvAvEOL);
 
928
 
 
929
#ifdef WITH_DEBUG_NLA
 
930
        printf("}\n");
 
931
#endif
 
932
}
 
933
 
 
934
/**
 
935
 * Output array of AV_PAIRs.\n
 
936
 * AV_PAIR @msdn{cc236646}
 
937
 * @param ntlmssp
 
938
 * @param s
 
939
 */
 
940
 
 
941
void ntlmssp_output_av_pairs(NTLMSSP* ntlmssp, STREAM* s)
 
942
{
 
943
        AV_PAIRS* av_pairs = ntlmssp->av_pairs;
 
944
        
 
945
        if (av_pairs->NbDomainName.length > 0)
 
946
        {
 
947
                stream_write_uint16(s, MsvAvNbDomainName); /* AvId */
 
948
                stream_write_uint16(s, av_pairs->NbDomainName.length); /* AvLen */
 
949
                stream_write(s, av_pairs->NbDomainName.value, av_pairs->NbDomainName.length); /* Value */
 
950
        }
 
951
 
 
952
        if (av_pairs->NbComputerName.length > 0)
 
953
        {
 
954
                stream_write_uint16(s, MsvAvNbComputerName); /* AvId */
 
955
                stream_write_uint16(s, av_pairs->NbComputerName.length); /* AvLen */
 
956
                stream_write(s, av_pairs->NbComputerName.value, av_pairs->NbComputerName.length); /* Value */
 
957
        }
 
958
 
 
959
        if (av_pairs->DnsDomainName.length > 0)
 
960
        {
 
961
                stream_write_uint16(s, MsvAvDnsDomainName); /* AvId */
 
962
                stream_write_uint16(s, av_pairs->DnsDomainName.length); /* AvLen */
 
963
                stream_write(s, av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length); /* Value */
 
964
        }
 
965
 
 
966
        if (av_pairs->DnsComputerName.length > 0)
 
967
        {
 
968
                stream_write_uint16(s, MsvAvDnsComputerName); /* AvId */
 
969
                stream_write_uint16(s, av_pairs->DnsComputerName.length); /* AvLen */
 
970
                stream_write(s, av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length); /* Value */
 
971
        }
 
972
 
 
973
        if (av_pairs->DnsTreeName.length > 0)
 
974
        {
 
975
                stream_write_uint16(s, MsvAvDnsTreeName); /* AvId */
 
976
                stream_write_uint16(s, av_pairs->DnsTreeName.length); /* AvLen */
 
977
                stream_write(s, av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length); /* Value */
 
978
        }
 
979
 
 
980
        if (av_pairs->Timestamp.length > 0)
 
981
        {
 
982
                stream_write_uint16(s, MsvAvTimestamp); /* AvId */
 
983
                stream_write_uint16(s, av_pairs->Timestamp.length); /* AvLen */
 
984
                stream_write(s, av_pairs->Timestamp.value, av_pairs->Timestamp.length); /* Value */
 
985
        }
 
986
 
 
987
        if (av_pairs->Flags > 0)
 
988
        {
 
989
                stream_write_uint16(s, MsvAvFlags); /* AvId */
 
990
                stream_write_uint16(s, 4); /* AvLen */
 
991
                stream_write_uint32(s, av_pairs->Flags); /* Value */
 
992
        }
 
993
 
 
994
        if (av_pairs->Restrictions.length > 0)
 
995
        {
 
996
                stream_write_uint16(s, MsvAvRestrictions); /* AvId */
 
997
                stream_write_uint16(s, av_pairs->Restrictions.length); /* AvLen */
 
998
                stream_write(s, av_pairs->Restrictions.value, av_pairs->Restrictions.length); /* Value */
 
999
        }
 
1000
 
 
1001
        if (av_pairs->ChannelBindings.length > 0)
 
1002
        {
 
1003
                stream_write_uint16(s, MsvChannelBindings); /* AvId */
 
1004
                stream_write_uint16(s, av_pairs->ChannelBindings.length); /* AvLen */
 
1005
                stream_write(s, av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length); /* Value */
 
1006
        }
 
1007
 
 
1008
        if (av_pairs->TargetName.length > 0)
 
1009
        {
 
1010
                stream_write_uint16(s, MsvAvTargetName); /* AvId */
 
1011
                stream_write_uint16(s, av_pairs->TargetName.length); /* AvLen */
 
1012
                stream_write(s, av_pairs->TargetName.value, av_pairs->TargetName.length); /* Value */
 
1013
        }
 
1014
 
 
1015
        /* This indicates the end of the AV_PAIR array */
 
1016
        stream_write_uint16(s, MsvAvEOL); /* AvId */
 
1017
        stream_write_uint16(s, 0); /* AvLen */
 
1018
 
 
1019
        if (ntlmssp->ntlm_v2)
 
1020
        {
 
1021
                stream_write_zero(s, 8);
 
1022
        }
 
1023
}
 
1024
 
 
1025
/**
 
1026
 * Print array of AV_PAIRs.\n
 
1027
 * AV_PAIR @msdn{cc236646}
 
1028
 * @param ntlmssp
 
1029
 * @param s
 
1030
 */
 
1031
 
 
1032
void ntlmssp_print_av_pairs(NTLMSSP* ntlmssp)
 
1033
{
 
1034
        AV_PAIRS* av_pairs = ntlmssp->av_pairs;
 
1035
 
 
1036
        printf("AV_PAIRS = {\n");
 
1037
 
 
1038
        if (av_pairs->NbDomainName.length > 0)
 
1039
        {
 
1040
                printf("\tAvId: MsvAvNbDomainName AvLen: %d\n", av_pairs->NbDomainName.length);
 
1041
                freerdp_hexdump(av_pairs->NbDomainName.value, av_pairs->NbDomainName.length);
 
1042
        }
 
1043
 
 
1044
        if (av_pairs->NbComputerName.length > 0)
 
1045
        {
 
1046
                printf("\tAvId: MsvAvNbComputerName AvLen: %d\n", av_pairs->NbComputerName.length);
 
1047
                freerdp_hexdump(av_pairs->NbComputerName.value, av_pairs->NbComputerName.length);
 
1048
        }
 
1049
 
 
1050
        if (av_pairs->DnsDomainName.length > 0)
 
1051
        {
 
1052
                printf("\tAvId: MsvAvDnsDomainName AvLen: %d\n", av_pairs->DnsDomainName.length);
 
1053
                freerdp_hexdump(av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length);
 
1054
        }
 
1055
 
 
1056
        if (av_pairs->DnsComputerName.length > 0)
 
1057
        {
 
1058
                printf("\tAvId: MsvAvDnsComputerName AvLen: %d\n", av_pairs->DnsComputerName.length);
 
1059
                freerdp_hexdump(av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length);
 
1060
        }
 
1061
 
 
1062
        if (av_pairs->DnsTreeName.length > 0)
 
1063
        {
 
1064
                printf("\tAvId: MsvAvDnsTreeName AvLen: %d\n", av_pairs->DnsTreeName.length);
 
1065
                freerdp_hexdump(av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length);
 
1066
        }
 
1067
 
 
1068
        if (av_pairs->Timestamp.length > 0)
 
1069
        {
 
1070
                printf("\tAvId: MsvAvTimestamp AvLen: %d\n", av_pairs->Timestamp.length);
 
1071
                freerdp_hexdump(av_pairs->Timestamp.value, av_pairs->Timestamp.length);
 
1072
        }
 
1073
 
 
1074
        if (av_pairs->Flags > 0)
 
1075
        {
 
1076
                printf("\tAvId: MsvAvFlags AvLen: %d\n", 4);
 
1077
                printf("0x%08X\n", av_pairs->Flags);
 
1078
        }
 
1079
 
 
1080
        if (av_pairs->Restrictions.length > 0)
 
1081
        {
 
1082
                printf("\tAvId: MsvAvRestrictions AvLen: %d\n", av_pairs->Restrictions.length);
 
1083
                freerdp_hexdump(av_pairs->Restrictions.value, av_pairs->Restrictions.length);
 
1084
        }
 
1085
 
 
1086
        if (av_pairs->ChannelBindings.length > 0)
 
1087
        {
 
1088
                printf("\tAvId: MsvChannelBindings AvLen: %d\n", av_pairs->ChannelBindings.length);
 
1089
                freerdp_hexdump(av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length);
 
1090
        }
 
1091
 
 
1092
        if (av_pairs->TargetName.length > 0)
 
1093
        {
 
1094
                printf("\tAvId: MsvAvTargetName AvLen: %d\n", av_pairs->TargetName.length);
 
1095
                freerdp_hexdump(av_pairs->TargetName.value, av_pairs->TargetName.length);
 
1096
        }
 
1097
 
 
1098
        printf("}\n");
 
1099
}
 
1100
 
 
1101
/**
 
1102
 * Free array of AV_PAIRs.\n
 
1103
 * AV_PAIR @msdn{cc236646}
 
1104
 * @param ntlmssp
 
1105
 */
 
1106
 
 
1107
void ntlmssp_free_av_pairs(NTLMSSP* ntlmssp)
 
1108
{
 
1109
        AV_PAIRS *av_pairs = ntlmssp->av_pairs;
 
1110
        
 
1111
        if (av_pairs != NULL)
 
1112
        {
 
1113
                if (av_pairs->NbComputerName.value != NULL)
 
1114
                        xfree(av_pairs->NbComputerName.value);
 
1115
                if (av_pairs->NbDomainName.value != NULL)
 
1116
                        xfree(av_pairs->NbDomainName.value);
 
1117
                if (av_pairs->DnsComputerName.value != NULL)
 
1118
                        xfree(av_pairs->DnsComputerName.value);
 
1119
                if (av_pairs->DnsDomainName.value != NULL)
 
1120
                        xfree(av_pairs->DnsDomainName.value);
 
1121
                if (av_pairs->DnsTreeName.value != NULL)
 
1122
                        xfree(av_pairs->DnsTreeName.value);
 
1123
                if (av_pairs->Timestamp.value != NULL)
 
1124
                        xfree(av_pairs->Timestamp.value);
 
1125
                if (av_pairs->Restrictions.value != NULL)
 
1126
                        xfree(av_pairs->Restrictions.value);
 
1127
                if (av_pairs->TargetName.value != NULL)
 
1128
                        xfree(av_pairs->TargetName.value);
 
1129
                if (av_pairs->ChannelBindings.value != NULL)
 
1130
                        xfree(av_pairs->ChannelBindings.value);
 
1131
 
 
1132
                xfree(av_pairs);
 
1133
        }
 
1134
 
 
1135
        ntlmssp->av_pairs = NULL;
 
1136
}
 
1137
 
 
1138
/**
 
1139
 * Output VERSION structure.\n
 
1140
 * VERSION @msdn{cc236654}
 
1141
 * @param s
 
1142
 */
 
1143
 
 
1144
static void ntlmssp_output_version(STREAM* s)
 
1145
{
 
1146
        /* The following version information was observed with Windows 7 */
 
1147
 
 
1148
        stream_write_uint8(s, WINDOWS_MAJOR_VERSION_6); /* ProductMajorVersion (1 byte) */
 
1149
        stream_write_uint8(s, WINDOWS_MINOR_VERSION_1); /* ProductMinorVersion (1 byte) */
 
1150
        stream_write_uint16(s, 7600); /* ProductBuild (2 bytes) */
 
1151
        stream_write_zero(s, 3); /* Reserved (3 bytes) */
 
1152
        stream_write_uint8(s, NTLMSSP_REVISION_W2K3); /* NTLMRevisionCurrent (1 byte) */
 
1153
}
 
1154
 
 
1155
void ntlmssp_compute_message_integrity_check(NTLMSSP* ntlmssp)
 
1156
{
 
1157
        HMAC_CTX hmac_ctx;
 
1158
 
 
1159
        /* 
 
1160
         * Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE,
 
1161
         * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey
 
1162
         */
 
1163
 
 
1164
        HMAC_CTX_init(&hmac_ctx);
 
1165
        HMAC_Init_ex(&hmac_ctx, ntlmssp->exported_session_key, 16, EVP_md5(), NULL);
 
1166
        HMAC_Update(&hmac_ctx, ntlmssp->negotiate_message.data, ntlmssp->negotiate_message.length);
 
1167
        HMAC_Update(&hmac_ctx, ntlmssp->challenge_message.data, ntlmssp->challenge_message.length);
 
1168
        HMAC_Update(&hmac_ctx, ntlmssp->authenticate_message.data, ntlmssp->authenticate_message.length);
 
1169
        HMAC_Final(&hmac_ctx, ntlmssp->message_integrity_check, NULL);
 
1170
}
 
1171
 
 
1172
/**
 
1173
 * Encrypt and sign message using NTLMSSP.\n
 
1174
 * GSS_WrapEx() @msdn{cc236718}\n
 
1175
 * EncryptMessage() @msdn{aa375378}
 
1176
 * @param ntlmssp
 
1177
 * @param[in] msg message to encrypt
 
1178
 * @param[out] encrypted_msg encrypted message
 
1179
 * @param[out] signature destination signature
 
1180
 */
 
1181
 
 
1182
void ntlmssp_encrypt_message(NTLMSSP* ntlmssp, rdpBlob* msg, rdpBlob* encrypted_msg, uint8* signature)
 
1183
{
 
1184
        HMAC_CTX hmac_ctx;
 
1185
        uint8 digest[16];
 
1186
        uint8 checksum[8];
 
1187
        uint32 version = 1;
 
1188
 
 
1189
        /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,msg) using the client signing key */
 
1190
        HMAC_CTX_init(&hmac_ctx);
 
1191
        HMAC_Init_ex(&hmac_ctx, ntlmssp->client_signing_key, 16, EVP_md5(), NULL);
 
1192
        HMAC_Update(&hmac_ctx, (void*) &ntlmssp->send_seq_num, 4);
 
1193
        HMAC_Update(&hmac_ctx, msg->data, msg->length);
 
1194
        HMAC_Final(&hmac_ctx, digest, NULL);
 
1195
 
 
1196
        /* Allocate space for encrypted message */
 
1197
        freerdp_blob_alloc(encrypted_msg, msg->length);
 
1198
 
 
1199
        /* Encrypt message using with RC4 */
 
1200
        crypto_rc4(ntlmssp->send_rc4_seal, msg->length, msg->data, encrypted_msg->data);
 
1201
 
 
1202
        /* RC4-encrypt first 8 bytes of digest */
 
1203
        crypto_rc4(ntlmssp->send_rc4_seal, 8, digest, checksum);
 
1204
 
 
1205
        /* Concatenate version, ciphertext and sequence number to build signature */
 
1206
        memcpy(signature, (void*) &version, 4);
 
1207
        memcpy(&signature[4], (void*) checksum, 8);
 
1208
        memcpy(&signature[12], (void*) &(ntlmssp->send_seq_num), 4);
 
1209
 
 
1210
        HMAC_CTX_cleanup(&hmac_ctx);
 
1211
 
 
1212
        ntlmssp->send_seq_num++;
 
1213
}
 
1214
 
 
1215
/**
 
1216
 * Decrypt message and verify signature using NTLMSSP.\n
 
1217
 * GSS_UnwrapEx() @msdn{cc236703}\n
 
1218
 * DecryptMessage() @msdn{aa375211}
 
1219
 * @param ntlmssp
 
1220
 * @param[in] encrypted_msg encrypted message
 
1221
 * @param[out] msg decrypted message
 
1222
 * @param[in] signature signature
 
1223
 * @return
 
1224
 */
 
1225
 
 
1226
int ntlmssp_decrypt_message(NTLMSSP* ntlmssp, rdpBlob* encrypted_msg, rdpBlob* msg, uint8* signature)
 
1227
{
 
1228
        HMAC_CTX hmac_ctx;
 
1229
        uint8 digest[16];
 
1230
        uint8 checksum[8];
 
1231
        uint32 version = 1;
 
1232
        uint8 expected_signature[16];
 
1233
 
 
1234
        /* Allocate space for encrypted message */
 
1235
        freerdp_blob_alloc(msg, encrypted_msg->length);
 
1236
 
 
1237
        /* Encrypt message using with RC4 */
 
1238
        crypto_rc4(ntlmssp->recv_rc4_seal, encrypted_msg->length, encrypted_msg->data, msg->data);
 
1239
 
 
1240
        /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,msg) using the client signing key */
 
1241
        HMAC_CTX_init(&hmac_ctx);
 
1242
        HMAC_Init_ex(&hmac_ctx, ntlmssp->server_signing_key, 16, EVP_md5(), NULL);
 
1243
        HMAC_Update(&hmac_ctx, (void*) &ntlmssp->recv_seq_num, 4);
 
1244
        HMAC_Update(&hmac_ctx, msg->data, msg->length);
 
1245
        HMAC_Final(&hmac_ctx, digest, NULL);
 
1246
 
 
1247
        /* RC4-encrypt first 8 bytes of digest */
 
1248
        crypto_rc4(ntlmssp->recv_rc4_seal, 8, digest, checksum);
 
1249
 
 
1250
        /* Concatenate version, ciphertext and sequence number to build signature */
 
1251
        memcpy(expected_signature, (void*) &version, 4);
 
1252
        memcpy(&expected_signature[4], (void*) checksum, 8);
 
1253
        memcpy(&expected_signature[12], (void*) &(ntlmssp->recv_seq_num), 4);
 
1254
 
 
1255
        if (memcmp(signature, expected_signature, 16) != 0)
 
1256
        {
 
1257
                /* signature verification failed! */
 
1258
                printf("signature verification failed, something nasty is going on!\n");
 
1259
                return 0;
 
1260
        }
 
1261
 
 
1262
        HMAC_CTX_cleanup(&hmac_ctx);
 
1263
 
 
1264
        ntlmssp->recv_seq_num++;
 
1265
        return 1;
 
1266
}
 
1267
 
 
1268
/**
 
1269
 * Send NTLMSSP NEGOTIATE_MESSAGE.\n
 
1270
 * NEGOTIATE_MESSAGE @msdn{cc236641}
 
1271
 * @param ntlmssp
 
1272
 * @param s
 
1273
 */
 
1274
 
 
1275
void ntlmssp_send_negotiate_message(NTLMSSP* ntlmssp, STREAM* s)
 
1276
{
 
1277
        int length;
 
1278
        uint32 negotiateFlags = 0;
 
1279
 
 
1280
        stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */
 
1281
        stream_write_uint32(s, 1); /* MessageType */
 
1282
 
 
1283
        if (ntlmssp->ntlm_v2)
 
1284
        {
 
1285
                DEBUG_NLA("Negotiating NTLMv2");
 
1286
                /* observed: B7 82 08 E2 (0xE20882B7) (Dmitrij Jasnov) */
 
1287
                negotiateFlags |= NTLMSSP_NEGOTIATE_56;
 
1288
                negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
 
1289
                negotiateFlags |= NTLMSSP_NEGOTIATE_128;
 
1290
                negotiateFlags |= NTLMSSP_NEGOTIATE_VERSION;
 
1291
                negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
 
1292
                negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
1293
                negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
 
1294
                negotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY;
 
1295
                negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
 
1296
                negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
 
1297
                negotiateFlags |= NTLMSSP_REQUEST_TARGET;
 
1298
                negotiateFlags |= NTLMSSP_NEGOTIATE_OEM;
 
1299
                negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
 
1300
        }
 
1301
        else
 
1302
        {
 
1303
                negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
 
1304
                negotiateFlags |= NTLMSSP_NEGOTIATE_128;
 
1305
                negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
 
1306
                negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
1307
                negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
 
1308
                negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
 
1309
                negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
 
1310
                negotiateFlags |= NTLMSSP_REQUEST_TARGET;
 
1311
                negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
 
1312
        }
 
1313
 
 
1314
        ntlmssp_output_negotiate_flags(s, negotiateFlags); /* NegotiateFlags (4 bytes) */
 
1315
 
 
1316
#ifdef WITH_DEBUG_NLA
 
1317
        ntlmssp_print_negotiate_flags(negotiateFlags);
 
1318
#endif
 
1319
 
 
1320
        /* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
 
1321
 
 
1322
        /* DomainNameFields (8 bytes) */
 
1323
        stream_write_uint16(s, 0); /* DomainNameLen */
 
1324
        stream_write_uint16(s, 0); /* DomainNameMaxLen */
 
1325
        stream_write_uint32(s, 0); /* DomainNameBufferOffset */
 
1326
 
 
1327
        /* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
 
1328
 
 
1329
        /* WorkstationFields (8 bytes) */
 
1330
        stream_write_uint16(s, 0); /* WorkstationLen */
 
1331
        stream_write_uint16(s, 0); /* WorkstationMaxLen */
 
1332
        stream_write_uint32(s, 0); /* WorkstationBufferOffset */
 
1333
 
 
1334
        if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
 
1335
        {
 
1336
                /* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
 
1337
                ntlmssp_output_version(s);
 
1338
 
 
1339
#ifdef WITH_DEBUG_NLA
 
1340
                printf("Version (length = 8)\n");
 
1341
                freerdp_hexdump((s->p - 8), 8);
 
1342
                printf("\n");
 
1343
#endif
 
1344
        }
 
1345
 
 
1346
        length = s->p - s->data;
 
1347
        freerdp_blob_alloc(&ntlmssp->negotiate_message, length);
 
1348
        memcpy(ntlmssp->negotiate_message.data, s->data, length);
 
1349
 
 
1350
#ifdef WITH_DEBUG_NLA
 
1351
        printf("NEGOTIATE_MESSAGE (length = %d)\n", length);
 
1352
        freerdp_hexdump(s->data, length);
 
1353
        printf("\n");
 
1354
#endif
 
1355
 
 
1356
        ntlmssp->state = NTLMSSP_STATE_CHALLENGE;
 
1357
}
 
1358
 
 
1359
/**
 
1360
 * Receive NTLMSSP CHALLENGE_MESSAGE.\n
 
1361
 * CHALLENGE_MESSAGE @msdn{cc236642}
 
1362
 * @param ntlmssp
 
1363
 * @param s
 
1364
 */
 
1365
 
 
1366
void ntlmssp_recv_challenge_message(NTLMSSP* ntlmssp, STREAM* s)
 
1367
{
 
1368
        uint8* p;
 
1369
        int length;
 
1370
        uint8* start_offset;
 
1371
        uint8* payload_offset;
 
1372
        uint16 targetNameLen;
 
1373
        uint16 targetNameMaxLen;
 
1374
        uint32 targetNameBufferOffset;
 
1375
        uint16 targetInfoLen;
 
1376
        uint16 targetInfoMaxLen;
 
1377
        uint32 targetInfoBufferOffset;
 
1378
 
 
1379
        start_offset = s->p - 12;
 
1380
 
 
1381
        /* TargetNameFields (8 bytes) */
 
1382
        stream_read_uint16(s, targetNameLen); /* TargetNameLen (2 bytes) */
 
1383
        stream_read_uint16(s, targetNameMaxLen); /* TargetNameMaxLen (2 bytes) */
 
1384
        stream_read_uint32(s, targetNameBufferOffset); /* TargetNameBufferOffset (4 bytes) */
 
1385
 
 
1386
        ntlmssp_input_negotiate_flags(s, &(ntlmssp->negotiate_flags)); /* NegotiateFlags (4 bytes) */
 
1387
 
 
1388
#ifdef WITH_DEBUG_NLA
 
1389
        ntlmssp_print_negotiate_flags(ntlmssp->negotiate_flags);
 
1390
#endif
 
1391
 
 
1392
        stream_read(s, ntlmssp->server_challenge, 8); /* ServerChallenge (8 bytes) */
 
1393
        stream_seek(s, 8); /* Reserved (8 bytes), should be ignored */
 
1394
 
 
1395
        /* TargetInfoFields (8 bytes) */
 
1396
        stream_read_uint16(s, targetInfoLen); /* TargetInfoLen (2 bytes) */
 
1397
        stream_read_uint16(s, targetInfoMaxLen); /* TargetInfoMaxLen (2 bytes) */
 
1398
        stream_read_uint32(s, targetInfoBufferOffset); /* TargetInfoBufferOffset (4 bytes) */
 
1399
 
 
1400
        /* only present if NTLMSSP_NEGOTIATE_VERSION is set */
 
1401
 
 
1402
        if (ntlmssp->negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
 
1403
        {
 
1404
                stream_seek(s, 8); /* Version (8 bytes), can be ignored */
 
1405
        }
 
1406
 
 
1407
        /* Payload (variable) */
 
1408
        payload_offset = s->p;
 
1409
 
 
1410
        if (targetNameLen > 0)
 
1411
        {
 
1412
                p = start_offset + targetNameBufferOffset;
 
1413
                freerdp_blob_alloc(&ntlmssp->target_name, targetNameLen);
 
1414
                memcpy(ntlmssp->target_name.data, p, targetNameLen);
 
1415
 
 
1416
#ifdef WITH_DEBUG_NLA
 
1417
                printf("targetName (length = %d, offset = %d)\n", targetNameLen, targetNameBufferOffset);
 
1418
                freerdp_hexdump(ntlmssp->target_name.data, ntlmssp->target_name.length);
 
1419
                printf("\n");
 
1420
#endif
 
1421
        }
 
1422
 
 
1423
        if (targetInfoLen > 0)
 
1424
        {
 
1425
                p = start_offset + targetInfoBufferOffset;
 
1426
                freerdp_blob_alloc(&ntlmssp->target_info, targetInfoLen);
 
1427
                memcpy(ntlmssp->target_info.data, p, targetInfoLen);
 
1428
 
 
1429
#ifdef WITH_DEBUG_NLA
 
1430
                printf("targetInfo (length = %d, offset = %d)\n", targetInfoLen, targetInfoBufferOffset);
 
1431
                freerdp_hexdump(ntlmssp->target_info.data, ntlmssp->target_info.length);
 
1432
                printf("\n");
 
1433
#endif
 
1434
 
 
1435
                if (ntlmssp->ntlm_v2)
 
1436
                {
 
1437
                        s->p = p;
 
1438
                        ntlmssp_input_av_pairs(ntlmssp, s);
 
1439
                }
 
1440
        }
 
1441
 
 
1442
        length = (payload_offset - start_offset) + targetNameLen + targetInfoLen;
 
1443
 
 
1444
        freerdp_blob_alloc(&ntlmssp->challenge_message, length);
 
1445
        memcpy(ntlmssp->challenge_message.data, start_offset, length);
 
1446
 
 
1447
#ifdef WITH_DEBUG_NLA
 
1448
        printf("CHALLENGE_MESSAGE (length = %d)\n", length);
 
1449
        freerdp_hexdump(start_offset, length);
 
1450
        printf("\n");
 
1451
#endif
 
1452
 
 
1453
        /* AV_PAIRs */
 
1454
        if (ntlmssp->ntlm_v2)
 
1455
                ntlmssp_populate_av_pairs(ntlmssp);
 
1456
 
 
1457
        /* Timestamp */
 
1458
        ntlmssp_generate_timestamp(ntlmssp);
 
1459
 
 
1460
        /* LmChallengeResponse */
 
1461
        ntlmssp_compute_lm_v2_response(ntlmssp);
 
1462
 
 
1463
        if (ntlmssp->ntlm_v2)
 
1464
                memset(ntlmssp->lm_challenge_response.data, '\0', 24);
 
1465
 
 
1466
        /* NtChallengeResponse */
 
1467
        ntlmssp_compute_ntlm_v2_response(ntlmssp);
 
1468
 
 
1469
        /* KeyExchangeKey */
 
1470
        ntlmssp_generate_key_exchange_key(ntlmssp);
 
1471
 
 
1472
        /* EncryptedRandomSessionKey */
 
1473
        ntlmssp_encrypt_random_session_key(ntlmssp);
 
1474
 
 
1475
        /* Generate signing keys */
 
1476
        ntlmssp_generate_client_signing_key(ntlmssp);
 
1477
        ntlmssp_generate_server_signing_key(ntlmssp);
 
1478
 
 
1479
        /* Generate sealing keys */
 
1480
        ntlmssp_generate_client_sealing_key(ntlmssp);
 
1481
        ntlmssp_generate_server_sealing_key(ntlmssp);
 
1482
 
 
1483
        /* Initialize RC4 seal state using client sealing key */
 
1484
        ntlmssp_init_rc4_seal_states(ntlmssp);
 
1485
 
 
1486
#ifdef WITH_DEBUG_NLA
 
1487
        printf("ClientChallenge\n");
 
1488
        freerdp_hexdump(ntlmssp->client_challenge, 8);
 
1489
        printf("\n");
 
1490
 
 
1491
        printf("ServerChallenge\n");
 
1492
        freerdp_hexdump(ntlmssp->server_challenge, 8);
 
1493
        printf("\n");
 
1494
 
 
1495
        printf("SessionBaseKey\n");
 
1496
        freerdp_hexdump(ntlmssp->session_base_key, 16);
 
1497
        printf("\n");
 
1498
 
 
1499
        printf("KeyExchangeKey\n");
 
1500
        freerdp_hexdump(ntlmssp->key_exchange_key, 16);
 
1501
        printf("\n");
 
1502
 
 
1503
        printf("ExportedSessionKey\n");
 
1504
        freerdp_hexdump(ntlmssp->exported_session_key, 16);
 
1505
        printf("\n");
 
1506
 
 
1507
        printf("RandomSessionKey\n");
 
1508
        freerdp_hexdump(ntlmssp->random_session_key, 16);
 
1509
        printf("\n");
 
1510
 
 
1511
        printf("ClientSignKey\n");
 
1512
        freerdp_hexdump(ntlmssp->client_signing_key, 16);
 
1513
        printf("\n");
 
1514
 
 
1515
        printf("ClientSealingKey\n");
 
1516
        freerdp_hexdump(ntlmssp->client_sealing_key, 16);
 
1517
        printf("\n");
 
1518
 
 
1519
        printf("Timestamp\n");
 
1520
        freerdp_hexdump(ntlmssp->timestamp, 8);
 
1521
        printf("\n");
 
1522
#endif
 
1523
 
 
1524
        ntlmssp->state = NTLMSSP_STATE_AUTHENTICATE;
 
1525
}
 
1526
 
 
1527
/**
 
1528
 * Send NTLMSSP AUTHENTICATE_MESSAGE.\n
 
1529
 * AUTHENTICATE_MESSAGE @msdn{cc236643}
 
1530
 * @param ntlmssp
 
1531
 * @param s
 
1532
 */
 
1533
 
 
1534
void ntlmssp_send_authenticate_message(NTLMSSP* ntlmssp, STREAM* s)
 
1535
{
 
1536
        int length;
 
1537
        uint32 negotiateFlags = 0;
 
1538
        uint8* mic_offset = NULL;
 
1539
 
 
1540
        uint16 DomainNameLen;
 
1541
        uint16 UserNameLen;
 
1542
        uint16 WorkstationLen;
 
1543
        uint16 LmChallengeResponseLen;
 
1544
        uint16 NtChallengeResponseLen;
 
1545
        uint16 EncryptedRandomSessionKeyLen;
 
1546
 
 
1547
        uint32 PayloadBufferOffset;
 
1548
        uint32 DomainNameBufferOffset;
 
1549
        uint32 UserNameBufferOffset;
 
1550
        uint32 WorkstationBufferOffset;
 
1551
        uint32 LmChallengeResponseBufferOffset;
 
1552
        uint32 NtChallengeResponseBufferOffset;
 
1553
        uint32 EncryptedRandomSessionKeyBufferOffset;
 
1554
 
 
1555
        uint8* UserNameBuffer;
 
1556
        uint8* DomainNameBuffer;
 
1557
        uint8* WorkstationBuffer;
 
1558
        uint8* EncryptedRandomSessionKeyBuffer;
 
1559
 
 
1560
        WorkstationLen = ntlmssp->workstation.length;
 
1561
        WorkstationBuffer = ntlmssp->workstation.data;
 
1562
 
 
1563
        if (ntlmssp->ntlm_v2 < 1)
 
1564
                WorkstationLen = 0;
 
1565
 
 
1566
        DomainNameLen = ntlmssp->domain.length;
 
1567
        DomainNameBuffer = ntlmssp->domain.data;
 
1568
 
 
1569
        UserNameLen = ntlmssp->username.length;
 
1570
        UserNameBuffer = ntlmssp->username.data;
 
1571
 
 
1572
        LmChallengeResponseLen = ntlmssp->lm_challenge_response.length;
 
1573
        NtChallengeResponseLen = ntlmssp->nt_challenge_response.length;
 
1574
 
 
1575
        EncryptedRandomSessionKeyLen = 16;
 
1576
        EncryptedRandomSessionKeyBuffer = ntlmssp->encrypted_random_session_key;
 
1577
 
 
1578
        if (ntlmssp->ntlm_v2)
 
1579
        {
 
1580
                /* observed: 35 82 88 e2 (0xE2888235) */
 
1581
                negotiateFlags |= NTLMSSP_NEGOTIATE_56;
 
1582
                negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
 
1583
                negotiateFlags |= NTLMSSP_NEGOTIATE_128;
 
1584
                negotiateFlags |= NTLMSSP_NEGOTIATE_VERSION;
 
1585
                negotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
 
1586
                negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
 
1587
                negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
1588
                negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
 
1589
                negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
 
1590
                negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
 
1591
                negotiateFlags |= NTLMSSP_REQUEST_TARGET;
 
1592
                negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
 
1593
        }
 
1594
        else
 
1595
        {
 
1596
                negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
 
1597
                negotiateFlags |= NTLMSSP_NEGOTIATE_128;
 
1598
                negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
 
1599
                negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
1600
                negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
 
1601
                negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
 
1602
                negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
 
1603
                negotiateFlags |= NTLMSSP_REQUEST_TARGET;
 
1604
                negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
 
1605
        }
 
1606
 
 
1607
        if (ntlmssp->ntlm_v2)
 
1608
                PayloadBufferOffset = 80; /* starting buffer offset */
 
1609
        else
 
1610
                PayloadBufferOffset = 64; /* starting buffer offset */
 
1611
 
 
1612
        if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
 
1613
                PayloadBufferOffset += 8;
 
1614
 
 
1615
        DomainNameBufferOffset = PayloadBufferOffset;
 
1616
        UserNameBufferOffset = DomainNameBufferOffset + DomainNameLen;
 
1617
        WorkstationBufferOffset = UserNameBufferOffset + UserNameLen;
 
1618
        LmChallengeResponseBufferOffset = WorkstationBufferOffset + WorkstationLen;
 
1619
        NtChallengeResponseBufferOffset = LmChallengeResponseBufferOffset + LmChallengeResponseLen;
 
1620
        EncryptedRandomSessionKeyBufferOffset = NtChallengeResponseBufferOffset + NtChallengeResponseLen;
 
1621
 
 
1622
        stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */
 
1623
        stream_write_uint32(s, 3); /* MessageType */
 
1624
 
 
1625
        /* LmChallengeResponseFields (8 bytes) */
 
1626
        stream_write_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseLen */
 
1627
        stream_write_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseMaxLen */
 
1628
        stream_write_uint32(s, LmChallengeResponseBufferOffset); /* LmChallengeResponseBufferOffset */
 
1629
 
 
1630
        /* NtChallengeResponseFields (8 bytes) */
 
1631
        stream_write_uint16(s, NtChallengeResponseLen); /* NtChallengeResponseLen */
 
1632
        stream_write_uint16(s, NtChallengeResponseLen); /* NtChallengeResponseMaxLen */
 
1633
        stream_write_uint32(s, NtChallengeResponseBufferOffset); /* NtChallengeResponseBufferOffset */
 
1634
 
 
1635
        /* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
 
1636
 
 
1637
        /* DomainNameFields (8 bytes) */
 
1638
        stream_write_uint16(s, DomainNameLen); /* DomainNameLen */
 
1639
        stream_write_uint16(s, DomainNameLen); /* DomainNameMaxLen */
 
1640
        stream_write_uint32(s, DomainNameBufferOffset); /* DomainNameBufferOffset */
 
1641
 
 
1642
        /* UserNameFields (8 bytes) */
 
1643
        stream_write_uint16(s, UserNameLen); /* UserNameLen */
 
1644
        stream_write_uint16(s, UserNameLen); /* UserNameMaxLen */
 
1645
        stream_write_uint32(s, UserNameBufferOffset); /* UserNameBufferOffset */
 
1646
 
 
1647
        /* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
 
1648
 
 
1649
        /* WorkstationFields (8 bytes) */
 
1650
        stream_write_uint16(s, WorkstationLen); /* WorkstationLen */
 
1651
        stream_write_uint16(s, WorkstationLen); /* WorkstationMaxLen */
 
1652
        stream_write_uint32(s, WorkstationBufferOffset); /* WorkstationBufferOffset */
 
1653
 
 
1654
        /* EncryptedRandomSessionKeyFields (8 bytes) */
 
1655
        stream_write_uint16(s, EncryptedRandomSessionKeyLen); /* EncryptedRandomSessionKeyLen */
 
1656
        stream_write_uint16(s, EncryptedRandomSessionKeyLen); /* EncryptedRandomSessionKeyMaxLen */
 
1657
        stream_write_uint32(s, EncryptedRandomSessionKeyBufferOffset); /* EncryptedRandomSessionKeyBufferOffset */
 
1658
 
 
1659
        ntlmssp_output_negotiate_flags(s, negotiateFlags); /* NegotiateFlags (4 bytes) */
 
1660
 
 
1661
#ifdef WITH_DEBUG_NLA
 
1662
        ntlmssp_print_negotiate_flags(negotiateFlags);
 
1663
#endif
 
1664
        
 
1665
        if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
 
1666
        {
 
1667
                /* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
 
1668
                ntlmssp_output_version(s);
 
1669
 
 
1670
#ifdef WITH_DEBUG_NLA
 
1671
                printf("Version (length = 8)\n");
 
1672
                freerdp_hexdump((s->p - 8), 8);
 
1673
                printf("\n");
 
1674
#endif
 
1675
        }
 
1676
 
 
1677
        if (ntlmssp->ntlm_v2)
 
1678
        {
 
1679
                /* Message Integrity Check */
 
1680
                mic_offset = s->p;
 
1681
                stream_write_zero(s, 16);
 
1682
        }
 
1683
 
 
1684
        /* DomainName */
 
1685
        if (DomainNameLen > 0)
 
1686
        {
 
1687
                stream_write(s, DomainNameBuffer, DomainNameLen);
 
1688
#ifdef WITH_DEBUG_NLA
 
1689
                printf("DomainName (length = %d, offset = %d)\n", DomainNameLen, DomainNameBufferOffset);
 
1690
                freerdp_hexdump(DomainNameBuffer, DomainNameLen);
 
1691
                printf("\n");
 
1692
#endif
 
1693
        }
 
1694
 
 
1695
        /* UserName */
 
1696
        stream_write(s, UserNameBuffer, UserNameLen);
 
1697
 
 
1698
#ifdef WITH_DEBUG_NLA
 
1699
        printf("UserName (length = %d, offset = %d)\n", UserNameLen, UserNameBufferOffset);
 
1700
        freerdp_hexdump(UserNameBuffer, UserNameLen);
 
1701
        printf("\n");
 
1702
#endif
 
1703
 
 
1704
        /* Workstation */
 
1705
        if (WorkstationLen > 0)
 
1706
        {
 
1707
                stream_write(s, WorkstationBuffer, WorkstationLen);
 
1708
#ifdef WITH_DEBUG_NLA
 
1709
                printf("Workstation (length = %d, offset = %d)\n", WorkstationLen, WorkstationBufferOffset);
 
1710
                freerdp_hexdump(WorkstationBuffer, WorkstationLen);
 
1711
                printf("\n");
 
1712
#endif
 
1713
        }
 
1714
 
 
1715
        /* LmChallengeResponse */
 
1716
        stream_write(s, ntlmssp->lm_challenge_response.data, LmChallengeResponseLen);
 
1717
 
 
1718
#ifdef WITH_DEBUG_NLA
 
1719
        printf("LmChallengeResponse (length = %d, offset = %d)\n", LmChallengeResponseLen, LmChallengeResponseBufferOffset);
 
1720
        freerdp_hexdump(ntlmssp->lm_challenge_response.data, LmChallengeResponseLen);
 
1721
        printf("\n");
 
1722
#endif
 
1723
 
 
1724
        /* NtChallengeResponse */
 
1725
        stream_write(s, ntlmssp->nt_challenge_response.data, NtChallengeResponseLen);
 
1726
 
 
1727
#ifdef WITH_DEBUG_NLA
 
1728
        if (ntlmssp->ntlm_v2)
 
1729
        {
 
1730
                ntlmssp_print_av_pairs(ntlmssp);
 
1731
 
 
1732
                printf("targetInfo (length = %d)\n", ntlmssp->target_info.length);
 
1733
                freerdp_hexdump(ntlmssp->target_info.data, ntlmssp->target_info.length);
 
1734
                printf("\n");
 
1735
        }
 
1736
#endif
 
1737
 
 
1738
#ifdef WITH_DEBUG_NLA
 
1739
        printf("NtChallengeResponse (length = %d, offset = %d)\n", NtChallengeResponseLen, NtChallengeResponseBufferOffset);
 
1740
        freerdp_hexdump(ntlmssp->nt_challenge_response.data, NtChallengeResponseLen);
 
1741
        printf("\n");
 
1742
#endif
 
1743
 
 
1744
        /* EncryptedRandomSessionKey */
 
1745
        stream_write(s, EncryptedRandomSessionKeyBuffer, EncryptedRandomSessionKeyLen);
 
1746
 
 
1747
#ifdef WITH_DEBUG_NLA
 
1748
        printf("EncryptedRandomSessionKey (length = %d, offset = %d)\n", EncryptedRandomSessionKeyLen, EncryptedRandomSessionKeyBufferOffset);
 
1749
        freerdp_hexdump(EncryptedRandomSessionKeyBuffer, EncryptedRandomSessionKeyLen);
 
1750
        printf("\n");
 
1751
#endif
 
1752
 
 
1753
        length = s->p - s->data;
 
1754
        freerdp_blob_alloc(&ntlmssp->authenticate_message, length);
 
1755
        memcpy(ntlmssp->authenticate_message.data, s->data, length);
 
1756
 
 
1757
        if (ntlmssp->ntlm_v2)
 
1758
        {
 
1759
                /* Message Integrity Check */
 
1760
                ntlmssp_compute_message_integrity_check(ntlmssp);
 
1761
                
 
1762
                s->p = mic_offset;
 
1763
                stream_write(s, ntlmssp->message_integrity_check, 16);
 
1764
                s->p = s->data + length;
 
1765
 
 
1766
#ifdef WITH_DEBUG_NLA
 
1767
                printf("MessageIntegrityCheck (length = 16)\n");
 
1768
                freerdp_hexdump(mic_offset, 16);
 
1769
                printf("\n");
 
1770
#endif
 
1771
        }
 
1772
 
 
1773
#ifdef WITH_DEBUG_NLA
 
1774
        printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
 
1775
        freerdp_hexdump(s->data, length);
 
1776
        printf("\n");
 
1777
#endif
 
1778
 
 
1779
        ntlmssp->state = NTLMSSP_STATE_FINAL;
 
1780
}
 
1781
 
 
1782
/**
 
1783
 * Send NTLMSSP message.
 
1784
 * @param ntlmssp
 
1785
 * @param s
 
1786
 * @return
 
1787
 */
 
1788
 
 
1789
int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s)
 
1790
{
 
1791
        if (ntlmssp->state == NTLMSSP_STATE_INITIAL)
 
1792
                ntlmssp->state = NTLMSSP_STATE_NEGOTIATE;
 
1793
 
 
1794
        if (ntlmssp->state == NTLMSSP_STATE_NEGOTIATE)
 
1795
                ntlmssp_send_negotiate_message(ntlmssp, s);
 
1796
        else if (ntlmssp->state == NTLMSSP_STATE_AUTHENTICATE)
 
1797
                ntlmssp_send_authenticate_message(ntlmssp, s);
 
1798
 
 
1799
        return (ntlmssp->state == NTLMSSP_STATE_FINAL) ? 0 : 1;
 
1800
}
 
1801
 
 
1802
/**
 
1803
 * Receive NTLMSSP message.
 
1804
 * @param ntlmssp
 
1805
 * @param s
 
1806
 * @return
 
1807
 */
 
1808
 
 
1809
int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s)
 
1810
{
 
1811
        char signature[8]; /* Signature, "NTLMSSP" */
 
1812
        uint32 messageType; /* MessageType */
 
1813
 
 
1814
        stream_read(s, signature, 8);
 
1815
        stream_read_uint32(s, messageType);
 
1816
 
 
1817
        if (messageType == 2 && ntlmssp->state == NTLMSSP_STATE_CHALLENGE)
 
1818
                ntlmssp_recv_challenge_message(ntlmssp, s);
 
1819
 
 
1820
        return 1;
 
1821
}
 
1822
 
 
1823
/**
 
1824
 * Create new NTLMSSP state machine instance.
 
1825
 * @return
 
1826
 */
 
1827
 
 
1828
NTLMSSP* ntlmssp_new()
 
1829
{
 
1830
        NTLMSSP* ntlmssp = (NTLMSSP*) xmalloc(sizeof(NTLMSSP));
 
1831
 
 
1832
        if (ntlmssp != NULL)
 
1833
        {
 
1834
                memset(ntlmssp, '\0', sizeof(NTLMSSP));
 
1835
                ntlmssp->av_pairs = (AV_PAIRS*) xmalloc(sizeof(AV_PAIRS));
 
1836
                memset(ntlmssp->av_pairs, 0, sizeof(AV_PAIRS));
 
1837
                ntlmssp_init(ntlmssp);
 
1838
        }
 
1839
 
 
1840
        return ntlmssp;
 
1841
}
 
1842
 
 
1843
/**
 
1844
 * Initialize NTLMSSP state machine.
 
1845
 * @param ntlmssp
 
1846
 */
 
1847
 
 
1848
void ntlmssp_init(NTLMSSP* ntlmssp)
 
1849
{
 
1850
        ntlmssp->state = NTLMSSP_STATE_INITIAL;
 
1851
        ntlmssp->uniconv = freerdp_uniconv_new();
 
1852
}
 
1853
 
 
1854
/**
 
1855
 * Finalize NTLMSSP state machine.
 
1856
 * @param ntlmssp
 
1857
 */
 
1858
 
 
1859
void ntlmssp_uninit(NTLMSSP* ntlmssp)
 
1860
{
 
1861
        freerdp_blob_free(&ntlmssp->username);
 
1862
        freerdp_blob_free(&ntlmssp->password);
 
1863
        freerdp_blob_free(&ntlmssp->domain);
 
1864
 
 
1865
        freerdp_blob_free(&ntlmssp->spn);
 
1866
        freerdp_blob_free(&ntlmssp->workstation);
 
1867
        freerdp_blob_free(&ntlmssp->target_info);
 
1868
        freerdp_blob_free(&ntlmssp->target_name);
 
1869
 
 
1870
        freerdp_blob_free(&ntlmssp->negotiate_message);
 
1871
        freerdp_blob_free(&ntlmssp->challenge_message);
 
1872
        freerdp_blob_free(&ntlmssp->authenticate_message);
 
1873
 
 
1874
        freerdp_blob_free(&ntlmssp->lm_challenge_response);
 
1875
        freerdp_blob_free(&ntlmssp->nt_challenge_response);
 
1876
 
 
1877
        ntlmssp_free_av_pairs(ntlmssp);
 
1878
        freerdp_uniconv_free(ntlmssp->uniconv);
 
1879
 
 
1880
        ntlmssp->state = NTLMSSP_STATE_FINAL;
 
1881
}
 
1882
 
 
1883
/**
 
1884
 * Free NTLMSSP state machine.
 
1885
 * @param ntlmssp
 
1886
 */
 
1887
 
 
1888
void ntlmssp_free(NTLMSSP* ntlmssp)
 
1889
{
 
1890
        ntlmssp_uninit(ntlmssp);
 
1891
 
 
1892
        if (ntlmssp->send_rc4_seal)
 
1893
                crypto_rc4_free(ntlmssp->send_rc4_seal);
 
1894
        if (ntlmssp->recv_rc4_seal)
 
1895
                crypto_rc4_free(ntlmssp->recv_rc4_seal);
 
1896
        xfree(ntlmssp);
 
1897
}