Skip to content

Commit c65c734

Browse files
authoredApr 1, 2025··
Merge pull request #3460 from matt335672/vnc_upgrade
Upgrade VNC module to support later RFB versions
2 parents 73bc82a + 4b2155b commit c65c734

File tree

2 files changed

+655
-320
lines changed

2 files changed

+655
-320
lines changed
 

‎vnc/rfb.h

+22
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,28 @@ typedef uint32_t encoding_type;
5858
#define RFB_ENC_DESKTOP_SIZE (encoding_type)-223
5959
#define RFB_ENC_EXTENDED_DESKTOP_SIZE (encoding_type)-308
6060

61+
/* Security types defined in RFC6143 7.2 (RFB Community wiki 7.1.2) */
62+
enum sec_type
63+
{
64+
SEC_TYPE_INVALID = 0,
65+
SEC_TYPE_NONE = 1,
66+
SEC_TYPE_VNC_AUTH = 2,
67+
SEC_TYPE_MAX = SEC_TYPE_VNC_AUTH // Max supported security type
68+
};
69+
70+
#define SEC_TYPE_TO_STR(st) \
71+
(((st) == SEC_TYPE_INVALID) ? "Invalid" : \
72+
((st) == SEC_TYPE_NONE) ? "None" : \
73+
((st) == SEC_TYPE_VNC_AUTH) ? "VNC Auth" : "Unknown")
74+
75+
/* Constructs an RFB version from a major and minor version */
76+
#define MAKE_RFBPROTO_VER(maj,min) ((maj * 1000) + (min))
77+
78+
/* Convenience macros */
79+
#define RFBPROTO_VER_3_3 MAKE_RFBPROTO_VER(3,3)
80+
#define RFBPROTO_VER_3_7 MAKE_RFBPROTO_VER(3,7)
81+
#define RFBPROTO_VER_3_8 MAKE_RFBPROTO_VER(3,8)
82+
6183
/**
6284
* Returns an error string for an ExtendedDesktopSize status code
6385
*/

‎vnc/vnc.c

+633-320
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <config_ac.h>
3131
#endif
3232

33+
#include <ctype.h>
34+
#include <limits.h>
3335
#include <X11/keysym.h>
3436

3537
#include "vnc.h"
@@ -1644,442 +1646,753 @@ lib_data_in(struct trans *trans)
16441646
}
16451647

16461648
/******************************************************************************/
1647-
/*
1648-
return error
1649-
*/
1649+
/**
1650+
* Gets a reason string from the server
1651+
*
1652+
* Sometimes the server sends an error, which is a 32-bit word
1653+
* followed by a string
1654+
*/
16501655
static int
1651-
lib_mod_connect(struct vnc *v)
1656+
get_reason_string(struct vnc *v, char buff[], unsigned int bufflen)
16521657
{
1653-
char cursor_data[32 * (32 * 3)];
1654-
char cursor_mask[32 * (32 / 8)];
1655-
char con_port[256];
1656-
char text[256];
1658+
int rv = 1;
16571659
struct stream *s;
1658-
struct stream *pixel_format;
1659-
int error;
1660-
int i;
1661-
int check_sec_result;
1662-
int socket_mode;
1663-
1664-
g_snprintf(con_port, sizeof(con_port), "%s", v->port);
1665-
1666-
v->server_msg(v, "VNC started connecting", 0);
1667-
check_sec_result = 1;
1668-
1669-
/* check if bpp is supported for rdp connection */
1670-
switch (v->server_bpp)
1671-
{
1672-
case 8:
1673-
case 15:
1674-
case 16:
1675-
case 24:
1676-
case 32:
1677-
break;
1678-
default:
1679-
v->server_msg(v, "VNC error - only supporting 8, 15, 16, 24 and 32 "
1680-
"bpp rdp connections", 0);
1681-
return 1;
1682-
}
1660+
make_stream(s);
1661+
init_stream(s, (int)(bufflen + 4));
16831662

1684-
/* Assume a TCP-port based connection (i.e. not a UDS connection)
1685-
* if the port is not an absolute path */
1686-
if (con_port[0] == '/')
1687-
{
1688-
socket_mode = TRANS_MODE_UNIX;
1689-
}
1690-
else
1663+
if (trans_force_read_s(v->trans, s, 4) == 0)
16911664
{
1692-
socket_mode = TRANS_MODE_TCP;
1693-
if (g_strcmp(v->ip, "") == 0)
1665+
unsigned int len;
1666+
in_uint32_be(s, len);
1667+
if (len < bufflen)
16941668
{
1695-
v->server_msg(v, "VNC error - no IP set for TCP connection", 0);
1696-
return 1;
1669+
if (trans_force_read_s(v->trans, s, len) == 0)
1670+
{
1671+
in_uint8a(s, buff, len);
1672+
buff[len] = '\0';
1673+
rv = 0;
1674+
}
16971675
}
16981676
}
16991677

1678+
free_stream(s);
1679+
return rv;
1680+
}
1681+
1682+
/******************************************************************************/
1683+
/**
1684+
* Negotiates the protocol version with the server
1685+
*
1686+
* @param v Module
1687+
* @param[out] next_char Either security-type (version 3.3) or
1688+
* number-of-security-types (versions > 3.3)
1689+
* @return 0 for error, or protocol version > 0
1690+
*
1691+
* The protocol negotiation is overlapped with the security negotiation.
1692+
* The result of the protocol negotiation is either good, in which case
1693+
* 'next_char' contains a protocol-dependent value, or not-good, in which
1694+
* case 'next_char' was set to zero and followed by a reason string. The
1695+
* reason string is consumed here, and logged.
1696+
*
1697+
* See sections 7.1.1 and 7.1.2 of the RFB community wiki
1698+
*/
1699+
static unsigned int
1700+
negotiate_protocol_version(struct vnc *v, unsigned char *next_char)
1701+
{
1702+
struct stream *s = NULL;
1703+
unsigned int major;
1704+
unsigned int minor;
1705+
unsigned int version;
1706+
int sec_type_size;
1707+
17001708
make_stream(s);
1701-
make_stream(pixel_format);
1709+
init_stream(s, 64);
1710+
if (trans_force_read_s(v->trans, s, 12) != 0)
1711+
{
1712+
LOG(LOG_LEVEL_ERROR, "Error reading server version string");
1713+
goto fail;
1714+
}
17021715

1703-
v->trans = trans_create(socket_mode, 8 * 8192, 8192);
1704-
if (v->trans == 0)
1716+
const char *p;
1717+
in_uint8p(s, p, 12); /* Moves s->p to end of string */
1718+
/* Expecting a string "RFB ???.???\n" where ? is a digit */
1719+
if (*p++ != 'R' || *p++ != 'F' || *p++ != 'B' ||
1720+
*p++ != ' ' ||
1721+
!isdigit(*p++) || !isdigit(*p++) || !isdigit(*p++) ||
1722+
*p++ != '.' ||
1723+
!isdigit(*p++) || !isdigit(*p++) || !isdigit(*p++) ||
1724+
*p++ != '\n')
17051725
{
1706-
v->server_msg(v, "VNC error: trans_create() failed", 0);
1707-
free_stream(s);
1708-
free_stream(pixel_format);
1709-
return 1;
1726+
LOG_HEXDUMP(LOG_LEVEL_ERROR, "Invalid RFB string :", s->data, 12);
1727+
goto fail;
17101728
}
17111729

1712-
v->sck_closed = 0;
1713-
if (v->delay_ms > 0)
1730+
/* Parse the major/minor versions in-place */
1731+
p = s->data;
1732+
major = (p[4] - '0') * 100 + (p[5] - '0') * 10 + (p[6] - '0');
1733+
minor = (p[8] - '0') * 100 + (p[9] - '0') * 10 + (p[10] - '0');
1734+
version = MAKE_RFBPROTO_VER(major, minor);
1735+
1736+
if (version == RFBPROTO_VER_3_3 ||
1737+
version == RFBPROTO_VER_3_7 ||
1738+
version == RFBPROTO_VER_3_8)
17141739
{
1715-
g_sprintf(text, "Waiting %d ms for VNC to start...", v->delay_ms);
1716-
v->server_msg(v, text, 0);
1717-
g_sleep(v->delay_ms);
1740+
/* Versions documented in RFC6143 */
1741+
LOG(LOG_LEVEL_INFO,
1742+
"RFB version %d.%d is supported by VNC server",
1743+
major, minor);
17181744
}
1745+
else if (major == 3)
1746+
{
1747+
/* RFC6143 section 6 states that unknown 3.x versions should
1748+
* be treated as 3.3 */
1749+
LOG(LOG_LEVEL_INFO, "RFB server reports version %d.%d.",
1750+
major, minor);
17191751

1720-
if (socket_mode == TRANS_MODE_TCP)
1752+
minor = 3;
1753+
version = MAKE_RFBPROTO_VER(major, minor);
1754+
LOG(LOG_LEVEL_INFO, "Proposing RFB version %d.%d to server",
1755+
major, minor);
1756+
}
1757+
else if (major > 3)
17211758
{
1722-
g_sprintf(text, "VNC connecting to TCP %s %s", v->ip, con_port);
1759+
/* This must be a new server version. Try to fall back to 3.8 */
1760+
LOG(LOG_LEVEL_INFO, "RFB server reports version %d.%d.",
1761+
major, minor);
1762+
1763+
major = 3;
1764+
minor = 8;
1765+
version = MAKE_RFBPROTO_VER(major, minor);
1766+
LOG(LOG_LEVEL_INFO, "Proposing RFB version %d.%d to server",
1767+
major, minor);
17231768
}
17241769
else
17251770
{
1726-
g_sprintf(text, "VNC connecting to local socket %s", con_port);
1771+
LOG(LOG_LEVEL_ERROR,
1772+
"Server reports unsupported RFB version %d.%d",
1773+
major, minor);
1774+
goto fail;
17271775
}
1728-
v->server_msg(v, text, 0);
1729-
1730-
v->trans->si = v->si;
1731-
v->trans->my_source = XRDP_SOURCE_MOD;
17321776

1733-
error = trans_connect(v->trans, v->ip, con_port, 3000);
1777+
/* Send our proposed version back to the server */
1778+
/* s->p should be in the right place to mark the end
1779+
* of the string */
1780+
g_snprintf(s->data, s->size, "RFB %03d.%03d\n", major, minor);
1781+
s_mark_end(s);
17341782

1735-
if (error != 0)
1783+
if (trans_force_write_s(v->trans, s) != 0)
17361784
{
1737-
g_snprintf(text, sizeof(text), "Error connecting to VNC server [%s]",
1738-
g_get_strerror());
1739-
v->server_msg(v, text, 0);
1740-
free_stream(s);
1741-
free_stream(pixel_format);
1742-
return 1;
1785+
LOG(LOG_LEVEL_ERROR, "Error writing server version string");
1786+
goto fail;
17431787
}
17441788

1745-
v->server_msg(v, "VNC tcp connected", 0);
1746-
/* protocol version */
1747-
init_stream(s, 8192);
1748-
error = trans_force_read_s(v->trans, s, 12);
1749-
if (error == 0)
1789+
// Version 3.3 sends back a U32 rather than a U8 for the security
1790+
// type, even though the values it supports fit easily in a U8
1791+
sec_type_size = (version == RFBPROTO_VER_3_3) ? 4 : 1;
1792+
init_stream(s, 64);
1793+
if (trans_force_read_s(v->trans, s, sec_type_size) != 0)
17501794
{
1751-
s->p = s->data;
1752-
out_uint8a(s, "RFB 003.003\n", 12);
1753-
s_mark_end(s);
1754-
error = trans_force_write_s(v->trans, s);
1795+
LOG(LOG_LEVEL_ERROR,
1796+
"Can't read negotiation result from server");
1797+
goto fail;
17551798
}
17561799

1757-
/* sec type */
1758-
if (error == 0)
1800+
// Read the next field, being careful to parse a whole U32 for
1801+
// version 3.3.
1802+
if (version == RFBPROTO_VER_3_3)
17591803
{
1760-
init_stream(s, 8192);
1761-
error = trans_force_read_s(v->trans, s, 4);
1804+
in_uint8s(s, 3); // Skip the three high octets
17621805
}
1806+
in_uint8(s, *next_char);
17631807

1764-
if (error == 0)
1808+
if (*next_char == 0)
17651809
{
1766-
in_uint32_be(s, i);
1767-
g_sprintf(text, "VNC security level is %d (1 = none, 2 = standard)", i);
1768-
v->server_msg(v, text, 0);
1769-
1770-
if (i == 1) /* none */
1810+
char text[256];
1811+
// Server reported a reason for failure
1812+
if (get_reason_string(v, text, sizeof(text)) != 0)
17711813
{
1772-
check_sec_result = 0;
1814+
g_snprintf(text, sizeof(text), "No reason given");
17731815
}
1774-
else if (i == 2) /* dec the password and the server random */
1816+
LOG(LOG_LEVEL_ERROR,
1817+
"Version negotiation with server failed [%s]", text);
1818+
goto fail;
1819+
}
1820+
1821+
free_stream(s);
1822+
return version;
1823+
1824+
fail:
1825+
free_stream(s);
1826+
return 0;
1827+
}
1828+
1829+
/******************************************************************************/
1830+
/**
1831+
* Chooses the security type from a list sent by the server
1832+
*
1833+
* @param v Module
1834+
* @param max_security_type Max security type to negotiate
1835+
* @return 0 for error, or security type ( > 0)
1836+
*
1837+
* See section 7.1.2 of the RFB community wiki
1838+
*
1839+
* This call is only made for RFB version 3.7 onwards
1840+
*/
1841+
static enum sec_type
1842+
choose_security_type(struct vnc *v, unsigned char number_of_security_types,
1843+
enum sec_type max_security_type)
1844+
{
1845+
enum sec_type sec_type = SEC_TYPE_INVALID;
1846+
1847+
struct stream *s = NULL;
1848+
make_stream(s);
1849+
init_stream(s, UCHAR_MAX);
1850+
1851+
if (trans_force_read_s(v->trans, s, number_of_security_types) != 0)
1852+
{
1853+
LOG(LOG_LEVEL_ERROR, "Can't read list of security types from server");
1854+
}
1855+
else
1856+
{
1857+
while (s_rem(s) > 0)
17751858
{
1776-
init_stream(s, 8192);
1777-
error = trans_force_read_s(v->trans, s, 16);
1859+
int j;
1860+
in_uint8(s, j);
1861+
enum sec_type st = (enum sec_type)j;
1862+
// Choose the highest security level that we support
1863+
if (st > max_security_type)
1864+
{
1865+
// If in development, log unsupported security types
1866+
LOG_DEVEL(LOG_LEVEL_INFO,
1867+
"Unsupported VNC security type %d was offered", j);
1868+
continue;
1869+
}
17781870

1779-
if (error == 0)
1871+
if (st > sec_type)
17801872
{
1781-
init_stream(s, 8192);
1782-
if (guid_is_set(&v->guid))
1783-
{
1784-
char guid_str[GUID_STR_SIZE];
1785-
guid_to_str(&v->guid, guid_str);
1786-
rfbHashEncryptBytes(s->data, guid_str);
1787-
}
1788-
else
1789-
{
1790-
rfbEncryptBytes(s->data, v->password);
1791-
}
1792-
s->p += 16;
1793-
s_mark_end(s);
1794-
error = trans_force_write_s(v->trans, s);
1795-
check_sec_result = 1; // not needed
1873+
sec_type = st;
17961874
}
17971875
}
1798-
else if (i == 0)
1876+
if (sec_type == SEC_TYPE_INVALID)
17991877
{
1800-
LOG(LOG_LEVEL_ERROR, "VNC Server will disconnect");
1801-
error = 1;
1878+
LOG(LOG_LEVEL_ERROR,
1879+
"RFB server did not offer a compatible security type");
18021880
}
18031881
else
18041882
{
1805-
LOG(LOG_LEVEL_ERROR, "VNC unsupported security level %d", i);
1806-
error = 1;
1883+
init_stream(s, 1);
1884+
out_uint8(s, sec_type);
1885+
s_mark_end(s);
1886+
if (trans_force_write_s(v->trans, s) != 0)
1887+
{
1888+
LOG(LOG_LEVEL_ERROR, "Can't send security type to server");
1889+
sec_type = SEC_TYPE_INVALID;
1890+
}
18071891
}
18081892
}
18091893

1810-
if (error != 0)
1894+
free_stream(s);
1895+
return sec_type;
1896+
}
1897+
1898+
/******************************************************************************/
1899+
/**
1900+
* Negotiates the security type with the server
1901+
*
1902+
* @param v Module
1903+
* @param rfbproto_version RFB version negotiated with the server
1904+
* @param next_char The character sent back (>0) when the protocol
1905+
* version was agreed.
1906+
* @return the negotiated security type (or SEC_TYPE_INVALID)
1907+
*/
1908+
static enum sec_type
1909+
negotiate_security_type(struct vnc *v, unsigned int rfbproto_version,
1910+
unsigned char next_char)
1911+
{
1912+
char text[256];
1913+
enum sec_type sec_type;
1914+
// Whether the SecurityResult word is read from the server
1915+
// (RFB Community wiki section 7.1.3)
1916+
int check_sec_result = 1;
1917+
1918+
struct stream *s = NULL;
1919+
make_stream(s);
1920+
init_stream(s, 64);
1921+
1922+
if (rfbproto_version == RFBPROTO_VER_3_3)
1923+
{
1924+
// The server has already chosen the security type
1925+
sec_type = (enum sec_type)next_char;
1926+
}
1927+
else
18111928
{
1812-
LOG(LOG_LEVEL_ERROR, "VNC error %d after security negotiation",
1813-
error);
1929+
// The client chooses the security type based on what's offered
1930+
sec_type = choose_security_type(v, next_char, SEC_TYPE_MAX);
18141931
}
18151932

1816-
if (error == 0 && check_sec_result)
1933+
if (sec_type == SEC_TYPE_INVALID)
18171934
{
1818-
/* sec result */
1819-
init_stream(s, 8192);
1820-
error = trans_force_read_s(v->trans, s, 4);
1935+
goto fail; // An error has already been logged
1936+
}
18211937

1822-
if (error == 0)
1823-
{
1824-
in_uint32_be(s, i);
1938+
g_sprintf(text, "VNC security type is %s", SEC_TYPE_TO_STR(sec_type));
1939+
v->server_msg(v, text, 0);
18251940

1826-
if (i != 0)
1941+
switch (sec_type)
1942+
{
1943+
case SEC_TYPE_NONE:
1944+
if (rfbproto_version < RFBPROTO_VER_3_8)
18271945
{
1828-
v->server_msg(v, "VNC password failed", 0);
1829-
error = 2;
1946+
check_sec_result = 0;
1947+
}
1948+
break;
1949+
1950+
case SEC_TYPE_VNC_AUTH:
1951+
{
1952+
init_stream(s, 64);
1953+
if (trans_force_read_s(v->trans, s, 16) != 0)
1954+
{
1955+
LOG(LOG_LEVEL_ERROR,
1956+
"Can't read VNC auth challenge from server");
1957+
goto fail;
1958+
}
1959+
if (guid_is_set(&v->guid))
1960+
{
1961+
char guid_str[GUID_STR_SIZE];
1962+
guid_to_str(&v->guid, guid_str);
1963+
rfbHashEncryptBytes(s->data, guid_str);
18301964
}
18311965
else
18321966
{
1833-
v->server_msg(v, "VNC password ok", 0);
1967+
rfbEncryptBytes(s->data, v->password);
1968+
}
1969+
s->p += 16;
1970+
s_mark_end(s);
1971+
if (trans_force_write_s(v->trans, s) != 0)
1972+
{
1973+
LOG(LOG_LEVEL_ERROR, "Can't send VNC auth response to server");
1974+
goto fail;
18341975
}
1976+
break;
18351977
}
1978+
default:
1979+
// Shouldn't get here
1980+
LOG(LOG_LEVEL_ERROR, "VNC unsupported security type %d", sec_type);
1981+
goto fail;
18361982
}
18371983

1838-
if (error == 0)
1984+
if (check_sec_result)
18391985
{
1840-
v->server_msg(v, "VNC sending share flag", 0);
1841-
init_stream(s, 8192);
1842-
s->data[0] = 1;
1843-
s->p++;
1844-
s_mark_end(s);
1845-
error = trans_force_write_s(v->trans, s); /* share flag */
1986+
/* RFB Community wiki 7.1.3 */
1987+
init_stream(s, 4);
1988+
if (trans_force_read_s(v->trans, s, 4) != 0)
1989+
{
1990+
LOG(LOG_LEVEL_ERROR, "Can't read SecurityResult from server");
1991+
goto fail;
1992+
}
1993+
1994+
int i;
1995+
in_uint32_be(s, i);
1996+
1997+
if (i != 0)
1998+
{
1999+
char msg[256];
2000+
// Versions >= 3.8 of the protocol send a reason string at
2001+
// this point
2002+
if (rfbproto_version < RFBPROTO_VER_3_8 ||
2003+
get_reason_string(v, text, sizeof(text)) != 0)
2004+
{
2005+
g_snprintf(text, sizeof(text), "No reason given");
2006+
}
2007+
g_snprintf(msg, sizeof(msg),
2008+
"VNC security negotiation failed [%s]", text);
2009+
v->server_msg(v, msg, 0);
2010+
goto fail;
2011+
}
18462012
}
1847-
else
2013+
2014+
free_stream(s);
2015+
return sec_type;
2016+
2017+
fail:
2018+
free_stream(s);
2019+
return SEC_TYPE_INVALID;
2020+
}
2021+
2022+
/******************************************************************************/
2023+
/**
2024+
* Sends the client init to the server (RFC6143 7.3.1)
2025+
*
2026+
* @param v Module
2027+
* @param share_flag Share flag value to send to the server
2028+
* @return 0 for success
2029+
*/
2030+
static int
2031+
send_client_init(struct vnc *v, int share_flag)
2032+
{
2033+
int rv;
2034+
struct stream *s;
2035+
make_stream(s);
2036+
init_stream(s, 64);
2037+
out_uint8(s, (share_flag) ? 1 : 0);
2038+
s_mark_end(s);
2039+
rv = trans_force_write_s(v->trans, s);
2040+
free_stream(s);
2041+
return rv;
2042+
}
2043+
2044+
/******************************************************************************/
2045+
/**
2046+
* Receives the server init from the server (RFC6143 7.3.2)
2047+
*
2048+
* @param v Module
2049+
* @return 0 for success
2050+
*/
2051+
static int
2052+
receive_server_init(struct vnc *v)
2053+
{
2054+
int rv;
2055+
struct stream *s;
2056+
int width;
2057+
int height;
2058+
int name_len;
2059+
make_stream(s);
2060+
init_stream(s, 256);
2061+
rv = trans_force_read_s(v->trans, s, 2 + 2 + 16 + 4);
2062+
if (rv == 0)
18482063
{
1849-
LOG(LOG_LEVEL_ERROR, "VNC error before sending share flag");
2064+
in_uint16_be(s, width);
2065+
in_uint16_be(s, height);
2066+
in_uint8s(s, 16); // skip server pixel format
2067+
in_uint32_be(s, name_len);
2068+
init_stream(s, 256); // Reset stream to read name
2069+
2070+
if (name_len > 255 || name_len < 0)
2071+
{
2072+
LOG(LOG_LEVEL_ERROR, "Unexpected name length %d received",
2073+
name_len);
2074+
rv = 1;
2075+
}
2076+
else if (trans_force_read_s(v->trans, s, name_len) != 0)
2077+
{
2078+
LOG(LOG_LEVEL_ERROR, "Error receiving desktop name");
2079+
rv = 1;
2080+
}
2081+
else
2082+
{
2083+
g_memcpy(v->mod_name, s->data, name_len);
2084+
v->mod_name[name_len] = 0;
2085+
2086+
init_single_screen_layout(width, height, &v->server_layout);
2087+
}
18502088
}
2089+
free_stream(s);
2090+
return rv;
2091+
}
18512092

1852-
if (error == 0)
2093+
/******************************************************************************/
2094+
/**
2095+
* Sets the pixel format (RFC6143 7.5.1)
2096+
*
2097+
* @param v Module
2098+
* @return 0 for success
2099+
*/
2100+
static int
2101+
set_pixel_format(struct vnc *v)
2102+
{
2103+
struct
2104+
{
2105+
unsigned char bits_per_pixel;
2106+
unsigned char depth;
2107+
unsigned char true_color;
2108+
unsigned short red_max;
2109+
unsigned short green_max;
2110+
unsigned short blue_max;
2111+
unsigned char red_shift;
2112+
unsigned char green_shift;
2113+
unsigned char blue_shift;
2114+
} pixel_format = {0};
2115+
2116+
int rv;
2117+
struct stream *s;
2118+
2119+
if (v->server_bpp == 8)
18532120
{
1854-
v->server_msg(v, "VNC receiving server init", 0);
1855-
init_stream(s, 8192);
1856-
error = trans_force_read_s(v->trans, s, 4); /* server init */
2121+
pixel_format.bits_per_pixel = 8;
2122+
pixel_format.depth = 8;
18572123
}
1858-
else
2124+
else if (v->server_bpp == 15)
18592125
{
1860-
LOG(LOG_LEVEL_ERROR, "VNC error before receiving server init");
2126+
pixel_format.bits_per_pixel = 16;
2127+
pixel_format.depth = 15;
2128+
pixel_format.true_color = 1;
2129+
pixel_format.red_max = 31;
2130+
pixel_format.green_max = 31;
2131+
pixel_format.blue_max = 31;
2132+
pixel_format.red_shift = 10;
2133+
pixel_format.green_shift = 5;
2134+
pixel_format.blue_shift = 0;
18612135
}
1862-
1863-
if (error == 0)
2136+
else if (v->server_bpp == 16)
18642137
{
1865-
int width;
1866-
int height;
1867-
in_uint16_be(s, width);
1868-
in_uint16_be(s, height);
1869-
init_single_screen_layout(width, height, &v->server_layout);
1870-
1871-
init_stream(pixel_format, 8192);
1872-
v->server_msg(v, "VNC receiving pixel format", 0);
1873-
error = trans_force_read_s(v->trans, pixel_format, 16);
2138+
pixel_format.bits_per_pixel = 16;
2139+
pixel_format.depth = 16;
2140+
pixel_format.true_color = 1;
2141+
pixel_format.red_max = 31;
2142+
pixel_format.green_max = 63;
2143+
pixel_format.blue_max = 31;
2144+
pixel_format.red_shift = 11;
2145+
pixel_format.green_shift = 5;
2146+
pixel_format.blue_shift = 0;
18742147
}
1875-
else
2148+
else if (v->server_bpp == 24 || v->server_bpp == 32)
18762149
{
1877-
LOG(LOG_LEVEL_ERROR, "VNC error before receiving pixel format");
2150+
pixel_format.bits_per_pixel = 32;
2151+
pixel_format.depth = 24;
2152+
pixel_format.true_color = 1;
2153+
pixel_format.red_max = 255;
2154+
pixel_format.green_max = 255;
2155+
pixel_format.blue_max = 255;
2156+
pixel_format.red_shift = 16;
2157+
pixel_format.green_shift = 8;
2158+
pixel_format.blue_shift = 0;
18782159
}
18792160

1880-
if (error == 0)
2161+
make_stream(s);
2162+
init_stream(s, 64);
2163+
out_uint8(s, RFB_C2S_SET_PIXEL_FORMAT);
2164+
out_uint8s(s, 3); /* pad */
2165+
/* Now send the pixel data block */
2166+
out_uint8(s, pixel_format.bits_per_pixel);
2167+
out_uint8(s, pixel_format.depth);
2168+
#if defined(B_ENDIAN)
2169+
out_uint8(s, 1); /* big endian */
2170+
#else
2171+
out_uint8(s, 0); /* big endian */
2172+
#endif
2173+
out_uint8(s, pixel_format.true_color);
2174+
out_uint16_be(s, pixel_format.red_max);
2175+
out_uint16_be(s, pixel_format.green_max);
2176+
out_uint16_be(s, pixel_format.blue_max);
2177+
out_uint8(s, pixel_format.red_shift);
2178+
out_uint8(s, pixel_format.green_shift);
2179+
out_uint8(s, pixel_format.blue_shift);
2180+
out_uint8s(s, 3); /* pad */
2181+
s_mark_end(s);
2182+
rv = trans_force_write_s(v->trans, s);
2183+
free_stream(s);
2184+
return rv;
2185+
}
2186+
2187+
/******************************************************************************/
2188+
/**
2189+
* Sets the encodings (RFC6143 7.5.2)
2190+
*
2191+
* @param v Module
2192+
* @return 0 for success
2193+
*/
2194+
static int
2195+
set_encodings(struct vnc *v)
2196+
{
2197+
encoding_type e[10];
2198+
unsigned int n = 0;
2199+
unsigned int i;
2200+
2201+
int rv;
2202+
struct stream *s;
2203+
2204+
/* These encodings are always supported */
2205+
e[n++] = RFB_ENC_RAW;
2206+
e[n++] = RFB_ENC_COPY_RECT;
2207+
e[n++] = RFB_ENC_CURSOR;
2208+
e[n++] = RFB_ENC_DESKTOP_SIZE;
2209+
if (v->enabled_encodings_mask & MSK_EXTENDED_DESKTOP_SIZE)
18812210
{
1882-
init_stream(s, 8192);
1883-
v->server_msg(v, "VNC receiving name length", 0);
1884-
error = trans_force_read_s(v->trans, s, 4); /* name len */
2211+
e[n++] = RFB_ENC_EXTENDED_DESKTOP_SIZE;
18852212
}
18862213
else
18872214
{
1888-
LOG(LOG_LEVEL_ERROR, "VNC error before receiving name length");
2215+
LOG(LOG_LEVEL_INFO,
2216+
"VNC User disabled EXTENDED_DESKTOP_SIZE");
18892217
}
18902218

1891-
if (error == 0)
2219+
make_stream(s);
2220+
init_stream(s, (int)(4 + sizeof(e)));
2221+
out_uint8(s, RFB_C2S_SET_ENCODINGS);
2222+
out_uint8(s, 0);
2223+
out_uint16_be(s, n); /* Number of encodings following */
2224+
for (i = 0 ; i < n; ++i)
18922225
{
1893-
in_uint32_be(s, i);
2226+
out_uint32_be(s, e[i]);
2227+
}
2228+
s_mark_end(s);
2229+
rv = trans_force_write_s(v->trans, s);
2230+
free_stream(s);
18942231

1895-
if (i > 255 || i < 0)
1896-
{
1897-
error = 3;
1898-
}
1899-
else
2232+
return rv;
2233+
}
2234+
2235+
/******************************************************************************/
2236+
/*
2237+
return error
2238+
*/
2239+
static int
2240+
lib_mod_connect(struct vnc *v)
2241+
{
2242+
char cursor_data[32 * (32 * 3)];
2243+
char cursor_mask[32 * (32 / 8)];
2244+
char con_port[256];
2245+
char text[256];
2246+
unsigned int rfbproto_version;
2247+
int error;
2248+
int socket_mode;
2249+
2250+
g_snprintf(con_port, sizeof(con_port), "%s", v->port);
2251+
2252+
/* check if bpp is supported for rdp connection */
2253+
switch (v->server_bpp)
2254+
{
2255+
case 8:
2256+
case 15:
2257+
case 16:
2258+
case 24:
2259+
case 32:
2260+
break;
2261+
default:
2262+
v->server_msg(v, "VNC error - only supporting 8, 15, 16, 24 and 32 "
2263+
"bpp rdp connections", 0);
2264+
return 1;
2265+
}
2266+
2267+
/* Assume a TCP-port based connection (i.e. not a UDS connection)
2268+
* if the port is not an absolute path */
2269+
if (con_port[0] == '/')
2270+
{
2271+
socket_mode = TRANS_MODE_UNIX;
2272+
}
2273+
else
2274+
{
2275+
socket_mode = TRANS_MODE_TCP;
2276+
if (g_strcmp(v->ip, "") == 0)
19002277
{
1901-
init_stream(s, 8192);
1902-
v->server_msg(v, "VNC receiving name", 0);
1903-
error = trans_force_read_s(v->trans, s, i); /* name len */
1904-
g_memcpy(v->mod_name, s->data, i);
1905-
v->mod_name[i] = 0;
2278+
v->server_msg(v, "VNC error - no IP set for TCP connection", 0);
2279+
goto fail;
19062280
}
19072281
}
1908-
else
2282+
2283+
v->trans = trans_create(socket_mode, 8 * 8192, 8192);
2284+
if (v->trans == 0)
19092285
{
1910-
LOG(LOG_LEVEL_ERROR, "VNC error before receiving name");
2286+
v->server_msg(v, "VNC error: trans_create() failed", 0);
2287+
goto fail;
19112288
}
19122289

1913-
/* should be connected */
1914-
if (error == 0)
2290+
v->sck_closed = 0;
2291+
if (v->delay_ms > 0)
19152292
{
1916-
init_stream(s, 8192);
1917-
out_uint8(s, RFB_C2S_SET_PIXEL_FORMAT);
1918-
out_uint8(s, 0);
1919-
out_uint8(s, 0);
1920-
out_uint8(s, 0);
1921-
init_stream(pixel_format, 8192);
2293+
g_sprintf(text, "Waiting %d ms for VNC to start...", v->delay_ms);
2294+
v->server_msg(v, text, 0);
2295+
g_sleep(v->delay_ms);
2296+
}
19222297

1923-
if (v->server_bpp == 8)
1924-
{
1925-
out_uint8(pixel_format, 8); /* bits per pixel */
1926-
out_uint8(pixel_format, 8); /* depth */
1927-
#if defined(B_ENDIAN)
1928-
out_uint8(pixel_format, 1); /* big endian */
1929-
#else
1930-
out_uint8(pixel_format, 0); /* big endian */
1931-
#endif
1932-
out_uint8(pixel_format, 0); /* true color flag */
1933-
out_uint16_be(pixel_format, 0); /* red max */
1934-
out_uint16_be(pixel_format, 0); /* green max */
1935-
out_uint16_be(pixel_format, 0); /* blue max */
1936-
out_uint8(pixel_format, 0); /* red shift */
1937-
out_uint8(pixel_format, 0); /* green shift */
1938-
out_uint8(pixel_format, 0); /* blue shift */
1939-
out_uint8s(pixel_format, 3); /* pad */
1940-
}
1941-
else if (v->server_bpp == 15)
1942-
{
1943-
out_uint8(pixel_format, 16); /* bits per pixel */
1944-
out_uint8(pixel_format, 15); /* depth */
1945-
#if defined(B_ENDIAN)
1946-
out_uint8(pixel_format, 1); /* big endian */
1947-
#else
1948-
out_uint8(pixel_format, 0); /* big endian */
1949-
#endif
1950-
out_uint8(pixel_format, 1); /* true color flag */
1951-
out_uint16_be(pixel_format, 31); /* red max */
1952-
out_uint16_be(pixel_format, 31); /* green max */
1953-
out_uint16_be(pixel_format, 31); /* blue max */
1954-
out_uint8(pixel_format, 10); /* red shift */
1955-
out_uint8(pixel_format, 5); /* green shift */
1956-
out_uint8(pixel_format, 0); /* blue shift */
1957-
out_uint8s(pixel_format, 3); /* pad */
1958-
}
1959-
else if (v->server_bpp == 16)
1960-
{
1961-
out_uint8(pixel_format, 16); /* bits per pixel */
1962-
out_uint8(pixel_format, 16); /* depth */
1963-
#if defined(B_ENDIAN)
1964-
out_uint8(pixel_format, 1); /* big endian */
1965-
#else
1966-
out_uint8(pixel_format, 0); /* big endian */
1967-
#endif
1968-
out_uint8(pixel_format, 1); /* true color flag */
1969-
out_uint16_be(pixel_format, 31); /* red max */
1970-
out_uint16_be(pixel_format, 63); /* green max */
1971-
out_uint16_be(pixel_format, 31); /* blue max */
1972-
out_uint8(pixel_format, 11); /* red shift */
1973-
out_uint8(pixel_format, 5); /* green shift */
1974-
out_uint8(pixel_format, 0); /* blue shift */
1975-
out_uint8s(pixel_format, 3); /* pad */
1976-
}
1977-
else if (v->server_bpp == 24 || v->server_bpp == 32)
1978-
{
1979-
out_uint8(pixel_format, 32); /* bits per pixel */
1980-
out_uint8(pixel_format, 24); /* depth */
1981-
#if defined(B_ENDIAN)
1982-
out_uint8(pixel_format, 1); /* big endian */
1983-
#else
1984-
out_uint8(pixel_format, 0); /* big endian */
1985-
#endif
1986-
out_uint8(pixel_format, 1); /* true color flag */
1987-
out_uint16_be(pixel_format, 255); /* red max */
1988-
out_uint16_be(pixel_format, 255); /* green max */
1989-
out_uint16_be(pixel_format, 255); /* blue max */
1990-
out_uint8(pixel_format, 16); /* red shift */
1991-
out_uint8(pixel_format, 8); /* green shift */
1992-
out_uint8(pixel_format, 0); /* blue shift */
1993-
out_uint8s(pixel_format, 3); /* pad */
1994-
}
2298+
v->trans->si = v->si;
2299+
v->trans->my_source = XRDP_SOURCE_MOD;
19952300

1996-
out_uint8a(s, pixel_format->data, 16);
1997-
v->server_msg(v, "VNC sending pixel format", 0);
1998-
s_mark_end(s);
1999-
error = trans_force_write_s(v->trans, s);
2000-
}
2301+
error = trans_connect(v->trans, v->ip, con_port, 3000);
20012302

2002-
if (error == 0)
2303+
if (error != 0)
20032304
{
2004-
encoding_type e[10];
2005-
unsigned int n = 0;
2006-
unsigned int i;
2305+
g_snprintf(text, sizeof(text), "Error connecting to VNC server [%s]",
2306+
g_get_strerror());
2307+
v->server_msg(v, text, 0);
2308+
goto fail;
2309+
}
20072310

2008-
/* These encodings are always supported */
2009-
e[n++] = RFB_ENC_RAW;
2010-
e[n++] = RFB_ENC_COPY_RECT;
2011-
e[n++] = RFB_ENC_CURSOR;
2012-
e[n++] = RFB_ENC_DESKTOP_SIZE;
2013-
if (v->enabled_encodings_mask & MSK_EXTENDED_DESKTOP_SIZE)
2014-
{
2015-
e[n++] = RFB_ENC_EXTENDED_DESKTOP_SIZE;
2016-
}
2017-
else
2018-
{
2019-
LOG(LOG_LEVEL_INFO,
2020-
"VNC User disabled EXTENDED_DESKTOP_SIZE");
2021-
}
2311+
if (socket_mode == TRANS_MODE_TCP)
2312+
{
2313+
g_sprintf(text, "VNC connected to TCP %s %s", v->ip, con_port);
2314+
}
2315+
else
2316+
{
2317+
g_sprintf(text, "VNC connected to local socket %s", con_port);
2318+
}
2319+
v->server_msg(v, text, 0);
20222320

2023-
init_stream(s, 8192);
2024-
out_uint8(s, RFB_C2S_SET_ENCODINGS);
2025-
out_uint8(s, 0);
2026-
out_uint16_be(s, n); /* Number of encodings following */
2027-
for (i = 0 ; i < n; ++i)
2028-
{
2029-
out_uint32_be(s, e[i]);
2030-
}
2031-
s_mark_end(s);
2032-
error = trans_force_write_s(v->trans, s);
2321+
/* protocol version */
2322+
unsigned char next_char;
2323+
if ((rfbproto_version = negotiate_protocol_version(v, &next_char)) == 0)
2324+
{
2325+
v->server_msg(v, "Error negotiating VNC version", 0);
2326+
goto fail;
20332327
}
20342328

2035-
if (error == 0)
2329+
if (negotiate_security_type(v, rfbproto_version, next_char) ==
2330+
SEC_TYPE_INVALID)
20362331
{
2037-
v->resize_supported = VRSS_UNKNOWN;
2038-
v->resize_status = VRS_WAITING_FOR_FIRST_UPDATE;
2039-
error = send_update_request_for_resize_status(v);
2332+
// An error has been logged
2333+
v->server_msg(v, "Error negotiating security type", 0);
2334+
goto fail;
20402335
}
20412336

2042-
if (error == 0)
2337+
if (send_client_init(v, 1) != 0)
20432338
{
2044-
/* set almost null cursor, this is the little dot cursor */
2045-
g_memset(cursor_data, 0, 32 * (32 * 3));
2046-
g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9);
2047-
g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9);
2048-
g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9);
2049-
g_memset(cursor_mask, 0xff, 32 * (32 / 8));
2050-
v->server_msg(v, "VNC sending cursor", 0);
2051-
error = v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask);
2339+
v->server_msg(v, "Error sending client init", 0);
2340+
goto fail;
20522341
}
20532342

2054-
free_stream(s);
2055-
free_stream(pixel_format);
2343+
if (receive_server_init(v) != 0)
2344+
{
2345+
v->server_msg(v, "Error receiving server init", 0);
2346+
goto fail;
2347+
}
20562348

2057-
if (error == 0)
2349+
if (set_pixel_format(v) != 0)
20582350
{
2059-
v->server_msg(v, "VNC connection complete, connected ok", 0);
2060-
vnc_clip_open_clip_channel(v);
2351+
v->server_msg(v, "Error setting pixel format", 0);
2352+
goto fail;
20612353
}
2062-
else
2354+
2355+
if (set_encodings(v) != 0)
20632356
{
2064-
v->server_msg(v, "VNC error - problem connecting", 0);
2357+
v->server_msg(v, "Error setting encodings", 0);
2358+
goto fail;
20652359
}
20662360

2067-
if (error != 0)
2361+
v->resize_supported = VRSS_UNKNOWN;
2362+
v->resize_status = VRS_WAITING_FOR_FIRST_UPDATE;
2363+
if (send_update_request_for_resize_status(v) != 0)
20682364
{
2069-
trans_delete(v->trans);
2070-
v->trans = 0;
2071-
v->server_msg(v, "some problem", 0);
2072-
return 1;
2365+
v->server_msg(v, "Error sending resize support request", 0);
2366+
goto fail;
20732367
}
2074-
else
2368+
2369+
/* set almost null cursor, this is the little dot cursor */
2370+
g_memset(cursor_data, 0, 32 * (32 * 3));
2371+
g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9);
2372+
g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9);
2373+
g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9);
2374+
g_memset(cursor_mask, 0xff, 32 * (32 / 8));
2375+
if (v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask) != 0)
20752376
{
2076-
v->server_msg(v, "connected ok", 0);
2077-
v->trans->trans_data_in = lib_data_in;
2078-
v->trans->header_size = 1;
2079-
v->trans->callback_data = v;
2377+
v->server_msg(v, "Error sending cursor", 0);
2378+
goto fail;
20802379
}
20812380

2082-
return error;
2381+
v->server_msg(v, "VNC connection complete, connected ok", 0);
2382+
vnc_clip_open_clip_channel(v);
2383+
2384+
v->trans->trans_data_in = lib_data_in;
2385+
v->trans->header_size = 1;
2386+
v->trans->callback_data = v;
2387+
2388+
return 0;
2389+
2390+
fail:
2391+
trans_delete(v->trans);
2392+
v->trans = NULL;
2393+
v->server_msg(v, "VNC error - problem connecting", 0);
2394+
2395+
return 1;
20832396
}
20842397

20852398
/******************************************************************************/

0 commit comments

Comments
 (0)
Please sign in to comment.