コード例 #1
0
ファイル: peer.c プロジェクト: KimDongChun/FreeRDP
static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
{
	rdpRdp* rdp;
	UINT16 length;
	UINT16 pduType;
	UINT16 pduLength;
	UINT16 pduSource;
	UINT16 channelId;
	UINT16 securityFlags;

	rdp = client->context->rdp;

	if (!rdp_read_header(rdp, s, &length, &channelId))
	{
		fprintf(stderr, "Incorrect RDP header.\n");
		return -1;
	}

	if (rdp->settings->DisableEncryption)
	{
		if (!rdp_read_security_header(s, &securityFlags))
			return -1;

		if (securityFlags & SEC_ENCRYPT)
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				fprintf(stderr, "rdp_decrypt failed\n");
				return -1;
			}
		}
	}

	if (channelId != MCS_GLOBAL_CHANNEL_ID)
	{
		if(!freerdp_channel_peer_process(client, s, channelId))
			return -1;
	}
	else
	{
		if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
			return -1;

		client->settings->PduSource = pduSource;

		switch (pduType)
		{
			case PDU_TYPE_DATA:
				if (!peer_recv_data_pdu(client, s))
					return -1;
				break;

			default:
				fprintf(stderr, "Client sent pduType %d\n", pduType);
				return -1;
		}
	}

	return 0;
}
コード例 #2
0
ファイル: info.c プロジェクト: adambprotiviti/FreeRDP
boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s)
{
	uint16 length;
	uint16 channelId;
	uint16 securityFlags;

	if (!rdp_read_header(rdp, s, &length, &channelId))
		return false;

	rdp_read_security_header(s, &securityFlags);
	if ((securityFlags & SEC_INFO_PKT) == 0)
		return false;

	if (rdp->settings->encryption)
	{
		if (securityFlags & SEC_REDIRECTION_PKT)
		{
			printf("Error: SEC_REDIRECTION_PKT unsupported\n");
			return false;
		}
		if (securityFlags & SEC_ENCRYPT)
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				printf("rdp_decrypt failed\n");
				return false;
			}
		}
	}

	return rdp_read_info_packet(s, rdp->settings);
}
コード例 #3
0
ファイル: rdp.c プロジェクト: JozLes77/FreeRDP
static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
{
    UINT16 length;
    rdpFastPath* fastpath;

    fastpath = rdp->fastpath;

    if (!fastpath_read_header_rdp(fastpath, s, &length))
        return -1;

    if ((length == 0) || (length > Stream_GetRemainingLength(s)))
    {
        DEBUG_WARN( "incorrect FastPath PDU header length %d\n", length);
        return -1;
    }

    if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
    {
        UINT16 flags = (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0;

        if (!rdp_decrypt(rdp, s, length, flags))
            return -1;
    }

    return fastpath_recv_updates(rdp->fastpath, s);
}
コード例 #4
0
ファイル: peer.c プロジェクト: KimDongChun/FreeRDP
static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s)
{
	rdpRdp* rdp;
	UINT16 length;
	rdpFastPath* fastpath;

	rdp = client->context->rdp;
	fastpath = rdp->fastpath;
	//if (!fastpath_read_header_rdp(fastpath, s, &length))
	//	return -1;

	fastpath_read_header_rdp(fastpath, s, &length);

	if ((length == 0) || (length > stream_get_left(s)))
	{
		fprintf(stderr, "incorrect FastPath PDU header length %d\n", length);
		return -1;
	}

	if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
	{
		if (!rdp_decrypt(rdp, s, length, (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0))
			return -1;
	}

	return fastpath_recv_inputs(fastpath, s);
}
コード例 #5
0
ファイル: peer.c プロジェクト: vworkspace/FreeRDP
static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s)
{
	rdpRdp* rdp;
	UINT16 length;
	rdpFastPath* fastpath;

	rdp = client->context->rdp;
	fastpath = rdp->fastpath;

	fastpath_read_header_rdp(fastpath, s, &length);

	if ((length == 0) || (length > Stream_GetRemainingLength(s)))
	{
		WLog_ERR(TAG,  "incorrect FastPath PDU header length %d", length);
		return -1;
	}

	if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
	{
		if (!rdp_decrypt(rdp, s, length, (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0))
			return -1;
	}

	return fastpath_recv_inputs(fastpath, s);
}
コード例 #6
0
ファイル: info.c プロジェクト: pevik/debian-freerdp
BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
{
	UINT16 length;
	UINT16 channelId;
	UINT16 securityFlags;

	if (!rdp_read_header(rdp, s, &length, &channelId))
		return FALSE;

	if (!rdp_read_security_header(s, &securityFlags))
		return FALSE;

	if ((securityFlags & SEC_INFO_PKT) == 0)
		return FALSE;

	if (rdp->settings->DisableEncryption)
	{
		if (securityFlags & SEC_REDIRECTION_PKT)
		{
			fprintf(stderr, "Error: SEC_REDIRECTION_PKT unsupported\n");
			return FALSE;
		}

		if (securityFlags & SEC_ENCRYPT)
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				fprintf(stderr, "rdp_decrypt failed\n");
				return FALSE;
			}
		}
	}

	return rdp_read_info_packet(s, rdp->settings);
}
コード例 #7
0
ファイル: rdp.c プロジェクト: cocoon/NeutrinoRDP
static tbool rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 length;
	uint16 securityFlags;
	rdpFastPath* fastpath;

	LLOGLN(10, ("rdp_recv_fastpath_pdu:"));
	LHEXDUMP(10, (s->p, 4));
	fastpath = rdp->fastpath;
	length = fastpath_read_header_rdp(fastpath, s);
	LLOGLN(10, ("rdp_recv_fastpath_pdu: length %d", length));

	if (length == 0 || length > stream_get_left(s))
	{
		LLOGLN(0, ("rdp_recv_fastpath_pdu: incorrect FastPath PDU header length %d", length));
		return false;
	}

	if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
	{
		securityFlags = fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM ? SEC_SECURE_CHECKSUM : 0;
		rdp_decrypt(rdp, s, length, securityFlags);
		LLOGLN(10, ("rdp_recv_fastpath_pdu: decrypted data length %d", length));
		LHEXDUMP(10, (s->p, length));
	}

	return fastpath_recv_updates(rdp->fastpath, s);
}
コード例 #8
0
ファイル: rdp.c プロジェクト: roman-b/FreeRDP-1.0
static boolean rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 length;

	length = fastpath_read_header_rdp(rdp->fastpath, s);
	
	if (length == 0 || length > stream_get_left(s))
	{
		printf("incorrect FastPath PDU header length %d\n", length);
		return False;
	}

	if (rdp->fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
	{
		rdp_decrypt(rdp, s, length);
	}

	return fastpath_recv_updates(rdp->fastpath, s);
}
コード例 #9
0
ファイル: rdp.c プロジェクト: easycat/NeutrinoRDP
static tbool rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 length;
	rdpFastPath* fastpath;

	fastpath = rdp->fastpath;
	length = fastpath_read_header_rdp(fastpath, s);

	if (length == 0 || length > stream_get_left(s))
	{
		printf("incorrect FastPath PDU header length %d\n", length);
		return false;
	}

	if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
	{
		rdp_decrypt(rdp, s, length, (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0);
	}

	return fastpath_recv_updates(rdp->fastpath, s);
}
コード例 #10
0
ファイル: connection.c プロジェクト: jat255/FreeRDP
BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
{
	BYTE* mark;
	UINT16 length;
	UINT16 channelId;

	/* If the MCS message channel has been joined... */
	if (rdp->mcs->messageChannelId != 0)
	{
		/* Process any MCS message channel PDUs. */
		Stream_GetPointer(s, mark);

		if (rdp_read_header(rdp, s, &length, &channelId))
		{
			if (channelId == rdp->mcs->messageChannelId)
			{
				UINT16 securityFlags = 0;

				if (!rdp_read_security_header(s, &securityFlags, &length))
					return FALSE;

				if (securityFlags & SEC_ENCRYPT)
				{
					if (!rdp_decrypt(rdp, s, length, securityFlags))
					{
						WLog_ERR(TAG, "rdp_decrypt failed");
						return FALSE;
					}
				}

				if (rdp_recv_message_channel_pdu(rdp, s, securityFlags) == 0)
					return TRUE;
			}
		}

		Stream_SetPointer(s, mark);
	}

	return FALSE;
}
コード例 #11
0
ファイル: rdp.c プロジェクト: JozLes77/FreeRDP
static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
{
    UINT16 length;
    UINT16 pduType;
    UINT16 pduLength;
    UINT16 pduSource;
    UINT16 channelId = 0;
    UINT16 securityFlags;
    int nextPosition;

    if (!rdp_read_header(rdp, s, &length, &channelId))
    {
        DEBUG_WARN( "Incorrect RDP header.\n");
        return -1;
    }

    if (rdp->settings->DisableEncryption)
    {
        if (!rdp_read_security_header(s, &securityFlags))
            return -1;

        if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
        {
            if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
            {
                DEBUG_WARN( "rdp_decrypt failed\n");
                return -1;
            }
        }

        if (securityFlags & SEC_REDIRECTION_PKT)
        {
            /*
             * [MS-RDPBCGR] 2.2.13.2.1
             *  - no share control header, nor the 2 byte pad
             */
            Stream_Rewind(s, 2);

            return rdp_recv_enhanced_security_redirection_packet(rdp, s);
        }
    }

    if (channelId == MCS_GLOBAL_CHANNEL_ID)
    {
        while (Stream_GetRemainingLength(s) > 3)
        {
            nextPosition = Stream_GetPosition(s);

            if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
                return -1;

            nextPosition += pduLength;

            rdp->settings->PduSource = pduSource;

            switch (pduType)
            {
            case PDU_TYPE_DATA:
                if (rdp_recv_data_pdu(rdp, s) < 0)
                {
                    DEBUG_WARN( "rdp_recv_data_pdu failed\n");
                    return -1;
                }
                break;

            case PDU_TYPE_DEACTIVATE_ALL:
                if (!rdp_recv_deactivate_all(rdp, s))
                    return -1;
                break;

            case PDU_TYPE_SERVER_REDIRECTION:
                return rdp_recv_enhanced_security_redirection_packet(rdp, s);
                break;

            default:
                DEBUG_WARN( "incorrect PDU type: 0x%04X\n", pduType);
                break;
            }

            Stream_SetPosition(s, nextPosition);
        }
    }
    else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId)
    {
        return rdp_recv_message_channel_pdu(rdp, s);
    }
    else
    {
        if (!freerdp_channel_process(rdp->instance, s, channelId))
            return -1;
    }

    return 0;
}
コード例 #12
0
ファイル: rdp.c プロジェクト: ydal/FreeRDP
static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 length;
	uint16 pduType;
	uint16 pduLength;
	uint16 pduSource;
	uint16 channelId;
	uint32 securityHeader;

	if (!rdp_read_header(rdp, s, &length, &channelId))
	{
		printf("Incorrect RDP header.\n");
		return false;
	}

	if (rdp->settings->encryption)
	{
		stream_read_uint32(s, securityHeader);
		if (securityHeader & SEC_SECURE_CHECKSUM)
		{
			printf("Error: TODO\n");
			return false;
		}
		if (securityHeader & SEC_ENCRYPT)
		{
			if (!rdp_decrypt(rdp, s, length - 4))
			{
				printf("rdp_decrypt failed\n");
				return false;
			}
		}
	}

	if (channelId != MCS_GLOBAL_CHANNEL_ID)
	{
		freerdp_channel_process(rdp->instance, s, channelId);
	}
	else
	{
		rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource);

		rdp->settings->pdu_source = pduSource;

		switch (pduType)
		{
			case PDU_TYPE_DATA:
				rdp_recv_data_pdu(rdp, s);
				break;

			case PDU_TYPE_DEACTIVATE_ALL:
				if (!rdp_recv_deactivate_all(rdp, s))
					return false;
				break;

			case PDU_TYPE_SERVER_REDIRECTION:
				rdp_recv_enhanced_security_redirection_packet(rdp, s);
				break;

			default:
				printf("incorrect PDU type: 0x%04X\n", pduType);
				break;
		}
	}

	return true;
}
コード例 #13
0
ファイル: rdp.c プロジェクト: mario911/FreeRDP
static int rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
{
	UINT16 length;
	UINT16 pduType;
	UINT16 pduLength;
	UINT16 pduSource;
	UINT16 channelId;
	UINT16 securityFlags;
	BYTE* nextp;

	if (!rdp_read_header(rdp, s, &length, &channelId))
	{
		printf("Incorrect RDP header.\n");
		return -1;
	}

	if (rdp->settings->DisableEncryption)
	{
		if (!rdp_read_security_header(s, &securityFlags))
			return -1;

		if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				printf("rdp_decrypt failed\n");
				return -1;
			}
		}

		if (securityFlags & SEC_REDIRECTION_PKT)
		{
			/*
			 * [MS-RDPBCGR] 2.2.13.2.1
			 *  - no share control header, nor the 2 byte pad
			 */
			s->p -= 2;
			rdp_recv_enhanced_security_redirection_packet(rdp, s);
			return -1;
		}
	}

	if (channelId != MCS_GLOBAL_CHANNEL_ID)
	{
		if (!freerdp_channel_process(rdp->instance, s, channelId))
			return -1;
	}
	else
	{
		while (stream_get_left(s) > 3)
		{
			stream_get_mark(s, nextp);

			if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
				return -1;

			nextp += pduLength;

			rdp->settings->PduSource = pduSource;

			switch (pduType)
			{
				case PDU_TYPE_DATA:
					if (rdp_recv_data_pdu(rdp, s) < 0)
					{
						printf("rdp_recv_data_pdu failed\n");
						return -1;
					}
					break;

				case PDU_TYPE_DEACTIVATE_ALL:
					if (!rdp_recv_deactivate_all(rdp, s))
						return -1;
					break;

				case PDU_TYPE_SERVER_REDIRECTION:
					if (!rdp_recv_enhanced_security_redirection_packet(rdp, s))
						return -1;
					break;

				default:
					printf("incorrect PDU type: 0x%04X\n", pduType);
					break;
			}
			stream_set_mark(s, nextp);
		}
	}

	return 0;
}
コード例 #14
0
ファイル: rdp.c プロジェクト: cocoon/NeutrinoRDP
static tbool rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 length;
	uint16 pduType;
	uint16 pduLength;
	uint16 pduSource;
	uint16 channelId;
	uint16 securityFlags;
	uint8* nextp;

	LLOGLN(10, ("rdp_recv_tpkt_pdu:"));
	if (!rdp_read_header(rdp, s, &length, &channelId))
	{
		LLOGLN(0, ("Incorrect RDP header."));
		return false;
	}
	LLOGLN(10, ("rdp_recv_tpkt_pdu: length %d", length));
	if (rdp->disconnect)
	{
		LLOGLN(0, ("rdp_recv_tpkt_pdu: disconnect"));
		return false;
	}

	if (rdp->settings->encryption)
	{
		rdp_read_security_header(s, &securityFlags);
		LLOGLN(10, ("rdp_recv_tpkt_pdu: securityFlags 0x%8.8x", securityFlags));
		if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				LLOGLN(0, ("rdp_decrypt failed"));
				return false;
			}
		}
		if (securityFlags & SEC_REDIRECTION_PKT)
		{
			LLOGLN(0, ("rdp_recv_tpkt_pdu: got SEC_REDIRECTION_PKT securityFlags 0x%8.8x", securityFlags));
			/*
			 * [MS-RDPBCGR] 2.2.13.2.1
			 *  - no share control header, nor the 2 byte pad
			 */
			s->p -= 2;
			rdp_recv_enhanced_security_redirection_packet(rdp, s);
			return true;
		}
	}

	if (channelId != MCS_GLOBAL_CHANNEL_ID)
	{
		freerdp_channel_process(rdp->instance, s, channelId);
	}
	else
	{
		while (stream_get_left(s) > 3)
		{
			stream_get_mark(s, nextp);
			rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource);
			nextp += pduLength;

			rdp->settings->pdu_source = pduSource;

			switch (pduType)
			{
				case PDU_TYPE_DATA:
					if (!rdp_recv_data_pdu(rdp, s))
					{
						LLOGLN(0, ("rdp_recv_data_pdu failed"));
						return false;
					}
					break;

				case PDU_TYPE_DEACTIVATE_ALL:
					if (!rdp_recv_deactivate_all(rdp, s))
						return false;
					break;

				case PDU_TYPE_SERVER_REDIRECTION:
					rdp_recv_enhanced_security_redirection_packet(rdp, s);
					break;

				default:
					LLOGLN(0, ("incorrect PDU type: 0x%04X", pduType));
					break;
			}
			stream_set_mark(s, nextp);
		}
	}

	return true;
}
コード例 #15
0
ファイル: rdp.c プロジェクト: CaledoniaProject/rdpscan
static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 length;
	uint16 pduType;
	uint16 pduLength;
	uint16 pduSource;
	uint16 channelId;
	uint16 securityFlags;

	if (!rdp_read_header(rdp, s, &length, &channelId))
	{
		printf("Incorrect RDP header.\n");
		return false;
	}

	if (rdp->settings->encryption)
	{
		rdp_read_security_header(s, &securityFlags);
		if (securityFlags & (SEC_ENCRYPT|SEC_REDIRECTION_PKT))
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				printf("rdp_decrypt failed\n");
				return false;
			}
		}
		if (securityFlags & SEC_REDIRECTION_PKT)
		{
			/*
			 * [MS-RDPBCGR] 2.2.13.2.1
			 *  - no share control header, nor the 2 byte pad
			 */
			s->p -= 2;
			rdp_recv_enhanced_security_redirection_packet(rdp, s);
			return true;
		}
	}

	if (channelId != MCS_GLOBAL_CHANNEL_ID)
	{
		freerdp_channel_process(rdp->instance, s, channelId);
	}
	else
	{
		rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource);

		rdp->settings->pdu_source = pduSource;

		switch (pduType)
		{
			case PDU_TYPE_DATA:
				rdp_recv_data_pdu(rdp, s);
				break;

			case PDU_TYPE_DEACTIVATE_ALL:
				if (!rdp_recv_deactivate_all(rdp, s))
					return false;
				break;

			case PDU_TYPE_SERVER_REDIRECTION:
				rdp_recv_enhanced_security_redirection_packet(rdp, s);
				break;

			default:
				printf("incorrect PDU type: 0x%04X\n", pduType);
				break;
		}
	}

	return true;
}
コード例 #16
0
ファイル: peer.c プロジェクト: awakecoding/FreeRDP
static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
{
	rdpRdp* rdp;
	UINT16 length;
	UINT16 pduType;
	UINT16 pduLength;
	UINT16 pduSource;
	UINT16 channelId;
	UINT16 securityFlags = 0;
	rdp = client->context->rdp;

	if (!rdp_read_header(rdp, s, &length, &channelId))
	{
		WLog_ERR(TAG, "Incorrect RDP header.");
		return -1;
	}

	if (freerdp_shall_disconnect(rdp->instance))
		return 0;

	if (rdp->settings->UseRdpSecurityLayer)
	{
		if (!rdp_read_security_header(s, &securityFlags))
			return -1;

		if (securityFlags & SEC_ENCRYPT)
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				WLog_ERR(TAG, "rdp_decrypt failed");
				return -1;
			}
		}
	}

	if (channelId == MCS_GLOBAL_CHANNEL_ID)
	{
		if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
			return -1;

		client->settings->PduSource = pduSource;

		switch (pduType)
		{
			case PDU_TYPE_DATA:
				if (!peer_recv_data_pdu(client, s))
					return -1;

				break;

			case PDU_TYPE_CONFIRM_ACTIVE:
				if (!rdp_server_accept_confirm_active(rdp, s))
					return -1;

				break;

			case PDU_TYPE_FLOW_RESPONSE:
			case PDU_TYPE_FLOW_STOP:
			case PDU_TYPE_FLOW_TEST:
				break;

			default:
				WLog_ERR(TAG, "Client sent pduType %"PRIu16"", pduType);
				return -1;
		}
	}
	else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId)
	{
		if (!rdp->settings->UseRdpSecurityLayer)
			if (!rdp_read_security_header(s, &securityFlags))
				return -1;

		return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
	}
	else
	{
		if (!freerdp_channel_peer_process(client, s, channelId))
			return -1;
	}

	return 0;
}
コード例 #17
0
ファイル: license.c プロジェクト: BUGgs/FreeRDP
int license_recv(rdpLicense* license, wStream* s)
{
	BYTE flags;
	BYTE bMsgType;
	UINT16 wMsgSize;
	UINT16 length;
	UINT16 channelId;
	UINT16 securityFlags;

	if (!rdp_read_header(license->rdp, s, &length, &channelId))
	{
		WLog_ERR(TAG, "Incorrect RDP header.");
		return -1;
	}

	if (!rdp_read_security_header(s, &securityFlags))
		return -1;

	if (securityFlags & SEC_ENCRYPT)
	{
		if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags))
		{
			WLog_ERR(TAG, "rdp_decrypt failed");
			return -1;
		}
	}

	if (!(securityFlags & SEC_LICENSE_PKT))
	{
		int status;

		if (!(securityFlags & SEC_ENCRYPT))
			Stream_Rewind(s, RDP_SECURITY_HEADER_LENGTH);

		status = rdp_recv_out_of_sequence_pdu(license->rdp, s);
		if (status < 0)
		{
			WLog_ERR(TAG, "unexpected license packet.");
			return status;
		}

		return 0;
	}

	if (!license_read_preamble(s, &bMsgType, &flags, &wMsgSize)) /* preamble (4 bytes) */
		return -1;

	DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]);

	switch (bMsgType)
	{
		case LICENSE_REQUEST:
			if (!license_read_license_request_packet(license, s))
				return -1;

			if (!license_send_new_license_request_packet(license))
				return -1;
			break;

		case PLATFORM_CHALLENGE:
			if (!license_read_platform_challenge_packet(license, s))
				return -1;

			if (!license_send_platform_challenge_response_packet(license))
				return -1;
			break;

		case NEW_LICENSE:
			license_read_new_license_packet(license, s);
			break;

		case UPGRADE_LICENSE:
			license_read_upgrade_license_packet(license, s);
			break;

		case ERROR_ALERT:
			if (!license_read_error_alert_packet(license, s))
				return -1;
			break;

		default:
			WLog_ERR(TAG, "invalid bMsgType:%d", bMsgType);
			return FALSE;
	}

	return 0;
}