1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
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  * Copyright 2016 Martin Fleisz <martin.fleisz@thincast.com>
9  * Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *		 http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include <time.h>
29 
30 #ifndef _WIN32
31 #include <unistd.h>
32 #endif
33 
34 #include <freerdp/log.h>
35 #include <freerdp/crypto/tls.h>
36 #include <freerdp/build-config.h>
37 #include <freerdp/peer.h>
38 
39 #include <winpr/crt.h>
40 #include <winpr/sam.h>
41 #include <winpr/sspi.h>
42 #include <winpr/print.h>
43 #include <winpr/tchar.h>
44 #include <winpr/dsparse.h>
45 #include <winpr/library.h>
46 #include <winpr/registry.h>
47 
48 #include "nla.h"
49 
50 #define TAG FREERDP_TAG("core.nla")
51 
52 #define SERVER_KEY "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING "\\Server"
53 
54 /**
55  * TSRequest ::= SEQUENCE {
56  * 	version    [0] INTEGER,
57  * 	negoTokens [1] NegoData OPTIONAL,
58  * 	authInfo   [2] OCTET STRING OPTIONAL,
59  * 	pubKeyAuth [3] OCTET STRING OPTIONAL,
60  * 	errorCode  [4] INTEGER OPTIONAL
61  * }
62  *
63  * NegoData ::= SEQUENCE OF NegoDataItem
64  *
65  * NegoDataItem ::= SEQUENCE {
66  * 	negoToken [0] OCTET STRING
67  * }
68  *
69  * TSCredentials ::= SEQUENCE {
70  * 	credType    [0] INTEGER,
71  * 	credentials [1] OCTET STRING
72  * }
73  *
74  * TSPasswordCreds ::= SEQUENCE {
75  * 	domainName  [0] OCTET STRING,
76  * 	userName    [1] OCTET STRING,
77  * 	password    [2] OCTET STRING
78  * }
79  *
80  * TSSmartCardCreds ::= SEQUENCE {
81  * 	pin        [0] OCTET STRING,
82  * 	cspData    [1] TSCspDataDetail,
83  * 	userHint   [2] OCTET STRING OPTIONAL,
84  * 	domainHint [3] OCTET STRING OPTIONAL
85  * }
86  *
87  * TSCspDataDetail ::= SEQUENCE {
88  * 	keySpec       [0] INTEGER,
89  * 	cardName      [1] OCTET STRING OPTIONAL,
90  * 	readerName    [2] OCTET STRING OPTIONAL,
91  * 	containerName [3] OCTET STRING OPTIONAL,
92  * 	cspName       [4] OCTET STRING OPTIONAL
93  * }
94  *
95  */
96 
97 #define NLA_PKG_NAME NEGO_SSP_NAME
98 
99 #define TERMSRV_SPN_PREFIX "TERMSRV/"
100 
101 struct rdp_nla
102 {
103 	BOOL server;
104 	NLA_STATE state;
105 	int sendSeqNum;
106 	int recvSeqNum;
107 	freerdp* instance;
108 	CtxtHandle context;
109 	LPTSTR SspiModule;
110 	char* SamFile;
111 	rdpSettings* settings;
112 	rdpTransport* transport;
113 	UINT32 cbMaxToken;
114 #if defined(UNICODE)
115 	SEC_WCHAR* packageName;
116 #else
117 	SEC_CHAR* packageName;
118 #endif
119 	UINT32 version;
120 	UINT32 peerVersion;
121 	UINT32 errorCode;
122 	ULONG fContextReq;
123 	ULONG pfContextAttr;
124 	BOOL haveContext;
125 	BOOL haveInputBuffer;
126 	BOOL havePubKeyAuth;
127 	SECURITY_STATUS status;
128 	CredHandle credentials;
129 	TimeStamp expiration;
130 	PSecPkgInfo pPackageInfo;
131 	SecBuffer inputBuffer;
132 	SecBuffer outputBuffer;
133 	SecBufferDesc inputBufferDesc;
134 	SecBufferDesc outputBufferDesc;
135 	SecBuffer negoToken;
136 	SecBuffer pubKeyAuth;
137 	SecBuffer authInfo;
138 	SecBuffer ClientNonce;
139 	SecBuffer PublicKey;
140 	SecBuffer tsCredentials;
141 	LPTSTR ServicePrincipalName;
142 	SEC_WINNT_AUTH_IDENTITY* identity;
143 	PSecurityFunctionTable table;
144 	SecPkgContext_Sizes ContextSizes;
145 };
146 
147 static BOOL nla_send(rdpNla* nla, const char* msg);
148 static int nla_recv(rdpNla* nla, const char* msg);
149 static void nla_buffer_print(rdpNla* nla);
150 static void nla_buffer_free(rdpNla* nla);
151 static SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla);
152 static SECURITY_STATUS nla_encrypt_public_key_hash(rdpNla* nla);
153 static SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla);
154 static SECURITY_STATUS nla_decrypt_public_key_hash(rdpNla* nla);
155 static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla);
156 static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla);
157 static BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s);
158 static void nla_identity_free(SEC_WINNT_AUTH_IDENTITY* identity);
159 
160 #define ber_sizeof_sequence_octet_string(length) \
161 	ber_sizeof_contextual_tag(ber_sizeof_octet_string(length)) + ber_sizeof_octet_string(length)
162 #define ber_write_sequence_octet_string(stream, context, value, length)                \
163 	ber_write_contextual_tag(stream, context, ber_sizeof_octet_string(length), TRUE) + \
164 	    ber_write_octet_string(stream, value, length)
165 
166 /* CredSSP Client-To-Server Binding Hash\0 */
167 static const BYTE ClientServerHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
168 	                                          0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x54,
169 	                                          0x6F, 0x2D, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
170 	                                          0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
171 	                                          0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
172 
173 /* CredSSP Server-To-Client Binding Hash\0 */
174 static const BYTE ServerClientHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
175 	                                          0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2D, 0x54,
176 	                                          0x6F, 0x2D, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74,
177 	                                          0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
178 	                                          0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
179 
180 static const UINT32 NonceLength = 32;
181 
nla_identity_free(SEC_WINNT_AUTH_IDENTITY * identity)182 void nla_identity_free(SEC_WINNT_AUTH_IDENTITY* identity)
183 {
184 	if (identity)
185 	{
186 		/* Password authentication */
187 		if (identity->User)
188 		{
189 			memset(identity->User, 0, identity->UserLength * 2);
190 			free(identity->User);
191 		}
192 
193 		if (identity->Password)
194 		{
195 			size_t len = identity->PasswordLength;
196 
197 			if (len > LB_PASSWORD_MAX_LENGTH) /* [pth] Password hash */
198 				len -= LB_PASSWORD_MAX_LENGTH;
199 
200 			memset(identity->Password, 0, len * 2);
201 			free(identity->Password);
202 		}
203 
204 		if (identity->Domain)
205 		{
206 			memset(identity->Domain, 0, identity->DomainLength * 2);
207 			free(identity->Domain);
208 		}
209 	}
210 
211 	free(identity);
212 }
213 
214 /**
215  * Initialize NTLM/Kerberos SSP authentication module (client).
216  * @param credssp
217  */
218 
is_empty(const char * str)219 static BOOL is_empty(const char* str)
220 {
221 	if (!str)
222 		return TRUE;
223 	if (strlen(str) == 0)
224 		return TRUE;
225 	return FALSE;
226 }
227 
nla_client_init(rdpNla * nla)228 static int nla_client_init(rdpNla* nla)
229 {
230 	char* spn;
231 	size_t length;
232 	rdpTls* tls = NULL;
233 	BOOL PromptPassword = FALSE;
234 	freerdp* instance = nla->instance;
235 	rdpSettings* settings = nla->settings;
236 	WINPR_SAM* sam;
237 	WINPR_SAM_ENTRY* entry;
238 	nla->state = NLA_STATE_INITIAL;
239 
240 	if (settings->RestrictedAdminModeRequired)
241 		settings->DisableCredentialsDelegation = TRUE;
242 
243 	if (is_empty(settings->Username) ||
244 	    (is_empty(settings->Password) && is_empty((const char*)settings->RedirectionPassword)))
245 	{
246 		PromptPassword = TRUE;
247 	}
248 
249 	if (PromptPassword && !is_empty(settings->Username))
250 	{
251 		sam = SamOpen(NULL, TRUE);
252 
253 		if (sam)
254 		{
255 			entry = SamLookupUserA(sam, settings->Username, strlen(settings->Username), NULL, 0);
256 
257 			if (entry)
258 			{
259 				/**
260 				 * The user could be found in SAM database.
261 				 * Use entry in SAM database later instead of prompt
262 				 */
263 				PromptPassword = FALSE;
264 				SamFreeEntry(sam, entry);
265 			}
266 
267 			SamClose(sam);
268 		}
269 	}
270 
271 #ifndef _WIN32
272 
273 	if (PromptPassword)
274 	{
275 		if (settings->RestrictedAdminModeRequired)
276 		{
277 			if (!is_empty(settings->PasswordHash))
278 				PromptPassword = FALSE;
279 		}
280 	}
281 
282 #endif
283 
284 	if (PromptPassword)
285 	{
286 		if (freerdp_shall_disconnect(instance))
287 			return 0;
288 
289 		if (!instance->Authenticate)
290 		{
291 			freerdp_set_last_error_log(instance->context,
292 			                           FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
293 			return 0;
294 		}
295 		else
296 		{
297 			BOOL proceed = instance->Authenticate(instance, &settings->Username,
298 			                                      &settings->Password, &settings->Domain);
299 
300 			if (!proceed)
301 			{
302 				freerdp_set_last_error_log(instance->context,
303 				                           FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
304 				return 0;
305 			}
306 		}
307 	}
308 
309 	if (!settings->Username)
310 	{
311 		nla_identity_free(nla->identity);
312 		nla->identity = NULL;
313 	}
314 	else
315 	{
316 		if (settings->RedirectionPassword && settings->RedirectionPasswordLength > 0)
317 		{
318 			if (sspi_SetAuthIdentityWithUnicodePassword(
319 			        nla->identity, settings->Username, settings->Domain,
320 			        (UINT16*)settings->RedirectionPassword,
321 			        settings->RedirectionPasswordLength / sizeof(WCHAR) - 1) < 0)
322 				return -1;
323 		}
324 		else
325 		{
326 			BOOL usePassword = TRUE;
327 
328 			if (settings->RestrictedAdminModeRequired)
329 			{
330 				if (settings->PasswordHash)
331 				{
332 					if (strlen(settings->PasswordHash) == 32)
333 					{
334 						if (sspi_SetAuthIdentity(nla->identity, settings->Username,
335 						                         settings->Domain, settings->PasswordHash) < 0)
336 							return -1;
337 
338 						/**
339 						 * Increase password hash length by LB_PASSWORD_MAX_LENGTH to obtain a
340 						 * length exceeding the maximum (LB_PASSWORD_MAX_LENGTH) and use it this for
341 						 * hash identification in WinPR.
342 						 */
343 						nla->identity->PasswordLength += LB_PASSWORD_MAX_LENGTH;
344 						usePassword = FALSE;
345 					}
346 				}
347 			}
348 
349 			if (usePassword)
350 			{
351 				if (sspi_SetAuthIdentity(nla->identity, settings->Username, settings->Domain,
352 				                         settings->Password) < 0)
353 					return -1;
354 			}
355 		}
356 	}
357 
358 	tls = nla->transport->tls;
359 
360 	if (!tls)
361 	{
362 		WLog_ERR(TAG, "Unknown NLA transport layer");
363 		return -1;
364 	}
365 
366 	if (!sspi_SecBufferAlloc(&nla->PublicKey, tls->PublicKeyLength))
367 	{
368 		WLog_ERR(TAG, "Failed to allocate sspi secBuffer");
369 		return -1;
370 	}
371 
372 	CopyMemory(nla->PublicKey.pvBuffer, tls->PublicKey, tls->PublicKeyLength);
373 	length = sizeof(TERMSRV_SPN_PREFIX) + strlen(settings->ServerHostname);
374 	spn = (SEC_CHAR*)malloc(length + 1);
375 
376 	if (!spn)
377 		return -1;
378 
379 	sprintf_s(spn, length + 1, "%s%s", TERMSRV_SPN_PREFIX, settings->ServerHostname);
380 #ifdef UNICODE
381 	nla->ServicePrincipalName = NULL;
382 	ConvertToUnicode(CP_UTF8, 0, spn, -1, &nla->ServicePrincipalName, 0);
383 	free(spn);
384 #else
385 	nla->ServicePrincipalName = spn;
386 #endif
387 	nla->table = InitSecurityInterfaceEx(0);
388 #ifdef WITH_GSSAPI /* KERBEROS SSP */
389 	nla->status = nla->table->QuerySecurityPackageInfo(KERBEROS_SSP_NAME, &nla->pPackageInfo);
390 
391 	if (nla->status != SEC_E_OK)
392 	{
393 		WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08" PRIX32 "]",
394 		         GetSecurityStatusString(nla->status), nla->status);
395 		return -1;
396 	}
397 
398 #else /* NTLM SSP */
399 	nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo);
400 
401 	if (nla->status != SEC_E_OK)
402 	{
403 		WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08" PRIX32 "]",
404 		         GetSecurityStatusString(nla->status), nla->status);
405 		return -1;
406 	}
407 
408 #endif
409 	nla->cbMaxToken = nla->pPackageInfo->cbMaxToken;
410 	nla->packageName = nla->pPackageInfo->Name;
411 	WLog_DBG(TAG, "%s %" PRIu32 " : packageName=%ls ; cbMaxToken=%d", __FUNCTION__, __LINE__,
412 	         nla->packageName, nla->cbMaxToken);
413 	nla->status = nla->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME, SECPKG_CRED_OUTBOUND,
414 	                                                   NULL, nla->identity, NULL, NULL,
415 	                                                   &nla->credentials, &nla->expiration);
416 
417 	if (nla->status != SEC_E_OK)
418 	{
419 		WLog_ERR(TAG, "AcquireCredentialsHandle status %s [0x%08" PRIX32 "]",
420 		         GetSecurityStatusString(nla->status), nla->status);
421 		return -1;
422 	}
423 
424 	nla->haveContext = FALSE;
425 	nla->haveInputBuffer = FALSE;
426 	nla->havePubKeyAuth = FALSE;
427 	ZeroMemory(&nla->inputBuffer, sizeof(SecBuffer));
428 	ZeroMemory(&nla->outputBuffer, sizeof(SecBuffer));
429 	ZeroMemory(&nla->ContextSizes, sizeof(SecPkgContext_Sizes));
430 	/*
431 	 * from tspkg.dll: 0x00000132
432 	 * ISC_REQ_MUTUAL_AUTH
433 	 * ISC_REQ_CONFIDENTIALITY
434 	 * ISC_REQ_USE_SESSION_KEY
435 	 * ISC_REQ_ALLOCATE_MEMORY
436 	 */
437 	nla->fContextReq = ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY;
438 	return 1;
439 }
440 
nla_client_begin(rdpNla * nla)441 int nla_client_begin(rdpNla* nla)
442 {
443 	if (nla_client_init(nla) < 1)
444 		return -1;
445 
446 	if (nla->state != NLA_STATE_INITIAL)
447 		return -1;
448 
449 	nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
450 	nla->outputBufferDesc.cBuffers = 1;
451 	nla->outputBufferDesc.pBuffers = &nla->outputBuffer;
452 	nla->outputBuffer.BufferType = SECBUFFER_TOKEN;
453 	nla->outputBuffer.cbBuffer = nla->cbMaxToken;
454 	nla->outputBuffer.pvBuffer = malloc(nla->outputBuffer.cbBuffer);
455 
456 	if (!nla->outputBuffer.pvBuffer)
457 		return -1;
458 
459 	nla->status = nla->table->InitializeSecurityContext(
460 	    &nla->credentials, NULL, nla->ServicePrincipalName, nla->fContextReq, 0,
461 	    SECURITY_NATIVE_DREP, NULL, 0, &nla->context, &nla->outputBufferDesc, &nla->pfContextAttr,
462 	    &nla->expiration);
463 	WLog_VRB(TAG, " InitializeSecurityContext status %s [0x%08" PRIX32 "]",
464 	         GetSecurityStatusString(nla->status), nla->status);
465 
466 	/* Handle kerberos context initialization failure.
467 	 * After kerberos failed initialize NTLM context */
468 	if (nla->status == SEC_E_NO_CREDENTIALS)
469 	{
470 		nla->status = nla->table->InitializeSecurityContext(
471 		    &nla->credentials, NULL, nla->ServicePrincipalName, nla->fContextReq, 0,
472 		    SECURITY_NATIVE_DREP, NULL, 0, &nla->context, &nla->outputBufferDesc,
473 		    &nla->pfContextAttr, &nla->expiration);
474 		WLog_VRB(TAG, " InitializeSecurityContext status %s [0x%08" PRIX32 "]",
475 		         GetSecurityStatusString(nla->status), nla->status);
476 
477 		if (nla->status)
478 		{
479 			SECURITY_STATUS status =
480 			    nla->table->QuerySecurityPackageInfo(NTLM_SSP_NAME, &nla->pPackageInfo);
481 
482 			if (status != SEC_E_OK)
483 			{
484 				WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08" PRIX32 "]",
485 				         GetSecurityStatusString(nla->status), status);
486 				return -1;
487 			}
488 
489 			nla->cbMaxToken = nla->pPackageInfo->cbMaxToken;
490 			nla->packageName = nla->pPackageInfo->Name;
491 		}
492 	}
493 
494 	if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
495 	{
496 		if (nla->table->CompleteAuthToken)
497 		{
498 			SECURITY_STATUS status;
499 			status = nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc);
500 
501 			if (status != SEC_E_OK)
502 			{
503 				WLog_WARN(TAG, "CompleteAuthToken status %s [0x%08" PRIX32 "]",
504 				          GetSecurityStatusString(status), status);
505 				return -1;
506 			}
507 		}
508 
509 		if (nla->status == SEC_I_COMPLETE_NEEDED)
510 			nla->status = SEC_E_OK;
511 		else if (nla->status == SEC_I_COMPLETE_AND_CONTINUE)
512 			nla->status = SEC_I_CONTINUE_NEEDED;
513 	}
514 
515 	if (nla->status != SEC_I_CONTINUE_NEEDED)
516 		return -1;
517 
518 	if (nla->outputBuffer.cbBuffer < 1)
519 		return -1;
520 
521 	nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
522 	nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
523 
524 	if (!nla_send(nla, "Client: Sending Authentication Token"))
525 	{
526 		nla_buffer_free(nla);
527 		return -1;
528 	}
529 
530 	nla_buffer_free(nla);
531 	nla->state = NLA_STATE_NEGO_TOKEN;
532 	return 1;
533 }
534 
nla_client_recv(rdpNla * nla)535 static int nla_client_recv(rdpNla* nla)
536 {
537 	int status = -1;
538 
539 	if (nla->state == NLA_STATE_NEGO_TOKEN)
540 	{
541 		nla->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
542 		nla->inputBufferDesc.cBuffers = 1;
543 		nla->inputBufferDesc.pBuffers = &nla->inputBuffer;
544 		nla->inputBuffer.BufferType = SECBUFFER_TOKEN;
545 		nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer;
546 		nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer;
547 		nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
548 		nla->outputBufferDesc.cBuffers = 1;
549 		nla->outputBufferDesc.pBuffers = &nla->outputBuffer;
550 		nla->outputBuffer.BufferType = SECBUFFER_TOKEN;
551 		nla->outputBuffer.cbBuffer = nla->cbMaxToken;
552 		nla->outputBuffer.pvBuffer = malloc(nla->outputBuffer.cbBuffer);
553 
554 		if (!nla->outputBuffer.pvBuffer)
555 			return -1;
556 
557 		nla->status = nla->table->InitializeSecurityContext(
558 		    &nla->credentials, &nla->context, nla->ServicePrincipalName, nla->fContextReq, 0,
559 		    SECURITY_NATIVE_DREP, &nla->inputBufferDesc, 0, &nla->context, &nla->outputBufferDesc,
560 		    &nla->pfContextAttr, &nla->expiration);
561 		WLog_VRB(TAG, "InitializeSecurityContext  %s [0x%08" PRIX32 "]",
562 		         GetSecurityStatusString(nla->status), nla->status);
563 		free(nla->inputBuffer.pvBuffer);
564 		nla->inputBuffer.pvBuffer = NULL;
565 
566 		if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
567 		{
568 			if (nla->table->CompleteAuthToken)
569 			{
570 				SECURITY_STATUS status;
571 				status = nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc);
572 
573 				if (status != SEC_E_OK)
574 				{
575 					WLog_WARN(TAG, "CompleteAuthToken status %s [0x%08" PRIX32 "]",
576 					          GetSecurityStatusString(status), status);
577 					return -1;
578 				}
579 			}
580 
581 			if (nla->status == SEC_I_COMPLETE_NEEDED)
582 				nla->status = SEC_E_OK;
583 			else if (nla->status == SEC_I_COMPLETE_AND_CONTINUE)
584 				nla->status = SEC_I_CONTINUE_NEEDED;
585 		}
586 
587 		if (nla->status == SEC_E_OK)
588 		{
589 			nla->havePubKeyAuth = TRUE;
590 			nla->status = nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES,
591 			                                                 &nla->ContextSizes);
592 
593 			if (nla->status != SEC_E_OK)
594 			{
595 				WLog_ERR(TAG,
596 				         "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [0x%08" PRIX32 "]",
597 				         GetSecurityStatusString(nla->status), nla->status);
598 				return -1;
599 			}
600 
601 			if (nla->peerVersion < 5)
602 				nla->status = nla_encrypt_public_key_echo(nla);
603 			else
604 				nla->status = nla_encrypt_public_key_hash(nla);
605 
606 			if (nla->status != SEC_E_OK)
607 				return -1;
608 		}
609 
610 		nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
611 		nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
612 
613 		if (!nla_send(nla, "Client: Sending Authentication Token"))
614 		{
615 			nla_buffer_free(nla);
616 			return -1;
617 		}
618 
619 		nla_buffer_free(nla);
620 
621 		if (nla->status == SEC_E_OK)
622 			nla->state = NLA_STATE_PUB_KEY_AUTH;
623 
624 		status = 1;
625 	}
626 	else if (nla->state == NLA_STATE_PUB_KEY_AUTH)
627 	{
628 		/* Verify Server Public Key Echo */
629 		if (nla->peerVersion < 5)
630 			nla->status = nla_decrypt_public_key_echo(nla);
631 		else
632 			nla->status = nla_decrypt_public_key_hash(nla);
633 
634 		nla_buffer_free(nla);
635 
636 		if (nla->status != SEC_E_OK)
637 		{
638 			WLog_ERR(TAG, "Could not verify public key echo %s [0x%08" PRIX32 "]",
639 			         GetSecurityStatusString(nla->status), nla->status);
640 			return -1;
641 		}
642 
643 		/* Send encrypted credentials */
644 		nla->status = nla_encrypt_ts_credentials(nla);
645 
646 		if (nla->status != SEC_E_OK)
647 		{
648 			WLog_ERR(TAG, "nla_encrypt_ts_credentials status %s [0x%08" PRIX32 "]",
649 			         GetSecurityStatusString(nla->status), nla->status);
650 			return -1;
651 		}
652 
653 		if (!nla_send(nla, "Client: Sending PubKeyAuth Token"))
654 		{
655 			nla_buffer_free(nla);
656 			return -1;
657 		}
658 
659 		nla_buffer_free(nla);
660 
661 		if (SecIsValidHandle(&nla->credentials))
662 		{
663 			nla->table->FreeCredentialsHandle(&nla->credentials);
664 			SecInvalidateHandle(&nla->credentials);
665 		}
666 
667 		if (nla->status != SEC_E_OK)
668 		{
669 			WLog_ERR(TAG, "FreeCredentialsHandle status %s [0x%08" PRIX32 "]",
670 			         GetSecurityStatusString(nla->status), nla->status);
671 		}
672 
673 		nla->status = nla->table->FreeContextBuffer(nla->pPackageInfo);
674 
675 		if (nla->status != SEC_E_OK)
676 		{
677 			WLog_ERR(TAG, "FreeContextBuffer status %s [0x%08" PRIX32 "]",
678 			         GetSecurityStatusString(nla->status), nla->status);
679 		}
680 
681 		if (nla->status != SEC_E_OK)
682 			return -1;
683 
684 		nla->state = NLA_STATE_AUTH_INFO;
685 		status = 1;
686 	}
687 
688 	return status;
689 }
690 
nla_client_authenticate(rdpNla * nla)691 static int nla_client_authenticate(rdpNla* nla)
692 {
693 	wStream* s;
694 	int status;
695 	s = Stream_New(NULL, 4096);
696 
697 	if (!s)
698 	{
699 		WLog_ERR(TAG, "Stream_New failed!");
700 		return -1;
701 	}
702 
703 	if (nla_client_begin(nla) < 1)
704 	{
705 		Stream_Free(s, TRUE);
706 		return -1;
707 	}
708 
709 	while (nla->state < NLA_STATE_AUTH_INFO)
710 	{
711 		Stream_SetPosition(s, 0);
712 		status = transport_read_pdu(nla->transport, s);
713 
714 		if (status < 0)
715 		{
716 			WLog_ERR(TAG, "nla_client_authenticate failure");
717 			Stream_Free(s, TRUE);
718 			return -1;
719 		}
720 
721 		status = nla_recv_pdu(nla, s);
722 
723 		if (status < 0)
724 		{
725 			Stream_Free(s, TRUE);
726 			return -1;
727 		}
728 	}
729 
730 	Stream_Free(s, TRUE);
731 	return 1;
732 }
733 
734 /**
735  * Initialize NTLMSSP authentication module (server).
736  * @param credssp
737  */
738 
nla_server_init(rdpNla * nla)739 static int nla_server_init(rdpNla* nla)
740 {
741 	rdpTls* tls = nla->transport->tls;
742 
743 	if (!sspi_SecBufferAlloc(&nla->PublicKey, tls->PublicKeyLength))
744 	{
745 		WLog_ERR(TAG, "Failed to allocate SecBuffer for public key");
746 		return -1;
747 	}
748 
749 	CopyMemory(nla->PublicKey.pvBuffer, tls->PublicKey, tls->PublicKeyLength);
750 
751 	if (nla->SspiModule)
752 	{
753 		HMODULE hSSPI;
754 		INIT_SECURITY_INTERFACE pInitSecurityInterface;
755 		hSSPI = LoadLibrary(nla->SspiModule);
756 
757 		if (!hSSPI)
758 		{
759 			WLog_ERR(TAG, "Failed to load SSPI module: %s", nla->SspiModule);
760 			return -1;
761 		}
762 
763 #ifdef UNICODE
764 		pInitSecurityInterface =
765 		    (INIT_SECURITY_INTERFACE)GetProcAddress(hSSPI, "InitSecurityInterfaceW");
766 #else
767 		pInitSecurityInterface =
768 		    (INIT_SECURITY_INTERFACE)GetProcAddress(hSSPI, "InitSecurityInterfaceA");
769 #endif
770 		nla->table = pInitSecurityInterface();
771 	}
772 	else
773 	{
774 		nla->table = InitSecurityInterfaceEx(0);
775 	}
776 
777 	nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo);
778 
779 	if (nla->status != SEC_E_OK)
780 	{
781 		WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08" PRIX32 "]",
782 		         GetSecurityStatusString(nla->status), nla->status);
783 		return -1;
784 	}
785 
786 	nla->cbMaxToken = nla->pPackageInfo->cbMaxToken;
787 	nla->packageName = nla->pPackageInfo->Name;
788 	nla->status =
789 	    nla->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME, SECPKG_CRED_INBOUND, NULL, NULL,
790 	                                         NULL, NULL, &nla->credentials, &nla->expiration);
791 
792 	if (nla->status != SEC_E_OK)
793 	{
794 		WLog_ERR(TAG, "AcquireCredentialsHandle status %s [0x%08" PRIX32 "]",
795 		         GetSecurityStatusString(nla->status), nla->status);
796 		return -1;
797 	}
798 
799 	nla->haveContext = FALSE;
800 	nla->haveInputBuffer = FALSE;
801 	nla->havePubKeyAuth = FALSE;
802 	ZeroMemory(&nla->inputBuffer, sizeof(SecBuffer));
803 	ZeroMemory(&nla->outputBuffer, sizeof(SecBuffer));
804 	ZeroMemory(&nla->inputBufferDesc, sizeof(SecBufferDesc));
805 	ZeroMemory(&nla->outputBufferDesc, sizeof(SecBufferDesc));
806 	ZeroMemory(&nla->ContextSizes, sizeof(SecPkgContext_Sizes));
807 	/*
808 	 * from tspkg.dll: 0x00000112
809 	 * ASC_REQ_MUTUAL_AUTH
810 	 * ASC_REQ_CONFIDENTIALITY
811 	 * ASC_REQ_ALLOCATE_MEMORY
812 	 */
813 	nla->fContextReq = 0;
814 	nla->fContextReq |= ASC_REQ_MUTUAL_AUTH;
815 	nla->fContextReq |= ASC_REQ_CONFIDENTIALITY;
816 	nla->fContextReq |= ASC_REQ_CONNECTION;
817 	nla->fContextReq |= ASC_REQ_USE_SESSION_KEY;
818 	nla->fContextReq |= ASC_REQ_REPLAY_DETECT;
819 	nla->fContextReq |= ASC_REQ_SEQUENCE_DETECT;
820 	nla->fContextReq |= ASC_REQ_EXTENDED_ERROR;
821 	return 1;
822 }
823 
824 /**
825  * Authenticate with client using CredSSP (server).
826  * @param credssp
827  * @return 1 if authentication is successful
828  */
829 
nla_server_authenticate(rdpNla * nla)830 static int nla_server_authenticate(rdpNla* nla)
831 {
832 	if (nla_server_init(nla) < 1)
833 		return -1;
834 
835 	while (TRUE)
836 	{
837 		/* receive authentication token */
838 		nla->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
839 		nla->inputBufferDesc.cBuffers = 1;
840 		nla->inputBufferDesc.pBuffers = &nla->inputBuffer;
841 		nla->inputBuffer.BufferType = SECBUFFER_TOKEN;
842 
843 		if (nla_recv(nla, "Receiving Authentication Token") < 0)
844 			return -1;
845 
846 		nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer;
847 		nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer;
848 
849 		if (nla->negoToken.cbBuffer < 1)
850 		{
851 			WLog_ERR(TAG, "CredSSP: invalid negoToken!");
852 			return -1;
853 		}
854 
855 		nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
856 		nla->outputBufferDesc.cBuffers = 1;
857 		nla->outputBufferDesc.pBuffers = &nla->outputBuffer;
858 		nla->outputBuffer.BufferType = SECBUFFER_TOKEN;
859 		nla->outputBuffer.cbBuffer = nla->cbMaxToken;
860 		nla->outputBuffer.pvBuffer = malloc(nla->outputBuffer.cbBuffer);
861 
862 		if (!nla->outputBuffer.pvBuffer)
863 			return -1;
864 
865 		nla->status = nla->table->AcceptSecurityContext(
866 		    &nla->credentials, nla->haveContext ? &nla->context : NULL, &nla->inputBufferDesc,
867 		    nla->fContextReq, SECURITY_NATIVE_DREP, &nla->context, &nla->outputBufferDesc,
868 		    &nla->pfContextAttr, &nla->expiration);
869 		WLog_VRB(TAG, "AcceptSecurityContext status %s [0x%08" PRIX32 "]",
870 		         GetSecurityStatusString(nla->status), nla->status);
871 		nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
872 		nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
873 
874 		if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
875 		{
876 			freerdp_peer* peer = nla->instance->context->peer;
877 
878 			if (peer->ComputeNtlmHash)
879 			{
880 				SECURITY_STATUS status;
881 				status = nla->table->SetContextAttributes(
882 				    &nla->context, SECPKG_ATTR_AUTH_NTLM_HASH_CB, peer->ComputeNtlmHash, 0);
883 
884 				if (status != SEC_E_OK)
885 				{
886 					WLog_ERR(TAG, "SetContextAttributesA(hash cb) status %s [0x%08" PRIX32 "]",
887 					         GetSecurityStatusString(status), status);
888 				}
889 
890 				status = nla->table->SetContextAttributes(
891 				    &nla->context, SECPKG_ATTR_AUTH_NTLM_HASH_CB_DATA, peer, 0);
892 
893 				if (status != SEC_E_OK)
894 				{
895 					WLog_ERR(TAG, "SetContextAttributesA(hash cb data) status %s [0x%08" PRIX32 "]",
896 					         GetSecurityStatusString(status), status);
897 				}
898 			}
899 			else if (nla->SamFile)
900 			{
901 				nla->table->SetContextAttributes(&nla->context, SECPKG_ATTR_AUTH_NTLM_SAM_FILE,
902 				                                 nla->SamFile, strlen(nla->SamFile) + 1);
903 			}
904 
905 			if (nla->table->CompleteAuthToken)
906 			{
907 				SECURITY_STATUS status;
908 				status = nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc);
909 
910 				if (status != SEC_E_OK)
911 				{
912 					WLog_WARN(TAG, "CompleteAuthToken status %s [0x%08" PRIX32 "]",
913 					          GetSecurityStatusString(status), status);
914 					return -1;
915 				}
916 			}
917 
918 			if (nla->status == SEC_I_COMPLETE_NEEDED)
919 				nla->status = SEC_E_OK;
920 			else if (nla->status == SEC_I_COMPLETE_AND_CONTINUE)
921 				nla->status = SEC_I_CONTINUE_NEEDED;
922 		}
923 
924 		if (nla->status == SEC_E_OK)
925 		{
926 			if (nla->outputBuffer.cbBuffer != 0)
927 			{
928 				if (!nla_send(nla, "Server: Sending response"))
929 				{
930 					nla_buffer_free(nla);
931 					return -1;
932 				}
933 
934 				if (nla_recv(nla, "Receiving pubkey Token") < 0)
935 					return -1;
936 			}
937 
938 			nla->havePubKeyAuth = TRUE;
939 			nla->status = nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES,
940 			                                                 &nla->ContextSizes);
941 
942 			if (nla->status != SEC_E_OK)
943 			{
944 				WLog_ERR(TAG,
945 				         "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [0x%08" PRIX32 "]",
946 				         GetSecurityStatusString(nla->status), nla->status);
947 				return -1;
948 			}
949 
950 			if (nla->peerVersion < 5)
951 				nla->status = nla_decrypt_public_key_echo(nla);
952 			else
953 				nla->status = nla_decrypt_public_key_hash(nla);
954 
955 			if (nla->status != SEC_E_OK)
956 			{
957 				WLog_ERR(TAG,
958 				         "Error: could not verify client's public key echo %s [0x%08" PRIX32 "]",
959 				         GetSecurityStatusString(nla->status), nla->status);
960 				return -1;
961 			}
962 
963 			sspi_SecBufferFree(&nla->negoToken);
964 			nla->negoToken.pvBuffer = NULL;
965 			nla->negoToken.cbBuffer = 0;
966 
967 			if (nla->peerVersion < 5)
968 				nla->status = nla_encrypt_public_key_echo(nla);
969 			else
970 				nla->status = nla_encrypt_public_key_hash(nla);
971 
972 			if (nla->status != SEC_E_OK)
973 				return -1;
974 		}
975 
976 		if ((nla->status != SEC_E_OK) && (nla->status != SEC_I_CONTINUE_NEEDED))
977 		{
978 			/* Special handling of these specific error codes as NTSTATUS_FROM_WIN32
979 			   unfortunately does not map directly to the corresponding NTSTATUS values
980 			 */
981 			switch (GetLastError())
982 			{
983 				case ERROR_PASSWORD_MUST_CHANGE:
984 					nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
985 					break;
986 
987 				case ERROR_PASSWORD_EXPIRED:
988 					nla->errorCode = STATUS_PASSWORD_EXPIRED;
989 					break;
990 
991 				case ERROR_ACCOUNT_DISABLED:
992 					nla->errorCode = STATUS_ACCOUNT_DISABLED;
993 					break;
994 
995 				default:
996 					nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
997 					break;
998 			}
999 
1000 			WLog_ERR(TAG, "AcceptSecurityContext status %s [0x%08" PRIX32 "]",
1001 			         GetSecurityStatusString(nla->status), nla->status);
1002 			nla_send(nla, "Server: Sending AcceptSecurityContext error status");
1003 			return -1; /* Access Denied */
1004 		}
1005 
1006 		/* send authentication token */
1007 		if (!nla_send(nla, "Server: Sending Authentication Token"))
1008 		{
1009 			nla_buffer_free(nla);
1010 			return -1;
1011 		}
1012 
1013 		nla_buffer_free(nla);
1014 
1015 		if (nla->status != SEC_I_CONTINUE_NEEDED)
1016 			break;
1017 
1018 		nla->haveContext = TRUE;
1019 	}
1020 
1021 	/* Receive encrypted credentials */
1022 
1023 	if (nla_recv(nla, "Receive Encryption Credentials") < 0)
1024 		return -1;
1025 
1026 	nla->status = nla_decrypt_ts_credentials(nla);
1027 
1028 	if (nla->status != SEC_E_OK)
1029 	{
1030 		WLog_ERR(TAG, "Could not decrypt TSCredentials status %s [0x%08" PRIX32 "]",
1031 		         GetSecurityStatusString(nla->status), nla->status);
1032 		return -1;
1033 	}
1034 
1035 	nla->status = nla->table->ImpersonateSecurityContext(&nla->context);
1036 
1037 	if (nla->status != SEC_E_OK)
1038 	{
1039 		WLog_ERR(TAG, "ImpersonateSecurityContext status %s [0x%08" PRIX32 "]",
1040 		         GetSecurityStatusString(nla->status), nla->status);
1041 		return -1;
1042 	}
1043 	else
1044 	{
1045 		nla->status = nla->table->RevertSecurityContext(&nla->context);
1046 
1047 		if (nla->status != SEC_E_OK)
1048 		{
1049 			WLog_ERR(TAG, "RevertSecurityContext status %s [0x%08" PRIX32 "]",
1050 			         GetSecurityStatusString(nla->status), nla->status);
1051 			return -1;
1052 		}
1053 	}
1054 
1055 	nla->status = nla->table->FreeContextBuffer(nla->pPackageInfo);
1056 
1057 	if (nla->status != SEC_E_OK)
1058 	{
1059 		WLog_ERR(TAG, "DeleteSecurityContext status %s [0x%08" PRIX32 "]",
1060 		         GetSecurityStatusString(nla->status), nla->status);
1061 		return -1;
1062 	}
1063 
1064 	return 1;
1065 }
1066 
1067 /**
1068  * Authenticate using CredSSP.
1069  * @param credssp
1070  * @return 1 if authentication is successful
1071  */
1072 
nla_authenticate(rdpNla * nla)1073 int nla_authenticate(rdpNla* nla)
1074 {
1075 	if (nla->server)
1076 		return nla_server_authenticate(nla);
1077 	else
1078 		return nla_client_authenticate(nla);
1079 }
1080 
ap_integer_increment_le(BYTE * number,int size)1081 static void ap_integer_increment_le(BYTE* number, int size)
1082 {
1083 	int index;
1084 
1085 	for (index = 0; index < size; index++)
1086 	{
1087 		if (number[index] < 0xFF)
1088 		{
1089 			number[index]++;
1090 			break;
1091 		}
1092 		else
1093 		{
1094 			number[index] = 0;
1095 			continue;
1096 		}
1097 	}
1098 }
1099 
ap_integer_decrement_le(BYTE * number,int size)1100 static void ap_integer_decrement_le(BYTE* number, int size)
1101 {
1102 	int index;
1103 
1104 	for (index = 0; index < size; index++)
1105 	{
1106 		if (number[index] > 0)
1107 		{
1108 			number[index]--;
1109 			break;
1110 		}
1111 		else
1112 		{
1113 			number[index] = 0xFF;
1114 			continue;
1115 		}
1116 	}
1117 }
1118 
nla_encrypt_public_key_echo(rdpNla * nla)1119 SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla)
1120 {
1121 	SecBuffer Buffers[2] = { { 0 } };
1122 	SecBufferDesc Message;
1123 	SECURITY_STATUS status;
1124 	ULONG public_key_length;
1125 	const BOOL krb =
1126 	    (_tcsncmp(nla->packageName, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0);
1127 	const BOOL nego = (_tcsncmp(nla->packageName, NEGO_SSP_NAME, ARRAYSIZE(NEGO_SSP_NAME)) == 0);
1128 	const BOOL ntlm = (_tcsncmp(nla->packageName, NTLM_SSP_NAME, ARRAYSIZE(NTLM_SSP_NAME)) == 0);
1129 	public_key_length = nla->PublicKey.cbBuffer;
1130 
1131 	sspi_SecBufferFree(&nla->pubKeyAuth);
1132 	if (!sspi_SecBufferAlloc(&nla->pubKeyAuth,
1133 	                         public_key_length + nla->ContextSizes.cbSecurityTrailer))
1134 		return SEC_E_INSUFFICIENT_MEMORY;
1135 
1136 	if (krb)
1137 	{
1138 		Message.cBuffers = 1;
1139 		Buffers[0].BufferType = SECBUFFER_DATA; /* TLS Public Key */
1140 		Buffers[0].cbBuffer = public_key_length;
1141 		Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
1142 		CopyMemory(Buffers[0].pvBuffer, nla->PublicKey.pvBuffer, Buffers[0].cbBuffer);
1143 	}
1144 	else if (ntlm || nego)
1145 	{
1146 		Message.cBuffers = 2;
1147 		Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1148 		Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
1149 		Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
1150 		Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
1151 		Buffers[1].cbBuffer = public_key_length;
1152 		Buffers[1].pvBuffer =
1153 		    ((BYTE*)nla->pubKeyAuth.pvBuffer) + nla->ContextSizes.cbSecurityTrailer;
1154 		CopyMemory(Buffers[1].pvBuffer, nla->PublicKey.pvBuffer, Buffers[1].cbBuffer);
1155 	}
1156 
1157 	if (!krb && nla->server)
1158 	{
1159 		/* server echos the public key +1 */
1160 		ap_integer_increment_le((BYTE*)Buffers[1].pvBuffer, Buffers[1].cbBuffer);
1161 	}
1162 
1163 	Message.ulVersion = SECBUFFER_VERSION;
1164 	Message.pBuffers = (PSecBuffer)&Buffers;
1165 	status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++);
1166 
1167 	if (status != SEC_E_OK)
1168 	{
1169 		WLog_ERR(TAG, "EncryptMessage status %s [0x%08" PRIX32 "]", GetSecurityStatusString(status),
1170 		         status);
1171 		return status;
1172 	}
1173 
1174 	if (Message.cBuffers == 2 && Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer)
1175 	{
1176 		/* IMPORTANT: EncryptMessage may not use all the signature space, so we need to shrink the
1177 		 * excess between the buffers */
1178 		MoveMemory(((BYTE*)Buffers[0].pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer,
1179 		           Buffers[1].cbBuffer);
1180 		nla->pubKeyAuth.cbBuffer = Buffers[0].cbBuffer + Buffers[1].cbBuffer;
1181 	}
1182 
1183 	return status;
1184 }
1185 
nla_encrypt_public_key_hash(rdpNla * nla)1186 SECURITY_STATUS nla_encrypt_public_key_hash(rdpNla* nla)
1187 {
1188 	SecBuffer Buffers[2] = { { 0 } };
1189 	SecBufferDesc Message;
1190 	SECURITY_STATUS status = SEC_E_INTERNAL_ERROR;
1191 	WINPR_DIGEST_CTX* sha256 = NULL;
1192 	const BOOL krb =
1193 	    (_tcsncmp(nla->packageName, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0);
1194 	const ULONG auth_data_length =
1195 	    (nla->ContextSizes.cbSecurityTrailer + WINPR_SHA256_DIGEST_LENGTH);
1196 	const BYTE* hashMagic = nla->server ? ServerClientHashMagic : ClientServerHashMagic;
1197 	const size_t hashSize =
1198 	    nla->server ? sizeof(ServerClientHashMagic) : sizeof(ClientServerHashMagic);
1199 
1200 	sspi_SecBufferFree(&nla->pubKeyAuth);
1201 	if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, auth_data_length))
1202 	{
1203 		status = SEC_E_INSUFFICIENT_MEMORY;
1204 		goto out;
1205 	}
1206 
1207 	/* generate SHA256 of following data: ClientServerHashMagic, Nonce, SubjectPublicKey */
1208 	if (!(sha256 = winpr_Digest_New()))
1209 		goto out;
1210 
1211 	if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
1212 		goto out;
1213 
1214 	/* include trailing \0 from hashMagic */
1215 	if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
1216 		goto out;
1217 
1218 	if (!winpr_Digest_Update(sha256, nla->ClientNonce.pvBuffer, nla->ClientNonce.cbBuffer))
1219 		goto out;
1220 
1221 	/* SubjectPublicKey */
1222 	if (!winpr_Digest_Update(sha256, nla->PublicKey.pvBuffer, nla->PublicKey.cbBuffer))
1223 		goto out;
1224 
1225 	if (krb)
1226 	{
1227 		Message.cBuffers = 1;
1228 		Buffers[0].BufferType = SECBUFFER_DATA; /* SHA256 hash */
1229 		Buffers[0].cbBuffer = WINPR_SHA256_DIGEST_LENGTH;
1230 		Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
1231 
1232 		if (!winpr_Digest_Final(sha256, Buffers[0].pvBuffer, Buffers[0].cbBuffer))
1233 			goto out;
1234 	}
1235 	else
1236 	{
1237 		Message.cBuffers = 2;
1238 		Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1239 		Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
1240 		Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
1241 		Buffers[1].BufferType = SECBUFFER_DATA; /* SHA256 hash */
1242 		Buffers[1].cbBuffer = WINPR_SHA256_DIGEST_LENGTH;
1243 		Buffers[1].pvBuffer =
1244 		    ((BYTE*)nla->pubKeyAuth.pvBuffer) + nla->ContextSizes.cbSecurityTrailer;
1245 
1246 		if (!winpr_Digest_Final(sha256, Buffers[1].pvBuffer, Buffers[1].cbBuffer))
1247 			goto out;
1248 	}
1249 
1250 	Message.pBuffers = (PSecBuffer)&Buffers;
1251 	Message.ulVersion = SECBUFFER_VERSION;
1252 	status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++);
1253 
1254 	if (status != SEC_E_OK)
1255 	{
1256 		WLog_ERR(TAG, "EncryptMessage status %s [0x%08" PRIX32 "]", GetSecurityStatusString(status),
1257 		         status);
1258 		goto out;
1259 	}
1260 
1261 	if (Message.cBuffers == 2 && Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer)
1262 	{
1263 		/* IMPORTANT: EncryptMessage may not use all the signature space, so we need to shrink the
1264 		 * excess between the buffers */
1265 		MoveMemory(((BYTE*)Buffers[0].pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer,
1266 		           Buffers[1].cbBuffer);
1267 		nla->pubKeyAuth.cbBuffer = Buffers[0].cbBuffer + Buffers[1].cbBuffer;
1268 	}
1269 
1270 out:
1271 	winpr_Digest_Free(sha256);
1272 	return status;
1273 }
1274 
nla_decrypt_public_key_echo(rdpNla * nla)1275 SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
1276 {
1277 	ULONG length;
1278 	BYTE* buffer = NULL;
1279 	ULONG pfQOP = 0;
1280 	BYTE* public_key1 = NULL;
1281 	BYTE* public_key2 = NULL;
1282 	ULONG public_key_length = 0;
1283 	int signature_length;
1284 	SecBuffer Buffers[2] = { { 0 } };
1285 	SecBufferDesc Message;
1286 	BOOL krb, ntlm, nego;
1287 	SECURITY_STATUS status = SEC_E_INVALID_TOKEN;
1288 
1289 	if (!nla)
1290 		goto fail;
1291 
1292 	krb = (_tcsncmp(nla->packageName, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0);
1293 	nego = (_tcsncmp(nla->packageName, NEGO_SSP_NAME, ARRAYSIZE(NEGO_SSP_NAME)) == 0);
1294 	ntlm = (_tcsncmp(nla->packageName, NTLM_SSP_NAME, ARRAYSIZE(NTLM_SSP_NAME)) == 0);
1295 	signature_length = nla->pubKeyAuth.cbBuffer - nla->PublicKey.cbBuffer;
1296 
1297 	if ((signature_length < 0) || ((UINT32)signature_length > nla->ContextSizes.cbSecurityTrailer))
1298 	{
1299 		WLog_ERR(TAG, "unexpected pubKeyAuth buffer size: %" PRIu32 "", nla->pubKeyAuth.cbBuffer);
1300 		goto fail;
1301 	}
1302 
1303 	length = nla->pubKeyAuth.cbBuffer;
1304 	buffer = (BYTE*)malloc(length);
1305 
1306 	if (!buffer)
1307 	{
1308 		status = SEC_E_INSUFFICIENT_MEMORY;
1309 		goto fail;
1310 	}
1311 
1312 	if (krb)
1313 	{
1314 		CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
1315 		Buffers[0].BufferType = SECBUFFER_DATA; /* Wrapped and encrypted TLS Public Key */
1316 		Buffers[0].cbBuffer = length;
1317 		Buffers[0].pvBuffer = buffer;
1318 		Message.cBuffers = 1;
1319 	}
1320 	else if (ntlm || nego)
1321 	{
1322 		CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
1323 		public_key_length = nla->PublicKey.cbBuffer;
1324 		Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1325 		Buffers[0].cbBuffer = signature_length;
1326 		Buffers[0].pvBuffer = buffer;
1327 		Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */
1328 		Buffers[1].cbBuffer = length - signature_length;
1329 		Buffers[1].pvBuffer = buffer + signature_length;
1330 		Message.cBuffers = 2;
1331 	}
1332 
1333 	Message.ulVersion = SECBUFFER_VERSION;
1334 	Message.pBuffers = (PSecBuffer)&Buffers;
1335 	status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
1336 
1337 	if (status != SEC_E_OK)
1338 	{
1339 		WLog_ERR(TAG, "DecryptMessage failure %s [%08" PRIX32 "]", GetSecurityStatusString(status),
1340 		         status);
1341 		goto fail;
1342 	}
1343 
1344 	if (krb)
1345 	{
1346 		public_key1 = public_key2 = (BYTE*)nla->pubKeyAuth.pvBuffer;
1347 		public_key_length = length;
1348 	}
1349 	else if (ntlm || nego)
1350 	{
1351 		public_key1 = (BYTE*)nla->PublicKey.pvBuffer;
1352 		public_key2 = (BYTE*)Buffers[1].pvBuffer;
1353 	}
1354 
1355 	if (!nla->server)
1356 	{
1357 		/* server echos the public key +1 */
1358 		ap_integer_decrement_le(public_key2, public_key_length);
1359 	}
1360 
1361 	if (!public_key1 || !public_key2 || memcmp(public_key1, public_key2, public_key_length) != 0)
1362 	{
1363 		WLog_ERR(TAG, "Could not verify server's public key echo");
1364 #if defined(WITH_DEBUG_NLA)
1365 		WLog_ERR(TAG, "Expected (length = %d):", public_key_length);
1366 		winpr_HexDump(TAG, WLOG_ERROR, public_key1, public_key_length);
1367 		WLog_ERR(TAG, "Actual (length = %d):", public_key_length);
1368 		winpr_HexDump(TAG, WLOG_ERROR, public_key2, public_key_length);
1369 #endif
1370 		status = SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */
1371 		goto fail;
1372 	}
1373 
1374 	status = SEC_E_OK;
1375 fail:
1376 	free(buffer);
1377 	return status;
1378 }
1379 
nla_decrypt_public_key_hash(rdpNla * nla)1380 SECURITY_STATUS nla_decrypt_public_key_hash(rdpNla* nla)
1381 {
1382 	unsigned long length;
1383 	BYTE* buffer = NULL;
1384 	ULONG pfQOP = 0;
1385 	int signature_length;
1386 	SecBuffer Buffers[2] = { { 0 } };
1387 	SecBufferDesc Message;
1388 	WINPR_DIGEST_CTX* sha256 = NULL;
1389 	BYTE serverClientHash[WINPR_SHA256_DIGEST_LENGTH];
1390 	SECURITY_STATUS status = SEC_E_INVALID_TOKEN;
1391 	const BOOL krb =
1392 	    (_tcsncmp(nla->packageName, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0);
1393 	const BYTE* hashMagic = nla->server ? ClientServerHashMagic : ServerClientHashMagic;
1394 	const size_t hashSize =
1395 	    nla->server ? sizeof(ClientServerHashMagic) : sizeof(ServerClientHashMagic);
1396 	signature_length = nla->pubKeyAuth.cbBuffer - WINPR_SHA256_DIGEST_LENGTH;
1397 
1398 	if ((signature_length < 0) || (signature_length > (int)nla->ContextSizes.cbSecurityTrailer))
1399 	{
1400 		WLog_ERR(TAG, "unexpected pubKeyAuth buffer size: %" PRIu32 "", nla->pubKeyAuth.cbBuffer);
1401 		goto fail;
1402 	}
1403 
1404 	length = nla->pubKeyAuth.cbBuffer;
1405 	buffer = (BYTE*)malloc(length);
1406 
1407 	if (!buffer)
1408 	{
1409 		status = SEC_E_INSUFFICIENT_MEMORY;
1410 		goto fail;
1411 	}
1412 
1413 	if (krb)
1414 	{
1415 		CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
1416 		Buffers[0].BufferType = SECBUFFER_DATA; /* Encrypted Hash */
1417 		Buffers[0].cbBuffer = length;
1418 		Buffers[0].pvBuffer = buffer;
1419 		Message.cBuffers = 1;
1420 	}
1421 	else
1422 	{
1423 		CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
1424 		Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1425 		Buffers[0].cbBuffer = signature_length;
1426 		Buffers[0].pvBuffer = buffer;
1427 		Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted Hash */
1428 		Buffers[1].cbBuffer = WINPR_SHA256_DIGEST_LENGTH;
1429 		Buffers[1].pvBuffer = buffer + signature_length;
1430 		Message.cBuffers = 2;
1431 	}
1432 
1433 	Message.ulVersion = SECBUFFER_VERSION;
1434 	Message.pBuffers = (PSecBuffer)&Buffers;
1435 	status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
1436 
1437 	if (status != SEC_E_OK)
1438 	{
1439 		WLog_ERR(TAG, "DecryptMessage failure %s [%08" PRIX32 "]", GetSecurityStatusString(status),
1440 		         status);
1441 		goto fail;
1442 	}
1443 
1444 	/* generate SHA256 of following data: ServerClientHashMagic, Nonce, SubjectPublicKey */
1445 	if (!(sha256 = winpr_Digest_New()))
1446 		goto fail;
1447 
1448 	if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
1449 		goto fail;
1450 
1451 	/* include trailing \0 from hashMagic */
1452 	if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
1453 		goto fail;
1454 
1455 	if (!winpr_Digest_Update(sha256, nla->ClientNonce.pvBuffer, nla->ClientNonce.cbBuffer))
1456 		goto fail;
1457 
1458 	/* SubjectPublicKey */
1459 	if (!winpr_Digest_Update(sha256, nla->PublicKey.pvBuffer, nla->PublicKey.cbBuffer))
1460 		goto fail;
1461 
1462 	if (!winpr_Digest_Final(sha256, serverClientHash, sizeof(serverClientHash)))
1463 		goto fail;
1464 
1465 	/* verify hash */
1466 	if (memcmp(serverClientHash, Buffers[krb ? 0 : 1].pvBuffer, WINPR_SHA256_DIGEST_LENGTH) != 0)
1467 	{
1468 		WLog_ERR(TAG, "Could not verify server's hash");
1469 		status = SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */
1470 		goto fail;
1471 	}
1472 
1473 	status = SEC_E_OK;
1474 fail:
1475 	free(buffer);
1476 	winpr_Digest_Free(sha256);
1477 	return status;
1478 }
1479 
nla_sizeof_ts_password_creds(rdpNla * nla)1480 static size_t nla_sizeof_ts_password_creds(rdpNla* nla)
1481 {
1482 	size_t length = 0;
1483 
1484 	if (nla->identity)
1485 	{
1486 		length += ber_sizeof_sequence_octet_string(nla->identity->DomainLength * 2);
1487 		length += ber_sizeof_sequence_octet_string(nla->identity->UserLength * 2);
1488 		length += ber_sizeof_sequence_octet_string(nla->identity->PasswordLength * 2);
1489 	}
1490 
1491 	return length;
1492 }
1493 
nla_sizeof_ts_credentials(rdpNla * nla)1494 static size_t nla_sizeof_ts_credentials(rdpNla* nla)
1495 {
1496 	size_t size = 0;
1497 	size += ber_sizeof_integer(1);
1498 	size += ber_sizeof_contextual_tag(ber_sizeof_integer(1));
1499 	size +=
1500 	    ber_sizeof_sequence_octet_string(ber_sizeof_sequence(nla_sizeof_ts_password_creds(nla)));
1501 	return size;
1502 }
1503 
nla_read_ts_password_creds(rdpNla * nla,wStream * s)1504 BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s)
1505 {
1506 	size_t length;
1507 
1508 	if (!nla->identity)
1509 	{
1510 		WLog_ERR(TAG, "nla->identity is NULL!");
1511 		return FALSE;
1512 	}
1513 
1514 	/* TSPasswordCreds (SEQUENCE)
1515 	 * Initialise to default values. */
1516 	nla->identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
1517 	nla->identity->UserLength = (UINT32)0;
1518 	nla->identity->User = NULL;
1519 	nla->identity->DomainLength = (UINT32)0;
1520 	nla->identity->Domain = NULL;
1521 	nla->identity->Password = NULL;
1522 	nla->identity->PasswordLength = (UINT32)0;
1523 
1524 	if (!ber_read_sequence_tag(s, &length))
1525 		return FALSE;
1526 
1527 	/* The sequence is empty, return early,
1528 	 * TSPasswordCreds (SEQUENCE) is optional. */
1529 	if (length == 0)
1530 		return TRUE;
1531 
1532 	/* [0] domainName (OCTET STRING) */
1533 	if (!ber_read_contextual_tag(s, 0, &length, TRUE) || !ber_read_octet_string_tag(s, &length))
1534 	{
1535 		return FALSE;
1536 	}
1537 
1538 	nla->identity->DomainLength = (UINT32)length;
1539 
1540 	if (nla->identity->DomainLength > 0)
1541 	{
1542 		nla->identity->Domain = (UINT16*)malloc(length);
1543 
1544 		if (!nla->identity->Domain)
1545 			return FALSE;
1546 
1547 		CopyMemory(nla->identity->Domain, Stream_Pointer(s), nla->identity->DomainLength);
1548 		Stream_Seek(s, nla->identity->DomainLength);
1549 		nla->identity->DomainLength /= 2;
1550 	}
1551 
1552 	/* [1] userName (OCTET STRING) */
1553 	if (!ber_read_contextual_tag(s, 1, &length, TRUE) || !ber_read_octet_string_tag(s, &length))
1554 	{
1555 		return FALSE;
1556 	}
1557 
1558 	nla->identity->UserLength = (UINT32)length;
1559 
1560 	if (nla->identity->UserLength > 0)
1561 	{
1562 		nla->identity->User = (UINT16*)malloc(length);
1563 
1564 		if (!nla->identity->User)
1565 			return FALSE;
1566 
1567 		CopyMemory(nla->identity->User, Stream_Pointer(s), nla->identity->UserLength);
1568 		Stream_Seek(s, nla->identity->UserLength);
1569 		nla->identity->UserLength /= 2;
1570 	}
1571 
1572 	/* [2] password (OCTET STRING) */
1573 	if (!ber_read_contextual_tag(s, 2, &length, TRUE) || !ber_read_octet_string_tag(s, &length))
1574 	{
1575 		return FALSE;
1576 	}
1577 
1578 	nla->identity->PasswordLength = (UINT32)length;
1579 
1580 	if (nla->identity->PasswordLength > 0)
1581 	{
1582 		nla->identity->Password = (UINT16*)malloc(length);
1583 
1584 		if (!nla->identity->Password)
1585 			return FALSE;
1586 
1587 		CopyMemory(nla->identity->Password, Stream_Pointer(s), nla->identity->PasswordLength);
1588 		Stream_Seek(s, nla->identity->PasswordLength);
1589 		nla->identity->PasswordLength /= 2;
1590 	}
1591 
1592 	return TRUE;
1593 }
1594 
nla_write_ts_password_creds(rdpNla * nla,wStream * s)1595 static size_t nla_write_ts_password_creds(rdpNla* nla, wStream* s)
1596 {
1597 	size_t size = 0;
1598 	size_t innerSize = nla_sizeof_ts_password_creds(nla);
1599 	/* TSPasswordCreds (SEQUENCE) */
1600 	size += ber_write_sequence_tag(s, innerSize);
1601 
1602 	if (nla->identity)
1603 	{
1604 		/* [0] domainName (OCTET STRING) */
1605 		size += ber_write_sequence_octet_string(s, 0, (BYTE*)nla->identity->Domain,
1606 		                                        nla->identity->DomainLength * 2);
1607 		/* [1] userName (OCTET STRING) */
1608 		size += ber_write_sequence_octet_string(s, 1, (BYTE*)nla->identity->User,
1609 		                                        nla->identity->UserLength * 2);
1610 		/* [2] password (OCTET STRING) */
1611 		size += ber_write_sequence_octet_string(s, 2, (BYTE*)nla->identity->Password,
1612 		                                        nla->identity->PasswordLength * 2);
1613 	}
1614 
1615 	return size;
1616 }
1617 
nla_read_ts_credentials(rdpNla * nla,PSecBuffer ts_credentials)1618 static BOOL nla_read_ts_credentials(rdpNla* nla, PSecBuffer ts_credentials)
1619 {
1620 	wStream* s;
1621 	size_t length;
1622 	size_t ts_password_creds_length = 0;
1623 	BOOL ret;
1624 
1625 	if (!ts_credentials || !ts_credentials->pvBuffer)
1626 		return FALSE;
1627 
1628 	s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer);
1629 
1630 	if (!s)
1631 	{
1632 		WLog_ERR(TAG, "Stream_New failed!");
1633 		return FALSE;
1634 	}
1635 
1636 	/* TSCredentials (SEQUENCE) */
1637 	ret = ber_read_sequence_tag(s, &length) &&
1638 	      /* [0] credType (INTEGER) */
1639 	      ber_read_contextual_tag(s, 0, &length, TRUE) && ber_read_integer(s, NULL) &&
1640 	      /* [1] credentials (OCTET STRING) */
1641 	      ber_read_contextual_tag(s, 1, &length, TRUE) &&
1642 	      ber_read_octet_string_tag(s, &ts_password_creds_length) &&
1643 	      nla_read_ts_password_creds(nla, s);
1644 	Stream_Free(s, FALSE);
1645 	return ret;
1646 }
1647 
nla_write_ts_credentials(rdpNla * nla,wStream * s)1648 static size_t nla_write_ts_credentials(rdpNla* nla, wStream* s)
1649 {
1650 	size_t size = 0;
1651 	size_t passwordSize;
1652 	size_t innerSize = nla_sizeof_ts_credentials(nla);
1653 	/* TSCredentials (SEQUENCE) */
1654 	size += ber_write_sequence_tag(s, innerSize);
1655 	/* [0] credType (INTEGER) */
1656 	size += ber_write_contextual_tag(s, 0, ber_sizeof_integer(1), TRUE);
1657 	size += ber_write_integer(s, 1);
1658 	/* [1] credentials (OCTET STRING) */
1659 	passwordSize = ber_sizeof_sequence(nla_sizeof_ts_password_creds(nla));
1660 	size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), TRUE);
1661 	size += ber_write_octet_string_tag(s, passwordSize);
1662 	size += nla_write_ts_password_creds(nla, s);
1663 	return size;
1664 }
1665 
1666 /**
1667  * Encode TSCredentials structure.
1668  * @param credssp
1669  */
1670 
nla_encode_ts_credentials(rdpNla * nla)1671 static BOOL nla_encode_ts_credentials(rdpNla* nla)
1672 {
1673 	wStream* s;
1674 	size_t length;
1675 	int DomainLength = 0;
1676 	int UserLength = 0;
1677 	int PasswordLength = 0;
1678 
1679 	if (nla->identity)
1680 	{
1681 		/* TSPasswordCreds */
1682 		DomainLength = nla->identity->DomainLength;
1683 		UserLength = nla->identity->UserLength;
1684 		PasswordLength = nla->identity->PasswordLength;
1685 	}
1686 
1687 	if (nla->settings->DisableCredentialsDelegation && nla->identity)
1688 	{
1689 		/* TSPasswordCreds */
1690 		nla->identity->DomainLength = 0;
1691 		nla->identity->UserLength = 0;
1692 		nla->identity->PasswordLength = 0;
1693 	}
1694 
1695 	length = ber_sizeof_sequence(nla_sizeof_ts_credentials(nla));
1696 
1697 	if (!sspi_SecBufferAlloc(&nla->tsCredentials, length))
1698 	{
1699 		WLog_ERR(TAG, "sspi_SecBufferAlloc failed!");
1700 		return FALSE;
1701 	}
1702 
1703 	s = Stream_New((BYTE*)nla->tsCredentials.pvBuffer, length);
1704 
1705 	if (!s)
1706 	{
1707 		sspi_SecBufferFree(&nla->tsCredentials);
1708 		WLog_ERR(TAG, "Stream_New failed!");
1709 		return FALSE;
1710 	}
1711 
1712 	nla_write_ts_credentials(nla, s);
1713 
1714 	if (nla->settings->DisableCredentialsDelegation && nla->identity)
1715 	{
1716 		/* TSPasswordCreds */
1717 		nla->identity->DomainLength = DomainLength;
1718 		nla->identity->UserLength = UserLength;
1719 		nla->identity->PasswordLength = PasswordLength;
1720 	}
1721 
1722 	Stream_Free(s, FALSE);
1723 	return TRUE;
1724 }
1725 
nla_encrypt_ts_credentials(rdpNla * nla)1726 static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla)
1727 {
1728 	SecBuffer Buffers[2] = { { 0 } };
1729 	SecBufferDesc Message;
1730 	SECURITY_STATUS status;
1731 	const BOOL krb =
1732 	    (_tcsncmp(nla->packageName, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0);
1733 	const BOOL nego = (_tcsncmp(nla->packageName, NEGO_SSP_NAME, ARRAYSIZE(NEGO_SSP_NAME)) == 0);
1734 	const BOOL ntlm = (_tcsncmp(nla->packageName, NTLM_SSP_NAME, ARRAYSIZE(NTLM_SSP_NAME)) == 0);
1735 
1736 	if (!nla_encode_ts_credentials(nla))
1737 		return SEC_E_INSUFFICIENT_MEMORY;
1738 
1739 	if (!sspi_SecBufferAlloc(&nla->authInfo,
1740 	                         nla->tsCredentials.cbBuffer + nla->ContextSizes.cbSecurityTrailer))
1741 		return SEC_E_INSUFFICIENT_MEMORY;
1742 
1743 	if (krb)
1744 	{
1745 		Buffers[0].BufferType = SECBUFFER_DATA; /* TSCredentials */
1746 		Buffers[0].cbBuffer = nla->tsCredentials.cbBuffer;
1747 		Buffers[0].pvBuffer = nla->authInfo.pvBuffer;
1748 		CopyMemory(Buffers[0].pvBuffer, nla->tsCredentials.pvBuffer, Buffers[0].cbBuffer);
1749 		Message.cBuffers = 1;
1750 	}
1751 	else if (ntlm || nego)
1752 	{
1753 		Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1754 		Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
1755 		Buffers[0].pvBuffer = nla->authInfo.pvBuffer;
1756 		MoveMemory(Buffers[0].pvBuffer, nla->authInfo.pvBuffer, Buffers[0].cbBuffer);
1757 		Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
1758 		Buffers[1].cbBuffer = nla->tsCredentials.cbBuffer;
1759 		Buffers[1].pvBuffer = &((BYTE*)nla->authInfo.pvBuffer)[Buffers[0].cbBuffer];
1760 		CopyMemory(Buffers[1].pvBuffer, nla->tsCredentials.pvBuffer, Buffers[1].cbBuffer);
1761 		Message.cBuffers = 2;
1762 	}
1763 
1764 	Message.ulVersion = SECBUFFER_VERSION;
1765 	Message.pBuffers = (PSecBuffer)&Buffers;
1766 	status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++);
1767 
1768 	if (status != SEC_E_OK)
1769 	{
1770 		WLog_ERR(TAG, "EncryptMessage failure %s [0x%08" PRIX32 "]",
1771 		         GetSecurityStatusString(status), status);
1772 		return status;
1773 	}
1774 
1775 	if (Message.cBuffers == 2 && Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer)
1776 	{
1777 		/* IMPORTANT: EncryptMessage may not use all the signature space, so we need to shrink the
1778 		 * excess between the buffers */
1779 		MoveMemory(((BYTE*)Buffers[0].pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer,
1780 		           Buffers[1].cbBuffer);
1781 		nla->authInfo.cbBuffer = Buffers[0].cbBuffer + Buffers[1].cbBuffer;
1782 	}
1783 
1784 	return SEC_E_OK;
1785 }
1786 
nla_decrypt_ts_credentials(rdpNla * nla)1787 static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
1788 {
1789 	int length;
1790 	BYTE* buffer;
1791 	ULONG pfQOP;
1792 	SecBuffer Buffers[2] = { { 0 } };
1793 	SecBufferDesc Message;
1794 	SECURITY_STATUS status;
1795 	const BOOL krb =
1796 	    (_tcsncmp(nla->packageName, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0);
1797 	const BOOL nego = (_tcsncmp(nla->packageName, NEGO_SSP_NAME, ARRAYSIZE(NEGO_SSP_NAME)) == 0);
1798 	const BOOL ntlm = (_tcsncmp(nla->packageName, NTLM_SSP_NAME, ARRAYSIZE(NTLM_SSP_NAME)) == 0);
1799 
1800 	if (nla->authInfo.cbBuffer < 1)
1801 	{
1802 		WLog_ERR(TAG, "nla_decrypt_ts_credentials missing authInfo buffer");
1803 		return SEC_E_INVALID_TOKEN;
1804 	}
1805 
1806 	length = nla->authInfo.cbBuffer;
1807 	buffer = (BYTE*)malloc(length);
1808 
1809 	if (!buffer)
1810 		return SEC_E_INSUFFICIENT_MEMORY;
1811 
1812 	if (krb)
1813 	{
1814 		CopyMemory(buffer, nla->authInfo.pvBuffer, length);
1815 		Buffers[0].BufferType = SECBUFFER_DATA; /* Wrapped and encrypted TSCredentials */
1816 		Buffers[0].cbBuffer = length;
1817 		Buffers[0].pvBuffer = buffer;
1818 		Message.cBuffers = 1;
1819 	}
1820 	else if (ntlm || nego)
1821 	{
1822 		CopyMemory(buffer, nla->authInfo.pvBuffer, length);
1823 		Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
1824 		Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
1825 		Buffers[0].pvBuffer = buffer;
1826 		Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
1827 		Buffers[1].cbBuffer = length - nla->ContextSizes.cbSecurityTrailer;
1828 		Buffers[1].pvBuffer = &buffer[Buffers[0].cbBuffer];
1829 		Message.cBuffers = 2;
1830 	}
1831 
1832 	Message.ulVersion = SECBUFFER_VERSION;
1833 	Message.pBuffers = (PSecBuffer)&Buffers;
1834 	status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
1835 
1836 	if (status != SEC_E_OK)
1837 	{
1838 		WLog_ERR(TAG, "DecryptMessage failure %s [0x%08" PRIX32 "]",
1839 		         GetSecurityStatusString(status), status);
1840 		free(buffer);
1841 		return status;
1842 	}
1843 
1844 	if (!nla_read_ts_credentials(nla, &Buffers[1]))
1845 	{
1846 		free(buffer);
1847 		return SEC_E_INSUFFICIENT_MEMORY;
1848 	}
1849 
1850 	free(buffer);
1851 	return SEC_E_OK;
1852 }
1853 
nla_sizeof_nego_token(size_t length)1854 static size_t nla_sizeof_nego_token(size_t length)
1855 {
1856 	length = ber_sizeof_octet_string(length);
1857 	length += ber_sizeof_contextual_tag(length);
1858 	return length;
1859 }
1860 
nla_sizeof_nego_tokens(size_t length)1861 static size_t nla_sizeof_nego_tokens(size_t length)
1862 {
1863 	length = nla_sizeof_nego_token(length);
1864 	length += ber_sizeof_sequence_tag(length);
1865 	length += ber_sizeof_sequence_tag(length);
1866 	length += ber_sizeof_contextual_tag(length);
1867 	return length;
1868 }
1869 
nla_sizeof_pub_key_auth(size_t length)1870 static size_t nla_sizeof_pub_key_auth(size_t length)
1871 {
1872 	length = ber_sizeof_octet_string(length);
1873 	length += ber_sizeof_contextual_tag(length);
1874 	return length;
1875 }
1876 
nla_sizeof_auth_info(size_t length)1877 static size_t nla_sizeof_auth_info(size_t length)
1878 {
1879 	length = ber_sizeof_octet_string(length);
1880 	length += ber_sizeof_contextual_tag(length);
1881 	return length;
1882 }
1883 
nla_sizeof_client_nonce(size_t length)1884 static size_t nla_sizeof_client_nonce(size_t length)
1885 {
1886 	length = ber_sizeof_octet_string(length);
1887 	length += ber_sizeof_contextual_tag(length);
1888 	return length;
1889 }
1890 
nla_sizeof_ts_request(size_t length)1891 static size_t nla_sizeof_ts_request(size_t length)
1892 {
1893 	length += ber_sizeof_integer(2);
1894 	length += ber_sizeof_contextual_tag(3);
1895 	return length;
1896 }
1897 
1898 /**
1899  * Send CredSSP message.
1900  * @param credssp
1901  */
1902 
nla_send(rdpNla * nla,const char * msg)1903 BOOL nla_send(rdpNla* nla, const char* msg)
1904 {
1905 	BOOL rc = TRUE;
1906 	wStream* s;
1907 	size_t length;
1908 	size_t ts_request_length;
1909 	size_t nego_tokens_length = 0;
1910 	size_t pub_key_auth_length = 0;
1911 	size_t auth_info_length = 0;
1912 	size_t error_code_context_length = 0;
1913 	size_t error_code_length = 0;
1914 	size_t client_nonce_length = 0;
1915 	WLog_DBG(TAG, "%s", msg);
1916 	nla_buffer_print(nla);
1917 
1918 	nego_tokens_length =
1919 	    (nla->negoToken.cbBuffer > 0) ? nla_sizeof_nego_tokens(nla->negoToken.cbBuffer) : 0;
1920 	pub_key_auth_length =
1921 	    (nla->pubKeyAuth.cbBuffer > 0) ? nla_sizeof_pub_key_auth(nla->pubKeyAuth.cbBuffer) : 0;
1922 	auth_info_length =
1923 	    (nla->authInfo.cbBuffer > 0) ? nla_sizeof_auth_info(nla->authInfo.cbBuffer) : 0;
1924 	client_nonce_length =
1925 	    (nla->ClientNonce.cbBuffer > 0) ? nla_sizeof_client_nonce(nla->ClientNonce.cbBuffer) : 0;
1926 
1927 	if (nla->peerVersion >= 3 && nla->peerVersion != 5 && nla->errorCode != 0)
1928 	{
1929 		error_code_length = ber_sizeof_integer(nla->errorCode);
1930 		error_code_context_length = ber_sizeof_contextual_tag(error_code_length);
1931 	}
1932 
1933 	length = nego_tokens_length + pub_key_auth_length + auth_info_length +
1934 	         error_code_context_length + error_code_length + client_nonce_length;
1935 	ts_request_length = nla_sizeof_ts_request(length);
1936 	s = Stream_New(NULL, ber_sizeof_sequence(ts_request_length));
1937 
1938 	if (!s)
1939 	{
1940 		WLog_ERR(TAG, "Stream_New failed!");
1941 		return FALSE;
1942 	}
1943 
1944 	/* TSRequest */
1945 	ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */
1946 	/* [0] version */
1947 	ber_write_contextual_tag(s, 0, 3, TRUE);
1948 	ber_write_integer(s, nla->version); /* INTEGER */
1949 
1950 	/* [1] negoTokens (NegoData) */
1951 	if (nego_tokens_length > 0)
1952 	{
1953 		length = ber_write_contextual_tag(
1954 		    s, 1,
1955 		    ber_sizeof_sequence(
1956 		        ber_sizeof_sequence(ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer))),
1957 		    TRUE); /* NegoData */
1958 		length +=
1959 		    ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(
1960 		                                  nla->negoToken.cbBuffer))); /* SEQUENCE OF NegoDataItem */
1961 		length += ber_write_sequence_tag(
1962 		    s, ber_sizeof_sequence_octet_string(nla->negoToken.cbBuffer)); /* NegoDataItem */
1963 		length += ber_write_sequence_octet_string(s, 0, (BYTE*)nla->negoToken.pvBuffer,
1964 		                                          nla->negoToken.cbBuffer); /* OCTET STRING */
1965 
1966 		if (length != nego_tokens_length)
1967 		{
1968 			Stream_Free(s, TRUE);
1969 			return FALSE;
1970 		}
1971 	}
1972 
1973 	/* [2] authInfo (OCTET STRING) */
1974 	if (auth_info_length > 0)
1975 	{
1976 		if (ber_write_sequence_octet_string(s, 2, nla->authInfo.pvBuffer, nla->authInfo.cbBuffer) !=
1977 		    auth_info_length)
1978 		{
1979 			Stream_Free(s, TRUE);
1980 			return FALSE;
1981 		}
1982 	}
1983 
1984 	/* [3] pubKeyAuth (OCTET STRING) */
1985 	if (pub_key_auth_length > 0)
1986 	{
1987 		if (ber_write_sequence_octet_string(s, 3, nla->pubKeyAuth.pvBuffer,
1988 		                                    nla->pubKeyAuth.cbBuffer) != pub_key_auth_length)
1989 		{
1990 			Stream_Free(s, TRUE);
1991 			return FALSE;
1992 		}
1993 	}
1994 
1995 	/* [4] errorCode (INTEGER) */
1996 	if (error_code_length > 0)
1997 	{
1998 		ber_write_contextual_tag(s, 4, error_code_length, TRUE);
1999 		ber_write_integer(s, nla->errorCode);
2000 	}
2001 
2002 	/* [5] clientNonce (OCTET STRING) */
2003 	if (client_nonce_length > 0)
2004 	{
2005 		if (ber_write_sequence_octet_string(s, 5, nla->ClientNonce.pvBuffer,
2006 		                                    nla->ClientNonce.cbBuffer) != client_nonce_length)
2007 		{
2008 			Stream_Free(s, TRUE);
2009 			return FALSE;
2010 		}
2011 	}
2012 
2013 	Stream_SealLength(s);
2014 
2015 	if (transport_write(nla->transport, s) < 0)
2016 		rc = FALSE;
2017 
2018 	Stream_Free(s, TRUE);
2019 	return rc;
2020 }
2021 
nla_decode_ts_request(rdpNla * nla,wStream * s)2022 static int nla_decode_ts_request(rdpNla* nla, wStream* s)
2023 {
2024 	size_t length;
2025 	UINT32 version = 0;
2026 
2027 	/* TSRequest */
2028 	if (!ber_read_sequence_tag(s, &length) || !ber_read_contextual_tag(s, 0, &length, TRUE) ||
2029 	    !ber_read_integer(s, &version))
2030 	{
2031 		return -1;
2032 	}
2033 
2034 	if (nla->peerVersion == 0)
2035 	{
2036 		WLog_DBG(TAG, "CredSSP protocol support %" PRIu32 ", peer supports %" PRIu32, nla->version,
2037 		         version);
2038 		nla->peerVersion = version;
2039 	}
2040 
2041 	/* if the peer suddenly changed its version - kick it */
2042 	if (nla->peerVersion != version)
2043 	{
2044 		WLog_ERR(TAG, "CredSSP peer changed protocol version from %" PRIu32 " to %" PRIu32,
2045 		         nla->peerVersion, version);
2046 		return -1;
2047 	}
2048 
2049 	/* [1] negoTokens (NegoData) */
2050 	if (ber_read_contextual_tag(s, 1, &length, TRUE) != FALSE)
2051 	{
2052 		if (!ber_read_sequence_tag(s, &length) ||            /* SEQUENCE OF NegoDataItem */
2053 		    !ber_read_sequence_tag(s, &length) ||            /* NegoDataItem */
2054 		    !ber_read_contextual_tag(s, 0, &length, TRUE) || /* [0] negoToken */
2055 		    !ber_read_octet_string_tag(s, &length) ||        /* OCTET STRING */
2056 		    Stream_GetRemainingLength(s) < length)
2057 		{
2058 			return -1;
2059 		}
2060 
2061 		sspi_SecBufferFree(&nla->negoToken);
2062 		if (!sspi_SecBufferAlloc(&nla->negoToken, length))
2063 			return -1;
2064 
2065 		Stream_Read(s, nla->negoToken.pvBuffer, length);
2066 		nla->negoToken.cbBuffer = length;
2067 	}
2068 
2069 	/* [2] authInfo (OCTET STRING) */
2070 	if (ber_read_contextual_tag(s, 2, &length, TRUE) != FALSE)
2071 	{
2072 		if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
2073 		    Stream_GetRemainingLength(s) < length)
2074 			return -1;
2075 
2076 		if (!sspi_SecBufferAlloc(&nla->authInfo, length))
2077 			return -1;
2078 
2079 		Stream_Read(s, nla->authInfo.pvBuffer, length);
2080 		nla->authInfo.cbBuffer = length;
2081 	}
2082 
2083 	/* [3] pubKeyAuth (OCTET STRING) */
2084 	if (ber_read_contextual_tag(s, 3, &length, TRUE) != FALSE)
2085 	{
2086 		if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
2087 		    Stream_GetRemainingLength(s) < length)
2088 			return -1;
2089 
2090 		sspi_SecBufferFree(&nla->pubKeyAuth);
2091 		if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, length))
2092 			return -1;
2093 
2094 		Stream_Read(s, nla->pubKeyAuth.pvBuffer, length);
2095 		nla->pubKeyAuth.cbBuffer = length;
2096 	}
2097 
2098 	/* [4] errorCode (INTEGER) */
2099 	if (nla->peerVersion >= 3)
2100 	{
2101 		if (ber_read_contextual_tag(s, 4, &length, TRUE) != FALSE)
2102 		{
2103 			if (!ber_read_integer(s, &nla->errorCode))
2104 				return -1;
2105 			WLog_WARN(TAG, "SPNEGO received NTSTATUS: %s [0x%08" PRIX32 "] from server",
2106 			          GetSecurityStatusString(nla->errorCode), nla->errorCode);
2107 		}
2108 
2109 		if (nla->peerVersion >= 5)
2110 		{
2111 			if (ber_read_contextual_tag(s, 5, &length, TRUE) != FALSE)
2112 			{
2113 				if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
2114 				    Stream_GetRemainingLength(s) < length)
2115 					return -1;
2116 
2117 				sspi_SecBufferFree(&nla->ClientNonce);
2118 				if (!sspi_SecBufferAlloc(&nla->ClientNonce, length))
2119 					return -1;
2120 
2121 				Stream_Read(s, nla->ClientNonce.pvBuffer, length);
2122 				nla->ClientNonce.cbBuffer = length;
2123 			}
2124 		}
2125 	}
2126 
2127 	return 1;
2128 }
2129 
nla_recv_pdu(rdpNla * nla,wStream * s)2130 int nla_recv_pdu(rdpNla* nla, wStream* s)
2131 {
2132 	if (nla_decode_ts_request(nla, s) < 1)
2133 		return -1;
2134 
2135 	if (nla->errorCode)
2136 	{
2137 		UINT32 code;
2138 
2139 		switch (nla->errorCode)
2140 		{
2141 			case STATUS_PASSWORD_MUST_CHANGE:
2142 				code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2143 				break;
2144 
2145 			case STATUS_PASSWORD_EXPIRED:
2146 				code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2147 				break;
2148 
2149 			case STATUS_ACCOUNT_DISABLED:
2150 				code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2151 				break;
2152 
2153 			case STATUS_LOGON_FAILURE:
2154 				code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2155 				break;
2156 
2157 			case STATUS_WRONG_PASSWORD:
2158 				code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2159 				break;
2160 
2161 			case STATUS_ACCESS_DENIED:
2162 				code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2163 				break;
2164 
2165 			case STATUS_ACCOUNT_RESTRICTION:
2166 				code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2167 				break;
2168 
2169 			case STATUS_ACCOUNT_LOCKED_OUT:
2170 				code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2171 				break;
2172 
2173 			case STATUS_ACCOUNT_EXPIRED:
2174 				code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2175 				break;
2176 
2177 			case STATUS_LOGON_TYPE_NOT_GRANTED:
2178 				code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2179 				break;
2180 
2181 			default:
2182 				WLog_ERR(TAG, "SPNEGO failed with NTSTATUS: %s [0x%08" PRIX32 "]",
2183 				         GetSecurityStatusString(nla->errorCode), nla->errorCode);
2184 				code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2185 				break;
2186 		}
2187 
2188 		freerdp_set_last_error_log(nla->instance->context, code);
2189 		return -1;
2190 	}
2191 
2192 	if (nla_client_recv(nla) < 1)
2193 		return -1;
2194 
2195 	return 1;
2196 }
2197 
nla_recv(rdpNla * nla,const char * msg)2198 int nla_recv(rdpNla* nla, const char* msg)
2199 {
2200 	wStream* s;
2201 	int status;
2202 	s = Stream_New(NULL, 4096);
2203 
2204 	if (!s)
2205 	{
2206 		WLog_ERR(TAG, "[%s] Stream_New failed!", __FUNCTION__);
2207 		return -1;
2208 	}
2209 
2210 	status = transport_read_pdu(nla->transport, s);
2211 
2212 	if (status < 0)
2213 	{
2214 		WLog_ERR(TAG, "[%s] error: %d", __FUNCTION__, status);
2215 		Stream_Free(s, TRUE);
2216 		return -1;
2217 	}
2218 
2219 	if (nla_decode_ts_request(nla, s) < 1)
2220 	{
2221 		WLog_ERR(TAG, "[%s] Invalid data received, aborting", __FUNCTION__);
2222 		Stream_Free(s, TRUE);
2223 		return -1;
2224 	}
2225 
2226 	Stream_Free(s, TRUE);
2227 	WLog_DBG(TAG, "[%s] %s", __FUNCTION__, msg);
2228 	nla_buffer_print(nla);
2229 	return 1;
2230 }
2231 
nla_buffer_print(rdpNla * nla)2232 void nla_buffer_print(rdpNla* nla)
2233 {
2234 	if (nla->negoToken.cbBuffer > 0)
2235 	{
2236 		WLog_DBG(TAG, "NLA.negoToken (length = %" PRIu32 "):", nla->negoToken.cbBuffer);
2237 #if defined(WITH_DEBUG_NLA)
2238 		winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);
2239 #endif
2240 	}
2241 
2242 	if (nla->pubKeyAuth.cbBuffer > 0)
2243 	{
2244 		WLog_DBG(TAG, "NLA.pubKeyAuth (length = %" PRIu32 "):", nla->pubKeyAuth.cbBuffer);
2245 #if defined(WITH_DEBUG_NLA)
2246 		winpr_HexDump(TAG, WLOG_DEBUG, nla->pubKeyAuth.pvBuffer, nla->pubKeyAuth.cbBuffer);
2247 #endif
2248 	}
2249 
2250 	if (nla->authInfo.cbBuffer > 0)
2251 	{
2252 		WLog_DBG(TAG, "NLA.authInfo (length = %" PRIu32 "):", nla->authInfo.cbBuffer);
2253 #if defined(WITH_DEBUG_NLA)
2254 		winpr_HexDump(TAG, WLOG_DEBUG, nla->authInfo.pvBuffer, nla->authInfo.cbBuffer);
2255 #endif
2256 	}
2257 }
2258 
nla_buffer_free(rdpNla * nla)2259 void nla_buffer_free(rdpNla* nla)
2260 {
2261 	sspi_SecBufferFree(&nla->negoToken);
2262 	sspi_SecBufferFree(&nla->pubKeyAuth);
2263 	sspi_SecBufferFree(&nla->authInfo);
2264 }
2265 
nla_make_spn(const char * ServiceClass,const char * hostname)2266 LPTSTR nla_make_spn(const char* ServiceClass, const char* hostname)
2267 {
2268 	DWORD status;
2269 	DWORD SpnLength;
2270 	LPTSTR hostnameX = NULL;
2271 	LPTSTR ServiceClassX = NULL;
2272 	LPTSTR ServicePrincipalName = NULL;
2273 #ifdef UNICODE
2274 	ConvertToUnicode(CP_UTF8, 0, hostname, -1, &hostnameX, 0);
2275 	ConvertToUnicode(CP_UTF8, 0, ServiceClass, -1, &ServiceClassX, 0);
2276 #else
2277 	hostnameX = _strdup(hostname);
2278 	ServiceClassX = _strdup(ServiceClass);
2279 #endif
2280 
2281 	if (!hostnameX || !ServiceClassX)
2282 	{
2283 		free(hostnameX);
2284 		free(ServiceClassX);
2285 		return NULL;
2286 	}
2287 
2288 	if (!ServiceClass)
2289 	{
2290 		ServicePrincipalName = (LPTSTR)_tcsdup(hostnameX);
2291 		free(ServiceClassX);
2292 		free(hostnameX);
2293 		return ServicePrincipalName;
2294 	}
2295 
2296 	SpnLength = 0;
2297 	status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, NULL);
2298 
2299 	if (status != ERROR_BUFFER_OVERFLOW)
2300 	{
2301 		free(ServiceClassX);
2302 		free(hostnameX);
2303 		return NULL;
2304 	}
2305 
2306 	ServicePrincipalName = (LPTSTR)calloc(SpnLength, sizeof(TCHAR));
2307 
2308 	if (!ServicePrincipalName)
2309 	{
2310 		free(ServiceClassX);
2311 		free(hostnameX);
2312 		return NULL;
2313 	}
2314 
2315 	status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, ServicePrincipalName);
2316 
2317 	if (status != ERROR_SUCCESS)
2318 	{
2319 		free(ServicePrincipalName);
2320 		free(ServiceClassX);
2321 		free(hostnameX);
2322 		return NULL;
2323 	}
2324 
2325 	free(ServiceClassX);
2326 	free(hostnameX);
2327 	return ServicePrincipalName;
2328 }
2329 
2330 /**
2331  * Create new CredSSP state machine.
2332  * @param transport
2333  * @return new CredSSP state machine.
2334  */
2335 
nla_new(freerdp * instance,rdpTransport * transport,rdpSettings * settings)2336 rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings)
2337 {
2338 	rdpNla* nla = (rdpNla*)calloc(1, sizeof(rdpNla));
2339 
2340 	if (!nla)
2341 		return NULL;
2342 
2343 	nla->identity = calloc(1, sizeof(SEC_WINNT_AUTH_IDENTITY));
2344 
2345 	if (!nla->identity)
2346 	{
2347 		free(nla);
2348 		return NULL;
2349 	}
2350 
2351 	nla->instance = instance;
2352 	nla->settings = settings;
2353 	nla->server = settings->ServerMode;
2354 	nla->transport = transport;
2355 	nla->sendSeqNum = 0;
2356 	nla->recvSeqNum = 0;
2357 	nla->version = 6;
2358 	SecInvalidateHandle(&nla->context);
2359 
2360 	if (settings->NtlmSamFile)
2361 	{
2362 		nla->SamFile = _strdup(settings->NtlmSamFile);
2363 
2364 		if (!nla->SamFile)
2365 			goto cleanup;
2366 	}
2367 
2368 	/* init to 0 or we end up freeing a bad pointer if the alloc fails */
2369 	if (!sspi_SecBufferAlloc(&nla->ClientNonce, NonceLength))
2370 		goto cleanup;
2371 
2372 	/* generate random 32-byte nonce */
2373 	if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2374 		goto cleanup;
2375 
2376 	if (nla->server)
2377 	{
2378 		LONG status;
2379 		HKEY hKey;
2380 		DWORD dwType;
2381 		DWORD dwSize;
2382 		status =
2383 		    RegOpenKeyExA(HKEY_LOCAL_MACHINE, SERVER_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
2384 
2385 		if (status != ERROR_SUCCESS)
2386 			return nla;
2387 
2388 		status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, NULL, &dwSize);
2389 
2390 		if (status != ERROR_SUCCESS)
2391 		{
2392 			RegCloseKey(hKey);
2393 			return nla;
2394 		}
2395 
2396 		nla->SspiModule = (LPTSTR)malloc(dwSize + sizeof(TCHAR));
2397 
2398 		if (!nla->SspiModule)
2399 		{
2400 			RegCloseKey(hKey);
2401 			goto cleanup;
2402 		}
2403 
2404 		status =
2405 		    RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, (BYTE*)nla->SspiModule, &dwSize);
2406 
2407 		if (status == ERROR_SUCCESS)
2408 			WLog_INFO(TAG, "Using SSPI Module: %s", nla->SspiModule);
2409 
2410 		RegCloseKey(hKey);
2411 	}
2412 
2413 	return nla;
2414 cleanup:
2415 	nla_free(nla);
2416 	return NULL;
2417 }
2418 
2419 /**
2420  * Free CredSSP state machine.
2421  * @param credssp
2422  */
2423 
nla_free(rdpNla * nla)2424 void nla_free(rdpNla* nla)
2425 {
2426 	if (!nla)
2427 		return;
2428 
2429 	if (nla->table)
2430 	{
2431 		SECURITY_STATUS status;
2432 
2433 		if (SecIsValidHandle(&nla->credentials))
2434 		{
2435 			status = nla->table->FreeCredentialsHandle(&nla->credentials);
2436 
2437 			if (status != SEC_E_OK)
2438 			{
2439 				WLog_WARN(TAG, "FreeCredentialsHandle status %s [0x%08" PRIX32 "]",
2440 				          GetSecurityStatusString(status), status);
2441 			}
2442 
2443 			SecInvalidateHandle(&nla->credentials);
2444 		}
2445 
2446 		status = nla->table->DeleteSecurityContext(&nla->context);
2447 
2448 		if (status != SEC_E_OK)
2449 		{
2450 			WLog_WARN(TAG, "DeleteSecurityContext status %s [0x%08" PRIX32 "]",
2451 			          GetSecurityStatusString(status), status);
2452 		}
2453 	}
2454 
2455 	free(nla->SamFile);
2456 	nla->SamFile = NULL;
2457 	sspi_SecBufferFree(&nla->ClientNonce);
2458 	sspi_SecBufferFree(&nla->PublicKey);
2459 	sspi_SecBufferFree(&nla->tsCredentials);
2460 	free(nla->ServicePrincipalName);
2461 	nla_identity_free(nla->identity);
2462 	nla_buffer_free(nla);
2463 	free(nla);
2464 }
2465 
nla_get_identity(rdpNla * nla)2466 SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2467 {
2468 	if (!nla)
2469 		return NULL;
2470 
2471 	return nla->identity;
2472 }
2473 
nla_get_state(rdpNla * nla)2474 NLA_STATE nla_get_state(rdpNla* nla)
2475 {
2476 	if (!nla)
2477 		return NLA_STATE_FINAL;
2478 
2479 	return nla->state;
2480 }
2481 
nla_set_state(rdpNla * nla,NLA_STATE state)2482 BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2483 {
2484 	if (!nla)
2485 		return FALSE;
2486 
2487 	nla->state = state;
2488 	return TRUE;
2489 }
2490 
nla_set_service_principal(rdpNla * nla,LPSTR principal)2491 BOOL nla_set_service_principal(rdpNla* nla, LPSTR principal)
2492 {
2493 	if (!nla || !principal)
2494 		return FALSE;
2495 
2496 	nla->ServicePrincipalName = principal;
2497 	return TRUE;
2498 }
2499 
nla_impersonate(rdpNla * nla)2500 BOOL nla_impersonate(rdpNla* nla)
2501 {
2502 	if (!nla)
2503 		return FALSE;
2504 
2505 	if (!nla->table || !nla->table->ImpersonateSecurityContext)
2506 		return FALSE;
2507 
2508 	return (nla->table->ImpersonateSecurityContext(&nla->context) == SEC_E_OK);
2509 }
2510 
nla_revert_to_self(rdpNla * nla)2511 BOOL nla_revert_to_self(rdpNla* nla)
2512 {
2513 	if (!nla)
2514 		return FALSE;
2515 
2516 	if (!nla->table || !nla->table->RevertSecurityContext)
2517 		return FALSE;
2518 
2519 	return (nla->table->RevertSecurityContext(&nla->context) == SEC_E_OK);
2520 }
2521