예제 #1
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT encomsp_server_receive_pdu(EncomspServerContext* context,
                                       wStream* s)
{
	UINT error = CHANNEL_RC_OK;
	ENCOMSP_ORDER_HEADER header;

	while (Stream_GetRemainingLength(s) > 0)
	{
		if ((error = encomsp_read_header(s, &header)))
		{
			WLog_ERR(TAG, "encomsp_read_header failed with error %u!", error);
			return error;
		}

		WLog_INFO(TAG, "EncomspReceive: Type: %d Length: %d", header.Type,
		          header.Length);

		switch (header.Type)
		{
			case ODTYPE_PARTICIPANT_CTRL_CHANGED:
				if ((error = encomsp_recv_change_participant_control_level_pdu(context, s,
				             &header)))
				{
					WLog_ERR(TAG,
					         "encomsp_recv_change_participant_control_level_pdu failed with error %u!",
					         error);
					return error;
				}

				break;

			default:
				WLog_ERR(TAG, "header.Type unknown %d!", header.Type);
				return ERROR_INVALID_DATA;
				break;
		}
	}

	return error;
}
예제 #2
0
파일: info.c 프로젝트: C4rt/FreeRDP
BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s)
{
	BYTE* p;
	ARC_SC_PRIVATE_PACKET* autoReconnectCookie;
	rdpSettings* settings = rdp->settings;

	autoReconnectCookie = settings->ServerAutoReconnectCookie;

	if (Stream_GetRemainingLength(s) < 28)
		return FALSE;

	Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
	Stream_Read_UINT32(s, autoReconnectCookie->version); /* Version (4 bytes) */
	Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
	Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* ArcRandomBits (16 bytes) */

	if (autoReconnectCookie->cbLen != 28)
	{
		WLog_ERR(TAG, "ServerAutoReconnectCookie.cbLen != 28");
		return FALSE;
	}

	p = autoReconnectCookie->arcRandomBits;

	WLog_DBG(TAG, "ServerAutoReconnectCookie: Version: %d LogonId: %d SecurityVerifier: "
			"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
			autoReconnectCookie->version, autoReconnectCookie->logonId,
			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
			p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);

	if ((settings->PrintReconnectCookie) && (autoReconnectCookie->cbLen > 0))
	{
		char* base64;
		base64 = crypto_base64_encode((BYTE*) autoReconnectCookie, sizeof(ARC_SC_PRIVATE_PACKET));
		WLog_INFO(TAG, "Reconnect-cookie: %s", base64);
		free(base64);
	}

	return TRUE;
}
예제 #3
0
파일: wf_info.c 프로젝트: dadoman11/FreeRDP
void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
{
	if (wf_info_lock(wfi) > 0)
	{
		int peerId;

		peerId = ((rdpContext*) context)->peer->pId;
		wfi->peers[peerId] = NULL;
		wfi->peerCount--;
		CloseHandle(context->updateEvent);
		WLog_INFO(TAG, "Unregistering Peer: id=%d, #=%d", peerId, wfi->peerCount);

#ifdef WITH_DXGI_1_2
		if (wfi->peerCount == 0)
			wf_dxgi_cleanup(wfi);
#endif

		wf_info_unlock(wfi);

		wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_DISCONNECT);
	}
}
예제 #4
0
void cliprdr_print_general_capability_flags(UINT32 flags)
{
	WLog_INFO(TAG,  "generalFlags (0x%08X) {", flags);

	if (flags & CB_USE_LONG_FORMAT_NAMES)
		WLog_INFO(TAG,  "\tCB_USE_LONG_FORMAT_NAMES");

	if (flags & CB_STREAM_FILECLIP_ENABLED)
		WLog_INFO(TAG,  "\tCB_STREAM_FILECLIP_ENABLED");

	if (flags & CB_FILECLIP_NO_FILE_PATHS)
		WLog_INFO(TAG,  "\tCB_FILECLIP_NO_FILE_PATHS");

	if (flags & CB_CAN_LOCK_CLIPDATA)
		WLog_INFO(TAG,  "\tCB_CAN_LOCK_CLIPDATA");

	WLog_INFO(TAG,  "}");
}
예제 #5
0
파일: h264.c 프로젝트: AMV007/FreeRDP
static void openh264_trace_callback(H264_CONTEXT* h264, int level, const char* message)
{
	WLog_INFO(TAG, "%d - %s", level, message);
}
예제 #6
0
파일: wf_rail.c 프로젝트: AMV007/FreeRDP
static void PrintRailIconInfo(WINDOW_ORDER_INFO* orderInfo, ICON_INFO* iconInfo)
{
	WLog_INFO(TAG, "ICON_INFO");
	WLog_INFO(TAG, "{");

	WLog_INFO(TAG, "\tbigIcon: %s", (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? "true" : "false");
	WLog_INFO(TAG, "\tcacheEntry; 0x%04X", iconInfo->cacheEntry);
	WLog_INFO(TAG, "\tcacheId: 0x%04X", iconInfo->cacheId);
	WLog_INFO(TAG, "\tbpp: %d", iconInfo->bpp);
	WLog_INFO(TAG, "\twidth: %d", iconInfo->width);
	WLog_INFO(TAG, "\theight: %d", iconInfo->height);
	WLog_INFO(TAG, "\tcbColorTable: %d", iconInfo->cbColorTable);
	WLog_INFO(TAG, "\tcbBitsMask: %d", iconInfo->cbBitsMask);
	WLog_INFO(TAG, "\tcbBitsColor: %d", iconInfo->cbBitsColor);
	WLog_INFO(TAG, "\tcolorTable: %p", iconInfo->colorTable);
	WLog_INFO(TAG, "\tbitsMask: %p", iconInfo->bitsMask);
	WLog_INFO(TAG, "\tbitsColor: %p", iconInfo->bitsColor);

	WLog_INFO(TAG, "}");
}
예제 #7
0
int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect)
{
	BOOL equal;
	BOOL allEqual;
	int tw, th;
	int tx, ty, k;
	int nrow, ncol;
	int l, t, r, b;
	BYTE *p1, *p2;
	BOOL rows[1024];
#ifdef WITH_DEBUG_SHADOW_CAPTURE
	BOOL cols[1024];
#endif

	allEqual = TRUE;
	ZeroMemory(rect, sizeof(RECTANGLE_16));
	FillMemory(rows, sizeof(rows), 0xFF);
#ifdef WITH_DEBUG_SHADOW_CAPTURE
	FillMemory(cols, sizeof(cols), 0xFF);
#endif

	nrow = (nHeight + 15) / 16;
	ncol = (nWidth + 15) / 16;

	l = ncol + 1;
	r = -1;

	t = nrow + 1;
	b = -1;

	for (ty = 0; ty < nrow; ty++)
	{
		th = ((ty + 1) == nrow) ? (nHeight % 16) : 16;

		if (!th)
			th = 16;

		for (tx = 0; tx < ncol; tx++)
		{
			equal = TRUE;

			tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16;

			if (!tw)
				tw = 16;

			p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)];
			p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)];

			for (k = 0; k < th; k++)
			{
				if (memcmp(p1, p2, tw * 4) != 0)
				{
					equal = FALSE;
					break;
				}

				p1 += nStep1;
				p2 += nStep2;
			}

			if (!equal)
			{
				rows[ty] = FALSE;
#ifdef WITH_DEBUG_SHADOW_CAPTURE
				cols[tx] = FALSE;
#endif

				if (l > tx)
					l = tx;

				if (r < tx)
					r = tx;
			}
		}

		if (!rows[ty])
		{
			allEqual = FALSE;

			if (t > ty)
				t = ty;

			if (b < ty)
				b = ty;
		}
	}

	if (allEqual)
		return 0;

	rect->left = l * 16;
	rect->top = t * 16;
	rect->right = (r + 1) * 16;
	rect->bottom = (b + 1) * 16;

	if (rect->right > nWidth)
		rect->right = nWidth;

	if (rect->bottom > nHeight)
		rect->bottom = nHeight;

#ifdef WITH_DEBUG_SHADOW_CAPTURE
	char *col_str = calloc(ncol + 1, sizeof(char));
	if (!col_str)
	{
		WLog_ERR(TAG, "calloc failed!");
		return 1;
	}

	for (tx = 0; tx < ncol; tx++)
		sprintf(&col_str[tx], "-");
	WLog_INFO(TAG, "%s", col_str);

	for (tx = 0; tx < ncol; tx++)
		sprintf(&col_str[tx], "%c", cols[tx] ? 'O' : 'X');
	WLog_INFO(TAG, "%s", col_str);

	for (tx = 0; tx < ncol; tx++)
		sprintf(&col_str[tx], "-");
	WLog_INFO(TAG, "%s", col_str);

	for (ty = 0; ty < nrow; ty++)
	{
		for (tx = 0; tx < ncol; tx++)
			sprintf(&col_str[tx], "%c", cols[tx] ? 'O' : 'X');
		WLog_INFO(TAG, "%s", col_str);
		WLog_INFO(TAG, "|%s|", rows[ty] ? "O" : "X");
	}

	WLog_INFO(TAG, "left: %d top: %d right: %d bottom: %d ncol: %d nrow: %d",
			l, t, r, b, ncol, nrow);
	free(col_str);
#endif

	return 1;
}
예제 #8
0
파일: gcc.c 프로젝트: vworkspace/FreeRDP
void gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
{
	CryptoMd5 md5;
	BYTE* sigData;
	int expLen, keyLen, sigDataLen;
	BYTE encryptedSignature[TSSK_KEY_LENGTH];
	BYTE signature[sizeof(initial_signature)];
	UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen;
	rdpSettings* settings = mcs->settings;

	/**
	 * Re: settings->EncryptionLevel:
	 * This is configured/set by the server implementation and serves the same
	 * purpose as the "Encryption Level" setting in the RDP-Tcp configuration
	 * dialog of Microsoft's Remote Desktop Session Host Configuration.
	 * Re: settings->EncryptionMethods:
	 * at this point this setting contains the client's supported encryption
	 * methods we've received in gcc_read_client_security_data()
	 */

	if (!settings->UseRdpSecurityLayer)
	{
		/* TLS/NLA is used: disable rdp style encryption */
		settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
	}

	/* verify server encryption level value */
	switch (settings->EncryptionLevel)
	{
		case ENCRYPTION_LEVEL_NONE:
			WLog_INFO(TAG, "Active rdp encryption level: NONE");
			break;
		case ENCRYPTION_LEVEL_FIPS:
			WLog_INFO(TAG, "Active rdp encryption level: FIPS Compliant");
			break;
		case ENCRYPTION_LEVEL_HIGH:
			WLog_INFO(TAG, "Active rdp encryption level: HIGH");
			break;
		case ENCRYPTION_LEVEL_LOW:
			WLog_INFO(TAG, "Active rdp encryption level: LOW");
			break;
		case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE:
			WLog_INFO(TAG, "Active rdp encryption level: CLIENT-COMPATIBLE");
			break;
		default:
			WLog_ERR(TAG, "Invalid server encryption level 0x%08X", settings->EncryptionLevel);
			WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE");
			settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
	}

	/* choose rdp encryption method based on server level and client methods */
	switch (settings->EncryptionLevel)
	{
		case ENCRYPTION_LEVEL_NONE:
			/* The only valid method is NONE in this case */
			settings->EncryptionMethods = ENCRYPTION_METHOD_NONE;
			break;
		case ENCRYPTION_LEVEL_FIPS:
			/* The only valid method is FIPS in this case */
			if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS))
			{
				WLog_WARN(TAG, "client does not support FIPS as required by server configuration");
			}
			settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS;
			break;
		case ENCRYPTION_LEVEL_HIGH:
			/* Maximum key strength supported by the server must be used (128 bit)*/
			if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT))
			{
				WLog_WARN(TAG, "client does not support 128 bit encryption method as required by server configuration");
			}
			settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT;
			break;
		case ENCRYPTION_LEVEL_LOW:
		case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE:
			/* Maximum key strength supported by the client must be used */
			if (settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT)
				settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT;
			else if (settings->EncryptionMethods & ENCRYPTION_METHOD_56BIT)
				settings->EncryptionMethods = ENCRYPTION_METHOD_56BIT;
			else if (settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT)
				settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT;
			else if (settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS)
				settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS;
			else
			{
				WLog_WARN(TAG, "client has not announced any supported encryption methods");
				settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT;
			}
			break;
		default:
			WLog_ERR(TAG, "internal error: unknown encryption level");
	}

	/* log selected encryption method */
	switch (settings->EncryptionMethods)
	{
		case ENCRYPTION_METHOD_NONE:
			WLog_INFO(TAG, "Selected rdp encryption method: NONE");
			break;
		case ENCRYPTION_METHOD_40BIT:
			WLog_INFO(TAG, "Selected rdp encryption method: 40BIT");
			break;
		case ENCRYPTION_METHOD_56BIT:
			WLog_INFO(TAG, "Selected rdp encryption method: 56BIT");
			break;
		case ENCRYPTION_METHOD_128BIT:
			WLog_INFO(TAG, "Selected rdp encryption method: 128BIT");
			break;
		case ENCRYPTION_METHOD_FIPS:
			WLog_INFO(TAG, "Selected rdp encryption method: FIPS");
			break;
		default:
			WLog_ERR(TAG, "internal error: unknown encryption method");
	}

	headerLen = 12;
	keyLen = 0;
	wPublicKeyBlobLen = 0;
	serverRandomLen = 0;
	serverCertLen = 0;

	if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE)
	{
		serverRandomLen = 32;

		keyLen = settings->RdpServerRsaKey->ModulusLength;
		expLen = sizeof(settings->RdpServerRsaKey->exponent);
		wPublicKeyBlobLen = 4; /* magic (RSA1) */
		wPublicKeyBlobLen += 4; /* keylen */
		wPublicKeyBlobLen += 4; /* bitlen */
		wPublicKeyBlobLen += 4; /* datalen */
		wPublicKeyBlobLen += expLen;
		wPublicKeyBlobLen += keyLen;
		wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */

		serverCertLen = 4; /* dwVersion */
		serverCertLen += 4; /* dwSigAlgId */
		serverCertLen += 4; /* dwKeyAlgId */
		serverCertLen += 2; /* wPublicKeyBlobType */
		serverCertLen += 2; /* wPublicKeyBlobLen */
		serverCertLen += wPublicKeyBlobLen;
		serverCertLen += 2; /* wSignatureBlobType */
		serverCertLen += 2; /* wSignatureBlobLen */
		serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */
		serverCertLen += 8; /* 8 bytes of zero padding */

		headerLen += sizeof(serverRandomLen);
		headerLen += sizeof(serverCertLen);
		headerLen += serverRandomLen;
		headerLen += serverCertLen;
	}

	gcc_write_user_data_header(s, SC_SECURITY, headerLen);

	Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */
	Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */

	if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
	{
		return;
	}

	Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */
	Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */

	settings->ServerRandomLength = serverRandomLen;
	settings->ServerRandom = (BYTE*) malloc(serverRandomLen);
	crypto_nonce(settings->ServerRandom, serverRandomLen);
	Stream_Write(s, settings->ServerRandom, serverRandomLen);

	sigData = Stream_Pointer(s);

	Stream_Write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */
	Stream_Write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */
	Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */
	Stream_Write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */

	Stream_Write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */
	Stream_Write(s, "RSA1", 4); /* magic */
	Stream_Write_UINT32(s, keyLen + 8); /* keylen */
	Stream_Write_UINT32(s, keyLen * 8); /* bitlen */
	Stream_Write_UINT32(s, keyLen - 1); /* datalen */

	Stream_Write(s, settings->RdpServerRsaKey->exponent, expLen);
	Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen);
	Stream_Zero(s, 8);

	sigDataLen = Stream_Pointer(s) - sigData;

	Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */
	Stream_Write_UINT16(s, sizeof(encryptedSignature) + 8); /* wSignatureBlobLen */

	memcpy(signature, initial_signature, sizeof(initial_signature));

	md5 = crypto_md5_init();
	if (!md5)
	{
		WLog_ERR(TAG,  "unable to allocate a md5");
		return;
	}

	crypto_md5_update(md5, sigData, sigDataLen);
	crypto_md5_final(md5, signature);

	crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH,
		tssk_modulus, tssk_privateExponent, encryptedSignature);

	Stream_Write(s, encryptedSignature, sizeof(encryptedSignature));
	Stream_Zero(s, 8);
}
예제 #9
0
파일: tls.c 프로젝트: Devolutions/FreeRDP
int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname,
                           int port)
{
	int match;
	int index;
	char* common_name = NULL;
	int common_name_length = 0;
	char** dns_names = 0;
	int dns_names_count = 0;
	int* dns_names_lengths = NULL;
	BOOL certificate_status;
	BOOL hostname_match = FALSE;
	BOOL verification_status = FALSE;
	rdpCertificateData* certificate_data;
	freerdp* instance = (freerdp*) tls->settings->instance;
	DWORD length;
	BYTE* pemCert;

	if (!tls_extract_pem(cert, &pemCert, &length))
		return -1;

	/* Check, if we already accepted this key. */
	if (is_accepted(tls, pemCert, length))
	{
		free(pemCert);
		return 1;
	}

	if (tls->settings->ExternalCertificateManagement)
	{
		int status = -1;

		if (instance->VerifyX509Certificate)
			status = instance->VerifyX509Certificate(instance, pemCert, length, hostname,
			         port, tls->isGatewayTransport | is_redirected(tls) ? 2 : 0);
		else
			WLog_ERR(TAG, "No VerifyX509Certificate callback registered!");

		if (status > 0)
		{
			accept_cert(tls, pemCert, length);
		}
		else if (status < 0)
		{
			WLog_ERR(TAG, "VerifyX509Certificate failed: (length = %d) status: [%d] %s",
			         length, status, pemCert);
			free(pemCert);
			return -1;
		}
		else
			free(pemCert);

		return (status == 0) ? 0 : 1;
	}

	/* ignore certificate verification if user explicitly required it (discouraged) */
	if (tls->settings->IgnoreCertificate)
	{
		free(pemCert);
		return 1;  /* success! */
	}

	if (!tls->isGatewayTransport && tls->settings->AuthenticationLevel == 0)
	{
		free(pemCert);
		return 1;  /* success! */
	}

	/* if user explicitly specified a certificate name, use it instead of the hostname */
	if (!tls->isGatewayTransport && tls->settings->CertificateName)
		hostname = tls->settings->CertificateName;

	/* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */
	certificate_status = x509_verify_certificate(cert,
	                     tls->certificate_store->path);
	/* verify certificate name match */
	certificate_data = crypto_get_certificate_data(cert->px509, hostname, port);
	/* extra common name and alternative names */
	common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length);
	dns_names = crypto_cert_get_dns_names(cert->px509, &dns_names_count,
	                                      &dns_names_lengths);

	/* compare against common name */

	if (common_name)
	{
		if (tls_match_hostname(common_name, common_name_length, hostname))
			hostname_match = TRUE;
	}

	/* compare against alternative names */

	if (dns_names)
	{
		for (index = 0; index < dns_names_count; index++)
		{
			if (tls_match_hostname(dns_names[index], dns_names_lengths[index], hostname))
			{
				hostname_match = TRUE;
				break;
			}
		}
	}

	/* if the certificate is valid and the certificate name matches, verification succeeds */
	if (certificate_status && hostname_match)
		verification_status = TRUE; /* success! */

	/* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */
	if (!certificate_status || !hostname_match)
	{
		char* issuer;
		char* subject;
		char* fingerprint;
		DWORD accept_certificate = 0;
		issuer = crypto_cert_issuer(cert->px509);
		subject = crypto_cert_subject(cert->px509);
		fingerprint = crypto_cert_fingerprint(cert->px509);
		/* search for matching entry in known_hosts file */
		match = certificate_data_match(tls->certificate_store, certificate_data);

		if (match == 1)
		{
			/* no entry was found in known_hosts file, prompt user for manual verification */
			if (!hostname_match)
				tls_print_certificate_name_mismatch_error(
				    hostname, port,
				    common_name, dns_names,
				    dns_names_count);

			/* Automatically accept certificate on first use */
			if (tls->settings->AutoAcceptCertificate)
			{
				WLog_INFO(TAG, "No certificate stored, automatically accepting.");
				accept_certificate = 1;
			}
			else if (instance->VerifyCertificate)
			{
				accept_certificate = instance->VerifyCertificate(
				                         instance, common_name,
				                         subject, issuer,
				                         fingerprint, !hostname_match);
			}

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_print(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == -1)
		{
			char* old_subject = NULL;
			char* old_issuer = NULL;
			char* old_fingerprint = NULL;
			/* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */
			tls_print_certificate_error(hostname, port, fingerprint,
			                            tls->certificate_store->file);

			if (!certificate_get_stored_data(tls->certificate_store,
			                                 certificate_data, &old_subject,
			                                 &old_issuer, &old_fingerprint))
				WLog_WARN(TAG, "Failed to get certificate entry for %s:%d",
				          hostname, port);

			if (instance->VerifyChangedCertificate)
			{
				accept_certificate = instance->VerifyChangedCertificate(
				                         instance, common_name, subject, issuer,
				                         fingerprint, old_subject, old_issuer,
				                         old_fingerprint);
			}

			free(old_subject);
			free(old_issuer);
			free(old_fingerprint);

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_replace(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == 0)
			verification_status = TRUE; /* success! */

		free(issuer);
		free(subject);
		free(fingerprint);
	}

	certificate_data_free(certificate_data);
	free(common_name);

	if (dns_names)
		crypto_cert_dns_names_free(dns_names_count, dns_names_lengths,
		                           dns_names);

	if (verification_status > 0)
	{
		accept_cert(tls, pemCert, length);
	}
	else
	{
		free(pemCert);
	}

	return (verification_status == 0) ? 0 : 1;
}
예제 #10
0
파일: rdg.c 프로젝트: mfleisz/FreeRDP
static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls,
        const char* method, const char* peerAddress, int timeout, BOOL* rpcFallback)
{
	HttpResponse* response = NULL;
	int statusCode;
	int bodyLength;

	if (!rdg_tls_connect(rdg, tls, peerAddress, timeout))
		return FALSE;

	if (rdg->extAuth == HTTP_EXTENDED_AUTH_NONE)
	{
		if (!rdg_ntlm_init(rdg, tls))
			return FALSE;

		if (!rdg_send_http_request(rdg, tls, method, NULL))
			return FALSE;

		response = http_response_recv(tls);

		if (!response)
			return FALSE;

		if (response->StatusCode == HTTP_STATUS_NOT_FOUND)
		{
			WLog_INFO(TAG, "RD Gateway does not support HTTP transport.");

			if (rpcFallback) *rpcFallback = TRUE;

			http_response_free(response);
			return FALSE;
		}

		if (!rdg_handle_ntlm_challenge(rdg->ntlm, response))
		{
			http_response_free(response);
			return FALSE;
		}

		http_response_free(response);
	}

	if (!rdg_send_http_request(rdg, tls, method, NULL))
		return FALSE;

	ntlm_free(rdg->ntlm);
	rdg->ntlm = NULL;
	response = http_response_recv(tls);

	if (!response)
		return FALSE;

	statusCode = response->StatusCode;
	bodyLength = response->BodyLength;
	http_response_free(response);
	WLog_DBG(TAG, "%s authorization result: %d", method, statusCode);

	if (statusCode != HTTP_STATUS_OK)
		return FALSE;

	if (strcmp(method, "RDG_OUT_DATA") == 0)
	{
		if (!rdg_skip_seed_payload(tls, bodyLength))
			return FALSE;
	}
	else
	{
		if (!rdg_send_http_request(rdg, tls, method, "chunked"))
			return FALSE;
	}

	return TRUE;
}
예제 #11
0
rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings)
{

	rdpNla* nla = (rdpNla*) calloc(1, sizeof(rdpNla));

	if (!nla)
		return NULL;

	nla->identity = calloc(1, sizeof(SEC_WINNT_AUTH_IDENTITY));
	if (!nla->identity)
	{
		free (nla);
		return NULL;
	}

	nla->instance = instance;
	nla->settings = settings;
	nla->server = settings->ServerMode;
	nla->transport = transport;
	nla->sendSeqNum = 0;
	nla->recvSeqNum = 0;
	nla->version = 3;

	ZeroMemory(&nla->negoToken, sizeof(SecBuffer));
	ZeroMemory(&nla->pubKeyAuth, sizeof(SecBuffer));
	ZeroMemory(&nla->authInfo, sizeof(SecBuffer));
	SecInvalidateHandle(&nla->context);

	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 = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, NULL, &dwSize);
		if (status != ERROR_SUCCESS)
		{
			RegCloseKey(hKey);
			return nla;
		}

		nla->SspiModule = (LPTSTR) malloc(dwSize + sizeof(TCHAR));
		if (!nla->SspiModule)
		{
			RegCloseKey(hKey);
			free(nla);
			return NULL;
		}

		status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType,
								 (BYTE*) nla->SspiModule, &dwSize);

		if (status == ERROR_SUCCESS)
			WLog_INFO(TAG, "Using SSPI Module: %s", nla->SspiModule);

		RegCloseKey(hKey);
	}

	return nla;
}
예제 #12
0
파일: profiler.c 프로젝트: BUGgs/FreeRDP
void profiler_print_footer()
{
	WLog_INFO(TAG,  "|--------------------------------------------------------------------|");
}
예제 #13
0
파일: win_shadow.c 프로젝트: BUGgs/FreeRDP
int win_shadow_surface_copy(winShadowSubsystem* subsystem)
{
	int x, y;
	int width;
	int height;
	int count;
	int status = 1;
	int nDstStep = 0;
	BYTE* pDstData = NULL;
	rdpShadowServer* server;
	rdpShadowSurface* surface;
	RECTANGLE_16 surfaceRect;
	RECTANGLE_16 invalidRect;
	const RECTANGLE_16* extents;

	server = subsystem->server;
	surface = server->surface;

	if (ArrayList_Count(server->clients) < 1)
	{
		region16_clear(&(subsystem->invalidRegion));
		return 1;
	}

	surfaceRect.left = surface->x;
	surfaceRect.top = surface->y;
	surfaceRect.right = surface->x + surface->width;
	surfaceRect.bottom = surface->y + surface->height;

	region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect);

	if (region16_is_empty(&(subsystem->invalidRegion)))
		return 1;

	extents = region16_extents(&(subsystem->invalidRegion));
	CopyMemory(&invalidRect, extents, sizeof(RECTANGLE_16));

	shadow_capture_align_clip_rect(&invalidRect, &surfaceRect);

	x = invalidRect.left;
	y = invalidRect.top;
	width = invalidRect.right - invalidRect.left;
	height = invalidRect.bottom - invalidRect.top;

	if (0)
	{
		x = 0;
		y = 0;
		width = surface->width;
		height = surface->height;
	}

	WLog_INFO(TAG, "SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d",
		x, y, width, height, x + width, y + height);

#if defined(WITH_WDS_API)
	{
		rdpGdi* gdi;
		shwContext* shw;
		rdpContext* context;

		shw = subsystem->shw;
		context = (rdpContext*) shw;
		gdi = context->gdi;

		pDstData = gdi->primary_buffer;
		nDstStep = gdi->width * 4;
	}
#elif defined(WITH_DXGI_1_2)
	status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y, width, height);
#endif

	if (status <= 0)
		return status;

	freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
			surface->scanline, x - surface->x, y - surface->y, width, height,
			pDstData, PIXEL_FORMAT_XRGB32, nDstStep, 0, 0, NULL);

	ArrayList_Lock(server->clients);

	count = ArrayList_Count(server->clients);

	shadow_multiclient_publish_and_wait(subsystem->updateEvent);

	ArrayList_Unlock(server->clients);

	region16_clear(&(subsystem->invalidRegion));

	return 1;
}
예제 #14
0
파일: file.c 프로젝트: BUGgs/FreeRDP
void AioSignalHandler(int signum, siginfo_t* siginfo, void* arg)
{
	WLog_INFO("%d", signum);
}
예제 #15
0
static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_address, UINT16 port)
{
	int status;
	int sockfd;
	char addr[64];
	void* sin_addr;
	int option_value;
	char servname[16];
	struct addrinfo* ai;
	struct addrinfo* res;
	struct addrinfo hints = { 0 };
	rdpListener* listener = (rdpListener*) instance->listener;
#ifdef _WIN32
	u_long arg;
#endif

	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if (!bind_address)
		hints.ai_flags = AI_PASSIVE;

	sprintf_s(servname, sizeof(servname), "%d", port);
	status = getaddrinfo(bind_address, servname, &hints, &res);

	if (status != 0)
	{
#ifdef _WIN32
		WLog_ERR("getaddrinfo error: %s", gai_strerrorA(status));
#else
		WLog_ERR(TAG, "getaddrinfo");
#endif
		return FALSE;
	}

	for (ai = res; ai && (listener->num_sockfds < 5); ai = ai->ai_next)
	{
		if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6))
			continue;

		if (listener->num_sockfds == MAX_LISTENER_HANDLES)
		{
			WLog_ERR(TAG, "too many listening sockets");
			continue;
		}

		sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

		if (sockfd == -1)
		{
			WLog_ERR(TAG, "socket");
			continue;
		}

		if (ai->ai_family == AF_INET)
			sin_addr = &(((struct sockaddr_in*) ai->ai_addr)->sin_addr);
		else
			sin_addr = &(((struct sockaddr_in6*) ai->ai_addr)->sin6_addr);

		inet_ntop(ai->ai_family, sin_addr, addr, sizeof(addr));

		option_value = 1;

		if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &option_value, sizeof(option_value)) == -1)
			WLog_ERR(TAG, "setsockopt");

#ifndef _WIN32
		fcntl(sockfd, F_SETFL, O_NONBLOCK);
#else
		arg = 1;
		ioctlsocket(sockfd, FIONBIO, &arg);
#endif

		status = _bind((SOCKET) sockfd, ai->ai_addr, ai->ai_addrlen);

		if (status != 0)
		{
			closesocket((SOCKET) sockfd);
			continue;
		}

		status = _listen((SOCKET) sockfd, 10);

		if (status != 0)
		{
			WLog_ERR(TAG, "listen");
			closesocket((SOCKET) sockfd);
			continue;
		}

		/* FIXME: these file descriptors do not work on Windows */

		listener->sockfds[listener->num_sockfds] = sockfd;
		listener->events[listener->num_sockfds] = WSACreateEvent();
		if (!listener->events[listener->num_sockfds])
		{
			listener->num_sockfds = 0;
			break;
		}
		WSAEventSelect(sockfd, listener->events[listener->num_sockfds], FD_READ | FD_ACCEPT | FD_CLOSE);
		listener->num_sockfds++;

		WLog_INFO(TAG, "Listening on %s:%s", addr, servname);
	}

	freeaddrinfo(res);

	return (listener->num_sockfds > 0 ? TRUE : FALSE);
}
예제 #16
0
static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* path)
{
#ifndef _WIN32
	int status;
	int sockfd;
	struct sockaddr_un addr;
	rdpListener* listener = (rdpListener*) instance->listener;
	HANDLE hevent;

	if (listener->num_sockfds == MAX_LISTENER_HANDLES)
	{
		WLog_ERR(TAG, "too many listening sockets");
		return FALSE;
	}

	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

	if (sockfd == -1)
	{
		WLog_ERR(TAG, "socket");
		return FALSE;
	}

	fcntl(sockfd, F_SETFL, O_NONBLOCK);

	addr.sun_family = AF_UNIX;
	strncpy(addr.sun_path, path, sizeof(addr.sun_path));
	unlink(path);

	status = _bind(sockfd, (struct sockaddr*) &addr, sizeof(addr));

	if (status != 0)
	{
		WLog_ERR(TAG, "bind");
		closesocket((SOCKET) sockfd);
		return FALSE;
	}

	status = _listen(sockfd, 10);

	if (status != 0)
	{
		WLog_ERR(TAG, "listen");
		closesocket((SOCKET) sockfd);
		return FALSE;
	}

	hevent = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd, WINPR_FD_READ);
	if (!hevent)
	{
		WLog_ERR(TAG, "failed to create sockfd event");
		closesocket((SOCKET) sockfd);
		return FALSE;
	}

	listener->sockfds[listener->num_sockfds] = sockfd;
	listener->events[listener->num_sockfds] = hevent;
	listener->num_sockfds++;
	WLog_INFO(TAG, "Listening on socket %s.", addr.sun_path);
	return TRUE;
#else
	return TRUE;
#endif
}
예제 #17
0
void rdp_print_redirection_flags(UINT32 flags)
{
	WLog_INFO(TAG, "redirectionFlags = {");

	if (flags & LB_TARGET_NET_ADDRESS)
		WLog_INFO(TAG, "\tLB_TARGET_NET_ADDRESS");

	if (flags & LB_LOAD_BALANCE_INFO)
		WLog_INFO(TAG, "\tLB_LOAD_BALANCE_INFO");

	if (flags & LB_USERNAME)
		WLog_INFO(TAG, "\tLB_USERNAME");

	if (flags & LB_DOMAIN)
		WLog_INFO(TAG, "\tLB_DOMAIN");

	if (flags & LB_PASSWORD)
		WLog_INFO(TAG, "\tLB_PASSWORD");

	if (flags & LB_DONTSTOREUSERNAME)
		WLog_INFO(TAG, "\tLB_DONTSTOREUSERNAME");

	if (flags & LB_SMARTCARD_LOGON)
		WLog_INFO(TAG, "\tLB_SMARTCARD_LOGON");

	if (flags & LB_NOREDIRECT)
		WLog_INFO(TAG, "\tLB_NOREDIRECT");

	if (flags & LB_TARGET_FQDN)
		WLog_INFO(TAG, "\tLB_TARGET_FQDN");

	if (flags & LB_TARGET_NETBIOS_NAME)
		WLog_INFO(TAG, "\tLB_TARGET_NETBIOS_NAME");

	if (flags & LB_TARGET_NET_ADDRESSES)
		WLog_INFO(TAG, "\tLB_TARGET_NET_ADDRESSES");

	if (flags & LB_CLIENT_TSV_URL)
		WLog_INFO(TAG, "\tLB_CLIENT_TSV_URL");

	if (flags & LB_SERVER_TSV_CAPABLE)
		WLog_INFO(TAG, "\tLB_SERVER_TSV_CAPABLE");

	WLog_INFO(TAG, "}");
}
예제 #18
0
static void shw_OnConnectionResultEventHandler(void* context,
        ConnectionResultEventArgs* e)
{
	shwContext* shw = (shwContext*) context;
	WLog_INFO(TAG, "OnConnectionResult: %d", e->result);
}
예제 #19
0
BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
{
	BOOL status;
	rdpSettings* settings = rdp->settings;
	rdpNego *nego = rdp->nego;

	transport_set_blocking_mode(rdp->transport, TRUE);

	if (!nego_read_request(nego, s))
		return FALSE;

	nego->selected_protocol = 0;
	WLog_INFO(TAG,  "Client Security: NLA:%d TLS:%d RDP:%d",
			 (nego->requested_protocols & PROTOCOL_NLA) ? 1 : 0,
			 (nego->requested_protocols & PROTOCOL_TLS) ? 1 : 0,
			 (nego->requested_protocols == PROTOCOL_RDP) ? 1 : 0
			);
	WLog_INFO(TAG,  "Server Security: NLA:%d TLS:%d RDP:%d",
			 settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);

	if ((settings->NlaSecurity) && (nego->requested_protocols & PROTOCOL_NLA))
	{
		nego->selected_protocol = PROTOCOL_NLA;
	}
	else if ((settings->TlsSecurity) && (nego->requested_protocols & PROTOCOL_TLS))
	{
		nego->selected_protocol = PROTOCOL_TLS;
	}
	else if ((settings->RdpSecurity) && (nego->selected_protocol == PROTOCOL_RDP))
	{
		nego->selected_protocol = PROTOCOL_RDP;
	}
	else
	{
		WLog_ERR(TAG,  "Protocol security negotiation failure");
	}

	WLog_INFO(TAG,  "Negotiated Security: NLA:%d TLS:%d RDP:%d",
			 (nego->selected_protocol & PROTOCOL_NLA) ? 1 : 0,
			 (nego->selected_protocol & PROTOCOL_TLS) ? 1 : 0,
			 (nego->selected_protocol == PROTOCOL_RDP) ? 1: 0
			);

	if (!nego_send_negotiation_response(nego))
		return FALSE;

	status = FALSE;

	if (nego->selected_protocol & PROTOCOL_NLA)
		status = transport_accept_nla(rdp->transport);
	else if (nego->selected_protocol & PROTOCOL_TLS)
		status = transport_accept_tls(rdp->transport);
	else if (nego->selected_protocol == PROTOCOL_RDP) /* 0 */
		status = transport_accept_rdp(rdp->transport);

	if (!status)
		return FALSE;

	transport_set_blocking_mode(rdp->transport, FALSE);

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_NEGO);

	return TRUE;
}
예제 #20
0
static DWORD WINAPI shw_client_thread(LPVOID arg)
{
	int index;
	int rcount;
	int wcount;
	BOOL bSuccess;
	void* rfds[32];
	void* wfds[32];
	int fds_count;
	HANDLE fds[64];
	shwContext* shw;
	rdpContext* context;
	rdpChannels* channels;
	freerdp* instance = (freerdp*) arg;
	ZeroMemory(rfds, sizeof(rfds));
	ZeroMemory(wfds, sizeof(wfds));
	context = (rdpContext*) instance->context;
	shw = (shwContext*) context;
	bSuccess = freerdp_connect(instance);
	WLog_INFO(TAG, "freerdp_connect: %d", bSuccess);

	if (!bSuccess)
	{
		ExitThread(0);
		return 0;
	}

	channels = instance->context->channels;

	while (1)
	{
		rcount = 0;
		wcount = 0;

		if (!freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount))
		{
			WLog_ERR(TAG, "Failed to get FreeRDP file descriptor");
			break;
		}

		if (!freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount))
		{
			WLog_ERR(TAG, "Failed to get channels file descriptor");
			break;
		}

		fds_count = 0;

		for (index = 0; index < rcount; index++)
			fds[fds_count++] = rfds[index];

		for (index = 0; index < wcount; index++)
			fds[fds_count++] = wfds[index];

		if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1000,
		                              QS_ALLINPUT) == WAIT_FAILED)
		{
			WLog_ERR(TAG, "MsgWaitForMultipleObjects failure: 0x%08lX", GetLastError());
			break;
		}

		if (!freerdp_check_fds(instance))
		{
			WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
			break;
		}

		if (freerdp_shall_disconnect(instance))
		{
			break;
		}

		if (!freerdp_channels_check_fds(channels, instance))
		{
			WLog_ERR(TAG, "Failed to check channels file descriptor");
			break;
		}
	}

	freerdp_free(instance);
	ExitThread(0);
	return 0;
}
예제 #21
0
파일: wf_client.c 프로젝트: C4rt/FreeRDP
BOOL wf_pre_connect(freerdp* instance)
{
	wfContext* wfc;
	int desktopWidth;
	int desktopHeight;
	rdpContext* context;
	rdpSettings* settings;

	context = instance->context;
	wfc = (wfContext*) instance->context;
	wfc->instance = instance;
	wfc->codecs = instance->context->codecs;

	settings = instance->settings;

	if (settings->ConnectionFile)
	{
		if (wfc->connectionRdpFile)
		{
			freerdp_client_rdp_file_free(wfc->connectionRdpFile);
		}

		wfc->connectionRdpFile = freerdp_client_rdp_file_new();
		WLog_INFO(TAG,  "Using connection file: %s", settings->ConnectionFile);
		freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile);
		freerdp_client_populate_settings_from_rdp_file(wfc->connectionRdpFile, settings);
	}

	settings->OsMajorType = OSMAJORTYPE_WINDOWS;
	settings->OsMinorType = OSMINORTYPE_WINDOWS_NT;
	settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
	settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
	settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
	settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE;
	settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE;
	settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE;
	settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE;
	settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE;
	settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE;
	settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE;
	settings->OrderSupport[NEG_LINETO_INDEX] = TRUE;
	settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE;
	settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE;
	settings->OrderSupport[NEG_MEM3BLT_INDEX] = FALSE;
	settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE;
	settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = FALSE;
	settings->OrderSupport[NEG_FAST_INDEX_INDEX] = FALSE;
	settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = FALSE;
	settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE;
	settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
	settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
	settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;

	settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE;

	wfc->fullscreen = settings->Fullscreen;

	if (wfc->fullscreen)
		wfc->fs_toggle = 1;

	wfc->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV));
	ZeroMemory(wfc->clrconv, sizeof(CLRCONV));

	wfc->clrconv->palette = NULL;
	wfc->clrconv->alpha = FALSE;

	instance->context->cache = cache_new(settings);

	desktopWidth = settings->DesktopWidth;
	desktopHeight = settings->DesktopHeight;

	if (wfc->percentscreen > 0)
	{
		desktopWidth = (GetSystemMetrics(SM_CXSCREEN) * wfc->percentscreen) / 100;
		settings->DesktopWidth = desktopWidth;

		desktopHeight = (GetSystemMetrics(SM_CYSCREEN) * wfc->percentscreen) / 100;
		settings->DesktopHeight = desktopHeight;
	}

	if (wfc->fullscreen)
	{
		if (settings->UseMultimon)
		{
			desktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
			desktopHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
		}
		else
		{
			desktopWidth = GetSystemMetrics(SM_CXSCREEN);
			desktopHeight = GetSystemMetrics(SM_CYSCREEN);
		}
	}

	/* FIXME: desktopWidth has a limitation that it should be divisible by 4,
	 *        otherwise the screen will crash when connecting to an XP desktop.*/
	desktopWidth = (desktopWidth + 3) & (~3);

	if (desktopWidth != settings->DesktopWidth)
	{
		freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, desktopWidth);
	}

	if (desktopHeight != settings->DesktopHeight)
	{
		freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, desktopHeight);
	}

	if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) ||
		(settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
	{
		WLog_ERR(TAG, "invalid dimensions %d %d", settings->DesktopWidth, settings->DesktopHeight);
		return 1;
	}

	freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout, (int) GetKeyboardLayout(0) & 0x0000FFFF);

	PubSub_SubscribeChannelConnected(instance->context->pubSub,
		(pChannelConnectedEventHandler) wf_OnChannelConnectedEventHandler);

	PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
		(pChannelDisconnectedEventHandler) wf_OnChannelDisconnectedEventHandler);

	freerdp_channels_pre_connect(instance->context->channels, instance);

	return TRUE;
}
예제 #22
0
static void shw_OnChannelDisconnectedEventHandler(void* context,
        ChannelDisconnectedEventArgs* e)
{
	shwContext* shw = (shwContext*) context;
	WLog_INFO(TAG, "OnChannelDisconnected: %s", e->name);
}
예제 #23
0
파일: wf_wasapi.c 프로젝트: BUGgs/FreeRDP
int wf_wasapi_get_device_string(LPWSTR pattern, LPWSTR * deviceStr)
{
	HRESULT hr;
	IMMDeviceEnumerator *pEnumerator = NULL;
	IMMDeviceCollection *pCollection = NULL;
	IMMDevice *pEndpoint = NULL;
	IPropertyStore *pProps = NULL;
	LPWSTR pwszID = NULL;
	unsigned int count, i;

	CoInitialize(NULL);
	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, (void **) &pEnumerator);
	if (FAILED(hr))
	{
		WLog_ERR(TAG, "Failed to cocreate device enumerator");
		exit(1);
	}

	hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eCapture, DEVICE_STATE_ACTIVE, &pCollection);
	if ( FAILED(hr) )
	{
		WLog_ERR(TAG, "Failed to create endpoint collection");
		exit(1);
	}

	pCollection->lpVtbl->GetCount(pCollection, &count);
	WLog_INFO(TAG, "Num endpoints: %d", count);

	if (count == 0)
	{
		WLog_ERR(TAG, "No endpoints!");
		exit(1);
	}

	for (i = 0; i < count; ++i)
	{
		PROPVARIANT nameVar;
		PropVariantInit(&nameVar);

		hr = pCollection->lpVtbl->Item(pCollection, i, &pEndpoint);
		if ( FAILED(hr) )
		{
			WLog_ERR(TAG, "Failed to get endpoint %d", i);
			exit(1);
		}

		hr = pEndpoint->lpVtbl->GetId(pEndpoint, &pwszID);
		if ( FAILED(hr) )
		{
			WLog_ERR(TAG, "Failed to get endpoint ID");
			exit(1);
		}

		hr = pEndpoint->lpVtbl->OpenPropertyStore(pEndpoint, STGM_READ, &pProps);
		if ( FAILED(hr) )
		{
			WLog_ERR(TAG, "Failed to open property store");
			exit(1);
		}

		hr = pProps->lpVtbl->GetValue(pProps, &PKEY_Device_FriendlyName, &nameVar);
		if ( FAILED(hr) )
		{
			WLog_ERR(TAG, "Failed to get device friendly name");
			exit(1);
		}

		//do this a more reliable way
		if (wcscmp(pattern, nameVar.pwszVal) < 0)
		{
			unsigned int devStrLen;
			WLog_INFO(TAG, "Using sound ouput endpoint: [%s] (%s)", nameVar.pwszVal, pwszID);
			//WLog_INFO(TAG, "matched %d characters", wcscmp(pattern, nameVar.pwszVal);
			devStrLen = wcslen(pwszID);
			*deviceStr = (LPWSTR) calloc(1, (devStrLen * 2) + 2);
			if (!deviceStr)
				return -1;
			wcscpy_s(*deviceStr, devStrLen+1, pwszID);
		}
		CoTaskMemFree(pwszID);
		pwszID = NULL;
		PropVariantClear(&nameVar);

		pProps->lpVtbl->Release(pProps);
		pProps = NULL;

		pEndpoint->lpVtbl->Release(pEndpoint);
		pEndpoint = NULL;

	}

	pCollection->lpVtbl->Release(pCollection);
	pCollection = NULL;

	pEnumerator->lpVtbl->Release(pEnumerator);
	pEnumerator = NULL;
	CoUninitialize();

	return 0;
}
예제 #24
0
파일: tls.c 프로젝트: dcatonR1/FreeRDP
int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname,
                           int port)
{
	int match;
	int index;
	char* common_name = NULL;
	int common_name_length = 0;
	char** alt_names = NULL;
	int alt_names_count = 0;
	int* alt_names_lengths = NULL;
	BOOL certificate_status;
	BOOL hostname_match = FALSE;
	BOOL verification_status = FALSE;
	rdpCertificateData* certificate_data;

	if (tls->settings->ExternalCertificateManagement)
	{
		BIO* bio;
		int status;
		int length;
		int offset;
		BYTE* pemCert;
		freerdp* instance = (freerdp*) tls->settings->instance;
		/**
		 * Don't manage certificates internally, leave it up entirely to the external client implementation
		 */
		bio = BIO_new(BIO_s_mem());

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new() failure");
			return -1;
		}

		status = PEM_write_bio_X509(bio, cert->px509);

		if (status < 0)
		{
			WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status);
			return -1;
		}

		offset = 0;
		length = 2048;
		pemCert = (BYTE*) malloc(length + 1);

		if (!pemCert)
		{
			WLog_ERR(TAG, "error allocating pemCert");
			return -1;
		}

		status = BIO_read(bio, pemCert, length);

		if (status < 0)
		{
			WLog_ERR(TAG, "failed to read certificate");
			return -1;
		}

		offset += status;

		while (offset >= length)
		{
			int new_len;
			BYTE* new_cert;
			new_len = length * 2;
			new_cert = (BYTE*) realloc(pemCert, new_len + 1);

			if (!new_cert)
				return -1;

			length = new_len;
			pemCert = new_cert;
			status = BIO_read(bio, &pemCert[offset], length);

			if (status < 0)
				break;

			offset += status;
		}

		if (status < 0)
		{
			WLog_ERR(TAG, "failed to read certificate");
			return -1;
		}

		length = offset;
		pemCert[length] = '\0';
		status = -1;

		if (instance->VerifyX509Certificate)
			status = instance->VerifyX509Certificate(instance, pemCert, length, hostname,
			         port, tls->isGatewayTransport);
		else
			WLog_ERR(TAG, "No VerifyX509Certificate callback registered!");

		free(pemCert);
		BIO_free(bio);

		if (status < 0)
		{
			WLog_ERR(TAG, "VerifyX509Certificate failed: (length = %d) status: [%d] %s",
			         length, status, pemCert);
			return -1;
		}

		return (status == 0) ? 0 : 1;
	}

	/* ignore certificate verification if user explicitly required it (discouraged) */
	if (tls->settings->IgnoreCertificate)
		return 1;  /* success! */

	/* if user explicitly specified a certificate name, use it instead of the hostname */
	if (tls->settings->CertificateName)
		hostname = tls->settings->CertificateName;

	/* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */
	certificate_status = x509_verify_certificate(cert,
	                     tls->certificate_store->path);
	/* verify certificate name match */
	certificate_data = crypto_get_certificate_data(cert->px509, hostname, port);
	/* extra common name and alternative names */
	common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length);
	alt_names = crypto_cert_subject_alt_name(cert->px509, &alt_names_count,
	            &alt_names_lengths);

	/* compare against common name */

	if (common_name)
	{
		if (tls_match_hostname(common_name, common_name_length, hostname))
			hostname_match = TRUE;
	}

	/* compare against alternative names */

	if (alt_names)
	{
		for (index = 0; index < alt_names_count; index++)
		{
			if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname))
			{
				hostname_match = TRUE;
				break;
			}
		}
	}

	/* if the certificate is valid and the certificate name matches, verification succeeds */
	if (certificate_status && hostname_match)
		verification_status = TRUE; /* success! */

	/* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */
	if (!certificate_status || !hostname_match)
	{
		char* issuer;
		char* subject;
		char* fingerprint;
		freerdp* instance = (freerdp*) tls->settings->instance;
		DWORD accept_certificate = 0;
		issuer = crypto_cert_issuer(cert->px509);
		subject = crypto_cert_subject(cert->px509);
		fingerprint = crypto_cert_fingerprint(cert->px509);
		/* search for matching entry in known_hosts file */
		match = certificate_data_match(tls->certificate_store, certificate_data);

		if (match == 1)
		{
			/* no entry was found in known_hosts file, prompt user for manual verification */
			if (!hostname_match)
				tls_print_certificate_name_mismatch_error(
				    hostname, port,
				    common_name, alt_names,
				    alt_names_count);

			/* Automatically accept certificate on first use */
			if (tls->settings->AutoAcceptCertificate)
			{
				WLog_INFO(TAG, "No certificate stored, automatically accepting.");
				accept_certificate = 1;
			}
			else if (instance->VerifyCertificate)
			{
				accept_certificate = instance->VerifyCertificate(
				                         instance, common_name,
				                         subject, issuer,
				                         fingerprint, !hostname_match);
			}

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_print(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == -1)
		{
			char* old_subject = NULL;
			char* old_issuer = NULL;
			char* old_fingerprint = NULL;
			/* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */
			tls_print_certificate_error(hostname, port, fingerprint,
			                            tls->certificate_store->file);

			if (!certificate_get_stored_data(tls->certificate_store,
			                                 certificate_data, &old_subject,
			                                 &old_issuer, &old_fingerprint))
				WLog_WARN(TAG, "Failed to get certificate entry for %s:%d",
				          hostname, port);

			if (instance->VerifyChangedCertificate)
			{
				accept_certificate = instance->VerifyChangedCertificate(
				                         instance, common_name, subject, issuer,
				                         fingerprint, old_subject, old_issuer,
				                         old_fingerprint);
			}

			free(old_subject);
			free(old_issuer);
			free(old_fingerprint);

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_replace(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == 0)
			verification_status = TRUE; /* success! */

		free(issuer);
		free(subject);
		free(fingerprint);
	}

	certificate_data_free(certificate_data);
	free(common_name);

	if (alt_names)
		crypto_cert_subject_alt_name_free(alt_names_count, alt_names_lengths,
		                                  alt_names);

	return (verification_status == 0) ? 0 : 1;
}
예제 #25
0
파일: wf_rail.c 프로젝트: AMV007/FreeRDP
void PrintRailWindowState(WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
	if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
		WLog_INFO(TAG, "WindowCreate: WindowId: 0x%04X", orderInfo->windowId);
	else
		WLog_INFO(TAG, "WindowUpdate: WindowId: 0x%04X", orderInfo->windowId);

	WLog_INFO(TAG, "{");

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
	{
		WLog_INFO(TAG, "\tOwnerWindowId: 0x%04X", windowState->ownerWindowId);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
		WLog_INFO(TAG, "\tStyle: 0x%04X ExtendedStyle: 0x%04X",
			windowState->style, windowState->extendedStyle);
		
		PrintWindowStyles(windowState->style);
		PrintExtendedWindowStyles(windowState->extendedStyle);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		WLog_INFO(TAG, "\tShowState: %d", windowState->showState);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		char* title = NULL;

		ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
				   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);

		WLog_INFO(TAG, "\tTitleInfo: %s (length = %d)", title,
			windowState->titleInfo.length);

		free(title);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
	{
		WLog_INFO(TAG, "\tClientOffsetX: %d ClientOffsetY: %d",
			windowState->clientOffsetX, windowState->clientOffsetY);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
	{
		WLog_INFO(TAG, "\tClientAreaWidth: %d ClientAreaHeight: %d",
			windowState->clientAreaWidth, windowState->clientAreaHeight);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
	{
		WLog_INFO(TAG, "\tRPContent: %d", windowState->RPContent);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
	{
		WLog_INFO(TAG, "\tRootParentHandle: 0x%04X", windowState->rootParentHandle);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
	{
		WLog_INFO(TAG, "\tWindowOffsetX: %d WindowOffsetY: %d",
			windowState->windowOffsetX, windowState->windowOffsetY);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
	{
		WLog_INFO(TAG, "\tWindowClientDeltaX: %d WindowClientDeltaY: %d",
			windowState->windowClientDeltaX, windowState->windowClientDeltaY);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
	{
		WLog_INFO(TAG, "\tWindowWidth: %d WindowHeight: %d",
			windowState->windowWidth, windowState->windowHeight);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		UINT32 index;
		RECTANGLE_16* rect;

		WLog_INFO(TAG, "\tnumWindowRects: %d", windowState->numWindowRects);

		for (index = 0; index < windowState->numWindowRects; index++)
		{
			rect = &windowState->windowRects[index];

			WLog_INFO(TAG, "\twindowRect[%d]: left: %d top: %d right: %d bottom: %d",
				index, rect->left, rect->top, rect->right, rect->bottom);
		}
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
	{
		WLog_INFO(TAG, "\tvisibileOffsetX: %d visibleOffsetY: %d",
			windowState->visibleOffsetX, windowState->visibleOffsetY);
	}

	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
	{
		UINT32 index;
		RECTANGLE_16* rect;

		WLog_INFO(TAG, "\tnumVisibilityRects: %d", windowState->numVisibilityRects);

		for (index = 0; index < windowState->numVisibilityRects; index++)
		{
			rect = &windowState->visibilityRects[index];

			WLog_INFO(TAG, "\tvisibilityRect[%d]: left: %d top: %d right: %d bottom: %d",
				index, rect->left, rect->top, rect->right, rect->bottom);
		}
	}

	WLog_INFO(TAG, "}");
}
예제 #26
0
파일: h264.c 프로젝트: AMV007/FreeRDP
int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
		BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstWidth,
		int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRects)
{
	int index;
	int status;
	int* iStride;
	BYTE* pDstData;
	BYTE* pDstPoint;
	prim_size_t roi;
	BYTE** pYUVData;
	int width, height;
	BYTE* pYUVPoint[3];
	RDPGFX_RECT16* rect;
	primitives_t *prims = primitives_get();

	if (!h264)
		return -1;

#if 0
	WLog_INFO(TAG, "h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nDstHeight=%d, numRegionRects=%d",
		pSrcData, SrcSize, *ppDstData, nDstStep, nDstHeight, numRegionRects);
#endif

	if (!(pDstData = *ppDstData))
		return -1;

	if ((status = h264->subsystem->Decompress(h264, pSrcData, SrcSize)) < 0)
		return status;

	pYUVData = h264->pYUVData;
	iStride = h264->iStride;

	for (index = 0; index < numRegionRects; index++)
	{
		rect = &(regionRects[index]);

		/* Check, if the ouput rectangle is valid in decoded h264 frame. */
		if ((rect->right > h264->width) || (rect->left > h264->width))
			return -1;
		if ((rect->top > h264->height) || (rect->bottom > h264->height))
			return -1;

		/* Check, if the output rectangle is valid in destination buffer. */
		if ((rect->right > nDstWidth) || (rect->left > nDstWidth))
			return -1;
		if ((rect->bottom > nDstHeight) || (rect->top > nDstHeight))
			return -1;

		width = rect->right - rect->left;
		height = rect->bottom - rect->top;
		
		pDstPoint = pDstData + rect->top * nDstStep + rect->left * 4;
		pYUVPoint[0] = pYUVData[0] + rect->top * iStride[0] + rect->left;

		pYUVPoint[1] = pYUVData[1] + rect->top/2 * iStride[1] + rect->left/2;
		pYUVPoint[2] = pYUVData[2] + rect->top/2 * iStride[2] + rect->left/2;

#if 0
		WLog_INFO(TAG, "regionRect: x: %d y: %d width: %d height: %d",
		       rect->left, rect->top, width, height);
#endif

		roi.width = width;
		roi.height = height;

		prims->YUV420ToRGB_8u_P3AC4R((const BYTE**) pYUVPoint, iStride, pDstPoint, nDstStep, &roi);
	}

	return 1;
}
예제 #27
0
static BOOL tsmf_oss_open(ITSMFAudioDevice* audio, const char* device)
{
	int tmp;
	TSMFOssAudioDevice* oss = (TSMFOssAudioDevice*)audio;

	if (oss == NULL || oss->pcm_handle != -1)
		return FALSE;

	if (device == NULL)   /* Default device. */
	{
		strncpy(oss->dev_name, "/dev/dsp", sizeof(oss->dev_name));
	}
	else
	{
		strncpy(oss->dev_name, device, sizeof(oss->dev_name));
	}

	if ((oss->pcm_handle = open(oss->dev_name, O_WRONLY)) < 0)
	{
		OSS_LOG_ERR("sound dev open failed", errno);
		oss->pcm_handle = -1;
		return FALSE;
	}

#if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_OUTPUT flag. */
	tmp = 0;

	if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETCAPS, &mask) == -1)
	{
		OSS_LOG_ERR("SNDCTL_DSP_GETCAPS failed, try ignory", errno);
	}
	else if ((mask & PCM_CAP_OUTPUT) == 0)
	{
		OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP);
		close(oss->pcm_handle);
		oss->pcm_handle = -1;
		return FALSE;
	}

#endif
	tmp = 0;

	if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETFMTS, &tmp) == -1)
	{
		OSS_LOG_ERR("SNDCTL_DSP_GETFMTS failed", errno);
		close(oss->pcm_handle);
		oss->pcm_handle = -1;
		return FALSE;
	}

	if ((AFMT_S16_LE & tmp) == 0)
	{
		OSS_LOG_ERR("SNDCTL_DSP_GETFMTS - AFMT_S16_LE", EOPNOTSUPP);
		close(oss->pcm_handle);
		oss->pcm_handle = -1;
		return FALSE;
	}

	WLog_INFO(TAG, "open: %s", oss->dev_name);
	return TRUE;
}
예제 #28
0
파일: h264.c 프로젝트: AMV007/FreeRDP
static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize)
{
	DECODING_STATE state;
	SBufferInfo sBufferInfo;
	SSysMEMBuffer* pSystemBuffer;
	H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData;

	if (!sys->pDecoder)
		return -1;

	/*
	 * Decompress the image.  The RDP host only seems to send I420 format.
	 */

	h264->pYUVData[0] = NULL;
	h264->pYUVData[1] = NULL;
	h264->pYUVData[2] = NULL;

	ZeroMemory(&sBufferInfo, sizeof(sBufferInfo));

	state = (*sys->pDecoder)->DecodeFrame2(
		sys->pDecoder,
		pSrcData,
		SrcSize,
		h264->pYUVData,
		&sBufferInfo);

	/**
	 * Calling DecodeFrame2 twice apparently works around Openh264 issue #1136:
	 * https://github.com/cisco/openh264/issues/1136
	 *
	 * This is a hack, but it works and it is only necessary for the first frame.
	 */

	if (sBufferInfo.iBufferStatus != 1)
		state = (*sys->pDecoder)->DecodeFrame2(sys->pDecoder, NULL, 0, h264->pYUVData, &sBufferInfo);

	pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer;

#if 0
	WLog_INFO(TAG, "h264_decompress: state=%u, pYUVData=[%p,%p,%p], bufferStatus=%d, width=%d, height=%d, format=%d, stride=[%d,%d]",
		state, h264->pYUVData[0], h264->pYUVData[1], h264->pYUVData[2], sBufferInfo.iBufferStatus,
		pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iFormat,
		pSystemBuffer->iStride[0], pSystemBuffer->iStride[1]);
#endif

	if (state != 0)
		return -1;

	if (sBufferInfo.iBufferStatus != 1)
		return -2;

	if (pSystemBuffer->iFormat != videoFormatI420)
		return -1;

	if (!h264->pYUVData[0] || !h264->pYUVData[1] || !h264->pYUVData[2])
		return -1;

	h264->iStride[0] = pSystemBuffer->iStride[0];
	h264->iStride[1] = pSystemBuffer->iStride[1];
	h264->iStride[2] = pSystemBuffer->iStride[1];

	h264->width = pSystemBuffer->iWidth;
	h264->height = pSystemBuffer->iHeight;

	return 1;
}
예제 #29
0
파일: nego.c 프로젝트: AMV007/FreeRDP
BOOL nego_send_negotiation_response(rdpNego* nego)
{
	int length;
	int bm, em;
	BOOL status;
	wStream* s;
	BYTE flags;
	rdpSettings* settings;

	status = TRUE;
	settings = nego->transport->settings;

	s = Stream_New(NULL, 512);
	if (!s)
		return FALSE;

	length = TPDU_CONNECTION_CONFIRM_LENGTH;
	bm = Stream_GetPosition(s);
	Stream_Seek(s, length);

	if (nego->SelectedProtocol & PROTOCOL_FAILED_NEGO)
	{
		UINT32 errorCode = (nego->SelectedProtocol & ~PROTOCOL_FAILED_NEGO);
		flags = 0;

		Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE);
		Stream_Write_UINT8(s, flags); /* flags */
		Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */

		Stream_Write_UINT32(s, errorCode);
		length += 8;
		status = FALSE;
	}
	else
	{
		flags = EXTENDED_CLIENT_DATA_SUPPORTED;

		if (settings->SupportGraphicsPipeline)
			flags |= DYNVC_GFX_PROTOCOL_SUPPORTED;

		/* RDP_NEG_DATA must be present for TLS, NLA, and RDP */
		Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
		Stream_Write_UINT8(s, flags); /* flags */
		Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
		Stream_Write_UINT32(s, nego->SelectedProtocol); /* selectedProtocol */
		length += 8;
	}

	em = Stream_GetPosition(s);
	Stream_SetPosition(s, bm);
	tpkt_write_header(s, length);
	tpdu_write_connection_confirm(s, length - 5);
	Stream_SetPosition(s, em);

	Stream_SealLength(s);

	if (transport_write(nego->transport, s) < 0)
	{
		Stream_Free(s, TRUE);
		return FALSE;
	}

	Stream_Free(s, TRUE);

	if (status)
	{
		/* update settings with negotiated protocol security */
		settings->RequestedProtocols = nego->RequestedProtocols;
		settings->SelectedProtocol = nego->SelectedProtocol;

		if (settings->SelectedProtocol == PROTOCOL_RDP)
		{
			settings->TlsSecurity = FALSE;
			settings->NlaSecurity = FALSE;
			settings->RdpSecurity = TRUE;
			settings->UseRdpSecurityLayer = TRUE;

			if (settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE)
			{
				/**
				 * If the server implementation did not explicitely set a
				 * encryption level we default to client compatible
				 */
				settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
			}

			if (settings->LocalConnection)
			{
				/**
				 * Note: This hack was firstly introduced in commit 95f5e115 to
				 * disable the unnecessary encryption with peers connecting to
				 * 127.0.0.1 or local unix sockets.
				 * This also affects connections via port tunnels! (e.g. ssh -L)
				 */
				WLog_INFO(TAG, "Turning off encryption for local peer with standard rdp security");
				settings->UseRdpSecurityLayer = FALSE;
				settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
			}

			if (!settings->RdpServerRsaKey && !settings->RdpKeyFile)
			{
				WLog_ERR(TAG, "Missing server certificate");
				return FALSE;
			}
		}
		else if (settings->SelectedProtocol == PROTOCOL_TLS)
		{
			settings->TlsSecurity = TRUE;
			settings->NlaSecurity = FALSE;
			settings->RdpSecurity = FALSE;
			settings->UseRdpSecurityLayer = FALSE;
			settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
		}
		else if (settings->SelectedProtocol == PROTOCOL_NLA)
		{
			settings->TlsSecurity = TRUE;
			settings->NlaSecurity = TRUE;
			settings->RdpSecurity = FALSE;
			settings->UseRdpSecurityLayer = FALSE;
			settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
		}
	}

	return status;
}
예제 #30
0
파일: connection.c 프로젝트: artemh/FreeRDP
BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
{
	BOOL status;
	rdpSettings* settings = rdp->settings;
	rdpNego *nego = rdp->nego;

	transport_set_blocking_mode(rdp->transport, TRUE);

	if (!nego_read_request(nego, s))
		return FALSE;

	nego->SelectedProtocol = 0;
	WLog_INFO(TAG, "Client Security: NLA:%d TLS:%d RDP:%d",
			 (nego->RequestedProtocols & PROTOCOL_NLA) ? 1 : 0,
			 (nego->RequestedProtocols & PROTOCOL_TLS) ? 1 : 0,
			 (nego->RequestedProtocols == PROTOCOL_RDP) ? 1 : 0
			);
	WLog_INFO(TAG, "Server Security: NLA:%d TLS:%d RDP:%d",
			 settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);

	if ((settings->NlaSecurity) && (nego->RequestedProtocols & PROTOCOL_NLA))
	{
		nego->SelectedProtocol = PROTOCOL_NLA;
	}
	else if ((settings->TlsSecurity) && (nego->RequestedProtocols & PROTOCOL_TLS))
	{
		nego->SelectedProtocol = PROTOCOL_TLS;
	}
	else if ((settings->RdpSecurity) && (nego->RequestedProtocols == PROTOCOL_RDP))
	{
		nego->SelectedProtocol = PROTOCOL_RDP;
	}
	else
	{
		/*
		 * when here client and server aren't compatible, we select the right
		 * error message to return to the client in the nego failure packet
		 */
		nego->SelectedProtocol = PROTOCOL_FAILED_NEGO;

		if (settings->RdpSecurity)
		{
			WLog_ERR(TAG, "server supports only Standard RDP Security");
			nego->SelectedProtocol |= SSL_NOT_ALLOWED_BY_SERVER;
		}
		else
		{
			if (settings->NlaSecurity && !settings->TlsSecurity)
			{
				WLog_ERR(TAG, "server supports only NLA Security");
				nego->SelectedProtocol |= HYBRID_REQUIRED_BY_SERVER;
			}
			else
			{
				WLog_ERR(TAG, "server supports only a SSL based Security (TLS or NLA)");
				nego->SelectedProtocol |= SSL_REQUIRED_BY_SERVER;
			}
		}

		WLog_ERR(TAG, "Protocol security negotiation failure");
	}

	if (!(nego->SelectedProtocol & PROTOCOL_FAILED_NEGO))
	{
		WLog_INFO(TAG, "Negotiated Security: NLA:%d TLS:%d RDP:%d",
				 (nego->SelectedProtocol & PROTOCOL_NLA) ? 1 : 0,
				 (nego->SelectedProtocol & PROTOCOL_TLS) ? 1 : 0,
				 (nego->SelectedProtocol == PROTOCOL_RDP) ? 1: 0
				);
	}

	if (!nego_send_negotiation_response(nego))
		return FALSE;

	status = FALSE;

	if (nego->SelectedProtocol & PROTOCOL_NLA)
		status = transport_accept_nla(rdp->transport);
	else if (nego->SelectedProtocol & PROTOCOL_TLS)
		status = transport_accept_tls(rdp->transport);
	else if (nego->SelectedProtocol == PROTOCOL_RDP) /* 0 */
		status = transport_accept_rdp(rdp->transport);

	if (!status)
		return FALSE;

	transport_set_blocking_mode(rdp->transport, FALSE);

	rdp_server_transition_to_state(rdp, CONNECTION_STATE_NEGO);

	return TRUE;
}