@@ -1654,10 +1654,15 @@ lib_mod_connect(struct vnc *v)
1654
1654
char cursor_mask [32 * (32 / 8 )];
1655
1655
char con_port [256 ];
1656
1656
char text [256 ];
1657
+ char * version_str ;
1658
+ char j ;
1657
1659
struct stream * s ;
1658
1660
struct stream * pixel_format ;
1659
1661
int error ;
1660
1662
int i ;
1663
+ int sec_lvl = 0 ;
1664
+ int version ;
1665
+ int n_sec_lvls ;
1661
1666
int check_sec_result ;
1662
1667
int socket_mode ;
1663
1668
@@ -1748,61 +1753,131 @@ lib_mod_connect(struct vnc *v)
1748
1753
error = trans_force_read_s (v -> trans , s , 12 );
1749
1754
if (error == 0 )
1750
1755
{
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 );
1756
+ in_uint8p (s , version_str , 12 );
1757
+ if (g_strncmp (version_str , "RFB 003.00" , 10 ) != 0 )
1758
+ {
1759
+ version_str [11 ] = '\0' ;
1760
+ LOG (LOG_LEVEL_ERROR , "Invalid server version string %s" , version_str );
1761
+ error = 1 ;
1762
+ }
1763
+ }
1764
+ if (error == 0 )
1765
+ {
1766
+ version = version_str [10 ] - '0' ;
1767
+ if (version != 3 && version != 7 && version != 8 )
1768
+ {
1769
+ LOG (LOG_LEVEL_ERROR , "Unsupported VNC version 3.%d" , version );
1770
+ error = 1 ;
1771
+ }
1755
1772
}
1756
-
1757
- /* sec type */
1758
1773
if (error == 0 )
1759
1774
{
1760
1775
init_stream (s , 8192 );
1761
- error = trans_force_read_s (v -> trans , s , 4 );
1776
+ out_uint8p (s , version_str , 12 );
1777
+ s_mark_end (s );
1778
+ error = trans_force_write_s (v -> trans , s );
1762
1779
}
1763
1780
1781
+ /* sec type */
1764
1782
if (error == 0 )
1765
1783
{
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 */
1784
+ if (version == 3 )
1771
1785
{
1772
- check_sec_result = 0 ;
1786
+ // The server chooses the security type
1787
+ error = trans_force_read_s (v -> trans , s , 4 );
1788
+ if (error == 0 )
1789
+ {
1790
+ in_uint32_be (s , sec_lvl );
1791
+ }
1773
1792
}
1774
- else if (i == 2 ) /* dec the password and the server random */
1793
+ else if (version >= 7 )
1775
1794
{
1776
- init_stream (s , 8192 );
1777
- error = trans_force_read_s (v -> trans , s , 16 );
1778
-
1795
+ // The client chooses the security type
1796
+ error = trans_force_read_s (v -> trans , s , 1 );
1779
1797
if (error == 0 )
1780
1798
{
1781
- init_stream (s , 8192 );
1782
- if (guid_is_set ( & v -> guid ) )
1799
+ in_uint8 (s , n_sec_lvls );
1800
+ if (n_sec_lvls > 0 )
1783
1801
{
1784
- char guid_str [GUID_STR_SIZE ];
1785
- guid_to_str (& v -> guid , guid_str );
1786
- rfbHashEncryptBytes (s -> data , guid_str );
1802
+ error = trans_force_read_s (v -> trans , s , n_sec_lvls );
1787
1803
}
1788
1804
else
1789
1805
{
1790
- rfbEncryptBytes (s -> data , v -> password );
1806
+ // Read size of reason
1807
+ error = trans_force_read_s (v -> trans , s , 4 );
1808
+ if (error == 0 )
1809
+ {
1810
+ in_uint32_be (s , i );
1811
+ error = trans_force_read_s (v -> trans , s , i );
1812
+ in_uint8a (s , text , i );
1813
+ text [i ] = '\0' ;
1814
+ LOG (LOG_LEVEL_ERROR , "Connection closed by server with reason: %s" , text );
1815
+ error = 1 ;
1816
+ }
1791
1817
}
1792
- s -> p += 16 ;
1818
+ }
1819
+ if (error == 0 )
1820
+ {
1821
+ for (; n_sec_lvls > 0 ; -- n_sec_lvls )
1822
+ {
1823
+ in_uint8 (s , j );
1824
+ // Choose the highest security level that we support
1825
+ if (j > sec_lvl && j <= 2 )
1826
+ {
1827
+ sec_lvl = j ;
1828
+ }
1829
+ }
1830
+ init_stream (s , 8192 );
1831
+ out_uint8 (s , sec_lvl );
1793
1832
s_mark_end (s );
1833
+
1794
1834
error = trans_force_write_s (v -> trans , s );
1795
- check_sec_result = 1 ; // not needed
1796
1835
}
1797
1836
}
1798
- else if (i == 0 )
1837
+ }
1838
+
1839
+ if (error == 0 )
1840
+ {
1841
+ g_sprintf (text , "VNC security level is %d (1 = none, 2 = standard)" , sec_lvl );
1842
+ v -> server_msg (v , text , 0 );
1843
+
1844
+ if (sec_lvl == 1 ) /* none */
1845
+ {
1846
+ if (version >= 8 )
1847
+ {
1848
+ check_sec_result = 1 ;
1849
+ }
1850
+ else
1851
+ {
1852
+ check_sec_result = 0 ;
1853
+ }
1854
+ }
1855
+ else if (sec_lvl == 2 ) /* dec the password and the server random */
1856
+ {
1857
+ init_stream (s , 8192 );
1858
+ if (guid_is_set (& v -> guid ))
1859
+ {
1860
+ char guid_str [GUID_STR_SIZE ];
1861
+ guid_to_str (& v -> guid , guid_str );
1862
+ rfbHashEncryptBytes (s -> data , guid_str );
1863
+ }
1864
+ else
1865
+ {
1866
+ rfbEncryptBytes (s -> data , v -> password );
1867
+ }
1868
+ s -> p += 16 ;
1869
+ s_mark_end (s );
1870
+ error = trans_force_write_s (v -> trans , s );
1871
+ check_sec_result = 1 ; // not needed
1872
+ }
1873
+ else if (sec_lvl == 0 )
1799
1874
{
1800
1875
LOG (LOG_LEVEL_ERROR , "VNC Server will disconnect" );
1801
1876
error = 1 ;
1802
1877
}
1803
1878
else
1804
1879
{
1805
- LOG (LOG_LEVEL_ERROR , "VNC unsupported security level %d" , i );
1880
+ LOG (LOG_LEVEL_ERROR , "VNC unsupported security level %d" , sec_lvl );
1806
1881
error = 1 ;
1807
1882
}
1808
1883
}
@@ -1839,8 +1914,7 @@ lib_mod_connect(struct vnc *v)
1839
1914
{
1840
1915
v -> server_msg (v , "VNC sending share flag" , 0 );
1841
1916
init_stream (s , 8192 );
1842
- s -> data [0 ] = 1 ;
1843
- s -> p ++ ;
1917
+ out_uint8 (s , 1 );
1844
1918
s_mark_end (s );
1845
1919
error = trans_force_write_s (v -> trans , s ); /* share flag */
1846
1920
}
0 commit comments