Malicious RDP server security fixes

This commit includes fixes for a set of 21 vulnerabilities in
rdesktop when a malicious RDP server is used.

All vulnerabilities was identified and reported by Eyal Itkin.

 * Add rdp_protocol_error function that is used in several fixes
 * Refactor of process_bitmap_updates
 * Fix possible integer overflow in s_check_rem() on 32bit arch
 * Fix memory corruption in process_bitmap_data - CVE-2018-8794
 * Fix remote code execution in process_bitmap_data - CVE-2018-8795
 * Fix remote code execution in process_plane - CVE-2018-8797
 * Fix Denial of Service in mcs_recv_connect_response - CVE-2018-20175
 * Fix Denial of Service in mcs_parse_domain_params - CVE-2018-20175
 * Fix Denial of Service in sec_parse_crypt_info - CVE-2018-20176
 * Fix Denial of Service in sec_recv - CVE-2018-20176
 * Fix minor information leak in rdpdr_process - CVE-2018-8791
 * Fix Denial of Service in cssp_read_tsrequest - CVE-2018-8792
 * Fix remote code execution in cssp_read_tsrequest - CVE-2018-8793
 * Fix Denial of Service in process_bitmap_data - CVE-2018-8796
 * Fix minor information leak in rdpsnd_process_ping - CVE-2018-8798
 * Fix Denial of Service in process_secondary_order - CVE-2018-8799
 * Fix remote code execution in in ui_clip_handle_data - CVE-2018-8800
 * Fix major information leak in ui_clip_handle_data - CVE-2018-20174
 * Fix memory corruption in rdp_in_unistr - CVE-2018-20177
 * Fix Denial of Service in process_demand_active - CVE-2018-20178
 * Fix remote code execution in lspci_process - CVE-2018-20179
 * Fix remote code execution in rdpsnddbg_process - CVE-2018-20180
 * Fix remote code execution in seamless_process - CVE-2018-20181
 * Fix remote code execution in seamless_process_line - CVE-2018-20182
rdp_out_unistr(STREAM s, char *string, int len)
{
	/* LEGACY:
	 *
	 *  Do not write new code that uses this function, use the ones defined
	 *  in stream.h for writing utf16 strings to a stream.
	 *
	 */
	static iconv_t icv_local_to_utf16;
	size_t ibl, obl;
	char *pin, *pout;


	if (string == NULL || len == 0)
		return;

	if (!icv_local_to_utf16)
	{
		icv_local_to_utf16 = iconv_open(WINDOWS_CODEPAGE, g_codepage);
		if (icv_local_to_utf16 == (iconv_t) - 1)
		{
			logger(Protocol, Error, "rdo_out_unistr(), iconv_open[%s -> %s] fail %p",
			       g_codepage, WINDOWS_CODEPAGE, icv_local_to_utf16);
			abort();
		}
	}


	ibl = strlen(string);
	obl = len + 2;
	pin = string;
	pout = (char *) s->p;

	memset(pout, 0, len + 4);


	if (iconv(icv_local_to_utf16, (char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
	{
		logger(Protocol, Error, "rdp_out_unistr(), iconv(2) fail, errno %d", errno);
		abort();
	}

	s->p += len + 2;
}

rdp_out_unistr(STREAM s, char *string, int len)
{
	/* LEGACY:
	 *
	 *  Do not write new code that uses this function, use the ones defined
	 *  in stream.h for writing utf16 strings to a stream.
	 *
	 */
	static iconv_t icv_local_to_utf16;
	size_t ibl, obl;
	char *pin, *pout;


	if (string == NULL || len == 0)
		return;

	if (!icv_local_to_utf16)
	{
		icv_local_to_utf16 = iconv_open(WINDOWS_CODEPAGE, g_codepage);
		if (icv_local_to_utf16 == (iconv_t) - 1)
		{
			logger(Protocol, Error, "rdo_out_unistr(), iconv_open[%s -> %s] fail %p",
			       g_codepage, WINDOWS_CODEPAGE, icv_local_to_utf16);
			abort();
		}
	}


	ibl = strlen(string);
	obl = len + 2;
	pin = string;
	pout = (char *) s->p;

	memset(pout, 0, len + 4);


	if (iconv(icv_local_to_utf16, (char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
	{
		logger(Protocol, Error, "rdp_out_unistr(), iconv(2) fail, errno %d", errno);
		abort();
	}

	s->p += len + 2;
}
