|
30 | 30 | #include <config_ac.h>
|
31 | 31 | #endif
|
32 | 32 |
|
| 33 | +#include <ctype.h> |
| 34 | +#include <limits.h> |
33 | 35 | #include <X11/keysym.h>
|
34 | 36 |
|
35 | 37 | #include "vnc.h"
|
@@ -1644,442 +1646,753 @@ lib_data_in(struct trans *trans)
|
1644 | 1646 | }
|
1645 | 1647 |
|
1646 | 1648 | /******************************************************************************/
|
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 | + */ |
1650 | 1655 | static int
|
1651 |
| -lib_mod_connect(struct vnc *v) |
| 1656 | +get_reason_string(struct vnc *v, char buff[], unsigned int bufflen) |
1652 | 1657 | {
|
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; |
1657 | 1659 | 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)); |
1683 | 1662 |
|
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) |
1691 | 1664 | {
|
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) |
1694 | 1668 | {
|
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 | + } |
1697 | 1675 | }
|
1698 | 1676 | }
|
1699 | 1677 |
|
| 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 | + |
1700 | 1708 | 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 | + } |
1702 | 1715 |
|
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') |
1705 | 1725 | {
|
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; |
1710 | 1728 | }
|
1711 | 1729 |
|
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) |
1714 | 1739 | {
|
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); |
1718 | 1744 | }
|
| 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); |
1719 | 1751 |
|
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) |
1721 | 1758 | {
|
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); |
1723 | 1768 | }
|
1724 | 1769 | else
|
1725 | 1770 | {
|
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; |
1727 | 1775 | }
|
1728 |
| - v->server_msg(v, text, 0); |
1729 |
| - |
1730 |
| - v->trans->si = v->si; |
1731 |
| - v->trans->my_source = XRDP_SOURCE_MOD; |
1732 | 1776 |
|
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); |
1734 | 1782 |
|
1735 |
| - if (error != 0) |
| 1783 | + if (trans_force_write_s(v->trans, s) != 0) |
1736 | 1784 | {
|
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; |
1743 | 1787 | }
|
1744 | 1788 |
|
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) |
1750 | 1794 | {
|
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; |
1755 | 1798 | }
|
1756 | 1799 |
|
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) |
1759 | 1803 | {
|
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 |
1762 | 1805 | }
|
| 1806 | + in_uint8(s, *next_char); |
1763 | 1807 |
|
1764 |
| - if (error == 0) |
| 1808 | + if (*next_char == 0) |
1765 | 1809 | {
|
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) |
1771 | 1813 | {
|
1772 |
| - check_sec_result = 0; |
| 1814 | + g_snprintf(text, sizeof(text), "No reason given"); |
1773 | 1815 | }
|
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) |
1775 | 1858 | {
|
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 | + } |
1778 | 1870 |
|
1779 |
| - if (error == 0) |
| 1871 | + if (st > sec_type) |
1780 | 1872 | {
|
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; |
1796 | 1874 | }
|
1797 | 1875 | }
|
1798 |
| - else if (i == 0) |
| 1876 | + if (sec_type == SEC_TYPE_INVALID) |
1799 | 1877 | {
|
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"); |
1802 | 1880 | }
|
1803 | 1881 | else
|
1804 | 1882 | {
|
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 | + } |
1807 | 1891 | }
|
1808 | 1892 | }
|
1809 | 1893 |
|
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 |
1811 | 1928 | {
|
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); |
1814 | 1931 | }
|
1815 | 1932 |
|
1816 |
| - if (error == 0 && check_sec_result) |
| 1933 | + if (sec_type == SEC_TYPE_INVALID) |
1817 | 1934 | {
|
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 | + } |
1821 | 1937 |
|
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); |
1825 | 1940 |
|
1826 |
| - if (i != 0) |
| 1941 | + switch (sec_type) |
| 1942 | + { |
| 1943 | + case SEC_TYPE_NONE: |
| 1944 | + if (rfbproto_version < RFBPROTO_VER_3_8) |
1827 | 1945 | {
|
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); |
1830 | 1964 | }
|
1831 | 1965 | else
|
1832 | 1966 | {
|
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; |
1834 | 1975 | }
|
| 1976 | + break; |
1835 | 1977 | }
|
| 1978 | + default: |
| 1979 | + // Shouldn't get here |
| 1980 | + LOG(LOG_LEVEL_ERROR, "VNC unsupported security type %d", sec_type); |
| 1981 | + goto fail; |
1836 | 1982 | }
|
1837 | 1983 |
|
1838 |
| - if (error == 0) |
| 1984 | + if (check_sec_result) |
1839 | 1985 | {
|
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 | + } |
1846 | 2012 | }
|
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) |
1848 | 2063 | {
|
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 | + } |
1850 | 2088 | }
|
| 2089 | + free_stream(s); |
| 2090 | + return rv; |
| 2091 | +} |
1851 | 2092 |
|
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) |
1853 | 2120 | {
|
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; |
1857 | 2123 | }
|
1858 |
| - else |
| 2124 | + else if (v->server_bpp == 15) |
1859 | 2125 | {
|
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; |
1861 | 2135 | }
|
1862 |
| - |
1863 |
| - if (error == 0) |
| 2136 | + else if (v->server_bpp == 16) |
1864 | 2137 | {
|
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; |
1874 | 2147 | }
|
1875 |
| - else |
| 2148 | + else if (v->server_bpp == 24 || v->server_bpp == 32) |
1876 | 2149 | {
|
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; |
1878 | 2159 | }
|
1879 | 2160 |
|
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) |
1881 | 2210 | {
|
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; |
1885 | 2212 | }
|
1886 | 2213 | else
|
1887 | 2214 | {
|
1888 |
| - LOG(LOG_LEVEL_ERROR, "VNC error before receiving name length"); |
| 2215 | + LOG(LOG_LEVEL_INFO, |
| 2216 | + "VNC User disabled EXTENDED_DESKTOP_SIZE"); |
1889 | 2217 | }
|
1890 | 2218 |
|
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) |
1892 | 2225 | {
|
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); |
1894 | 2231 |
|
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) |
1900 | 2277 | {
|
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; |
1906 | 2280 | }
|
1907 | 2281 | }
|
1908 |
| - else |
| 2282 | + |
| 2283 | + v->trans = trans_create(socket_mode, 8 * 8192, 8192); |
| 2284 | + if (v->trans == 0) |
1909 | 2285 | {
|
1910 |
| - LOG(LOG_LEVEL_ERROR, "VNC error before receiving name"); |
| 2286 | + v->server_msg(v, "VNC error: trans_create() failed", 0); |
| 2287 | + goto fail; |
1911 | 2288 | }
|
1912 | 2289 |
|
1913 |
| - /* should be connected */ |
1914 |
| - if (error == 0) |
| 2290 | + v->sck_closed = 0; |
| 2291 | + if (v->delay_ms > 0) |
1915 | 2292 | {
|
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 | + } |
1922 | 2297 |
|
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; |
1995 | 2300 |
|
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); |
2001 | 2302 |
|
2002 |
| - if (error == 0) |
| 2303 | + if (error != 0) |
2003 | 2304 | {
|
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 | + } |
2007 | 2310 |
|
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); |
2022 | 2320 |
|
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; |
2033 | 2327 | }
|
2034 | 2328 |
|
2035 |
| - if (error == 0) |
| 2329 | + if (negotiate_security_type(v, rfbproto_version, next_char) == |
| 2330 | + SEC_TYPE_INVALID) |
2036 | 2331 | {
|
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; |
2040 | 2335 | }
|
2041 | 2336 |
|
2042 |
| - if (error == 0) |
| 2337 | + if (send_client_init(v, 1) != 0) |
2043 | 2338 | {
|
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; |
2052 | 2341 | }
|
2053 | 2342 |
|
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 | + } |
2056 | 2348 |
|
2057 |
| - if (error == 0) |
| 2349 | + if (set_pixel_format(v) != 0) |
2058 | 2350 | {
|
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; |
2061 | 2353 | }
|
2062 |
| - else |
| 2354 | + |
| 2355 | + if (set_encodings(v) != 0) |
2063 | 2356 | {
|
2064 |
| - v->server_msg(v, "VNC error - problem connecting", 0); |
| 2357 | + v->server_msg(v, "Error setting encodings", 0); |
| 2358 | + goto fail; |
2065 | 2359 | }
|
2066 | 2360 |
|
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) |
2068 | 2364 | {
|
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; |
2073 | 2367 | }
|
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) |
2075 | 2376 | {
|
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; |
2080 | 2379 | }
|
2081 | 2380 |
|
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; |
2083 | 2396 | }
|
2084 | 2397 |
|
2085 | 2398 | /******************************************************************************/
|
|
0 commit comments