Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 176 lines (147 sloc) 5.738 kb
274b6fc Add more missing files
aliguori authored
1 /*
2 * QEMU VNC display driver: VeNCrypt authentication setup
3 *
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27 #include "vnc.h"
28
29
30 static void start_auth_vencrypt_subauth(VncState *vs)
31 {
32 switch (vs->vd->subauth) {
33 case VNC_AUTH_VENCRYPT_TLSNONE:
34 case VNC_AUTH_VENCRYPT_X509NONE:
35 VNC_DEBUG("Accept TLS auth none\n");
36 vnc_write_u32(vs, 0); /* Accept auth completion */
37 start_client_init(vs);
38 break;
39
40 case VNC_AUTH_VENCRYPT_TLSVNC:
41 case VNC_AUTH_VENCRYPT_X509VNC:
42 VNC_DEBUG("Start TLS auth VNC\n");
43 start_auth_vnc(vs);
44 break;
45
46 #ifdef CONFIG_VNC_SASL
47 case VNC_AUTH_VENCRYPT_TLSSASL:
48 case VNC_AUTH_VENCRYPT_X509SASL:
49 VNC_DEBUG("Start TLS auth SASL\n");
50 return start_auth_sasl(vs);
51 #endif /* CONFIG_VNC_SASL */
52
53 default: /* Should not be possible, but just in case */
54 VNC_DEBUG("Reject subauth %d server bug\n", vs->vd->auth);
55 vnc_write_u8(vs, 1);
56 if (vs->minor >= 8) {
57 static const char err[] = "Unsupported authentication type";
58 vnc_write_u32(vs, sizeof(err));
59 vnc_write(vs, err, sizeof(err));
60 }
61 vnc_client_error(vs);
62 }
63 }
64
65 static void vnc_tls_handshake_io(void *opaque);
66
67 static int vnc_start_vencrypt_handshake(struct VncState *vs) {
68 int ret;
69
70 if ((ret = gnutls_handshake(vs->tls.session)) < 0) {
71 if (!gnutls_error_is_fatal(ret)) {
72 VNC_DEBUG("Handshake interrupted (blocking)\n");
73 if (!gnutls_record_get_direction(vs->tls.session))
74 qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs);
75 else
76 qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs);
77 return 0;
78 }
79 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
80 vnc_client_error(vs);
81 return -1;
82 }
83
84 if (vs->vd->tls.x509verify) {
85 if (vnc_tls_validate_certificate(vs) < 0) {
86 VNC_DEBUG("Client verification failed\n");
87 vnc_client_error(vs);
88 return -1;
89 } else {
90 VNC_DEBUG("Client verification passed\n");
91 }
92 }
93
94 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
95 vs->tls.wiremode = VNC_WIREMODE_TLS;
96 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
97
98 start_auth_vencrypt_subauth(vs);
99
100 return 0;
101 }
102
103 static void vnc_tls_handshake_io(void *opaque) {
104 struct VncState *vs = (struct VncState *)opaque;
105
106 VNC_DEBUG("Handshake IO continue\n");
107 vnc_start_vencrypt_handshake(vs);
108 }
109
110
111
112 #define NEED_X509_AUTH(vs) \
113 ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
114 (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
115 (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN || \
116 (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL)
117
118
119 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
120 {
121 int auth = read_u32(data, 0);
122
123 if (auth != vs->vd->subauth) {
124 VNC_DEBUG("Rejecting auth %d\n", auth);
125 vnc_write_u8(vs, 0); /* Reject auth */
126 vnc_flush(vs);
127 vnc_client_error(vs);
128 } else {
129 VNC_DEBUG("Accepting auth %d, setting up TLS for handshake\n", auth);
130 vnc_write_u8(vs, 1); /* Accept auth */
131 vnc_flush(vs);
132
133 if (vnc_tls_client_setup(vs, NEED_X509_AUTH(vs)) < 0) {
134 VNC_DEBUG("Failed to setup TLS\n");
135 return 0;
136 }
137
138 VNC_DEBUG("Start TLS VeNCrypt handshake process\n");
139 if (vnc_start_vencrypt_handshake(vs) < 0) {
140 VNC_DEBUG("Failed to start TLS handshake\n");
141 return 0;
142 }
143 }
144 return 0;
145 }
146
147 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
148 {
149 if (data[0] != 0 ||
150 data[1] != 2) {
151 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
152 vnc_write_u8(vs, 1); /* Reject version */
153 vnc_flush(vs);
154 vnc_client_error(vs);
155 } else {
156 VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);
157 vnc_write_u8(vs, 0); /* Accept version */
158 vnc_write_u8(vs, 1); /* Number of sub-auths */
159 vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */
160 vnc_flush(vs);
161 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
162 }
163 return 0;
164 }
165
166
167 void start_auth_vencrypt(VncState *vs)
168 {
169 /* Send VeNCrypt version 0.2 */
170 vnc_write_u8(vs, 0);
171 vnc_write_u8(vs, 2);
172
173 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
174 }
175
Something went wrong with that request. Please try again.