Commit 5fb6c7a8b26eab1a22207d24b4784bd2b39ab54b

Authored by aliguori
1 parent 19a490bf

Move TLS auth into separate file ("Daniel P. Berrange")

This patch refactors the existing TLS code to make the main VNC code
more managable. The code moves to two new files

 - vnc-tls.c: generic helpers for TLS handshake & credential setup
 - vnc-auth-vencrypt.c: the actual VNC TLS authentication mechanism.

The reason for this split is that there are other TLS based auth
mechanisms which we may like to use in the future. These can all
share the same vnc-tls.c routines. In addition this will facilitate
anyone who may want to port the vnc-tls.c file to allow for choice
of GNUTLS & NSS for impl.

The TLS state is moved out of the VncState struct, and into a separate
VncStateTLS struct, defined in vnc-tls.h. This is then referenced from
the main VncState. End size of the struct is the same, but it keeps
things a little more managable.

The vnc.h file gains a bunch more function prototypes, for functions
in vnc.c that were previously static, but now need to be accessed
from the separate auth code files.

The only TLS related code still in the main vl.c is the command line
argument handling / setup, and the low level I/O routines calling
gnutls_send/recv.


 Makefile              |   11 
 b/vnc-auth-vencrypt.c |  167 ++++++++++++++
 b/vnc-auth-vencrypt.h |   33 ++
 b/vnc-tls.c           |  414 +++++++++++++++++++++++++++++++++++
 b/vnc-tls.h           |   70 ++++++
 vnc.c                 |  581 +++-----------------------------------------------
 vnc.h                 |   76 ++++--
 7 files changed, 780 insertions(+), 572 deletions(-)

   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6723 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 96 additions and 572 deletions
Makefile
@@ -145,6 +145,9 @@ ifdef CONFIG_CURSES @@ -145,6 +145,9 @@ ifdef CONFIG_CURSES
145 OBJS+=curses.o 145 OBJS+=curses.o
146 endif 146 endif
147 OBJS+=vnc.o d3des.o 147 OBJS+=vnc.o d3des.o
  148 +ifdef CONFIG_VNC_TLS
  149 +OBJS+=vnc-tls.o vnc-auth-vencrypt.o
  150 +endif
148 151
149 ifdef CONFIG_COCOA 152 ifdef CONFIG_COCOA
150 OBJS+=cocoa.o 153 OBJS+=cocoa.o
@@ -168,10 +171,16 @@ sdl.o: sdl.c keymaps.h sdl_keysym.h @@ -168,10 +171,16 @@ sdl.o: sdl.c keymaps.h sdl_keysym.h
168 171
169 sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS) 172 sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
170 173
171 -vnc.o: vnc.c keymaps.h sdl_keysym.h vnchextile.h d3des.c d3des.h 174 +vnc.h: vnc-tls.h vnc-auth-vencrypt.h keymaps.h
  175 +
  176 +vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h
172 177
173 vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS) 178 vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
174 179
  180 +vnc-tls.o: vnc-tls.c vnc.h
  181 +
  182 +vnc-auth-vencrypt.o: vnc-auth-vencrypt.c vnc.h
  183 +
175 curses.o: curses.c keymaps.h curses_keys.h 184 curses.o: curses.c keymaps.h curses_keys.h
176 185
177 bt-host.o: CFLAGS += $(CONFIG_BLUEZ_CFLAGS) 186 bt-host.o: CFLAGS += $(CONFIG_BLUEZ_CFLAGS)
@@ -34,21 +34,6 @@ @@ -34,21 +34,6 @@
34 #include "vnc_keysym.h" 34 #include "vnc_keysym.h"
35 #include "d3des.h" 35 #include "d3des.h"
36 36
37 -// #define _VNC_DEBUG 1  
38 -  
39 -#ifdef _VNC_DEBUG  
40 -#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)  
41 -  
42 -#if defined(CONFIG_VNC_TLS) && _VNC_DEBUG >= 2  
43 -/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */  
44 -static void vnc_debug_gnutls_log(int level, const char* str) {  
45 - VNC_DEBUG("%d %s", level, str);  
46 -}  
47 -#endif /* CONFIG_VNC_TLS && _VNC_DEBUG */  
48 -#else  
49 -#define VNC_DEBUG(fmt, ...) do { } while (0)  
50 -#endif  
51 -  
52 #define count_bits(c, v) { \ 37 #define count_bits(c, v) { \
53 for (c = 0; v; v >>= 1) \ 38 for (c = 0; v; v >>= 1) \
54 { \ 39 { \
@@ -204,14 +189,7 @@ static inline uint32_t vnc_has_feature(VncState *vs, int feature) { @@ -204,14 +189,7 @@ static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
204 3) resolutions > 1024 189 3) resolutions > 1024
205 */ 190 */
206 191
207 -static void vnc_write(VncState *vs, const void *data, size_t len);  
208 -static void vnc_write_u32(VncState *vs, uint32_t value);  
209 -static void vnc_write_s32(VncState *vs, int32_t value);  
210 -static void vnc_write_u16(VncState *vs, uint16_t value);  
211 -static void vnc_write_u8(VncState *vs, uint8_t value);  
212 -static void vnc_flush(VncState *vs);  
213 static void vnc_update_client(void *opaque); 192 static void vnc_update_client(void *opaque);
214 -static void vnc_client_read(void *opaque);  
215 193
216 static void vnc_colordepth(VncState *vs); 194 static void vnc_colordepth(VncState *vs);
217 195
@@ -868,10 +846,7 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno) @@ -868,10 +846,7 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
868 if (vs->input.buffer) qemu_free(vs->input.buffer); 846 if (vs->input.buffer) qemu_free(vs->input.buffer);
869 if (vs->output.buffer) qemu_free(vs->output.buffer); 847 if (vs->output.buffer) qemu_free(vs->output.buffer);
870 #ifdef CONFIG_VNC_TLS 848 #ifdef CONFIG_VNC_TLS
871 - if (vs->tls_session) {  
872 - gnutls_deinit(vs->tls_session);  
873 - vs->tls_session = NULL;  
874 - } 849 + vnc_tls_client_cleanup(vs);
875 #endif /* CONFIG_VNC_TLS */ 850 #endif /* CONFIG_VNC_TLS */
876 audio_del(vs); 851 audio_del(vs);
877 852
@@ -897,19 +872,20 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno) @@ -897,19 +872,20 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
897 return ret; 872 return ret;
898 } 873 }
899 874
900 -static void vnc_client_error(VncState *vs) 875 +
  876 +void vnc_client_error(VncState *vs)
901 { 877 {
902 vnc_client_io_error(vs, -1, EINVAL); 878 vnc_client_io_error(vs, -1, EINVAL);
903 } 879 }
904 880
905 -static void vnc_client_write(void *opaque) 881 +void vnc_client_write(void *opaque)
906 { 882 {
907 long ret; 883 long ret;
908 VncState *vs = opaque; 884 VncState *vs = opaque;
909 885
910 #ifdef CONFIG_VNC_TLS 886 #ifdef CONFIG_VNC_TLS
911 - if (vs->tls_session) {  
912 - ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset); 887 + if (vs->tls.session) {
  888 + ret = gnutls_write(vs->tls.session, vs->output.buffer, vs->output.offset);
913 if (ret < 0) { 889 if (ret < 0) {
914 if (ret == GNUTLS_E_AGAIN) 890 if (ret == GNUTLS_E_AGAIN)
915 errno = EAGAIN; 891 errno = EAGAIN;
@@ -932,13 +908,13 @@ static void vnc_client_write(void *opaque) @@ -932,13 +908,13 @@ static void vnc_client_write(void *opaque)
932 } 908 }
933 } 909 }
934 910
935 -static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting) 911 +void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
936 { 912 {
937 vs->read_handler = func; 913 vs->read_handler = func;
938 vs->read_handler_expect = expecting; 914 vs->read_handler_expect = expecting;
939 } 915 }
940 916
941 -static void vnc_client_read(void *opaque) 917 +void vnc_client_read(void *opaque)
942 { 918 {
943 VncState *vs = opaque; 919 VncState *vs = opaque;
944 long ret; 920 long ret;
@@ -946,8 +922,8 @@ static void vnc_client_read(void *opaque) @@ -946,8 +922,8 @@ static void vnc_client_read(void *opaque)
946 buffer_reserve(&vs->input, 4096); 922 buffer_reserve(&vs->input, 4096);
947 923
948 #ifdef CONFIG_VNC_TLS 924 #ifdef CONFIG_VNC_TLS
949 - if (vs->tls_session) {  
950 - ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096); 925 + if (vs->tls.session) {
  926 + ret = gnutls_read(vs->tls.session, buffer_end(&vs->input), 4096);
951 if (ret < 0) { 927 if (ret < 0) {
952 if (ret == GNUTLS_E_AGAIN) 928 if (ret == GNUTLS_E_AGAIN)
953 errno = EAGAIN; 929 errno = EAGAIN;
@@ -981,7 +957,7 @@ static void vnc_client_read(void *opaque) @@ -981,7 +957,7 @@ static void vnc_client_read(void *opaque)
981 } 957 }
982 } 958 }
983 959
984 -static void vnc_write(VncState *vs, const void *data, size_t len) 960 +void vnc_write(VncState *vs, const void *data, size_t len)
985 { 961 {
986 buffer_reserve(&vs->output, len); 962 buffer_reserve(&vs->output, len);
987 963
@@ -992,12 +968,12 @@ static void vnc_write(VncState *vs, const void *data, size_t len) @@ -992,12 +968,12 @@ static void vnc_write(VncState *vs, const void *data, size_t len)
992 buffer_append(&vs->output, data, len); 968 buffer_append(&vs->output, data, len);
993 } 969 }
994 970
995 -static void vnc_write_s32(VncState *vs, int32_t value) 971 +void vnc_write_s32(VncState *vs, int32_t value)
996 { 972 {
997 vnc_write_u32(vs, *(uint32_t *)&value); 973 vnc_write_u32(vs, *(uint32_t *)&value);
998 } 974 }
999 975
1000 -static void vnc_write_u32(VncState *vs, uint32_t value) 976 +void vnc_write_u32(VncState *vs, uint32_t value)
1001 { 977 {
1002 uint8_t buf[4]; 978 uint8_t buf[4];
1003 979
@@ -1009,7 +985,7 @@ static void vnc_write_u32(VncState *vs, uint32_t value) @@ -1009,7 +985,7 @@ static void vnc_write_u32(VncState *vs, uint32_t value)
1009 vnc_write(vs, buf, 4); 985 vnc_write(vs, buf, 4);
1010 } 986 }
1011 987
1012 -static void vnc_write_u16(VncState *vs, uint16_t value) 988 +void vnc_write_u16(VncState *vs, uint16_t value)
1013 { 989 {
1014 uint8_t buf[2]; 990 uint8_t buf[2];
1015 991
@@ -1019,74 +995,39 @@ static void vnc_write_u16(VncState *vs, uint16_t value) @@ -1019,74 +995,39 @@ static void vnc_write_u16(VncState *vs, uint16_t value)
1019 vnc_write(vs, buf, 2); 995 vnc_write(vs, buf, 2);
1020 } 996 }
1021 997
1022 -static void vnc_write_u8(VncState *vs, uint8_t value) 998 +void vnc_write_u8(VncState *vs, uint8_t value)
1023 { 999 {
1024 vnc_write(vs, (char *)&value, 1); 1000 vnc_write(vs, (char *)&value, 1);
1025 } 1001 }
1026 1002
1027 -static void vnc_flush(VncState *vs) 1003 +void vnc_flush(VncState *vs)
1028 { 1004 {
1029 if (vs->output.offset) 1005 if (vs->output.offset)
1030 vnc_client_write(vs); 1006 vnc_client_write(vs);
1031 } 1007 }
1032 1008
1033 -static uint8_t read_u8(uint8_t *data, size_t offset) 1009 +uint8_t read_u8(uint8_t *data, size_t offset)
1034 { 1010 {
1035 return data[offset]; 1011 return data[offset];
1036 } 1012 }
1037 1013
1038 -static uint16_t read_u16(uint8_t *data, size_t offset) 1014 +uint16_t read_u16(uint8_t *data, size_t offset)
1039 { 1015 {
1040 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF); 1016 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1041 } 1017 }
1042 1018
1043 -static int32_t read_s32(uint8_t *data, size_t offset) 1019 +int32_t read_s32(uint8_t *data, size_t offset)
1044 { 1020 {
1045 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) | 1021 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1046 (data[offset + 2] << 8) | data[offset + 3]); 1022 (data[offset + 2] << 8) | data[offset + 3]);
1047 } 1023 }
1048 1024
1049 -static uint32_t read_u32(uint8_t *data, size_t offset) 1025 +uint32_t read_u32(uint8_t *data, size_t offset)
1050 { 1026 {
1051 return ((data[offset] << 24) | (data[offset + 1] << 16) | 1027 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1052 (data[offset + 2] << 8) | data[offset + 3]); 1028 (data[offset + 2] << 8) | data[offset + 3]);
1053 } 1029 }
1054 1030
1055 -#ifdef CONFIG_VNC_TLS  
1056 -static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,  
1057 - const void *data,  
1058 - size_t len) {  
1059 - struct VncState *vs = (struct VncState *)transport;  
1060 - int ret;  
1061 -  
1062 - retry:  
1063 - ret = send(vs->csock, data, len, 0);  
1064 - if (ret < 0) {  
1065 - if (errno == EINTR)  
1066 - goto retry;  
1067 - return -1;  
1068 - }  
1069 - return ret;  
1070 -}  
1071 -  
1072 -  
1073 -static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,  
1074 - void *data,  
1075 - size_t len) {  
1076 - struct VncState *vs = (struct VncState *)transport;  
1077 - int ret;  
1078 -  
1079 - retry:  
1080 - ret = recv(vs->csock, data, len, 0);  
1081 - if (ret < 0) {  
1082 - if (errno == EINTR)  
1083 - goto retry;  
1084 - return -1;  
1085 - }  
1086 - return ret;  
1087 -}  
1088 -#endif /* CONFIG_VNC_TLS */  
1089 -  
1090 static void client_cut_text(VncState *vs, size_t len, uint8_t *text) 1031 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1091 { 1032 {
1092 } 1033 }
@@ -1669,6 +1610,11 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) @@ -1669,6 +1610,11 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1669 return 0; 1610 return 0;
1670 } 1611 }
1671 1612
  1613 +void start_client_init(VncState *vs)
  1614 +{
  1615 + vnc_read_when(vs, protocol_client_init, 1);
  1616 +}
  1617 +
1672 static void make_challenge(VncState *vs) 1618 static void make_challenge(VncState *vs)
1673 { 1619 {
1674 int i; 1620 int i;
@@ -1724,12 +1670,12 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) @@ -1724,12 +1670,12 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1724 vnc_write_u32(vs, 0); /* Accept auth */ 1670 vnc_write_u32(vs, 0); /* Accept auth */
1725 vnc_flush(vs); 1671 vnc_flush(vs);
1726 1672
1727 - vnc_read_when(vs, protocol_client_init, 1); 1673 + start_client_init(vs);
1728 } 1674 }
1729 return 0; 1675 return 0;
1730 } 1676 }
1731 1677
1732 -static int start_auth_vnc(VncState *vs) 1678 +void start_auth_vnc(VncState *vs)
1733 { 1679 {
1734 make_challenge(vs); 1680 make_challenge(vs);
1735 /* Send client a 'random' challenge */ 1681 /* Send client a 'random' challenge */
@@ -1737,411 +1683,9 @@ static int start_auth_vnc(VncState *vs) @@ -1737,411 +1683,9 @@ static int start_auth_vnc(VncState *vs)
1737 vnc_flush(vs); 1683 vnc_flush(vs);
1738 1684
1739 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge)); 1685 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1740 - return 0;  
1741 -}  
1742 -  
1743 -  
1744 -#ifdef CONFIG_VNC_TLS  
1745 -#define DH_BITS 1024  
1746 -static gnutls_dh_params_t dh_params;  
1747 -  
1748 -static int vnc_tls_initialize(void)  
1749 -{  
1750 - static int tlsinitialized = 0;  
1751 -  
1752 - if (tlsinitialized)  
1753 - return 1;  
1754 -  
1755 - if (gnutls_global_init () < 0)  
1756 - return 0;  
1757 -  
1758 - /* XXX ought to re-generate diffie-hellmen params periodically */  
1759 - if (gnutls_dh_params_init (&dh_params) < 0)  
1760 - return 0;  
1761 - if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)  
1762 - return 0;  
1763 -  
1764 -#if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2  
1765 - gnutls_global_set_log_level(10);  
1766 - gnutls_global_set_log_function(vnc_debug_gnutls_log);  
1767 -#endif  
1768 -  
1769 - tlsinitialized = 1;  
1770 -  
1771 - return 1;  
1772 -}  
1773 -  
1774 -static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)  
1775 -{  
1776 - gnutls_anon_server_credentials anon_cred;  
1777 - int ret;  
1778 -  
1779 - if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {  
1780 - VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));  
1781 - return NULL;  
1782 - }  
1783 -  
1784 - gnutls_anon_set_server_dh_params(anon_cred, dh_params);  
1785 -  
1786 - return anon_cred;  
1787 -}  
1788 -  
1789 -  
1790 -static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)  
1791 -{  
1792 - gnutls_certificate_credentials_t x509_cred;  
1793 - int ret;  
1794 -  
1795 - if (!vs->vd->x509cacert) {  
1796 - VNC_DEBUG("No CA x509 certificate specified\n");  
1797 - return NULL;  
1798 - }  
1799 - if (!vs->vd->x509cert) {  
1800 - VNC_DEBUG("No server x509 certificate specified\n");  
1801 - return NULL;  
1802 - }  
1803 - if (!vs->vd->x509key) {  
1804 - VNC_DEBUG("No server private key specified\n");  
1805 - return NULL;  
1806 - }  
1807 -  
1808 - if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {  
1809 - VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));  
1810 - return NULL;  
1811 - }  
1812 - if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,  
1813 - vs->vd->x509cacert,  
1814 - GNUTLS_X509_FMT_PEM)) < 0) {  
1815 - VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));  
1816 - gnutls_certificate_free_credentials(x509_cred);  
1817 - return NULL;  
1818 - }  
1819 -  
1820 - if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,  
1821 - vs->vd->x509cert,  
1822 - vs->vd->x509key,  
1823 - GNUTLS_X509_FMT_PEM)) < 0) {  
1824 - VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));  
1825 - gnutls_certificate_free_credentials(x509_cred);  
1826 - return NULL;  
1827 - }  
1828 -  
1829 - if (vs->vd->x509cacrl) {  
1830 - if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,  
1831 - vs->vd->x509cacrl,  
1832 - GNUTLS_X509_FMT_PEM)) < 0) {  
1833 - VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));  
1834 - gnutls_certificate_free_credentials(x509_cred);  
1835 - return NULL;  
1836 - }  
1837 - }  
1838 -  
1839 - gnutls_certificate_set_dh_params (x509_cred, dh_params);  
1840 -  
1841 - return x509_cred;  
1842 -}  
1843 -  
1844 -static int vnc_validate_certificate(struct VncState *vs)  
1845 -{  
1846 - int ret;  
1847 - unsigned int status;  
1848 - const gnutls_datum_t *certs;  
1849 - unsigned int nCerts, i;  
1850 - time_t now;  
1851 -  
1852 - VNC_DEBUG("Validating client certificate\n");  
1853 - if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {  
1854 - VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));  
1855 - return -1;  
1856 - }  
1857 -  
1858 - if ((now = time(NULL)) == ((time_t)-1)) {  
1859 - return -1;  
1860 - }  
1861 -  
1862 - if (status != 0) {  
1863 - if (status & GNUTLS_CERT_INVALID)  
1864 - VNC_DEBUG("The certificate is not trusted.\n");  
1865 -  
1866 - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)  
1867 - VNC_DEBUG("The certificate hasn't got a known issuer.\n");  
1868 -  
1869 - if (status & GNUTLS_CERT_REVOKED)  
1870 - VNC_DEBUG("The certificate has been revoked.\n");  
1871 -  
1872 - if (status & GNUTLS_CERT_INSECURE_ALGORITHM)  
1873 - VNC_DEBUG("The certificate uses an insecure algorithm\n");  
1874 -  
1875 - return -1;  
1876 - } else {  
1877 - VNC_DEBUG("Certificate is valid!\n");  
1878 - }  
1879 -  
1880 - /* Only support x509 for now */  
1881 - if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)  
1882 - return -1;  
1883 -  
1884 - if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))  
1885 - return -1;  
1886 -  
1887 - for (i = 0 ; i < nCerts ; i++) {  
1888 - gnutls_x509_crt_t cert;  
1889 - VNC_DEBUG ("Checking certificate chain %d\n", i);  
1890 - if (gnutls_x509_crt_init (&cert) < 0)  
1891 - return -1;  
1892 -  
1893 - if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {  
1894 - gnutls_x509_crt_deinit (cert);  
1895 - return -1;  
1896 - }  
1897 -  
1898 - if (gnutls_x509_crt_get_expiration_time (cert) < now) {  
1899 - VNC_DEBUG("The certificate has expired\n");  
1900 - gnutls_x509_crt_deinit (cert);  
1901 - return -1;  
1902 - }  
1903 -  
1904 - if (gnutls_x509_crt_get_activation_time (cert) > now) {  
1905 - VNC_DEBUG("The certificate is not yet activated\n");  
1906 - gnutls_x509_crt_deinit (cert);  
1907 - return -1;  
1908 - }  
1909 -  
1910 - if (gnutls_x509_crt_get_activation_time (cert) > now) {  
1911 - VNC_DEBUG("The certificate is not yet activated\n");  
1912 - gnutls_x509_crt_deinit (cert);  
1913 - return -1;  
1914 - }  
1915 -  
1916 - gnutls_x509_crt_deinit (cert);  
1917 - }  
1918 -  
1919 - return 0;  
1920 } 1686 }
1921 1687
1922 1688
1923 -static int start_auth_vencrypt_subauth(VncState *vs)  
1924 -{  
1925 - switch (vs->vd->subauth) {  
1926 - case VNC_AUTH_VENCRYPT_TLSNONE:  
1927 - case VNC_AUTH_VENCRYPT_X509NONE:  
1928 - VNC_DEBUG("Accept TLS auth none\n");  
1929 - vnc_write_u32(vs, 0); /* Accept auth completion */  
1930 - vnc_read_when(vs, protocol_client_init, 1);  
1931 - break;  
1932 -  
1933 - case VNC_AUTH_VENCRYPT_TLSVNC:  
1934 - case VNC_AUTH_VENCRYPT_X509VNC:  
1935 - VNC_DEBUG("Start TLS auth VNC\n");  
1936 - return start_auth_vnc(vs);  
1937 -  
1938 - default: /* Should not be possible, but just in case */  
1939 - VNC_DEBUG("Reject auth %d\n", vs->vd->auth);  
1940 - vnc_write_u8(vs, 1);  
1941 - if (vs->minor >= 8) {  
1942 - static const char err[] = "Unsupported authentication type";  
1943 - vnc_write_u32(vs, sizeof(err));  
1944 - vnc_write(vs, err, sizeof(err));  
1945 - }  
1946 - vnc_client_error(vs);  
1947 - }  
1948 -  
1949 - return 0;  
1950 -}  
1951 -  
1952 -static void vnc_handshake_io(void *opaque);  
1953 -  
1954 -static int vnc_continue_handshake(struct VncState *vs) {  
1955 - int ret;  
1956 -  
1957 - if ((ret = gnutls_handshake(vs->tls_session)) < 0) {  
1958 - if (!gnutls_error_is_fatal(ret)) {  
1959 - VNC_DEBUG("Handshake interrupted (blocking)\n");  
1960 - if (!gnutls_record_get_direction(vs->tls_session))  
1961 - qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);  
1962 - else  
1963 - qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);  
1964 - return 0;  
1965 - }  
1966 - VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));  
1967 - vnc_client_error(vs);  
1968 - return -1;  
1969 - }  
1970 -  
1971 - if (vs->vd->x509verify) {  
1972 - if (vnc_validate_certificate(vs) < 0) {  
1973 - VNC_DEBUG("Client verification failed\n");  
1974 - vnc_client_error(vs);  
1975 - return -1;  
1976 - } else {  
1977 - VNC_DEBUG("Client verification passed\n");  
1978 - }  
1979 - }  
1980 -  
1981 - VNC_DEBUG("Handshake done, switching to TLS data mode\n");  
1982 - vs->wiremode = VNC_WIREMODE_TLS;  
1983 - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);  
1984 -  
1985 - return start_auth_vencrypt_subauth(vs);  
1986 -}  
1987 -  
1988 -static void vnc_handshake_io(void *opaque) {  
1989 - struct VncState *vs = (struct VncState *)opaque;  
1990 -  
1991 - VNC_DEBUG("Handshake IO continue\n");  
1992 - vnc_continue_handshake(vs);  
1993 -}  
1994 -  
1995 -#define NEED_X509_AUTH(vs) \  
1996 - ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE || \  
1997 - (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC || \  
1998 - (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)  
1999 -  
2000 -  
2001 -static int vnc_start_tls(struct VncState *vs) {  
2002 - static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };  
2003 - static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };  
2004 - static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};  
2005 - static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};  
2006 -  
2007 - VNC_DEBUG("Do TLS setup\n");  
2008 - if (vnc_tls_initialize() < 0) {  
2009 - VNC_DEBUG("Failed to init TLS\n");  
2010 - vnc_client_error(vs);  
2011 - return -1;  
2012 - }  
2013 - if (vs->tls_session == NULL) {  
2014 - if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {  
2015 - vnc_client_error(vs);  
2016 - return -1;  
2017 - }  
2018 -  
2019 - if (gnutls_set_default_priority(vs->tls_session) < 0) {  
2020 - gnutls_deinit(vs->tls_session);  
2021 - vs->tls_session = NULL;  
2022 - vnc_client_error(vs);  
2023 - return -1;  
2024 - }  
2025 -  
2026 - if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {  
2027 - gnutls_deinit(vs->tls_session);  
2028 - vs->tls_session = NULL;  
2029 - vnc_client_error(vs);  
2030 - return -1;  
2031 - }  
2032 -  
2033 - if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {  
2034 - gnutls_deinit(vs->tls_session);  
2035 - vs->tls_session = NULL;  
2036 - vnc_client_error(vs);  
2037 - return -1;  
2038 - }  
2039 -  
2040 - if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {  
2041 - gnutls_deinit(vs->tls_session);  
2042 - vs->tls_session = NULL;  
2043 - vnc_client_error(vs);  
2044 - return -1;  
2045 - }  
2046 -  
2047 - if (NEED_X509_AUTH(vs)) {  
2048 - gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);  
2049 - if (!x509_cred) {  
2050 - gnutls_deinit(vs->tls_session);  
2051 - vs->tls_session = NULL;  
2052 - vnc_client_error(vs);  
2053 - return -1;  
2054 - }  
2055 - if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {  
2056 - gnutls_deinit(vs->tls_session);  
2057 - vs->tls_session = NULL;  
2058 - gnutls_certificate_free_credentials(x509_cred);  
2059 - vnc_client_error(vs);  
2060 - return -1;  
2061 - }  
2062 - if (vs->vd->x509verify) {  
2063 - VNC_DEBUG("Requesting a client certificate\n");  
2064 - gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);  
2065 - }  
2066 -  
2067 - } else {  
2068 - gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();  
2069 - if (!anon_cred) {  
2070 - gnutls_deinit(vs->tls_session);  
2071 - vs->tls_session = NULL;  
2072 - vnc_client_error(vs);  
2073 - return -1;  
2074 - }  
2075 - if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {  
2076 - gnutls_deinit(vs->tls_session);  
2077 - vs->tls_session = NULL;  
2078 - gnutls_anon_free_server_credentials(anon_cred);  
2079 - vnc_client_error(vs);  
2080 - return -1;  
2081 - }  
2082 - }  
2083 -  
2084 - gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);  
2085 - gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);  
2086 - gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);  
2087 - }  
2088 -  
2089 - VNC_DEBUG("Start TLS handshake process\n");  
2090 - return vnc_continue_handshake(vs);  
2091 -}  
2092 -  
2093 -static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)  
2094 -{  
2095 - int auth = read_u32(data, 0);  
2096 -  
2097 - if (auth != vs->vd->subauth) {  
2098 - VNC_DEBUG("Rejecting auth %d\n", auth);  
2099 - vnc_write_u8(vs, 0); /* Reject auth */  
2100 - vnc_flush(vs);  
2101 - vnc_client_error(vs);  
2102 - } else {  
2103 - VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);  
2104 - vnc_write_u8(vs, 1); /* Accept auth */  
2105 - vnc_flush(vs);  
2106 -  
2107 - if (vnc_start_tls(vs) < 0) {  
2108 - VNC_DEBUG("Failed to complete TLS\n");  
2109 - return 0;  
2110 - }  
2111 - }  
2112 - return 0;  
2113 -}  
2114 -  
2115 -static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)  
2116 -{  
2117 - if (data[0] != 0 ||  
2118 - data[1] != 2) {  
2119 - VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);  
2120 - vnc_write_u8(vs, 1); /* Reject version */  
2121 - vnc_flush(vs);  
2122 - vnc_client_error(vs);  
2123 - } else {  
2124 - VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);  
2125 - vnc_write_u8(vs, 0); /* Accept version */  
2126 - vnc_write_u8(vs, 1); /* Number of sub-auths */  
2127 - vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */  
2128 - vnc_flush(vs);  
2129 - vnc_read_when(vs, protocol_client_vencrypt_auth, 4);  
2130 - }  
2131 - return 0;  
2132 -}  
2133 -  
2134 -static int start_auth_vencrypt(VncState *vs)  
2135 -{  
2136 - /* Send VeNCrypt version 0.2 */  
2137 - vnc_write_u8(vs, 0);  
2138 - vnc_write_u8(vs, 2);  
2139 -  
2140 - vnc_read_when(vs, protocol_client_vencrypt_init, 2);  
2141 - return 0;  
2142 -}  
2143 -#endif /* CONFIG_VNC_TLS */  
2144 -  
2145 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) 1689 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2146 { 1690 {
2147 /* We only advertise 1 auth scheme at a time, so client 1691 /* We only advertise 1 auth scheme at a time, so client
@@ -2164,17 +1708,19 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) @@ -2164,17 +1708,19 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2164 vnc_write_u32(vs, 0); /* Accept auth completion */ 1708 vnc_write_u32(vs, 0); /* Accept auth completion */
2165 vnc_flush(vs); 1709 vnc_flush(vs);
2166 } 1710 }
2167 - vnc_read_when(vs, protocol_client_init, 1); 1711 + start_client_init(vs);
2168 break; 1712 break;
2169 1713
2170 case VNC_AUTH_VNC: 1714 case VNC_AUTH_VNC:
2171 VNC_DEBUG("Start VNC auth\n"); 1715 VNC_DEBUG("Start VNC auth\n");
2172 - return start_auth_vnc(vs); 1716 + start_auth_vnc(vs);
  1717 + break;
2173 1718
2174 #ifdef CONFIG_VNC_TLS 1719 #ifdef CONFIG_VNC_TLS
2175 case VNC_AUTH_VENCRYPT: 1720 case VNC_AUTH_VENCRYPT:
2176 VNC_DEBUG("Accept VeNCrypt auth\n");; 1721 VNC_DEBUG("Accept VeNCrypt auth\n");;
2177 - return start_auth_vencrypt(vs); 1722 + start_auth_vencrypt(vs);
  1723 + break;
2178 #endif /* CONFIG_VNC_TLS */ 1724 #endif /* CONFIG_VNC_TLS */
2179 1725
2180 default: /* Should not be possible, but just in case */ 1726 default: /* Should not be possible, but just in case */
@@ -2227,7 +1773,7 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len) @@ -2227,7 +1773,7 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2227 VNC_DEBUG("Tell client auth none\n"); 1773 VNC_DEBUG("Tell client auth none\n");
2228 vnc_write_u32(vs, vs->vd->auth); 1774 vnc_write_u32(vs, vs->vd->auth);
2229 vnc_flush(vs); 1775 vnc_flush(vs);
2230 - vnc_read_when(vs, protocol_client_init, 1); 1776 + start_client_init(vs);
2231 } else if (vs->vd->auth == VNC_AUTH_VNC) { 1777 } else if (vs->vd->auth == VNC_AUTH_VNC) {
2232 VNC_DEBUG("Tell client VNC auth\n"); 1778 VNC_DEBUG("Tell client VNC auth\n");
2233 vnc_write_u32(vs, vs->vd->auth); 1779 vnc_write_u32(vs, vs->vd->auth);
@@ -2329,61 +1875,6 @@ void vnc_display_init(DisplayState *ds) @@ -2329,61 +1875,6 @@ void vnc_display_init(DisplayState *ds)
2329 register_displaychangelistener(ds, dcl); 1875 register_displaychangelistener(ds, dcl);
2330 } 1876 }
2331 1877
2332 -#ifdef CONFIG_VNC_TLS  
2333 -static int vnc_set_x509_credential(VncDisplay *vs,  
2334 - const char *certdir,  
2335 - const char *filename,  
2336 - char **cred,  
2337 - int ignoreMissing)  
2338 -{  
2339 - struct stat sb;  
2340 -  
2341 - if (*cred) {  
2342 - qemu_free(*cred);  
2343 - *cred = NULL;  
2344 - }  
2345 -  
2346 - *cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2);  
2347 -  
2348 - strcpy(*cred, certdir);  
2349 - strcat(*cred, "/");  
2350 - strcat(*cred, filename);  
2351 -  
2352 - VNC_DEBUG("Check %s\n", *cred);  
2353 - if (stat(*cred, &sb) < 0) {  
2354 - qemu_free(*cred);  
2355 - *cred = NULL;  
2356 - if (ignoreMissing && errno == ENOENT)  
2357 - return 0;  
2358 - return -1;  
2359 - }  
2360 -  
2361 - return 0;  
2362 -}  
2363 -  
2364 -static int vnc_set_x509_credential_dir(VncDisplay *vs,  
2365 - const char *certdir)  
2366 -{  
2367 - if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)  
2368 - goto cleanup;  
2369 - if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)  
2370 - goto cleanup;  
2371 - if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)  
2372 - goto cleanup;  
2373 - if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)  
2374 - goto cleanup;  
2375 -  
2376 - return 0;  
2377 -  
2378 - cleanup:  
2379 - qemu_free(vs->x509cacert);  
2380 - qemu_free(vs->x509cacrl);  
2381 - qemu_free(vs->x509cert);  
2382 - qemu_free(vs->x509key);  
2383 - vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;  
2384 - return -1;  
2385 -}  
2386 -#endif /* CONFIG_VNC_TLS */  
2387 1878
2388 void vnc_display_close(DisplayState *ds) 1879 void vnc_display_close(DisplayState *ds)
2389 { 1880 {
@@ -2403,7 +1894,7 @@ void vnc_display_close(DisplayState *ds) @@ -2403,7 +1894,7 @@ void vnc_display_close(DisplayState *ds)
2403 vs->auth = VNC_AUTH_INVALID; 1894 vs->auth = VNC_AUTH_INVALID;
2404 #ifdef CONFIG_VNC_TLS 1895 #ifdef CONFIG_VNC_TLS
2405 vs->subauth = VNC_AUTH_INVALID; 1896 vs->subauth = VNC_AUTH_INVALID;
2406 - vs->x509verify = 0; 1897 + vs->tls.x509verify = 0;
2407 #endif 1898 #endif
2408 } 1899 }
2409 1900
@@ -2459,7 +1950,7 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2459,7 +1950,7 @@ int vnc_display_open(DisplayState *ds, const char *display)
2459 char *start, *end; 1950 char *start, *end;
2460 x509 = 1; /* Require x509 certificates */ 1951 x509 = 1; /* Require x509 certificates */
2461 if (strncmp(options, "x509verify", 10) == 0) 1952 if (strncmp(options, "x509verify", 10) == 0)
2462 - vs->x509verify = 1; /* ...and verify client certs */ 1953 + vs->tls.x509verify = 1; /* ...and verify client certs */
2463 1954
2464 /* Now check for 'x509=/some/path' postfix 1955 /* Now check for 'x509=/some/path' postfix
2465 * and use that to setup x509 certificate/key paths */ 1956 * and use that to setup x509 certificate/key paths */
@@ -2470,7 +1961,7 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2470,7 +1961,7 @@ int vnc_display_open(DisplayState *ds, const char *display)
2470 char *path = qemu_strndup(start + 1, len); 1961 char *path = qemu_strndup(start + 1, len);
2471 1962
2472 VNC_DEBUG("Trying certificate path '%s'\n", path); 1963 VNC_DEBUG("Trying certificate path '%s'\n", path);
2473 - if (vnc_set_x509_credential_dir(vs, path) < 0) { 1964 + if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2474 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path); 1965 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2475 qemu_free(path); 1966 qemu_free(path);
2476 qemu_free(vs->display); 1967 qemu_free(vs->display);
@@ -33,13 +33,16 @@ @@ -33,13 +33,16 @@
33 #include "audio/audio.h" 33 #include "audio/audio.h"
34 #include <zlib.h> 34 #include <zlib.h>
35 35
36 -#ifdef CONFIG_VNC_TLS  
37 -#include <gnutls/gnutls.h>  
38 -#include <gnutls/x509.h>  
39 -#endif /* CONFIG_VNC_TLS */  
40 -  
41 #include "keymaps.h" 36 #include "keymaps.h"
42 37
  38 +// #define _VNC_DEBUG 1
  39 +
  40 +#ifdef _VNC_DEBUG
  41 +#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
  42 +#else
  43 +#define VNC_DEBUG(fmt, ...) do { } while (0)
  44 +#endif
  45 +
43 /***************************************************************************** 46 /*****************************************************************************
44 * 47 *
45 * Core data structures 48 * Core data structures
@@ -73,6 +76,11 @@ typedef void VncSendHextileTile(VncState *vs, @@ -73,6 +76,11 @@ typedef void VncSendHextileTile(VncState *vs,
73 76
74 typedef struct VncDisplay VncDisplay; 77 typedef struct VncDisplay VncDisplay;
75 78
  79 +#ifdef CONFIG_VNC_TLS
  80 +#include "vnc-tls.h"
  81 +#include "vnc-auth-vencrypt.h"
  82 +#endif
  83 +
76 struct VncDisplay 84 struct VncDisplay
77 { 85 {
78 int lsock; 86 int lsock;
@@ -84,13 +92,8 @@ struct VncDisplay @@ -84,13 +92,8 @@ struct VncDisplay
84 char *password; 92 char *password;
85 int auth; 93 int auth;
86 #ifdef CONFIG_VNC_TLS 94 #ifdef CONFIG_VNC_TLS
87 - int subauth;  
88 - int x509verify;  
89 -  
90 - char *x509cacert;  
91 - char *x509cacrl;  
92 - char *x509cert;  
93 - char *x509key; 95 + int subauth; /* Used by VeNCrypt */
  96 + VncDisplayTLS tls;
94 #endif 97 #endif
95 }; 98 };
96 99
@@ -118,8 +121,7 @@ struct VncState @@ -118,8 +121,7 @@ struct VncState
118 char challenge[VNC_AUTH_CHALLENGE_SIZE]; 121 char challenge[VNC_AUTH_CHALLENGE_SIZE];
119 122
120 #ifdef CONFIG_VNC_TLS 123 #ifdef CONFIG_VNC_TLS
121 - int wiremode;  
122 - gnutls_session_t tls_session; 124 + VncStateTLS tls;
123 #endif 125 #endif
124 126
125 Buffer output; 127 Buffer output;
@@ -163,12 +165,6 @@ enum { @@ -163,12 +165,6 @@ enum {
163 VNC_AUTH_VENCRYPT = 19 165 VNC_AUTH_VENCRYPT = 19
164 }; 166 };
165 167
166 -#ifdef CONFIG_VNC_TLS  
167 -enum {  
168 - VNC_WIREMODE_CLEAR,  
169 - VNC_WIREMODE_TLS,  
170 -};  
171 -  
172 enum { 168 enum {
173 VNC_AUTH_VENCRYPT_PLAIN = 256, 169 VNC_AUTH_VENCRYPT_PLAIN = 256,
174 VNC_AUTH_VENCRYPT_TLSNONE = 257, 170 VNC_AUTH_VENCRYPT_TLSNONE = 257,
@@ -179,12 +175,6 @@ enum { @@ -179,12 +175,6 @@ enum {
179 VNC_AUTH_VENCRYPT_X509PLAIN = 262, 175 VNC_AUTH_VENCRYPT_X509PLAIN = 262,
180 }; 176 };
181 177
182 -#define X509_CA_CERT_FILE "ca-cert.pem"  
183 -#define X509_CA_CRL_FILE "ca-crl.pem"  
184 -#define X509_SERVER_KEY_FILE "server-key.pem"  
185 -#define X509_SERVER_CERT_FILE "server-cert.pem"  
186 -  
187 -#endif /* CONFIG_VNC_TLS */  
188 178
189 /***************************************************************************** 179 /*****************************************************************************
190 * 180 *
@@ -255,4 +245,38 @@ enum { @@ -255,4 +245,38 @@ enum {
255 #define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB) 245 #define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB)
256 #define VNC_FEATURE_COPYRECT_MASK (1 << VNC_FEATURE_COPYRECT) 246 #define VNC_FEATURE_COPYRECT_MASK (1 << VNC_FEATURE_COPYRECT)
257 247
  248 +
  249 +/*****************************************************************************
  250 + *
  251 + * Internal APIs
  252 + *
  253 + *****************************************************************************/
  254 +
  255 +/* Event loop functions */
  256 +void vnc_client_read(void *opaque);
  257 +void vnc_client_write(void *opaque);
  258 +
  259 +
  260 +/* Protocol I/O functions */
  261 +void vnc_write(VncState *vs, const void *data, size_t len);
  262 +void vnc_write_u32(VncState *vs, uint32_t value);
  263 +void vnc_write_s32(VncState *vs, int32_t value);
  264 +void vnc_write_u16(VncState *vs, uint16_t value);
  265 +void vnc_write_u8(VncState *vs, uint8_t value);
  266 +void vnc_flush(VncState *vs);
  267 +void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting);
  268 +
  269 +
  270 +/* Buffer I/O functions */
  271 +uint8_t read_u8(uint8_t *data, size_t offset);
  272 +uint16_t read_u16(uint8_t *data, size_t offset);
  273 +int32_t read_s32(uint8_t *data, size_t offset);
  274 +uint32_t read_u32(uint8_t *data, size_t offset);
  275 +
  276 +/* Protocol stage functions */
  277 +void vnc_client_error(VncState *vs);
  278 +
  279 +void start_client_init(VncState *vs);
  280 +void start_auth_vnc(VncState *vs);
  281 +
258 #endif /* __QEMU_VNC_H */ 282 #endif /* __QEMU_VNC_H */