rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
{
	rdpNla* nla = (rdpNla*)calloc(1, sizeof(rdpNla));
	rdpSettings* settings;

	WINPR_ASSERT(transport);
	WINPR_ASSERT(context);

	settings = context->settings;
	WINPR_ASSERT(settings);

	if (!nla)
		return NULL;

	nla->identity = (SEC_WINNT_AUTH_IDENTITY*)&nla->identityWinPr;
	nla->identity->Flags = SEC_WINNT_AUTH_IDENTITY_EXTENDED;
	nla->rdpcontext = context;
	nla->server = settings->ServerMode;
	nla->transport = transport;
	nla->sendSeqNum = 0;
	nla->recvSeqNum = 0;
	nla->version = 6;
	nla->kerberosSettings = &nla->identityWinPr.kerberosSettings;
	SecInvalidateHandle(&nla->context);

	if (settings->NtlmSamFile)
	{
		nla->SamFile = _strdup(settings->NtlmSamFile);

		if (!nla->SamFile)
			goto cleanup;
	}

	if (settings->SspiModule)
	{
		nla->SspiModule = _strdup(settings->SspiModule);

		if (!nla->SspiModule)
			goto cleanup;
	}

	/* init to 0 or we end up freeing a bad pointer if the alloc fails */
	if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
		goto cleanup;

	/* generate random 32-byte nonce */
	if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
		goto cleanup;

	if (nla->server)
	{
		LONG status;
		HKEY hKey;
		DWORD dwType;
		DWORD dwSize;
		status =
		    RegOpenKeyExA(HKEY_LOCAL_MACHINE, SERVER_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);

		if (status != ERROR_SUCCESS)
			return nla;

		status = RegQueryValueExA(hKey, "SspiModule", NULL, &dwType, NULL, &dwSize);
		if (status != ERROR_SUCCESS)
		{
			RegCloseKey(hKey);
			return nla;
		}

		nla->SspiModule = (LPSTR)malloc(dwSize + sizeof(CHAR));
		if (!nla->SspiModule)
		{
			RegCloseKey(hKey);
			goto cleanup;
		}

		status =
		    RegQueryValueExA(hKey, "SspiModule", NULL, &dwType, (BYTE*)nla->SspiModule, &dwSize);
		if (status == ERROR_SUCCESS)
			WLog_INFO(TAG, "Using SSPI Module: %s", nla->SspiModule);

		RegCloseKey(hKey);
	}

	return nla;
cleanup:
	nla_free(nla);
	return NULL;
}
rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
{
	rdpNla* nla = (rdpNla*)calloc(1, sizeof(rdpNla));
	rdpSettings* settings;

	WINPR_ASSERT(transport);
	WINPR_ASSERT(context);

	settings = context->settings;
	WINPR_ASSERT(settings);

	if (!nla)
		return NULL;

	nla->identity = (SEC_WINNT_AUTH_IDENTITY*)&nla->identityWinPr;
	nla->identity->Flags = SEC_WINNT_AUTH_IDENTITY_EXTENDED;
	nla->rdpcontext = context;
	nla->server = settings->ServerMode;
	nla->transport = transport;
	nla->sendSeqNum = 0;
	nla->recvSeqNum = 0;
	nla->version = 6;
	nla->kerberosSettings = &nla->identityWinPr.kerberosSettings;
	SecInvalidateHandle(&nla->context);

	if (settings->NtlmSamFile)
	{
		nla->SamFile = _strdup(settings->NtlmSamFile);

		if (!nla->SamFile)
			goto cleanup;
	}

	if (settings->SspiModule)
	{
		nla->SspiModule = _strdup(settings->SspiModule);

		if (!nla->SspiModule)
			goto cleanup;
	}

	 
	if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
		goto cleanup;

	 
	if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
		goto cleanup;

	if (nla->server)
	{
		LONG status;
		HKEY hKey;
		DWORD dwType;
		DWORD dwSize;
		status =
		    RegOpenKeyExA(HKEY_LOCAL_MACHINE, SERVER_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);

		if (status != ERROR_SUCCESS)
			return nla;

		status = RegQueryValueExA(hKey, "SspiModule", NULL, &dwType, NULL, &dwSize);
		if (status != ERROR_SUCCESS)
		{
			RegCloseKey(hKey);
			return nla;
		}

		nla->SspiModule = (LPSTR)malloc(dwSize + sizeof(CHAR));
		if (!nla->SspiModule)
		{
			RegCloseKey(hKey);
			goto cleanup;
		}

		status =
		    RegQueryValueExA(hKey, "SspiModule", NULL, &dwType, (BYTE*)nla->SspiModule, &dwSize);
		if (status == ERROR_SUCCESS)
			WLog_INFO(TAG, "Using SSPI Module: %s", nla->SspiModule);

		RegCloseKey(hKey);
	}

	return nla;
cleanup:
	nla_free(nla);
	return NULL;
}