NLA identity now a pointer, allowing NULL.
[platform/upstream/freerdp.git] / libfreerdp / core / nla.c
1 /**
2  * WinPR: Windows Portable Runtime
3  * Network Level Authentication (NLA)
4  *
5  * Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2015 Thincast Technologies GmbH
7  * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *               http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <time.h>
27
28 #ifndef _WIN32
29 #include <unistd.h>
30 #endif
31
32 #include <freerdp/log.h>
33 #include <freerdp/crypto/tls.h>
34
35 #include <winpr/crt.h>
36 #include <winpr/sspi.h>
37 #include <winpr/print.h>
38 #include <winpr/tchar.h>
39 #include <winpr/dsparse.h>
40 #include <winpr/library.h>
41 #include <winpr/registry.h>
42
43 #include "nla.h"
44
45 #define TAG FREERDP_TAG("core.nla")
46
47 /**
48  * TSRequest ::= SEQUENCE {
49  *      version    [0] INTEGER,
50  *      negoTokens [1] NegoData OPTIONAL,
51  *      authInfo   [2] OCTET STRING OPTIONAL,
52  *      pubKeyAuth [3] OCTET STRING OPTIONAL
53  * }
54  *
55  * NegoData ::= SEQUENCE OF NegoDataItem
56  *
57  * NegoDataItem ::= SEQUENCE {
58  *      negoToken [0] OCTET STRING
59  * }
60  *
61  * TSCredentials ::= SEQUENCE {
62  *      credType    [0] INTEGER,
63  *      credentials [1] OCTET STRING
64  * }
65  *
66  * TSPasswordCreds ::= SEQUENCE {
67  *      domainName  [0] OCTET STRING,
68  *      userName    [1] OCTET STRING,
69  *      password    [2] OCTET STRING
70  * }
71  *
72  * TSSmartCardCreds ::= SEQUENCE {
73  *      pin        [0] OCTET STRING,
74  *      cspData    [1] TSCspDataDetail,
75  *      userHint   [2] OCTET STRING OPTIONAL,
76  *      domainHint [3] OCTET STRING OPTIONAL
77  * }
78  *
79  * TSCspDataDetail ::= SEQUENCE {
80  *      keySpec       [0] INTEGER,
81  *      cardName      [1] OCTET STRING OPTIONAL,
82  *      readerName    [2] OCTET STRING OPTIONAL,
83  *      containerName [3] OCTET STRING OPTIONAL,
84  *      cspName       [4] OCTET STRING OPTIONAL
85  * }
86  *
87  */
88
89 #define NLA_PKG_NAME    NEGOSSP_NAME
90
91 #define TERMSRV_SPN_PREFIX      "TERMSRV/"
92
93 static BOOL nla_send(rdpNla* nla);
94 static int nla_recv(rdpNla* nla);
95 static void nla_buffer_print(rdpNla* nla);
96 static void nla_buffer_free(rdpNla* nla);
97 static SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla);
98 static SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla);
99 static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla);
100 static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla);
101 static BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s);
102
103 #define ber_sizeof_sequence_octet_string(length) ber_sizeof_contextual_tag(ber_sizeof_octet_string(length)) + ber_sizeof_octet_string(length)
104 #define ber_write_sequence_octet_string(stream, context, value, length) ber_write_contextual_tag(stream, context, ber_sizeof_octet_string(length), TRUE) + ber_write_octet_string(stream, value, length)
105
106 /**
107  * Initialize NTLMSSP authentication module (client).
108  * @param credssp
109  */
110
111 int nla_client_init(rdpNla* nla)
112 {
113         char* spn;
114         int length;
115         rdpTls* tls = NULL;
116         BOOL PromptPassword = FALSE;
117         freerdp* instance = nla->instance;
118         rdpSettings* settings = nla->settings;
119
120         nla->state = NLA_STATE_INITIAL;
121
122         if (settings->RestrictedAdminModeRequired)
123                 settings->DisableCredentialsDelegation = TRUE;
124
125         if ((!settings->Password) || (!settings->Username)
126                         || (!strlen(settings->Password)) || (!strlen(settings->Username)))
127         {
128                 PromptPassword = TRUE;
129         }
130
131 #ifndef _WIN32
132         if (PromptPassword)
133         {
134                 if (settings->RestrictedAdminModeRequired)
135                 {
136                         if ((settings->PasswordHash) && (strlen(settings->PasswordHash) > 0))
137                                 PromptPassword = FALSE;
138                 }
139         }
140 #endif
141
142         if (PromptPassword)
143         {
144                 if (instance->Authenticate)
145                 {
146                         BOOL proceed = instance->Authenticate(instance,
147                                                 &settings->Username, &settings->Password, &settings->Domain);
148
149                         if (!proceed)
150                         {
151                                 freerdp_set_last_error(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
152                                 return 0;
153                         }
154                 }
155         }
156
157         if (!settings->Username)
158         {
159                 free (nla->identity);
160                 nla->identity = NULL;
161         }
162         else
163                 sspi_SetAuthIdentity(nla->identity, settings->Username, settings->Domain,
164                         settings->Password);
165
166 #ifndef _WIN32
167         {
168                 SEC_WINNT_AUTH_IDENTITY* identity = nla->identity;
169
170                 if (settings->RestrictedAdminModeRequired)
171                 {
172                         if (settings->PasswordHash)
173                         {
174                                 if (strlen(settings->PasswordHash) == 32)
175                                 {
176                                         free(identity->Password);
177
178                                         identity->PasswordLength = ConvertToUnicode(CP_UTF8, 0,
179                                                         settings->PasswordHash, -1, &identity->Password, 0) - 1;
180                                         /**
181                                          * Multiply password hash length by 64 to obtain a length exceeding
182                                          * the maximum (256) and use it this for hash identification in WinPR.
183                                          */
184                                         identity->PasswordLength = 32 * 64; /* 2048 */
185                                 }
186                         }
187                 }
188         }
189 #endif
190
191         tls = nla->transport->tls;
192
193         if (!tls)
194         {
195                 WLog_ERR(TAG, "Unknown NLA transport layer");
196                 return -1;
197         }
198
199         if (!sspi_SecBufferAlloc(&nla->PublicKey, tls->PublicKeyLength))
200         {
201                 WLog_ERR(TAG, "Failed to allocate sspic secBuffer");
202                 return -1;
203         }
204         CopyMemory(nla->PublicKey.pvBuffer, tls->PublicKey, tls->PublicKeyLength);
205         length = sizeof(TERMSRV_SPN_PREFIX) + strlen(settings->ServerHostname);
206
207         spn = (SEC_CHAR*) malloc(length + 1);
208
209         if (!spn)
210                 return -1;
211
212         sprintf(spn, "%s%s", TERMSRV_SPN_PREFIX, settings->ServerHostname);
213
214 #ifdef UNICODE
215         nla->ServicePrincipalName = NULL;
216         ConvertToUnicode(CP_UTF8, 0, spn, -1, &nla->ServicePrincipalName, 0);
217         free(spn);
218 #else
219         nla->ServicePrincipalName = spn;
220 #endif
221
222         nla->table = InitSecurityInterfaceEx(SSPI_INTERFACE_WINPR);
223         nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo);
224
225         if (nla->status != SEC_E_OK)
226         {
227                 WLog_ERR(TAG, "QuerySecurityPackageInfo status: 0x%08X", nla->status);
228                 return -1;
229         }
230
231         nla->cbMaxToken = nla->pPackageInfo->cbMaxToken;
232         nla->status = nla->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME,
233                         SECPKG_CRED_OUTBOUND, NULL, nla->identity, NULL, NULL, &nla->credentials,
234                         &nla->expiration);
235
236         if (nla->status != SEC_E_OK)
237         {
238                 WLog_ERR(TAG, "AcquireCredentialsHandle status: 0x%08X", nla->status);
239                 return -1;
240         }
241
242         nla->haveContext = FALSE;
243         nla->haveInputBuffer = FALSE;
244         nla->havePubKeyAuth = FALSE;
245         ZeroMemory(&nla->inputBuffer, sizeof(SecBuffer));
246         ZeroMemory(&nla->outputBuffer, sizeof(SecBuffer));
247         ZeroMemory(&nla->ContextSizes, sizeof(SecPkgContext_Sizes));
248
249         /*
250          * from tspkg.dll: 0x00000132
251          * ISC_REQ_MUTUAL_AUTH
252          * ISC_REQ_CONFIDENTIALITY
253          * ISC_REQ_USE_SESSION_KEY
254          * ISC_REQ_ALLOCATE_MEMORY
255          */
256         nla->fContextReq = ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY;
257
258         return 1;
259 }
260
261 int nla_client_begin(rdpNla* nla)
262 {
263         if (nla_client_init(nla) < 1)
264                 return -1;
265
266         if (nla->state != NLA_STATE_INITIAL)
267                 return -1;
268
269         nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
270         nla->outputBufferDesc.cBuffers = 1;
271         nla->outputBufferDesc.pBuffers = &nla->outputBuffer;
272         nla->outputBuffer.BufferType = SECBUFFER_TOKEN;
273         nla->outputBuffer.cbBuffer = nla->cbMaxToken;
274         nla->outputBuffer.pvBuffer = malloc(nla->outputBuffer.cbBuffer);
275
276         if (!nla->outputBuffer.pvBuffer)
277                 return -1;
278
279         nla->status = nla->table->InitializeSecurityContext(&nla->credentials,
280                         NULL, nla->ServicePrincipalName, nla->fContextReq, 0,
281                         SECURITY_NATIVE_DREP, NULL, 0, &nla->context,
282                         &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration);
283
284         if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
285         {
286                 if (nla->table->CompleteAuthToken)
287                         nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc);
288
289                 if (nla->status == SEC_I_COMPLETE_NEEDED)
290                         nla->status = SEC_E_OK;
291                 else if (nla->status == SEC_I_COMPLETE_AND_CONTINUE)
292                         nla->status = SEC_I_CONTINUE_NEEDED;
293         }
294
295         if (nla->status != SEC_I_CONTINUE_NEEDED)
296                 return -1;
297
298         if (nla->outputBuffer.cbBuffer < 1)
299                 return -1;
300
301         nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
302         nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
303
304         WLog_DBG(TAG, "Sending Authentication Token");
305         winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);
306
307         if (!nla_send(nla))
308         {
309                 nla_buffer_free(nla);
310                 return -1;
311         }
312
313         nla_buffer_free(nla);
314
315         nla->state = NLA_STATE_NEGO_TOKEN;
316
317         return 1;
318 }
319
320 int nla_client_recv(rdpNla* nla)
321 {
322         int status = -1;
323
324         if (nla->state == NLA_STATE_NEGO_TOKEN)
325         {
326                 nla->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
327                 nla->inputBufferDesc.cBuffers = 1;
328                 nla->inputBufferDesc.pBuffers = &nla->inputBuffer;
329                 nla->inputBuffer.BufferType = SECBUFFER_TOKEN;
330                 nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer;
331                 nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer;
332
333                 nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
334                 nla->outputBufferDesc.cBuffers = 1;
335                 nla->outputBufferDesc.pBuffers = &nla->outputBuffer;
336                 nla->outputBuffer.BufferType = SECBUFFER_TOKEN;
337                 nla->outputBuffer.cbBuffer = nla->cbMaxToken;
338                 nla->outputBuffer.pvBuffer = malloc(nla->outputBuffer.cbBuffer);
339
340                 if (!nla->outputBuffer.pvBuffer)
341                         return -1;
342
343                 nla->status = nla->table->InitializeSecurityContext(&nla->credentials,
344                                 &nla->context, nla->ServicePrincipalName, nla->fContextReq, 0,
345                                 SECURITY_NATIVE_DREP, &nla->inputBufferDesc,
346                                 0, &nla->context, &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration);
347
348                 free(nla->inputBuffer.pvBuffer);
349                 nla->inputBuffer.pvBuffer = NULL;
350
351                 if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
352                 {
353                         if (nla->table->CompleteAuthToken)
354                                 nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc);
355
356                         if (nla->status == SEC_I_COMPLETE_NEEDED)
357                                 nla->status = SEC_E_OK;
358                         else if (nla->status == SEC_I_COMPLETE_AND_CONTINUE)
359                                 nla->status = SEC_I_CONTINUE_NEEDED;
360                 }
361
362                 if (nla->status == SEC_E_OK)
363                 {
364                         nla->havePubKeyAuth = TRUE;
365
366                         if (nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES, &nla->ContextSizes) != SEC_E_OK)
367                         {
368                                 WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure");
369                                 return -1;
370                         }
371
372                         nla_encrypt_public_key_echo(nla);
373                 }
374
375                 if (nla->outputBuffer.cbBuffer < 1)
376                         return -1;
377
378                 nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
379                 nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
380
381                 WLog_DBG(TAG, "Sending Authentication Token");
382                 winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);
383
384                 if (!nla_send(nla))
385                 {
386                         nla_buffer_free(nla);
387                         return -1;
388                 }
389                 nla_buffer_free(nla);
390
391                 nla->state = NLA_STATE_PUB_KEY_AUTH;
392                 status = 1;
393         }
394         else if (nla->state == NLA_STATE_PUB_KEY_AUTH)
395         {
396                 /* Verify Server Public Key Echo */
397                 nla->status = nla_decrypt_public_key_echo(nla);
398                 nla_buffer_free(nla);
399
400                 if (nla->status != SEC_E_OK)
401                 {
402                         WLog_ERR(TAG, "Could not verify public key echo!");
403                         return -1;
404                 }
405
406                 /* Send encrypted credentials */
407                 nla->status = nla_encrypt_ts_credentials(nla);
408
409                 if (nla->status != SEC_E_OK)
410                 {
411                         WLog_ERR(TAG, "nla_encrypt_ts_credentials status: 0x%08X", nla->status);
412                         return -1;
413                 }
414
415                 if (!nla_send(nla))
416                 {
417                         nla_buffer_free(nla);
418                         return -1;
419                 }
420                 nla_buffer_free(nla);
421
422                 nla->table->FreeCredentialsHandle(&nla->credentials);
423                 nla->table->FreeContextBuffer(nla->pPackageInfo);
424
425                 nla->state = NLA_STATE_AUTH_INFO;
426                 status = 1;
427         }
428
429         return status;
430 }
431
432 int nla_client_authenticate(rdpNla* nla)
433 {
434         wStream* s;
435         int status;
436
437         s = Stream_New(NULL, 4096);
438
439         if (!s)
440         {
441                 WLog_ERR(TAG, "Stream_New failed!");
442                 return -1;
443         }
444
445         if (nla_client_begin(nla) < 1)
446                 return -1;
447
448         while (nla->state < NLA_STATE_AUTH_INFO)
449         {
450                 Stream_SetPosition(s, 0);
451
452                 status = transport_read_pdu(nla->transport, s);
453
454                 if (status < 0)
455                 {
456                         WLog_ERR(TAG, "nla_client_authenticate failure");
457                         Stream_Free(s, TRUE);
458                         return -1;
459                 }
460
461                 status = nla_recv_pdu(nla, s);
462
463                 if (status < 0)
464                         return -1;
465         }
466
467         Stream_Free(s, TRUE);
468
469         return 1;
470 }
471
472 /**
473  * Initialize NTLMSSP authentication module (server).
474  * @param credssp
475  */
476
477 int nla_server_init(rdpNla* nla)
478 {
479         rdpTls* tls = nla->transport->tls;
480
481         if (!sspi_SecBufferAlloc(&nla->PublicKey, tls->PublicKeyLength))
482         {
483                 WLog_ERR(TAG, "Failed to allocate SecBuffer for public key");
484                 return -1;
485         }
486         CopyMemory(nla->PublicKey.pvBuffer, tls->PublicKey, tls->PublicKeyLength);
487
488         if (nla->SspiModule)
489         {
490                 HMODULE hSSPI;
491                 INIT_SECURITY_INTERFACE pInitSecurityInterface;
492
493                 hSSPI = LoadLibrary(nla->SspiModule);
494
495                 if (!hSSPI)
496                 {
497                         WLog_ERR(TAG, "Failed to load SSPI module: %s", nla->SspiModule);
498                         return -1;
499                 }
500
501 #ifdef UNICODE
502                 pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW");
503 #else
504                 pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA");
505 #endif
506                 nla->table = pInitSecurityInterface();
507         }
508         else
509         {
510                 nla->table = InitSecurityInterfaceEx(0);
511         }
512
513         nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo);
514
515         if (nla->status != SEC_E_OK)
516         {
517                 WLog_ERR(TAG, "QuerySecurityPackageInfo status: 0x%08X", nla->status);
518                 return -1;
519         }
520
521         nla->cbMaxToken = nla->pPackageInfo->cbMaxToken;
522         nla->status = nla->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME,
523                          SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &nla->credentials, &nla->expiration);
524
525         if (nla->status != SEC_E_OK)
526         {
527                 WLog_ERR(TAG, "AcquireCredentialsHandle status: 0x%08X", nla->status);
528                 return -1;
529         }
530
531         nla->haveContext = FALSE;
532         nla->haveInputBuffer = FALSE;
533         nla->havePubKeyAuth = FALSE;
534         ZeroMemory(&nla->inputBuffer, sizeof(SecBuffer));
535         ZeroMemory(&nla->outputBuffer, sizeof(SecBuffer));
536         ZeroMemory(&nla->inputBufferDesc, sizeof(SecBufferDesc));
537         ZeroMemory(&nla->outputBufferDesc, sizeof(SecBufferDesc));
538         ZeroMemory(&nla->ContextSizes, sizeof(SecPkgContext_Sizes));
539
540         /*
541          * from tspkg.dll: 0x00000112
542          * ASC_REQ_MUTUAL_AUTH
543          * ASC_REQ_CONFIDENTIALITY
544          * ASC_REQ_ALLOCATE_MEMORY
545          */
546         nla->fContextReq = 0;
547         nla->fContextReq |= ASC_REQ_MUTUAL_AUTH;
548         nla->fContextReq |= ASC_REQ_CONFIDENTIALITY;
549         nla->fContextReq |= ASC_REQ_CONNECTION;
550         nla->fContextReq |= ASC_REQ_USE_SESSION_KEY;
551         nla->fContextReq |= ASC_REQ_REPLAY_DETECT;
552         nla->fContextReq |= ASC_REQ_SEQUENCE_DETECT;
553         nla->fContextReq |= ASC_REQ_EXTENDED_ERROR;
554
555         return 1;
556 }
557
558 /**
559  * Authenticate with client using CredSSP (server).
560  * @param credssp
561  * @return 1 if authentication is successful
562  */
563
564 int nla_server_authenticate(rdpNla* nla)
565 {
566         if (nla_server_init(nla) < 1)
567                 return -1;
568
569         while (TRUE)
570         {
571                 /* receive authentication token */
572                 nla->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
573                 nla->inputBufferDesc.cBuffers = 1;
574                 nla->inputBufferDesc.pBuffers = &nla->inputBuffer;
575                 nla->inputBuffer.BufferType = SECBUFFER_TOKEN;
576
577                 if (nla_recv(nla) < 0)
578                         return -1;
579
580                 WLog_DBG(TAG, "Receiving Authentication Token");
581                 nla_buffer_print(nla);
582
583                 nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer;
584                 nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer;
585
586                 if (nla->negoToken.cbBuffer < 1)
587                 {
588                         WLog_ERR(TAG, "CredSSP: invalid negoToken!");
589                         return -1;
590                 }
591
592                 nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
593                 nla->outputBufferDesc.cBuffers = 1;
594                 nla->outputBufferDesc.pBuffers = &nla->outputBuffer;
595                 nla->outputBuffer.BufferType = SECBUFFER_TOKEN;
596                 nla->outputBuffer.cbBuffer = nla->cbMaxToken;
597                 nla->outputBuffer.pvBuffer = malloc(nla->outputBuffer.cbBuffer);
598
599                 if (!nla->outputBuffer.pvBuffer)
600                         return -1;
601
602                 nla->status = nla->table->AcceptSecurityContext(&nla->credentials,
603                                 nla-> haveContext? &nla->context: NULL,
604                                  &nla->inputBufferDesc, nla->fContextReq, SECURITY_NATIVE_DREP, &nla->context,
605                                  &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration);
606
607                 nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
608                 nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
609
610                 if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
611                 {
612                         if (nla->table->CompleteAuthToken)
613                                 nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc);
614
615                         if (nla->status == SEC_I_COMPLETE_NEEDED)
616                                 nla->status = SEC_E_OK;
617                         else if (nla->status == SEC_I_COMPLETE_AND_CONTINUE)
618                                 nla->status = SEC_I_CONTINUE_NEEDED;
619                 }
620
621                 if (nla->status == SEC_E_OK)
622                 {
623                         nla->havePubKeyAuth = TRUE;
624
625                         if (nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES, &nla->ContextSizes) != SEC_E_OK)
626                         {
627                                 WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure");
628                                 return -1;
629                         }
630
631                         if (nla_decrypt_public_key_echo(nla) != SEC_E_OK)
632                         {
633                                 WLog_ERR(TAG, "Error: could not verify client's public key echo");
634                                 return -1;
635                         }
636
637                         sspi_SecBufferFree(&nla->negoToken);
638                         nla->negoToken.pvBuffer = NULL;
639                         nla->negoToken.cbBuffer = 0;
640                         nla_encrypt_public_key_echo(nla);
641                 }
642
643                 if ((nla->status != SEC_E_OK) && (nla->status != SEC_I_CONTINUE_NEEDED))
644                 {
645                         WLog_ERR(TAG, "AcceptSecurityContext status: 0x%08X", nla->status);
646                         return -1; /* Access Denied */
647                 }
648
649                 /* send authentication token */
650
651                 WLog_DBG(TAG, "Sending Authentication Token");
652                 nla_buffer_print(nla);
653
654                 if (!nla_send(nla))
655                 {
656                         nla_buffer_free(nla);
657                         return -1;
658                 }
659                 nla_buffer_free(nla);
660
661                 if (nla->status != SEC_I_CONTINUE_NEEDED)
662                         break;
663
664                 nla->haveContext = TRUE;
665         }
666
667         /* Receive encrypted credentials */
668
669         if (nla_recv(nla) < 0)
670                 return -1;
671
672         if (nla_decrypt_ts_credentials(nla) != SEC_E_OK)
673         {
674                 WLog_ERR(TAG, "Could not decrypt TSCredentials status: 0x%08X", nla->status);
675                 return -1;
676         }
677
678         if (nla->status != SEC_E_OK)
679         {
680                 WLog_ERR(TAG, "AcceptSecurityContext status: 0x%08X", nla->status);
681                 return -1;
682         }
683
684         nla->status = nla->table->ImpersonateSecurityContext(&nla->context);
685
686         if (nla->status != SEC_E_OK)
687         {
688                 WLog_ERR(TAG, "ImpersonateSecurityContext status: 0x%08X", nla->status);
689                 return -1;
690         }
691         else
692         {
693                 nla->status = nla->table->RevertSecurityContext(&nla->context);
694
695                 if (nla->status != SEC_E_OK)
696                 {
697                         WLog_ERR(TAG, "RevertSecurityContext status: 0x%08X", nla->status);
698                         return -1;
699                 }
700         }
701
702         nla->table->FreeContextBuffer(nla->pPackageInfo);
703
704         return 1;
705 }
706
707 /**
708  * Authenticate using CredSSP.
709  * @param credssp
710  * @return 1 if authentication is successful
711  */
712
713 int nla_authenticate(rdpNla* nla)
714 {
715         if (nla->server)
716                 return nla_server_authenticate(nla);
717         else
718                 return nla_client_authenticate(nla);
719 }
720
721 void ap_integer_increment_le(BYTE* number, int size)
722 {
723         int index;
724
725         for (index = 0; index < size; index++)
726         {
727                 if (number[index] < 0xFF)
728                 {
729                         number[index]++;
730                         break;
731                 }
732                 else
733                 {
734                         number[index] = 0;
735                         continue;
736                 }
737         }
738 }
739
740 void ap_integer_decrement_le(BYTE* number, int size)
741 {
742         int index;
743
744         for (index = 0; index < size; index++)
745         {
746                 if (number[index] > 0)
747                 {
748                         number[index]--;
749                         break;
750                 }
751                 else
752                 {
753                         number[index] = 0xFF;
754                         continue;
755                 }
756         }
757 }
758
759 SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla)
760 {
761         SecBuffer Buffers[2];
762         SecBufferDesc Message;
763         SECURITY_STATUS status;
764         int public_key_length;
765
766         public_key_length = nla->PublicKey.cbBuffer;
767         if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, nla->ContextSizes.cbMaxSignature + public_key_length))
768                 return SEC_E_INSUFFICIENT_MEMORY;
769         Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
770         Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
771         Buffers[0].cbBuffer = nla->ContextSizes.cbMaxSignature;
772         Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
773         Buffers[1].cbBuffer = public_key_length;
774         Buffers[1].pvBuffer = ((BYTE*) nla->pubKeyAuth.pvBuffer) + nla->ContextSizes.cbMaxSignature;
775         CopyMemory(Buffers[1].pvBuffer, nla->PublicKey.pvBuffer, Buffers[1].cbBuffer);
776
777         if (nla->server)
778         {
779                 /* server echos the public key +1 */
780                 ap_integer_increment_le((BYTE*) Buffers[1].pvBuffer, Buffers[1].cbBuffer);
781         }
782
783         Message.cBuffers = 2;
784         Message.ulVersion = SECBUFFER_VERSION;
785         Message.pBuffers = (PSecBuffer) &Buffers;
786         status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++);
787
788         if (status != SEC_E_OK)
789         {
790                 WLog_ERR(TAG, "EncryptMessage status: 0x%08X", status);
791                 return status;
792         }
793
794         return status;
795 }
796
797 SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
798 {
799         int length;
800         BYTE* buffer;
801         ULONG pfQOP = 0;
802         BYTE* public_key1;
803         BYTE* public_key2;
804         int public_key_length;
805         SecBuffer Buffers[2];
806         SecBufferDesc Message;
807         SECURITY_STATUS status;
808
809         if ((nla->PublicKey.cbBuffer + nla->ContextSizes.cbMaxSignature) != nla->pubKeyAuth.cbBuffer)
810         {
811                 WLog_ERR(TAG, "unexpected pubKeyAuth buffer size: %d", (int) nla->pubKeyAuth.cbBuffer);
812                 return SEC_E_INVALID_TOKEN;
813         }
814
815         length = nla->pubKeyAuth.cbBuffer;
816         buffer = (BYTE*) malloc(length);
817
818         if (!buffer)
819                 return SEC_E_INSUFFICIENT_MEMORY;
820
821         CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
822         public_key_length = nla->PublicKey.cbBuffer;
823         Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
824         Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */
825         Buffers[0].cbBuffer = nla->ContextSizes.cbMaxSignature;
826         Buffers[0].pvBuffer = buffer;
827         Buffers[1].cbBuffer = length - nla->ContextSizes.cbMaxSignature;
828         Buffers[1].pvBuffer = buffer + nla->ContextSizes.cbMaxSignature;
829         Message.cBuffers = 2;
830         Message.ulVersion = SECBUFFER_VERSION;
831         Message.pBuffers = (PSecBuffer) &Buffers;
832         status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
833
834         if (status != SEC_E_OK)
835         {
836                 WLog_ERR(TAG, "DecryptMessage failure: 0x%08X", status);
837                 return status;
838         }
839
840         public_key1 = (BYTE*) nla->PublicKey.pvBuffer;
841         public_key2 = (BYTE*) Buffers[1].pvBuffer;
842
843         if (!nla->server)
844         {
845                 /* server echos the public key +1 */
846                 ap_integer_decrement_le(public_key2, public_key_length);
847         }
848
849         if (memcmp(public_key1, public_key2, public_key_length) != 0)
850         {
851                 WLog_ERR(TAG, "Could not verify server's public key echo");
852                 WLog_ERR(TAG, "Expected (length = %d):", public_key_length);
853                 winpr_HexDump(TAG, WLOG_ERROR, public_key1, public_key_length);
854                 WLog_ERR(TAG, "Actual (length = %d):", public_key_length);
855                 winpr_HexDump(TAG, WLOG_ERROR, public_key2, public_key_length);
856                 return SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */
857         }
858
859         free(buffer);
860         return SEC_E_OK;
861 }
862
863 int nla_sizeof_ts_password_creds(rdpNla* nla)
864 {
865         int length = 0;
866         if (nla->identity)
867         {
868                 length += ber_sizeof_sequence_octet_string(nla->identity->DomainLength * 2);
869                 length += ber_sizeof_sequence_octet_string(nla->identity->UserLength * 2);
870                 length += ber_sizeof_sequence_octet_string(nla->identity->PasswordLength * 2);
871         }
872         return length;
873 }
874
875 BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s)
876 {
877         int length;
878
879         if (!nla->identity)
880         {
881                 WLog_ERR(TAG, "nla->identity is NULL!");
882                 return FALSE;
883         }
884
885         /* TSPasswordCreds (SEQUENCE) */
886         ber_read_sequence_tag(s, &length);
887
888         /* [0] domainName (OCTET STRING) */
889         ber_read_contextual_tag(s, 0, &length, TRUE);
890         ber_read_octet_string_tag(s, &length);
891         nla->identity->DomainLength = (UINT32) length;
892         nla->identity->Domain = (UINT16*) malloc(length);
893         CopyMemory(nla->identity->Domain, Stream_Pointer(s), nla->identity->DomainLength);
894         Stream_Seek(s, nla->identity->DomainLength);
895         nla->identity->DomainLength /= 2;
896
897         /* [1] userName (OCTET STRING) */
898         ber_read_contextual_tag(s, 1, &length, TRUE);
899         ber_read_octet_string_tag(s, &length);
900         nla->identity->UserLength = (UINT32) length;
901         nla->identity->User = (UINT16*) malloc(length);
902         CopyMemory(nla->identity->User, Stream_Pointer(s), nla->identity->UserLength);
903         Stream_Seek(s, nla->identity->UserLength);
904         nla->identity->UserLength /= 2;
905
906         /* [2] password (OCTET STRING) */
907         ber_read_contextual_tag(s, 2, &length, TRUE);
908         ber_read_octet_string_tag(s, &length);
909         nla->identity->PasswordLength = (UINT32) length;
910         nla->identity->Password = (UINT16*) malloc(length);
911         CopyMemory(nla->identity->Password, Stream_Pointer(s), nla->identity->PasswordLength);
912         Stream_Seek(s, nla->identity->PasswordLength);
913         nla->identity->PasswordLength /= 2;
914         nla->identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
915
916         return TRUE;
917 }
918
919 int nla_write_ts_password_creds(rdpNla* nla, wStream* s)
920 {
921         int size = 0;
922         int innerSize = nla_sizeof_ts_password_creds(nla);
923         /* TSPasswordCreds (SEQUENCE) */
924         size += ber_write_sequence_tag(s, innerSize);
925         if (nla->identity)
926         {
927                 /* [0] domainName (OCTET STRING) */
928                 size += ber_write_sequence_octet_string(
929                                 s, 0, (BYTE*) nla->identity->Domain,
930                                 nla->identity->DomainLength * 2);
931                 /* [1] userName (OCTET STRING) */
932                 size += ber_write_sequence_octet_string(
933                                 s, 1, (BYTE*) nla->identity->User,
934                                 nla->identity->UserLength * 2);
935                 /* [2] password (OCTET STRING) */
936                 size += ber_write_sequence_octet_string(
937                                 s, 2, (BYTE*) nla->identity->Password,
938                                 nla->identity->PasswordLength * 2);
939         }
940         return size;
941 }
942
943 int nla_sizeof_ts_credentials(rdpNla* nla)
944 {
945         int size = 0;
946         size += ber_sizeof_integer(1);
947         size += ber_sizeof_contextual_tag(ber_sizeof_integer(1));
948         size += ber_sizeof_sequence_octet_string(ber_sizeof_sequence(nla_sizeof_ts_password_creds(nla)));
949         return size;
950 }
951
952 static BOOL nla_read_ts_credentials(rdpNla* nla, PSecBuffer ts_credentials)
953 {
954         BOOL rc;
955         wStream* s;
956         int length;
957         int ts_password_creds_length;
958
959         s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer);
960
961         if (!s)
962         {
963                 WLog_ERR(TAG, "Stream_New failed!");
964                 return FALSE;
965         }
966
967
968         /* TSCredentials (SEQUENCE) */
969         ber_read_sequence_tag(s, &length);
970
971         /* [0] credType (INTEGER) */
972         ber_read_contextual_tag(s, 0, &length, TRUE);
973         ber_read_integer(s, NULL);
974
975         /* [1] credentials (OCTET STRING) */
976         ber_read_contextual_tag(s, 1, &length, TRUE);
977         ber_read_octet_string_tag(s, &ts_password_creds_length);
978
979         rc = nla_read_ts_password_creds(nla, s);
980
981         Stream_Free(s, FALSE);
982         return rc;
983 }
984
985 int nla_write_ts_credentials(rdpNla* nla, wStream* s)
986 {
987         int size = 0;
988         int passwordSize;
989         int innerSize = nla_sizeof_ts_credentials(nla);
990
991         /* TSCredentials (SEQUENCE) */
992         size += ber_write_sequence_tag(s, innerSize);
993
994         /* [0] credType (INTEGER) */
995         size += ber_write_contextual_tag(s, 0, ber_sizeof_integer(1), TRUE);
996         size += ber_write_integer(s, 1);
997
998         /* [1] credentials (OCTET STRING) */
999         passwordSize = ber_sizeof_sequence(nla_sizeof_ts_password_creds(nla));
1000         size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), TRUE);
1001         size += ber_write_octet_string_tag(s, passwordSize);
1002         size += nla_write_ts_password_creds(nla, s);
1003
1004         return size;
1005 }
1006
1007 /**
1008  * Encode TSCredentials structure.
1009  * @param credssp
1010  */
1011
1012 BOOL nla_encode_ts_credentials(rdpNla* nla)
1013 {
1014         wStream* s;
1015         int length;
1016         int DomainLength = 0;
1017         int UserLength = 0;
1018         int PasswordLength = 0;
1019
1020         if (nla->identity)
1021         {
1022                 DomainLength = nla->identity->DomainLength;
1023                 UserLength = nla->identity->UserLength;
1024                 PasswordLength = nla->identity->PasswordLength;
1025         }
1026
1027         if (nla->settings->DisableCredentialsDelegation && nla->identity)
1028         {
1029                 nla->identity->DomainLength = 0;
1030                 nla->identity->UserLength = 0;
1031                 nla->identity->PasswordLength = 0;
1032         }
1033
1034         length = ber_sizeof_sequence(nla_sizeof_ts_credentials(nla));
1035         if (!sspi_SecBufferAlloc(&nla->tsCredentials, length))
1036         {
1037                 WLog_ERR(TAG, "sspi_SecBufferAlloc failed!");
1038                 return FALSE;
1039         }
1040         s = Stream_New((BYTE*) nla->tsCredentials.pvBuffer, length);
1041
1042         if (!s)
1043         {
1044                 sspi_SecBufferFree(&nla->tsCredentials);
1045                 WLog_ERR(TAG, "Stream_New failed!");
1046                 return FALSE;
1047         }
1048
1049         nla_write_ts_credentials(nla, s);
1050
1051         if (nla->settings->DisableCredentialsDelegation)
1052         {
1053                 nla->identity->DomainLength = DomainLength;
1054                 nla->identity->UserLength = UserLength;
1055                 nla->identity->PasswordLength = PasswordLength;
1056         }
1057
1058         Stream_Free(s, FALSE);
1059         return TRUE;
1060 }
1061
1062 SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla)
1063 {
1064         SecBuffer Buffers[2];
1065         SecBufferDesc Message;
1066         SECURITY_STATUS status;
1067
1068         if (!nla_encode_ts_credentials(nla))
1069                 return SEC_E_INSUFFICIENT_MEMORY;
1070
1071         if (!sspi_SecBufferAlloc(&nla->authInfo, nla->ContextSizes.cbMaxSignature + nla->tsCredentials.cbBuffer))
1072                 return SEC_E_INSUFFICIENT_MEMORY;
1073         Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1074         Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
1075         Buffers[0].cbBuffer = nla->ContextSizes.cbMaxSignature;
1076         Buffers[0].pvBuffer = nla->authInfo.pvBuffer;
1077         ZeroMemory(Buffers[0].pvBuffer, Buffers[0].cbBuffer);
1078         Buffers[1].cbBuffer = nla->tsCredentials.cbBuffer;
1079         Buffers[1].pvBuffer = &((BYTE*) nla->authInfo.pvBuffer)[Buffers[0].cbBuffer];
1080         CopyMemory(Buffers[1].pvBuffer, nla->tsCredentials.pvBuffer, Buffers[1].cbBuffer);
1081
1082         Message.cBuffers = 2;
1083         Message.ulVersion = SECBUFFER_VERSION;
1084         Message.pBuffers = (PSecBuffer) &Buffers;
1085
1086         status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++);
1087
1088         if (status != SEC_E_OK)
1089                 return status;
1090
1091         return SEC_E_OK;
1092 }
1093
1094 SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
1095 {
1096         int length;
1097         BYTE* buffer;
1098         ULONG pfQOP;
1099         SecBuffer Buffers[2];
1100         SecBufferDesc Message;
1101         SECURITY_STATUS status;
1102         Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1103         Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
1104
1105         if (nla->authInfo.cbBuffer < 1)
1106         {
1107                 WLog_ERR(TAG, "nla_decrypt_ts_credentials missing authInfo buffer");
1108                 return SEC_E_INVALID_TOKEN;
1109         }
1110
1111         length = nla->authInfo.cbBuffer;
1112         buffer = (BYTE*) malloc(length);
1113
1114         if (!buffer)
1115                 return SEC_E_INSUFFICIENT_MEMORY;
1116
1117         CopyMemory(buffer, nla->authInfo.pvBuffer, length);
1118         Buffers[0].cbBuffer = nla->ContextSizes.cbMaxSignature;
1119         Buffers[0].pvBuffer = buffer;
1120         Buffers[1].cbBuffer = length - nla->ContextSizes.cbMaxSignature;
1121         Buffers[1].pvBuffer = &buffer[nla->ContextSizes.cbMaxSignature];
1122         Message.cBuffers = 2;
1123         Message.ulVersion = SECBUFFER_VERSION;
1124         Message.pBuffers = (PSecBuffer) &Buffers;
1125         status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
1126
1127         if (status != SEC_E_OK)
1128                 return status;
1129
1130         if(!nla_read_ts_credentials(nla, &Buffers[1]))
1131         {
1132                 free(buffer);
1133                 return SEC_E_INSUFFICIENT_MEMORY;
1134         }
1135         free(buffer);
1136
1137         return SEC_E_OK;
1138 }
1139
1140 int nla_sizeof_nego_token(int length)
1141 {
1142         length = ber_sizeof_octet_string(length);
1143         length += ber_sizeof_contextual_tag(length);
1144         return length;
1145 }
1146
1147 int nla_sizeof_nego_tokens(int length)
1148 {
1149         length = nla_sizeof_nego_token(length);
1150         length += ber_sizeof_sequence_tag(length);
1151         length += ber_sizeof_sequence_tag(length);
1152         length += ber_sizeof_contextual_tag(length);
1153         return length;
1154 }
1155
1156 int nla_sizeof_pub_key_auth(int length)
1157 {
1158         length = ber_sizeof_octet_string(length);
1159         length += ber_sizeof_contextual_tag(length);
1160         return length;
1161 }
1162
1163 int nla_sizeof_auth_info(int length)
1164 {
1165         length = ber_sizeof_octet_string(length);
1166         length += ber_sizeof_contextual_tag(length);
1167         return length;
1168 }
1169
1170 int nla_sizeof_ts_request(int length)
1171 {
1172         length += ber_sizeof_integer(2);
1173         length += ber_sizeof_contextual_tag(3);
1174         return length;
1175 }
1176
1177 /**
1178  * Send CredSSP message.
1179  * @param credssp
1180  */
1181
1182 BOOL nla_send(rdpNla* nla)
1183 {
1184         wStream* s;
1185         int length;
1186         int ts_request_length;
1187         int nego_tokens_length;
1188         int pub_key_auth_length;
1189         int auth_info_length;
1190
1191         nego_tokens_length = (nla->negoToken.cbBuffer > 0) ? nla_sizeof_nego_tokens(nla->negoToken.cbBuffer) : 0;
1192         pub_key_auth_length = (nla->pubKeyAuth.cbBuffer > 0) ? nla_sizeof_pub_key_auth(nla->pubKeyAuth.cbBuffer) : 0;
1193         auth_info_length = (nla->authInfo.cbBuffer > 0) ? nla_sizeof_auth_info(nla->authInfo.cbBuffer) : 0;
1194         length = nego_tokens_length + pub_key_auth_length + auth_info_length;
1195         ts_request_length = nla_sizeof_ts_request(length);
1196
1197         s = Stream_New(NULL, ber_sizeof_sequence(ts_request_length));
1198
1199         if (!s)
1200         {
1201                 WLog_ERR(TAG, "Stream_New failed!");
1202                 return FALSE;
1203         }
1204
1205
1206         /* TSRequest */
1207         ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */
1208         /* [0] version */
1209         ber_write_contextual_tag(s, 0, 3, TRUE);
1210         ber_write_integer(s, 2); /* INTEGER */
1211
1212         /* [1] negoTokens (NegoData) */
1213         if (nego_tokens_length > 0)
1214         {
1215                 length = nego_tokens_length;
1216                 length -= ber_write_contextual_tag(s, 1, ber_sizeof_sequence(ber_sizeof_sequence(ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer))), TRUE); /* NegoData */
1217                 length -= ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer))); /* SEQUENCE OF NegoDataItem */
1218                 length -= ber_write_sequence_tag(s, ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer)); /* NegoDataItem */
1219                 length -= ber_write_sequence_octet_string(s, 0, (BYTE*) nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);  /* OCTET STRING */
1220         }
1221
1222         /* [2] authInfo (OCTET STRING) */
1223         if (auth_info_length > 0)
1224         {
1225                 length = auth_info_length;
1226                 length -= ber_write_sequence_octet_string(s, 2, nla->authInfo.pvBuffer, nla->authInfo.cbBuffer);
1227         }
1228
1229         /* [3] pubKeyAuth (OCTET STRING) */
1230         if (pub_key_auth_length > 0)
1231         {
1232                 length = pub_key_auth_length;
1233                 length -= ber_write_sequence_octet_string(s, 3, nla->pubKeyAuth.pvBuffer, nla->pubKeyAuth.cbBuffer);
1234         }
1235
1236         Stream_SealLength(s);
1237         transport_write(nla->transport, s);
1238         Stream_Free(s, TRUE);
1239         return TRUE;
1240 }
1241
1242 int nla_decode_ts_request(rdpNla* nla, wStream* s)
1243 {
1244         int length;
1245         UINT32 version;
1246
1247         /* TSRequest */
1248         if (!ber_read_sequence_tag(s, &length) ||
1249                         !ber_read_contextual_tag(s, 0, &length, TRUE) ||
1250                         !ber_read_integer(s, &version))
1251         {
1252                 Stream_Free(s, TRUE);
1253                 return -1;
1254         }
1255
1256         /* [1] negoTokens (NegoData) */
1257         if (ber_read_contextual_tag(s, 1, &length, TRUE) != FALSE)
1258         {
1259                 if (!ber_read_sequence_tag(s, &length) || /* SEQUENCE OF NegoDataItem */
1260                                 !ber_read_sequence_tag(s, &length) || /* NegoDataItem */
1261                                 !ber_read_contextual_tag(s, 0, &length, TRUE) || /* [0] negoToken */
1262                                 !ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
1263                                 ((int) Stream_GetRemainingLength(s)) < length)
1264                 {
1265                         Stream_Free(s, TRUE);
1266                         return -1;
1267                 }
1268
1269                 if (!sspi_SecBufferAlloc(&nla->negoToken, length))
1270                 {
1271                         Stream_Free(s, TRUE);
1272                         return -1;
1273                 }
1274                 Stream_Read(s, nla->negoToken.pvBuffer, length);
1275                 nla->negoToken.cbBuffer = length;
1276         }
1277
1278         /* [2] authInfo (OCTET STRING) */
1279         if (ber_read_contextual_tag(s, 2, &length, TRUE) != FALSE)
1280         {
1281                 if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
1282                                 ((int) Stream_GetRemainingLength(s)) < length)
1283                 {
1284                         Stream_Free(s, TRUE);
1285                         return -1;
1286                 }
1287
1288                 if (!sspi_SecBufferAlloc(&nla->authInfo, length))
1289                 {
1290                         Stream_Free(s, TRUE);
1291                         return -1;
1292                 }
1293                 Stream_Read(s, nla->authInfo.pvBuffer, length);
1294                 nla->authInfo.cbBuffer = length;
1295         }
1296
1297         /* [3] pubKeyAuth (OCTET STRING) */
1298         if (ber_read_contextual_tag(s, 3, &length, TRUE) != FALSE)
1299         {
1300                 if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
1301                                 ((int) Stream_GetRemainingLength(s)) < length)
1302                 {
1303                         Stream_Free(s, TRUE);
1304                         return -1;
1305                 }
1306
1307                 if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, length))
1308                 {
1309                         Stream_Free(s, TRUE);
1310                         return -1;
1311                 }
1312                 Stream_Read(s, nla->pubKeyAuth.pvBuffer, length);
1313                 nla->pubKeyAuth.cbBuffer = length;
1314         }
1315
1316         return 1;
1317 }
1318
1319 int nla_recv_pdu(rdpNla* nla, wStream* s)
1320 {
1321         if (nla_decode_ts_request(nla, s) < 1)
1322                 return -1;
1323
1324         if (nla_client_recv(nla) < 1)
1325                 return -1;
1326
1327         return 1;
1328 }
1329
1330 int nla_recv(rdpNla* nla)
1331 {
1332         wStream* s;
1333         int status;
1334
1335         s = Stream_New(NULL, 4096);
1336
1337         if (!s)
1338         {
1339                 WLog_ERR(TAG, "Stream_New failed!");
1340                 return -1;
1341         }
1342
1343         status = transport_read_pdu(nla->transport, s);
1344
1345         if (status < 0)
1346         {
1347                 WLog_ERR(TAG, "nla_recv() error: %d", status);
1348                 Stream_Free(s, TRUE);
1349                 return -1;
1350         }
1351
1352         if (nla_decode_ts_request(nla, s) < 1)
1353                 return -1;
1354
1355         Stream_Free(s, TRUE);
1356         return 1;
1357 }
1358
1359 void nla_buffer_print(rdpNla* nla)
1360 {
1361         if (nla->negoToken.cbBuffer > 0)
1362         {
1363                 WLog_DBG(TAG, "NLA.negoToken (length = %d):", (int) nla->negoToken.cbBuffer);
1364                 winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);
1365         }
1366
1367         if (nla->pubKeyAuth.cbBuffer > 0)
1368         {
1369                 WLog_DBG(TAG, "NLA.pubKeyAuth (length = %d):", (int) nla->pubKeyAuth.cbBuffer);
1370                 winpr_HexDump(TAG, WLOG_DEBUG, nla->pubKeyAuth.pvBuffer, nla->pubKeyAuth.cbBuffer);
1371         }
1372
1373         if (nla->authInfo.cbBuffer > 0)
1374         {
1375                 WLog_DBG(TAG, "NLA.authInfo (length = %d):", (int) nla->authInfo.cbBuffer);
1376                 winpr_HexDump(TAG, WLOG_DEBUG, nla->authInfo.pvBuffer, nla->authInfo.cbBuffer);
1377         }
1378 }
1379
1380 void nla_buffer_free(rdpNla* nla)
1381 {
1382         sspi_SecBufferFree(&nla->negoToken);
1383         sspi_SecBufferFree(&nla->pubKeyAuth);
1384         sspi_SecBufferFree(&nla->authInfo);
1385 }
1386
1387 LPTSTR nla_make_spn(const char* ServiceClass, const char* hostname)
1388 {
1389         DWORD status;
1390         DWORD SpnLength;
1391         LPTSTR hostnameX = NULL;
1392         LPTSTR ServiceClassX = NULL;
1393         LPTSTR ServicePrincipalName = NULL;
1394 #ifdef UNICODE
1395         ConvertToUnicode(CP_UTF8, 0, hostname, -1, &hostnameX, 0);
1396         ConvertToUnicode(CP_UTF8, 0, ServiceClass, -1, &ServiceClassX, 0);
1397 #else
1398         hostnameX = _strdup(hostname);
1399         ServiceClassX = _strdup(ServiceClass);
1400 #endif
1401
1402         if (!ServiceClass)
1403         {
1404                 ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX);
1405                 free(ServiceClassX);
1406                 free(hostnameX);
1407                 return ServicePrincipalName;
1408         }
1409
1410         SpnLength = 0;
1411         status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, NULL);
1412
1413         if (status != ERROR_BUFFER_OVERFLOW)
1414         {
1415                 free(ServiceClassX);
1416                 free(hostnameX);
1417                 return NULL;
1418         }
1419
1420         ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR));
1421
1422         if (!ServicePrincipalName)
1423                 return NULL;
1424
1425         status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, ServicePrincipalName);
1426
1427         if (status != ERROR_SUCCESS)
1428         {
1429                 free(ServicePrincipalName);
1430                 free(ServiceClassX);
1431                 free(hostnameX);
1432                 return NULL;
1433         }
1434
1435         free(ServiceClassX);
1436         free(hostnameX);
1437         return ServicePrincipalName;
1438 }
1439
1440 /**
1441  * Create new CredSSP state machine.
1442  * @param transport
1443  * @return new CredSSP state machine.
1444  */
1445
1446 rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings)
1447 {
1448         HKEY hKey;
1449         LONG status;
1450         DWORD dwType;
1451         DWORD dwSize;
1452
1453         rdpNla* nla = (rdpNla*) calloc(1, sizeof(rdpNla));
1454
1455         if (!nla)
1456                 return NULL;
1457
1458         nla->identity = calloc(1, sizeof(SEC_WINNT_AUTH_IDENTITY));
1459         if (!nla->identity)
1460         {
1461                 free (nla);
1462                 return NULL;
1463         }
1464
1465         nla->instance = instance;
1466         nla->settings = settings;
1467         nla->server = settings->ServerMode;
1468         nla->transport = transport;
1469         nla->sendSeqNum = 0;
1470         nla->recvSeqNum = 0;
1471         ZeroMemory(&nla->negoToken, sizeof(SecBuffer));
1472         ZeroMemory(&nla->pubKeyAuth, sizeof(SecBuffer));
1473         ZeroMemory(&nla->authInfo, sizeof(SecBuffer));
1474         SecInvalidateHandle(&nla->context);
1475
1476         if (nla->server)
1477         {
1478                 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"),
1479                                                                 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
1480
1481                 if (status == ERROR_SUCCESS)
1482                 {
1483                         status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, NULL, &dwSize);
1484
1485                         if (status == ERROR_SUCCESS)
1486                         {
1487                                 nla->SspiModule = (LPTSTR) malloc(dwSize + sizeof(TCHAR));
1488                                 status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType,
1489                                                                                  (BYTE*) nla->SspiModule, &dwSize);
1490
1491                                 if (status == ERROR_SUCCESS)
1492                                 {
1493                                         WLog_INFO(TAG, "Using SSPI Module: %s", nla->SspiModule);
1494                                         RegCloseKey(hKey);
1495                                 }
1496                         }
1497                 }
1498         }
1499
1500         return nla;
1501 }
1502
1503 /**
1504  * Free CredSSP state machine.
1505  * @param credssp
1506  */
1507
1508 void nla_free(rdpNla* nla)
1509 {
1510         if (!nla)
1511                 return;
1512
1513         if (nla->table)
1514                 nla->table->DeleteSecurityContext(&nla->context);
1515
1516         sspi_SecBufferFree(&nla->PublicKey);
1517         sspi_SecBufferFree(&nla->tsCredentials);
1518
1519         free(nla->ServicePrincipalName);
1520         if (nla->identity)
1521         {
1522                 free(nla->identity->User);
1523                 free(nla->identity->Domain);
1524                 free(nla->identity->Password);
1525         }
1526         free(nla->identity);
1527
1528         free(nla);
1529 }