Statistics
| Branch: | Revision:

root / vnc.c @ ec6338ba

History | View | Annotate | Download (56.9 kB)

1 7d510b8c bellard
/*
2 7d510b8c bellard
 * QEMU VNC display driver
3 5fafdf24 ths
 *
4 7d510b8c bellard
 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 7d510b8c bellard
 * Copyright (C) 2006 Fabrice Bellard
6 5fafdf24 ths
 *
7 7d510b8c bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 7d510b8c bellard
 * of this software and associated documentation files (the "Software"), to deal
9 7d510b8c bellard
 * in the Software without restriction, including without limitation the rights
10 7d510b8c bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 7d510b8c bellard
 * copies of the Software, and to permit persons to whom the Software is
12 7d510b8c bellard
 * furnished to do so, subject to the following conditions:
13 7d510b8c bellard
 *
14 7d510b8c bellard
 * The above copyright notice and this permission notice shall be included in
15 7d510b8c bellard
 * all copies or substantial portions of the Software.
16 7d510b8c bellard
 *
17 7d510b8c bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 7d510b8c bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 7d510b8c bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 7d510b8c bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 7d510b8c bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 7d510b8c bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 7d510b8c bellard
 * THE SOFTWARE.
24 7d510b8c bellard
 */
25 7d510b8c bellard
26 24236869 bellard
#include "vl.h"
27 6ca957f0 bellard
#include "qemu_socket.h"
28 24236869 bellard
29 24236869 bellard
#define VNC_REFRESH_INTERVAL (1000 / 30)
30 24236869 bellard
31 24236869 bellard
#include "vnc_keysym.h"
32 24236869 bellard
#include "keymaps.c"
33 70848515 ths
#include "d3des.h"
34 70848515 ths
35 8d5d2d4c ths
#if CONFIG_VNC_TLS
36 8d5d2d4c ths
#include <gnutls/gnutls.h>
37 8d5d2d4c ths
#include <gnutls/x509.h>
38 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
39 70848515 ths
40 8d5d2d4c ths
// #define _VNC_DEBUG 1
41 8d5d2d4c ths
42 8d5d2d4c ths
#if _VNC_DEBUG
43 70848515 ths
#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
44 8d5d2d4c ths
45 8d5d2d4c ths
#if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
46 8d5d2d4c ths
/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
47 8d5d2d4c ths
static void vnc_debug_gnutls_log(int level, const char* str) {
48 8d5d2d4c ths
    VNC_DEBUG("%d %s", level, str);
49 8d5d2d4c ths
}
50 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
51 70848515 ths
#else
52 70848515 ths
#define VNC_DEBUG(fmt, ...) do { } while (0)
53 70848515 ths
#endif
54 24236869 bellard
55 8d5d2d4c ths
56 24236869 bellard
typedef struct Buffer
57 24236869 bellard
{
58 24236869 bellard
    size_t capacity;
59 24236869 bellard
    size_t offset;
60 24236869 bellard
    char *buffer;
61 24236869 bellard
} Buffer;
62 24236869 bellard
63 24236869 bellard
typedef struct VncState VncState;
64 24236869 bellard
65 24236869 bellard
typedef int VncReadEvent(VncState *vs, char *data, size_t len);
66 24236869 bellard
67 3512779a bellard
typedef void VncWritePixels(VncState *vs, void *data, int size);
68 3512779a bellard
69 3512779a bellard
typedef void VncSendHextileTile(VncState *vs,
70 3512779a bellard
                                int x, int y, int w, int h,
71 5fafdf24 ths
                                uint32_t *last_bg,
72 3512779a bellard
                                uint32_t *last_fg,
73 3512779a bellard
                                int *has_bg, int *has_fg);
74 3512779a bellard
75 99589bdc bellard
#define VNC_MAX_WIDTH 2048
76 99589bdc bellard
#define VNC_MAX_HEIGHT 2048
77 99589bdc bellard
#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
78 99589bdc bellard
79 70848515 ths
#define VNC_AUTH_CHALLENGE_SIZE 16
80 70848515 ths
81 70848515 ths
enum {
82 70848515 ths
    VNC_AUTH_INVALID = 0,
83 70848515 ths
    VNC_AUTH_NONE = 1,
84 70848515 ths
    VNC_AUTH_VNC = 2,
85 70848515 ths
    VNC_AUTH_RA2 = 5,
86 70848515 ths
    VNC_AUTH_RA2NE = 6,
87 70848515 ths
    VNC_AUTH_TIGHT = 16,
88 70848515 ths
    VNC_AUTH_ULTRA = 17,
89 70848515 ths
    VNC_AUTH_TLS = 18,
90 70848515 ths
    VNC_AUTH_VENCRYPT = 19
91 70848515 ths
};
92 70848515 ths
93 8d5d2d4c ths
#if CONFIG_VNC_TLS
94 8d5d2d4c ths
enum {
95 8d5d2d4c ths
    VNC_WIREMODE_CLEAR,
96 8d5d2d4c ths
    VNC_WIREMODE_TLS,
97 8d5d2d4c ths
};
98 8d5d2d4c ths
99 8d5d2d4c ths
enum {
100 8d5d2d4c ths
    VNC_AUTH_VENCRYPT_PLAIN = 256,
101 8d5d2d4c ths
    VNC_AUTH_VENCRYPT_TLSNONE = 257,
102 8d5d2d4c ths
    VNC_AUTH_VENCRYPT_TLSVNC = 258,
103 8d5d2d4c ths
    VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
104 8d5d2d4c ths
    VNC_AUTH_VENCRYPT_X509NONE = 260,
105 8d5d2d4c ths
    VNC_AUTH_VENCRYPT_X509VNC = 261,
106 8d5d2d4c ths
    VNC_AUTH_VENCRYPT_X509PLAIN = 262,
107 8d5d2d4c ths
};
108 3a702699 ths
109 3a702699 ths
#if CONFIG_VNC_TLS
110 3a702699 ths
#define X509_CA_CERT_FILE "ca-cert.pem"
111 3a702699 ths
#define X509_CA_CRL_FILE "ca-crl.pem"
112 3a702699 ths
#define X509_SERVER_KEY_FILE "server-key.pem"
113 3a702699 ths
#define X509_SERVER_CERT_FILE "server-cert.pem"
114 3a702699 ths
#endif
115 3a702699 ths
116 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
117 8d5d2d4c ths
118 24236869 bellard
struct VncState
119 24236869 bellard
{
120 24236869 bellard
    QEMUTimer *timer;
121 24236869 bellard
    int lsock;
122 24236869 bellard
    int csock;
123 24236869 bellard
    DisplayState *ds;
124 24236869 bellard
    int need_update;
125 24236869 bellard
    int width;
126 24236869 bellard
    int height;
127 99589bdc bellard
    uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
128 24236869 bellard
    char *old_data;
129 3512779a bellard
    int depth; /* internal VNC frame buffer byte per pixel */
130 24236869 bellard
    int has_resize;
131 24236869 bellard
    int has_hextile;
132 564c337e bellard
    int has_pointer_type_change;
133 564c337e bellard
    int absolute;
134 564c337e bellard
    int last_x;
135 564c337e bellard
    int last_y;
136 564c337e bellard
137 70848515 ths
    int major;
138 70848515 ths
    int minor;
139 70848515 ths
140 71cab5ca ths
    char *display;
141 70848515 ths
    char *password;
142 70848515 ths
    int auth;
143 8d5d2d4c ths
#if CONFIG_VNC_TLS
144 8d5d2d4c ths
    int subauth;
145 469b15c6 ths
    int x509verify;
146 6f43024c ths
147 6f43024c ths
    char *x509cacert;
148 6f43024c ths
    char *x509cacrl;
149 6f43024c ths
    char *x509cert;
150 6f43024c ths
    char *x509key;
151 8d5d2d4c ths
#endif
152 70848515 ths
    char challenge[VNC_AUTH_CHALLENGE_SIZE];
153 a9ce8590 bellard
154 8d5d2d4c ths
#if CONFIG_VNC_TLS
155 8d5d2d4c ths
    int wiremode;
156 8d5d2d4c ths
    gnutls_session_t tls_session;
157 8d5d2d4c ths
#endif
158 8d5d2d4c ths
159 24236869 bellard
    Buffer output;
160 24236869 bellard
    Buffer input;
161 24236869 bellard
    kbd_layout_t *kbd_layout;
162 3512779a bellard
    /* current output mode information */
163 3512779a bellard
    VncWritePixels *write_pixels;
164 3512779a bellard
    VncSendHextileTile *send_hextile_tile;
165 3512779a bellard
    int pix_bpp, pix_big_endian;
166 3512779a bellard
    int red_shift, red_max, red_shift1;
167 3512779a bellard
    int green_shift, green_max, green_shift1;
168 3512779a bellard
    int blue_shift, blue_max, blue_shift1;
169 24236869 bellard
170 24236869 bellard
    VncReadEvent *read_handler;
171 24236869 bellard
    size_t read_handler_expect;
172 64f5a135 bellard
    /* input */
173 64f5a135 bellard
    uint8_t modifiers_state[256];
174 24236869 bellard
};
175 24236869 bellard
176 a9ce8590 bellard
static VncState *vnc_state; /* needed for info vnc */
177 a9ce8590 bellard
178 a9ce8590 bellard
void do_info_vnc(void)
179 a9ce8590 bellard
{
180 a9ce8590 bellard
    if (vnc_state == NULL)
181 a9ce8590 bellard
        term_printf("VNC server disabled\n");
182 a9ce8590 bellard
    else {
183 a9ce8590 bellard
        term_printf("VNC server active on: ");
184 a9ce8590 bellard
        term_print_filename(vnc_state->display);
185 a9ce8590 bellard
        term_printf("\n");
186 a9ce8590 bellard
187 a9ce8590 bellard
        if (vnc_state->csock == -1)
188 a9ce8590 bellard
            term_printf("No client connected\n");
189 a9ce8590 bellard
        else
190 a9ce8590 bellard
            term_printf("Client connected\n");
191 a9ce8590 bellard
    }
192 a9ce8590 bellard
}
193 a9ce8590 bellard
194 24236869 bellard
/* TODO
195 24236869 bellard
   1) Get the queue working for IO.
196 24236869 bellard
   2) there is some weirdness when using the -S option (the screen is grey
197 24236869 bellard
      and not totally invalidated
198 24236869 bellard
   3) resolutions > 1024
199 24236869 bellard
*/
200 24236869 bellard
201 24236869 bellard
static void vnc_write(VncState *vs, const void *data, size_t len);
202 24236869 bellard
static void vnc_write_u32(VncState *vs, uint32_t value);
203 24236869 bellard
static void vnc_write_s32(VncState *vs, int32_t value);
204 24236869 bellard
static void vnc_write_u16(VncState *vs, uint16_t value);
205 24236869 bellard
static void vnc_write_u8(VncState *vs, uint8_t value);
206 24236869 bellard
static void vnc_flush(VncState *vs);
207 24236869 bellard
static void vnc_update_client(void *opaque);
208 24236869 bellard
static void vnc_client_read(void *opaque);
209 24236869 bellard
210 99589bdc bellard
static inline void vnc_set_bit(uint32_t *d, int k)
211 99589bdc bellard
{
212 99589bdc bellard
    d[k >> 5] |= 1 << (k & 0x1f);
213 99589bdc bellard
}
214 99589bdc bellard
215 99589bdc bellard
static inline void vnc_clear_bit(uint32_t *d, int k)
216 99589bdc bellard
{
217 99589bdc bellard
    d[k >> 5] &= ~(1 << (k & 0x1f));
218 99589bdc bellard
}
219 99589bdc bellard
220 99589bdc bellard
static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
221 99589bdc bellard
{
222 99589bdc bellard
    int j;
223 99589bdc bellard
224 99589bdc bellard
    j = 0;
225 99589bdc bellard
    while (n >= 32) {
226 99589bdc bellard
        d[j++] = -1;
227 99589bdc bellard
        n -= 32;
228 99589bdc bellard
    }
229 5fafdf24 ths
    if (n > 0)
230 99589bdc bellard
        d[j++] = (1 << n) - 1;
231 99589bdc bellard
    while (j < nb_words)
232 99589bdc bellard
        d[j++] = 0;
233 99589bdc bellard
}
234 99589bdc bellard
235 99589bdc bellard
static inline int vnc_get_bit(const uint32_t *d, int k)
236 99589bdc bellard
{
237 99589bdc bellard
    return (d[k >> 5] >> (k & 0x1f)) & 1;
238 99589bdc bellard
}
239 99589bdc bellard
240 5fafdf24 ths
static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
241 99589bdc bellard
                               int nb_words)
242 99589bdc bellard
{
243 99589bdc bellard
    int i;
244 99589bdc bellard
    for(i = 0; i < nb_words; i++) {
245 99589bdc bellard
        if ((d1[i] & d2[i]) != 0)
246 99589bdc bellard
            return 1;
247 99589bdc bellard
    }
248 99589bdc bellard
    return 0;
249 99589bdc bellard
}
250 99589bdc bellard
251 24236869 bellard
static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
252 24236869 bellard
{
253 24236869 bellard
    VncState *vs = ds->opaque;
254 24236869 bellard
    int i;
255 24236869 bellard
256 24236869 bellard
    h += y;
257 24236869 bellard
258 24236869 bellard
    for (; y < h; y++)
259 24236869 bellard
        for (i = 0; i < w; i += 16)
260 99589bdc bellard
            vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
261 24236869 bellard
}
262 24236869 bellard
263 24236869 bellard
static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
264 24236869 bellard
                                   int32_t encoding)
265 24236869 bellard
{
266 24236869 bellard
    vnc_write_u16(vs, x);
267 24236869 bellard
    vnc_write_u16(vs, y);
268 24236869 bellard
    vnc_write_u16(vs, w);
269 24236869 bellard
    vnc_write_u16(vs, h);
270 24236869 bellard
271 24236869 bellard
    vnc_write_s32(vs, encoding);
272 24236869 bellard
}
273 24236869 bellard
274 24236869 bellard
static void vnc_dpy_resize(DisplayState *ds, int w, int h)
275 24236869 bellard
{
276 73e14b62 ths
    int size_changed;
277 24236869 bellard
    VncState *vs = ds->opaque;
278 24236869 bellard
279 24236869 bellard
    ds->data = realloc(ds->data, w * h * vs->depth);
280 24236869 bellard
    vs->old_data = realloc(vs->old_data, w * h * vs->depth);
281 24236869 bellard
282 24236869 bellard
    if (ds->data == NULL || vs->old_data == NULL) {
283 24236869 bellard
        fprintf(stderr, "vnc: memory allocation failed\n");
284 24236869 bellard
        exit(1);
285 24236869 bellard
    }
286 24236869 bellard
287 a528b80c balrog
    if (ds->depth != vs->depth * 8) {
288 a528b80c balrog
        ds->depth = vs->depth * 8;
289 a528b80c balrog
        console_color_init(ds);
290 a528b80c balrog
    }
291 73e14b62 ths
    size_changed = ds->width != w || ds->height != h;
292 24236869 bellard
    ds->width = w;
293 24236869 bellard
    ds->height = h;
294 24236869 bellard
    ds->linesize = w * vs->depth;
295 73e14b62 ths
    if (vs->csock != -1 && vs->has_resize && size_changed) {
296 24236869 bellard
        vnc_write_u8(vs, 0);  /* msg id */
297 24236869 bellard
        vnc_write_u8(vs, 0);
298 24236869 bellard
        vnc_write_u16(vs, 1); /* number of rects */
299 24236869 bellard
        vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
300 24236869 bellard
        vnc_flush(vs);
301 24236869 bellard
        vs->width = ds->width;
302 24236869 bellard
        vs->height = ds->height;
303 24236869 bellard
    }
304 24236869 bellard
}
305 24236869 bellard
306 3512779a bellard
/* fastest code */
307 3512779a bellard
static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
308 3512779a bellard
{
309 3512779a bellard
    vnc_write(vs, pixels, size);
310 3512779a bellard
}
311 3512779a bellard
312 3512779a bellard
/* slowest but generic code. */
313 3512779a bellard
static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
314 3512779a bellard
{
315 3512779a bellard
    unsigned int r, g, b;
316 3512779a bellard
317 3512779a bellard
    r = (v >> vs->red_shift1) & vs->red_max;
318 3512779a bellard
    g = (v >> vs->green_shift1) & vs->green_max;
319 3512779a bellard
    b = (v >> vs->blue_shift1) & vs->blue_max;
320 5fafdf24 ths
    v = (r << vs->red_shift) |
321 5fafdf24 ths
        (g << vs->green_shift) |
322 3512779a bellard
        (b << vs->blue_shift);
323 3512779a bellard
    switch(vs->pix_bpp) {
324 3512779a bellard
    case 1:
325 3512779a bellard
        buf[0] = v;
326 3512779a bellard
        break;
327 3512779a bellard
    case 2:
328 3512779a bellard
        if (vs->pix_big_endian) {
329 3512779a bellard
            buf[0] = v >> 8;
330 3512779a bellard
            buf[1] = v;
331 3512779a bellard
        } else {
332 3512779a bellard
            buf[1] = v >> 8;
333 3512779a bellard
            buf[0] = v;
334 3512779a bellard
        }
335 3512779a bellard
        break;
336 3512779a bellard
    default:
337 3512779a bellard
    case 4:
338 3512779a bellard
        if (vs->pix_big_endian) {
339 3512779a bellard
            buf[0] = v >> 24;
340 3512779a bellard
            buf[1] = v >> 16;
341 3512779a bellard
            buf[2] = v >> 8;
342 3512779a bellard
            buf[3] = v;
343 3512779a bellard
        } else {
344 3512779a bellard
            buf[3] = v >> 24;
345 3512779a bellard
            buf[2] = v >> 16;
346 3512779a bellard
            buf[1] = v >> 8;
347 3512779a bellard
            buf[0] = v;
348 3512779a bellard
        }
349 3512779a bellard
        break;
350 3512779a bellard
    }
351 3512779a bellard
}
352 3512779a bellard
353 3512779a bellard
static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
354 3512779a bellard
{
355 3512779a bellard
    uint32_t *pixels = pixels1;
356 3512779a bellard
    uint8_t buf[4];
357 3512779a bellard
    int n, i;
358 3512779a bellard
359 3512779a bellard
    n = size >> 2;
360 3512779a bellard
    for(i = 0; i < n; i++) {
361 3512779a bellard
        vnc_convert_pixel(vs, buf, pixels[i]);
362 3512779a bellard
        vnc_write(vs, buf, vs->pix_bpp);
363 3512779a bellard
    }
364 3512779a bellard
}
365 3512779a bellard
366 24236869 bellard
static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
367 24236869 bellard
{
368 24236869 bellard
    int i;
369 24236869 bellard
    char *row;
370 24236869 bellard
371 24236869 bellard
    vnc_framebuffer_update(vs, x, y, w, h, 0);
372 24236869 bellard
373 24236869 bellard
    row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
374 24236869 bellard
    for (i = 0; i < h; i++) {
375 3512779a bellard
        vs->write_pixels(vs, row, w * vs->depth);
376 24236869 bellard
        row += vs->ds->linesize;
377 24236869 bellard
    }
378 24236869 bellard
}
379 24236869 bellard
380 24236869 bellard
static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
381 24236869 bellard
{
382 24236869 bellard
    ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
383 24236869 bellard
    ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
384 24236869 bellard
}
385 24236869 bellard
386 24236869 bellard
#define BPP 8
387 24236869 bellard
#include "vnchextile.h"
388 24236869 bellard
#undef BPP
389 24236869 bellard
390 24236869 bellard
#define BPP 16
391 24236869 bellard
#include "vnchextile.h"
392 24236869 bellard
#undef BPP
393 24236869 bellard
394 24236869 bellard
#define BPP 32
395 24236869 bellard
#include "vnchextile.h"
396 24236869 bellard
#undef BPP
397 24236869 bellard
398 3512779a bellard
#define GENERIC
399 3512779a bellard
#define BPP 32
400 3512779a bellard
#include "vnchextile.h"
401 3512779a bellard
#undef BPP
402 3512779a bellard
#undef GENERIC
403 3512779a bellard
404 24236869 bellard
static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
405 24236869 bellard
{
406 24236869 bellard
    int i, j;
407 24236869 bellard
    int has_fg, has_bg;
408 24236869 bellard
    uint32_t last_fg32, last_bg32;
409 24236869 bellard
410 24236869 bellard
    vnc_framebuffer_update(vs, x, y, w, h, 5);
411 24236869 bellard
412 24236869 bellard
    has_fg = has_bg = 0;
413 24236869 bellard
    for (j = y; j < (y + h); j += 16) {
414 24236869 bellard
        for (i = x; i < (x + w); i += 16) {
415 5fafdf24 ths
            vs->send_hextile_tile(vs, i, j,
416 3512779a bellard
                                  MIN(16, x + w - i), MIN(16, y + h - j),
417 3512779a bellard
                                  &last_bg32, &last_fg32, &has_bg, &has_fg);
418 24236869 bellard
        }
419 24236869 bellard
    }
420 24236869 bellard
}
421 24236869 bellard
422 24236869 bellard
static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
423 24236869 bellard
{
424 24236869 bellard
        if (vs->has_hextile)
425 24236869 bellard
            send_framebuffer_update_hextile(vs, x, y, w, h);
426 24236869 bellard
        else
427 24236869 bellard
            send_framebuffer_update_raw(vs, x, y, w, h);
428 24236869 bellard
}
429 24236869 bellard
430 24236869 bellard
static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
431 24236869 bellard
{
432 24236869 bellard
    int src, dst;
433 24236869 bellard
    char *src_row;
434 24236869 bellard
    char *dst_row;
435 24236869 bellard
    char *old_row;
436 24236869 bellard
    int y = 0;
437 24236869 bellard
    int pitch = ds->linesize;
438 24236869 bellard
    VncState *vs = ds->opaque;
439 24236869 bellard
440 24236869 bellard
    vnc_update_client(vs);
441 24236869 bellard
442 24236869 bellard
    if (dst_y > src_y) {
443 24236869 bellard
        y = h - 1;
444 24236869 bellard
        pitch = -pitch;
445 24236869 bellard
    }
446 24236869 bellard
447 24236869 bellard
    src = (ds->linesize * (src_y + y) + vs->depth * src_x);
448 24236869 bellard
    dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
449 24236869 bellard
450 24236869 bellard
    src_row = ds->data + src;
451 24236869 bellard
    dst_row = ds->data + dst;
452 24236869 bellard
    old_row = vs->old_data + dst;
453 24236869 bellard
454 24236869 bellard
    for (y = 0; y < h; y++) {
455 24236869 bellard
        memmove(old_row, src_row, w * vs->depth);
456 24236869 bellard
        memmove(dst_row, src_row, w * vs->depth);
457 24236869 bellard
        src_row += pitch;
458 24236869 bellard
        dst_row += pitch;
459 24236869 bellard
        old_row += pitch;
460 24236869 bellard
    }
461 24236869 bellard
462 24236869 bellard
    vnc_write_u8(vs, 0);  /* msg id */
463 24236869 bellard
    vnc_write_u8(vs, 0);
464 24236869 bellard
    vnc_write_u16(vs, 1); /* number of rects */
465 24236869 bellard
    vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
466 24236869 bellard
    vnc_write_u16(vs, src_x);
467 24236869 bellard
    vnc_write_u16(vs, src_y);
468 24236869 bellard
    vnc_flush(vs);
469 24236869 bellard
}
470 24236869 bellard
471 24236869 bellard
static int find_dirty_height(VncState *vs, int y, int last_x, int x)
472 24236869 bellard
{
473 24236869 bellard
    int h;
474 24236869 bellard
475 24236869 bellard
    for (h = 1; h < (vs->height - y); h++) {
476 24236869 bellard
        int tmp_x;
477 99589bdc bellard
        if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
478 24236869 bellard
            break;
479 24236869 bellard
        for (tmp_x = last_x; tmp_x < x; tmp_x++)
480 99589bdc bellard
            vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
481 24236869 bellard
    }
482 24236869 bellard
483 24236869 bellard
    return h;
484 24236869 bellard
}
485 24236869 bellard
486 24236869 bellard
static void vnc_update_client(void *opaque)
487 24236869 bellard
{
488 24236869 bellard
    VncState *vs = opaque;
489 24236869 bellard
490 24236869 bellard
    if (vs->need_update && vs->csock != -1) {
491 24236869 bellard
        int y;
492 24236869 bellard
        char *row;
493 24236869 bellard
        char *old_row;
494 99589bdc bellard
        uint32_t width_mask[VNC_DIRTY_WORDS];
495 24236869 bellard
        int n_rectangles;
496 24236869 bellard
        int saved_offset;
497 24236869 bellard
        int has_dirty = 0;
498 24236869 bellard
499 99589bdc bellard
        vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
500 24236869 bellard
501 24236869 bellard
        /* Walk through the dirty map and eliminate tiles that
502 24236869 bellard
           really aren't dirty */
503 24236869 bellard
        row = vs->ds->data;
504 24236869 bellard
        old_row = vs->old_data;
505 24236869 bellard
506 24236869 bellard
        for (y = 0; y < vs->height; y++) {
507 99589bdc bellard
            if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
508 24236869 bellard
                int x;
509 24236869 bellard
                char *ptr, *old_ptr;
510 24236869 bellard
511 24236869 bellard
                ptr = row;
512 24236869 bellard
                old_ptr = old_row;
513 24236869 bellard
514 24236869 bellard
                for (x = 0; x < vs->ds->width; x += 16) {
515 24236869 bellard
                    if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
516 99589bdc bellard
                        vnc_clear_bit(vs->dirty_row[y], (x / 16));
517 24236869 bellard
                    } else {
518 24236869 bellard
                        has_dirty = 1;
519 24236869 bellard
                        memcpy(old_ptr, ptr, 16 * vs->depth);
520 24236869 bellard
                    }
521 24236869 bellard
522 24236869 bellard
                    ptr += 16 * vs->depth;
523 24236869 bellard
                    old_ptr += 16 * vs->depth;
524 24236869 bellard
                }
525 24236869 bellard
            }
526 24236869 bellard
527 24236869 bellard
            row += vs->ds->linesize;
528 24236869 bellard
            old_row += vs->ds->linesize;
529 24236869 bellard
        }
530 24236869 bellard
531 24236869 bellard
        if (!has_dirty) {
532 24236869 bellard
            qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
533 24236869 bellard
            return;
534 24236869 bellard
        }
535 24236869 bellard
536 24236869 bellard
        /* Count rectangles */
537 24236869 bellard
        n_rectangles = 0;
538 24236869 bellard
        vnc_write_u8(vs, 0);  /* msg id */
539 24236869 bellard
        vnc_write_u8(vs, 0);
540 24236869 bellard
        saved_offset = vs->output.offset;
541 24236869 bellard
        vnc_write_u16(vs, 0);
542 24236869 bellard
543 24236869 bellard
        for (y = 0; y < vs->height; y++) {
544 24236869 bellard
            int x;
545 24236869 bellard
            int last_x = -1;
546 24236869 bellard
            for (x = 0; x < vs->width / 16; x++) {
547 99589bdc bellard
                if (vnc_get_bit(vs->dirty_row[y], x)) {
548 24236869 bellard
                    if (last_x == -1) {
549 24236869 bellard
                        last_x = x;
550 24236869 bellard
                    }
551 99589bdc bellard
                    vnc_clear_bit(vs->dirty_row[y], x);
552 24236869 bellard
                } else {
553 24236869 bellard
                    if (last_x != -1) {
554 24236869 bellard
                        int h = find_dirty_height(vs, y, last_x, x);
555 24236869 bellard
                        send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
556 24236869 bellard
                        n_rectangles++;
557 24236869 bellard
                    }
558 24236869 bellard
                    last_x = -1;
559 24236869 bellard
                }
560 24236869 bellard
            }
561 24236869 bellard
            if (last_x != -1) {
562 24236869 bellard
                int h = find_dirty_height(vs, y, last_x, x);
563 24236869 bellard
                send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
564 24236869 bellard
                n_rectangles++;
565 24236869 bellard
            }
566 24236869 bellard
        }
567 24236869 bellard
        vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
568 24236869 bellard
        vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
569 24236869 bellard
        vnc_flush(vs);
570 24236869 bellard
571 24236869 bellard
    }
572 24236869 bellard
    qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
573 24236869 bellard
}
574 24236869 bellard
575 24236869 bellard
static void vnc_timer_init(VncState *vs)
576 24236869 bellard
{
577 24236869 bellard
    if (vs->timer == NULL) {
578 24236869 bellard
        vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
579 24236869 bellard
        qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
580 24236869 bellard
    }
581 24236869 bellard
}
582 24236869 bellard
583 24236869 bellard
static void vnc_dpy_refresh(DisplayState *ds)
584 24236869 bellard
{
585 24236869 bellard
    VncState *vs = ds->opaque;
586 24236869 bellard
    vnc_timer_init(vs);
587 24236869 bellard
    vga_hw_update();
588 24236869 bellard
}
589 24236869 bellard
590 24236869 bellard
static int vnc_listen_poll(void *opaque)
591 24236869 bellard
{
592 24236869 bellard
    VncState *vs = opaque;
593 24236869 bellard
    if (vs->csock == -1)
594 24236869 bellard
        return 1;
595 24236869 bellard
    return 0;
596 24236869 bellard
}
597 24236869 bellard
598 24236869 bellard
static void buffer_reserve(Buffer *buffer, size_t len)
599 24236869 bellard
{
600 24236869 bellard
    if ((buffer->capacity - buffer->offset) < len) {
601 24236869 bellard
        buffer->capacity += (len + 1024);
602 24236869 bellard
        buffer->buffer = realloc(buffer->buffer, buffer->capacity);
603 24236869 bellard
        if (buffer->buffer == NULL) {
604 24236869 bellard
            fprintf(stderr, "vnc: out of memory\n");
605 24236869 bellard
            exit(1);
606 24236869 bellard
        }
607 24236869 bellard
    }
608 24236869 bellard
}
609 24236869 bellard
610 24236869 bellard
static int buffer_empty(Buffer *buffer)
611 24236869 bellard
{
612 24236869 bellard
    return buffer->offset == 0;
613 24236869 bellard
}
614 24236869 bellard
615 24236869 bellard
static char *buffer_end(Buffer *buffer)
616 24236869 bellard
{
617 24236869 bellard
    return buffer->buffer + buffer->offset;
618 24236869 bellard
}
619 24236869 bellard
620 24236869 bellard
static void buffer_reset(Buffer *buffer)
621 24236869 bellard
{
622 24236869 bellard
        buffer->offset = 0;
623 24236869 bellard
}
624 24236869 bellard
625 24236869 bellard
static void buffer_append(Buffer *buffer, const void *data, size_t len)
626 24236869 bellard
{
627 24236869 bellard
    memcpy(buffer->buffer + buffer->offset, data, len);
628 24236869 bellard
    buffer->offset += len;
629 24236869 bellard
}
630 24236869 bellard
631 6ca957f0 bellard
static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
632 24236869 bellard
{
633 24236869 bellard
    if (ret == 0 || ret == -1) {
634 6ca957f0 bellard
        if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN))
635 24236869 bellard
            return 0;
636 24236869 bellard
637 8d5d2d4c ths
        VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
638 24236869 bellard
        qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
639 6ca957f0 bellard
        closesocket(vs->csock);
640 24236869 bellard
        vs->csock = -1;
641 24236869 bellard
        buffer_reset(&vs->input);
642 24236869 bellard
        buffer_reset(&vs->output);
643 24236869 bellard
        vs->need_update = 0;
644 8d5d2d4c ths
#if CONFIG_VNC_TLS
645 8d5d2d4c ths
        if (vs->tls_session) {
646 8d5d2d4c ths
            gnutls_deinit(vs->tls_session);
647 8d5d2d4c ths
            vs->tls_session = NULL;
648 8d5d2d4c ths
        }
649 8d5d2d4c ths
        vs->wiremode = VNC_WIREMODE_CLEAR;
650 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
651 24236869 bellard
        return 0;
652 24236869 bellard
    }
653 24236869 bellard
    return ret;
654 24236869 bellard
}
655 24236869 bellard
656 24236869 bellard
static void vnc_client_error(VncState *vs)
657 24236869 bellard
{
658 6ca957f0 bellard
    vnc_client_io_error(vs, -1, EINVAL);
659 24236869 bellard
}
660 24236869 bellard
661 24236869 bellard
static void vnc_client_write(void *opaque)
662 24236869 bellard
{
663 ceb5caaf bellard
    long ret;
664 24236869 bellard
    VncState *vs = opaque;
665 24236869 bellard
666 8d5d2d4c ths
#if CONFIG_VNC_TLS
667 8d5d2d4c ths
    if (vs->tls_session) {
668 8d5d2d4c ths
        ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
669 8d5d2d4c ths
        if (ret < 0) {
670 8d5d2d4c ths
            if (ret == GNUTLS_E_AGAIN)
671 8d5d2d4c ths
                errno = EAGAIN;
672 8d5d2d4c ths
            else
673 8d5d2d4c ths
                errno = EIO;
674 8d5d2d4c ths
            ret = -1;
675 8d5d2d4c ths
        }
676 8d5d2d4c ths
    } else
677 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
678 8d5d2d4c ths
        ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
679 6ca957f0 bellard
    ret = vnc_client_io_error(vs, ret, socket_error());
680 24236869 bellard
    if (!ret)
681 24236869 bellard
        return;
682 24236869 bellard
683 24236869 bellard
    memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
684 24236869 bellard
    vs->output.offset -= ret;
685 24236869 bellard
686 24236869 bellard
    if (vs->output.offset == 0) {
687 24236869 bellard
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
688 24236869 bellard
    }
689 24236869 bellard
}
690 24236869 bellard
691 24236869 bellard
static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
692 24236869 bellard
{
693 24236869 bellard
    vs->read_handler = func;
694 24236869 bellard
    vs->read_handler_expect = expecting;
695 24236869 bellard
}
696 24236869 bellard
697 24236869 bellard
static void vnc_client_read(void *opaque)
698 24236869 bellard
{
699 24236869 bellard
    VncState *vs = opaque;
700 ceb5caaf bellard
    long ret;
701 24236869 bellard
702 24236869 bellard
    buffer_reserve(&vs->input, 4096);
703 24236869 bellard
704 8d5d2d4c ths
#if CONFIG_VNC_TLS
705 8d5d2d4c ths
    if (vs->tls_session) {
706 8d5d2d4c ths
        ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
707 8d5d2d4c ths
        if (ret < 0) {
708 8d5d2d4c ths
            if (ret == GNUTLS_E_AGAIN)
709 8d5d2d4c ths
                errno = EAGAIN;
710 8d5d2d4c ths
            else
711 8d5d2d4c ths
                errno = EIO;
712 8d5d2d4c ths
            ret = -1;
713 8d5d2d4c ths
        }
714 8d5d2d4c ths
    } else
715 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
716 8d5d2d4c ths
        ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
717 6ca957f0 bellard
    ret = vnc_client_io_error(vs, ret, socket_error());
718 24236869 bellard
    if (!ret)
719 24236869 bellard
        return;
720 24236869 bellard
721 24236869 bellard
    vs->input.offset += ret;
722 24236869 bellard
723 24236869 bellard
    while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
724 24236869 bellard
        size_t len = vs->read_handler_expect;
725 24236869 bellard
        int ret;
726 24236869 bellard
727 24236869 bellard
        ret = vs->read_handler(vs, vs->input.buffer, len);
728 24236869 bellard
        if (vs->csock == -1)
729 24236869 bellard
            return;
730 24236869 bellard
731 24236869 bellard
        if (!ret) {
732 24236869 bellard
            memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
733 24236869 bellard
            vs->input.offset -= len;
734 24236869 bellard
        } else {
735 24236869 bellard
            vs->read_handler_expect = ret;
736 24236869 bellard
        }
737 24236869 bellard
    }
738 24236869 bellard
}
739 24236869 bellard
740 24236869 bellard
static void vnc_write(VncState *vs, const void *data, size_t len)
741 24236869 bellard
{
742 24236869 bellard
    buffer_reserve(&vs->output, len);
743 24236869 bellard
744 24236869 bellard
    if (buffer_empty(&vs->output)) {
745 24236869 bellard
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
746 24236869 bellard
    }
747 24236869 bellard
748 24236869 bellard
    buffer_append(&vs->output, data, len);
749 24236869 bellard
}
750 24236869 bellard
751 24236869 bellard
static void vnc_write_s32(VncState *vs, int32_t value)
752 24236869 bellard
{
753 24236869 bellard
    vnc_write_u32(vs, *(uint32_t *)&value);
754 24236869 bellard
}
755 24236869 bellard
756 24236869 bellard
static void vnc_write_u32(VncState *vs, uint32_t value)
757 24236869 bellard
{
758 24236869 bellard
    uint8_t buf[4];
759 24236869 bellard
760 24236869 bellard
    buf[0] = (value >> 24) & 0xFF;
761 24236869 bellard
    buf[1] = (value >> 16) & 0xFF;
762 24236869 bellard
    buf[2] = (value >>  8) & 0xFF;
763 24236869 bellard
    buf[3] = value & 0xFF;
764 24236869 bellard
765 24236869 bellard
    vnc_write(vs, buf, 4);
766 24236869 bellard
}
767 24236869 bellard
768 24236869 bellard
static void vnc_write_u16(VncState *vs, uint16_t value)
769 24236869 bellard
{
770 64f5a135 bellard
    uint8_t buf[2];
771 24236869 bellard
772 24236869 bellard
    buf[0] = (value >> 8) & 0xFF;
773 24236869 bellard
    buf[1] = value & 0xFF;
774 24236869 bellard
775 24236869 bellard
    vnc_write(vs, buf, 2);
776 24236869 bellard
}
777 24236869 bellard
778 24236869 bellard
static void vnc_write_u8(VncState *vs, uint8_t value)
779 24236869 bellard
{
780 24236869 bellard
    vnc_write(vs, (char *)&value, 1);
781 24236869 bellard
}
782 24236869 bellard
783 24236869 bellard
static void vnc_flush(VncState *vs)
784 24236869 bellard
{
785 24236869 bellard
    if (vs->output.offset)
786 24236869 bellard
        vnc_client_write(vs);
787 24236869 bellard
}
788 24236869 bellard
789 64f5a135 bellard
static uint8_t read_u8(uint8_t *data, size_t offset)
790 24236869 bellard
{
791 24236869 bellard
    return data[offset];
792 24236869 bellard
}
793 24236869 bellard
794 64f5a135 bellard
static uint16_t read_u16(uint8_t *data, size_t offset)
795 24236869 bellard
{
796 24236869 bellard
    return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
797 24236869 bellard
}
798 24236869 bellard
799 64f5a135 bellard
static int32_t read_s32(uint8_t *data, size_t offset)
800 24236869 bellard
{
801 24236869 bellard
    return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
802 24236869 bellard
                     (data[offset + 2] << 8) | data[offset + 3]);
803 24236869 bellard
}
804 24236869 bellard
805 64f5a135 bellard
static uint32_t read_u32(uint8_t *data, size_t offset)
806 24236869 bellard
{
807 24236869 bellard
    return ((data[offset] << 24) | (data[offset + 1] << 16) |
808 24236869 bellard
            (data[offset + 2] << 8) | data[offset + 3]);
809 24236869 bellard
}
810 24236869 bellard
811 8d5d2d4c ths
#if CONFIG_VNC_TLS
812 8d5d2d4c ths
ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
813 8d5d2d4c ths
                     const void *data,
814 8d5d2d4c ths
                     size_t len) {
815 8d5d2d4c ths
    struct VncState *vs = (struct VncState *)transport;
816 8d5d2d4c ths
    int ret;
817 8d5d2d4c ths
818 8d5d2d4c ths
 retry:
819 8d5d2d4c ths
    ret = send(vs->csock, data, len, 0);
820 8d5d2d4c ths
    if (ret < 0) {
821 8d5d2d4c ths
        if (errno == EINTR)
822 8d5d2d4c ths
            goto retry;
823 8d5d2d4c ths
        return -1;
824 8d5d2d4c ths
    }
825 8d5d2d4c ths
    return ret;
826 8d5d2d4c ths
}
827 8d5d2d4c ths
828 8d5d2d4c ths
829 8d5d2d4c ths
ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
830 8d5d2d4c ths
                     void *data,
831 8d5d2d4c ths
                     size_t len) {
832 8d5d2d4c ths
    struct VncState *vs = (struct VncState *)transport;
833 8d5d2d4c ths
    int ret;
834 8d5d2d4c ths
835 8d5d2d4c ths
 retry:
836 8d5d2d4c ths
    ret = recv(vs->csock, data, len, 0);
837 8d5d2d4c ths
    if (ret < 0) {
838 8d5d2d4c ths
        if (errno == EINTR)
839 8d5d2d4c ths
            goto retry;
840 8d5d2d4c ths
        return -1;
841 8d5d2d4c ths
    }
842 8d5d2d4c ths
    return ret;
843 8d5d2d4c ths
}
844 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
845 8d5d2d4c ths
846 24236869 bellard
static void client_cut_text(VncState *vs, size_t len, char *text)
847 24236869 bellard
{
848 24236869 bellard
}
849 24236869 bellard
850 564c337e bellard
static void check_pointer_type_change(VncState *vs, int absolute)
851 564c337e bellard
{
852 564c337e bellard
    if (vs->has_pointer_type_change && vs->absolute != absolute) {
853 564c337e bellard
        vnc_write_u8(vs, 0);
854 564c337e bellard
        vnc_write_u8(vs, 0);
855 564c337e bellard
        vnc_write_u16(vs, 1);
856 564c337e bellard
        vnc_framebuffer_update(vs, absolute, 0,
857 564c337e bellard
                               vs->ds->width, vs->ds->height, -257);
858 564c337e bellard
        vnc_flush(vs);
859 564c337e bellard
    }
860 564c337e bellard
    vs->absolute = absolute;
861 564c337e bellard
}
862 564c337e bellard
863 24236869 bellard
static void pointer_event(VncState *vs, int button_mask, int x, int y)
864 24236869 bellard
{
865 24236869 bellard
    int buttons = 0;
866 24236869 bellard
    int dz = 0;
867 24236869 bellard
868 24236869 bellard
    if (button_mask & 0x01)
869 24236869 bellard
        buttons |= MOUSE_EVENT_LBUTTON;
870 24236869 bellard
    if (button_mask & 0x02)
871 24236869 bellard
        buttons |= MOUSE_EVENT_MBUTTON;
872 24236869 bellard
    if (button_mask & 0x04)
873 24236869 bellard
        buttons |= MOUSE_EVENT_RBUTTON;
874 24236869 bellard
    if (button_mask & 0x08)
875 24236869 bellard
        dz = -1;
876 24236869 bellard
    if (button_mask & 0x10)
877 24236869 bellard
        dz = 1;
878 564c337e bellard
879 564c337e bellard
    if (vs->absolute) {
880 24236869 bellard
        kbd_mouse_event(x * 0x7FFF / vs->ds->width,
881 24236869 bellard
                        y * 0x7FFF / vs->ds->height,
882 24236869 bellard
                        dz, buttons);
883 564c337e bellard
    } else if (vs->has_pointer_type_change) {
884 564c337e bellard
        x -= 0x7FFF;
885 564c337e bellard
        y -= 0x7FFF;
886 24236869 bellard
887 564c337e bellard
        kbd_mouse_event(x, y, dz, buttons);
888 564c337e bellard
    } else {
889 564c337e bellard
        if (vs->last_x != -1)
890 564c337e bellard
            kbd_mouse_event(x - vs->last_x,
891 564c337e bellard
                            y - vs->last_y,
892 564c337e bellard
                            dz, buttons);
893 564c337e bellard
        vs->last_x = x;
894 564c337e bellard
        vs->last_y = y;
895 24236869 bellard
    }
896 564c337e bellard
897 564c337e bellard
    check_pointer_type_change(vs, kbd_mouse_is_absolute());
898 24236869 bellard
}
899 24236869 bellard
900 64f5a135 bellard
static void reset_keys(VncState *vs)
901 64f5a135 bellard
{
902 64f5a135 bellard
    int i;
903 64f5a135 bellard
    for(i = 0; i < 256; i++) {
904 64f5a135 bellard
        if (vs->modifiers_state[i]) {
905 64f5a135 bellard
            if (i & 0x80)
906 64f5a135 bellard
                kbd_put_keycode(0xe0);
907 64f5a135 bellard
            kbd_put_keycode(i | 0x80);
908 64f5a135 bellard
            vs->modifiers_state[i] = 0;
909 64f5a135 bellard
        }
910 64f5a135 bellard
    }
911 64f5a135 bellard
}
912 64f5a135 bellard
913 a528b80c balrog
static void press_key(VncState *vs, int keysym)
914 a528b80c balrog
{
915 a528b80c balrog
    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
916 a528b80c balrog
    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
917 a528b80c balrog
}
918 a528b80c balrog
919 bdbd7676 bellard
static void do_key_event(VncState *vs, int down, uint32_t sym)
920 24236869 bellard
{
921 24236869 bellard
    int keycode;
922 24236869 bellard
923 24236869 bellard
    keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
924 3b46e624 ths
925 64f5a135 bellard
    /* QEMU console switch */
926 64f5a135 bellard
    switch(keycode) {
927 64f5a135 bellard
    case 0x2a:                          /* Left Shift */
928 64f5a135 bellard
    case 0x36:                          /* Right Shift */
929 64f5a135 bellard
    case 0x1d:                          /* Left CTRL */
930 64f5a135 bellard
    case 0x9d:                          /* Right CTRL */
931 64f5a135 bellard
    case 0x38:                          /* Left ALT */
932 64f5a135 bellard
    case 0xb8:                          /* Right ALT */
933 64f5a135 bellard
        if (down)
934 64f5a135 bellard
            vs->modifiers_state[keycode] = 1;
935 64f5a135 bellard
        else
936 64f5a135 bellard
            vs->modifiers_state[keycode] = 0;
937 64f5a135 bellard
        break;
938 5fafdf24 ths
    case 0x02 ... 0x0a: /* '1' to '9' keys */
939 64f5a135 bellard
        if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
940 64f5a135 bellard
            /* Reset the modifiers sent to the current console */
941 64f5a135 bellard
            reset_keys(vs);
942 64f5a135 bellard
            console_select(keycode - 0x02);
943 64f5a135 bellard
            return;
944 64f5a135 bellard
        }
945 64f5a135 bellard
        break;
946 a528b80c balrog
    case 0x45:                        /* NumLock */
947 a528b80c balrog
        if (!down)
948 a528b80c balrog
            vs->modifiers_state[keycode] ^= 1;
949 a528b80c balrog
        break;
950 a528b80c balrog
    }
951 a528b80c balrog
952 a528b80c balrog
    if (keycode_is_keypad(vs->kbd_layout, keycode)) {
953 a528b80c balrog
        /* If the numlock state needs to change then simulate an additional
954 a528b80c balrog
           keypress before sending this one.  This will happen if the user
955 a528b80c balrog
           toggles numlock away from the VNC window.
956 a528b80c balrog
        */
957 a528b80c balrog
        if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
958 a528b80c balrog
            if (!vs->modifiers_state[0x45]) {
959 a528b80c balrog
                vs->modifiers_state[0x45] = 1;
960 a528b80c balrog
                press_key(vs, 0xff7f);
961 a528b80c balrog
            }
962 a528b80c balrog
        } else {
963 a528b80c balrog
            if (vs->modifiers_state[0x45]) {
964 a528b80c balrog
                vs->modifiers_state[0x45] = 0;
965 a528b80c balrog
                press_key(vs, 0xff7f);
966 a528b80c balrog
            }
967 a528b80c balrog
        }
968 64f5a135 bellard
    }
969 24236869 bellard
970 64f5a135 bellard
    if (is_graphic_console()) {
971 64f5a135 bellard
        if (keycode & 0x80)
972 64f5a135 bellard
            kbd_put_keycode(0xe0);
973 64f5a135 bellard
        if (down)
974 64f5a135 bellard
            kbd_put_keycode(keycode & 0x7f);
975 64f5a135 bellard
        else
976 64f5a135 bellard
            kbd_put_keycode(keycode | 0x80);
977 64f5a135 bellard
    } else {
978 64f5a135 bellard
        /* QEMU console emulation */
979 64f5a135 bellard
        if (down) {
980 64f5a135 bellard
            switch (keycode) {
981 64f5a135 bellard
            case 0x2a:                          /* Left Shift */
982 64f5a135 bellard
            case 0x36:                          /* Right Shift */
983 64f5a135 bellard
            case 0x1d:                          /* Left CTRL */
984 64f5a135 bellard
            case 0x9d:                          /* Right CTRL */
985 64f5a135 bellard
            case 0x38:                          /* Left ALT */
986 64f5a135 bellard
            case 0xb8:                          /* Right ALT */
987 64f5a135 bellard
                break;
988 64f5a135 bellard
            case 0xc8:
989 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_UP);
990 64f5a135 bellard
                break;
991 64f5a135 bellard
            case 0xd0:
992 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_DOWN);
993 64f5a135 bellard
                break;
994 64f5a135 bellard
            case 0xcb:
995 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_LEFT);
996 64f5a135 bellard
                break;
997 64f5a135 bellard
            case 0xcd:
998 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_RIGHT);
999 64f5a135 bellard
                break;
1000 64f5a135 bellard
            case 0xd3:
1001 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_DELETE);
1002 64f5a135 bellard
                break;
1003 64f5a135 bellard
            case 0xc7:
1004 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_HOME);
1005 64f5a135 bellard
                break;
1006 64f5a135 bellard
            case 0xcf:
1007 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_END);
1008 64f5a135 bellard
                break;
1009 64f5a135 bellard
            case 0xc9:
1010 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_PAGEUP);
1011 64f5a135 bellard
                break;
1012 64f5a135 bellard
            case 0xd1:
1013 64f5a135 bellard
                kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1014 64f5a135 bellard
                break;
1015 64f5a135 bellard
            default:
1016 64f5a135 bellard
                kbd_put_keysym(sym);
1017 64f5a135 bellard
                break;
1018 64f5a135 bellard
            }
1019 64f5a135 bellard
        }
1020 64f5a135 bellard
    }
1021 24236869 bellard
}
1022 24236869 bellard
1023 bdbd7676 bellard
static void key_event(VncState *vs, int down, uint32_t sym)
1024 bdbd7676 bellard
{
1025 a528b80c balrog
    if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1026 bdbd7676 bellard
        sym = sym - 'A' + 'a';
1027 bdbd7676 bellard
    do_key_event(vs, down, sym);
1028 bdbd7676 bellard
}
1029 bdbd7676 bellard
1030 24236869 bellard
static void framebuffer_update_request(VncState *vs, int incremental,
1031 24236869 bellard
                                       int x_position, int y_position,
1032 24236869 bellard
                                       int w, int h)
1033 24236869 bellard
{
1034 cf2d385c ths
    if (x_position > vs->ds->width)
1035 cf2d385c ths
        x_position = vs->ds->width;
1036 cf2d385c ths
    if (y_position > vs->ds->height)
1037 cf2d385c ths
        y_position = vs->ds->height;
1038 cf2d385c ths
    if (x_position + w >= vs->ds->width)
1039 cf2d385c ths
        w = vs->ds->width  - x_position;
1040 cf2d385c ths
    if (y_position + h >= vs->ds->height)
1041 cf2d385c ths
        h = vs->ds->height - y_position;
1042 cf2d385c ths
1043 24236869 bellard
    int i;
1044 24236869 bellard
    vs->need_update = 1;
1045 24236869 bellard
    if (!incremental) {
1046 24236869 bellard
        char *old_row = vs->old_data + y_position * vs->ds->linesize;
1047 24236869 bellard
1048 24236869 bellard
        for (i = 0; i < h; i++) {
1049 5fafdf24 ths
            vnc_set_bits(vs->dirty_row[y_position + i],
1050 99589bdc bellard
                         (vs->ds->width / 16), VNC_DIRTY_WORDS);
1051 24236869 bellard
            memset(old_row, 42, vs->ds->width * vs->depth);
1052 24236869 bellard
            old_row += vs->ds->linesize;
1053 24236869 bellard
        }
1054 24236869 bellard
    }
1055 24236869 bellard
}
1056 24236869 bellard
1057 24236869 bellard
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1058 24236869 bellard
{
1059 24236869 bellard
    int i;
1060 24236869 bellard
1061 24236869 bellard
    vs->has_hextile = 0;
1062 24236869 bellard
    vs->has_resize = 0;
1063 564c337e bellard
    vs->has_pointer_type_change = 0;
1064 564c337e bellard
    vs->absolute = -1;
1065 24236869 bellard
    vs->ds->dpy_copy = NULL;
1066 24236869 bellard
1067 24236869 bellard
    for (i = n_encodings - 1; i >= 0; i--) {
1068 24236869 bellard
        switch (encodings[i]) {
1069 24236869 bellard
        case 0: /* Raw */
1070 24236869 bellard
            vs->has_hextile = 0;
1071 24236869 bellard
            break;
1072 24236869 bellard
        case 1: /* CopyRect */
1073 24236869 bellard
            vs->ds->dpy_copy = vnc_copy;
1074 24236869 bellard
            break;
1075 24236869 bellard
        case 5: /* Hextile */
1076 24236869 bellard
            vs->has_hextile = 1;
1077 24236869 bellard
            break;
1078 24236869 bellard
        case -223: /* DesktopResize */
1079 24236869 bellard
            vs->has_resize = 1;
1080 24236869 bellard
            break;
1081 564c337e bellard
        case -257:
1082 564c337e bellard
            vs->has_pointer_type_change = 1;
1083 564c337e bellard
            break;
1084 24236869 bellard
        default:
1085 24236869 bellard
            break;
1086 24236869 bellard
        }
1087 24236869 bellard
    }
1088 564c337e bellard
1089 564c337e bellard
    check_pointer_type_change(vs, kbd_mouse_is_absolute());
1090 24236869 bellard
}
1091 24236869 bellard
1092 3512779a bellard
static int compute_nbits(unsigned int val)
1093 3512779a bellard
{
1094 3512779a bellard
    int n;
1095 3512779a bellard
    n = 0;
1096 3512779a bellard
    while (val != 0) {
1097 3512779a bellard
        n++;
1098 3512779a bellard
        val >>= 1;
1099 3512779a bellard
    }
1100 3512779a bellard
    return n;
1101 3512779a bellard
}
1102 3512779a bellard
1103 24236869 bellard
static void set_pixel_format(VncState *vs,
1104 24236869 bellard
                             int bits_per_pixel, int depth,
1105 24236869 bellard
                             int big_endian_flag, int true_color_flag,
1106 24236869 bellard
                             int red_max, int green_max, int blue_max,
1107 24236869 bellard
                             int red_shift, int green_shift, int blue_shift)
1108 24236869 bellard
{
1109 3512779a bellard
    int host_big_endian_flag;
1110 24236869 bellard
1111 3512779a bellard
#ifdef WORDS_BIGENDIAN
1112 3512779a bellard
    host_big_endian_flag = 1;
1113 3512779a bellard
#else
1114 3512779a bellard
    host_big_endian_flag = 0;
1115 3512779a bellard
#endif
1116 3512779a bellard
    if (!true_color_flag) {
1117 3512779a bellard
    fail:
1118 24236869 bellard
        vnc_client_error(vs);
1119 3512779a bellard
        return;
1120 3512779a bellard
    }
1121 5fafdf24 ths
    if (bits_per_pixel == 32 &&
1122 3512779a bellard
        host_big_endian_flag == big_endian_flag &&
1123 3512779a bellard
        red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1124 3512779a bellard
        red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1125 3512779a bellard
        vs->depth = 4;
1126 3512779a bellard
        vs->write_pixels = vnc_write_pixels_copy;
1127 3512779a bellard
        vs->send_hextile_tile = send_hextile_tile_32;
1128 5fafdf24 ths
    } else
1129 5fafdf24 ths
    if (bits_per_pixel == 16 &&
1130 3512779a bellard
        host_big_endian_flag == big_endian_flag &&
1131 3512779a bellard
        red_max == 31 && green_max == 63 && blue_max == 31 &&
1132 3512779a bellard
        red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1133 3512779a bellard
        vs->depth = 2;
1134 3512779a bellard
        vs->write_pixels = vnc_write_pixels_copy;
1135 3512779a bellard
        vs->send_hextile_tile = send_hextile_tile_16;
1136 5fafdf24 ths
    } else
1137 5fafdf24 ths
    if (bits_per_pixel == 8 &&
1138 3512779a bellard
        red_max == 7 && green_max == 7 && blue_max == 3 &&
1139 3512779a bellard
        red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1140 3512779a bellard
        vs->depth = 1;
1141 3512779a bellard
        vs->write_pixels = vnc_write_pixels_copy;
1142 3512779a bellard
        vs->send_hextile_tile = send_hextile_tile_8;
1143 5fafdf24 ths
    } else
1144 3512779a bellard
    {
1145 3512779a bellard
        /* generic and slower case */
1146 3512779a bellard
        if (bits_per_pixel != 8 &&
1147 3512779a bellard
            bits_per_pixel != 16 &&
1148 3512779a bellard
            bits_per_pixel != 32)
1149 3512779a bellard
            goto fail;
1150 3512779a bellard
        vs->depth = 4;
1151 3512779a bellard
        vs->red_shift = red_shift;
1152 3512779a bellard
        vs->red_max = red_max;
1153 3512779a bellard
        vs->red_shift1 = 24 - compute_nbits(red_max);
1154 3512779a bellard
        vs->green_shift = green_shift;
1155 3512779a bellard
        vs->green_max = green_max;
1156 3512779a bellard
        vs->green_shift1 = 16 - compute_nbits(green_max);
1157 3512779a bellard
        vs->blue_shift = blue_shift;
1158 3512779a bellard
        vs->blue_max = blue_max;
1159 3512779a bellard
        vs->blue_shift1 = 8 - compute_nbits(blue_max);
1160 3512779a bellard
        vs->pix_bpp = bits_per_pixel / 8;
1161 3512779a bellard
        vs->pix_big_endian = big_endian_flag;
1162 3512779a bellard
        vs->write_pixels = vnc_write_pixels_generic;
1163 3512779a bellard
        vs->send_hextile_tile = send_hextile_tile_generic;
1164 3512779a bellard
    }
1165 24236869 bellard
1166 24236869 bellard
    vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1167 24236869 bellard
    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1168 24236869 bellard
    memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
1169 24236869 bellard
1170 24236869 bellard
    vga_hw_invalidate();
1171 24236869 bellard
    vga_hw_update();
1172 24236869 bellard
}
1173 24236869 bellard
1174 24236869 bellard
static int protocol_client_msg(VncState *vs, char *data, size_t len)
1175 24236869 bellard
{
1176 24236869 bellard
    int i;
1177 24236869 bellard
    uint16_t limit;
1178 24236869 bellard
1179 24236869 bellard
    switch (data[0]) {
1180 24236869 bellard
    case 0:
1181 24236869 bellard
        if (len == 1)
1182 24236869 bellard
            return 20;
1183 24236869 bellard
1184 24236869 bellard
        set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1185 24236869 bellard
                         read_u8(data, 6), read_u8(data, 7),
1186 24236869 bellard
                         read_u16(data, 8), read_u16(data, 10),
1187 24236869 bellard
                         read_u16(data, 12), read_u8(data, 14),
1188 24236869 bellard
                         read_u8(data, 15), read_u8(data, 16));
1189 24236869 bellard
        break;
1190 24236869 bellard
    case 2:
1191 24236869 bellard
        if (len == 1)
1192 24236869 bellard
            return 4;
1193 24236869 bellard
1194 24236869 bellard
        if (len == 4)
1195 24236869 bellard
            return 4 + (read_u16(data, 2) * 4);
1196 24236869 bellard
1197 24236869 bellard
        limit = read_u16(data, 2);
1198 24236869 bellard
        for (i = 0; i < limit; i++) {
1199 24236869 bellard
            int32_t val = read_s32(data, 4 + (i * 4));
1200 24236869 bellard
            memcpy(data + 4 + (i * 4), &val, sizeof(val));
1201 24236869 bellard
        }
1202 24236869 bellard
1203 24236869 bellard
        set_encodings(vs, (int32_t *)(data + 4), limit);
1204 24236869 bellard
        break;
1205 24236869 bellard
    case 3:
1206 24236869 bellard
        if (len == 1)
1207 24236869 bellard
            return 10;
1208 24236869 bellard
1209 24236869 bellard
        framebuffer_update_request(vs,
1210 24236869 bellard
                                   read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1211 24236869 bellard
                                   read_u16(data, 6), read_u16(data, 8));
1212 24236869 bellard
        break;
1213 24236869 bellard
    case 4:
1214 24236869 bellard
        if (len == 1)
1215 24236869 bellard
            return 8;
1216 24236869 bellard
1217 24236869 bellard
        key_event(vs, read_u8(data, 1), read_u32(data, 4));
1218 24236869 bellard
        break;
1219 24236869 bellard
    case 5:
1220 24236869 bellard
        if (len == 1)
1221 24236869 bellard
            return 6;
1222 24236869 bellard
1223 24236869 bellard
        pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1224 24236869 bellard
        break;
1225 24236869 bellard
    case 6:
1226 24236869 bellard
        if (len == 1)
1227 24236869 bellard
            return 8;
1228 24236869 bellard
1229 baa7666c ths
        if (len == 8) {
1230 baa7666c ths
            uint32_t dlen = read_u32(data, 4);
1231 baa7666c ths
            if (dlen > 0)
1232 baa7666c ths
                return 8 + dlen;
1233 baa7666c ths
        }
1234 24236869 bellard
1235 24236869 bellard
        client_cut_text(vs, read_u32(data, 4), data + 8);
1236 24236869 bellard
        break;
1237 24236869 bellard
    default:
1238 24236869 bellard
        printf("Msg: %d\n", data[0]);
1239 24236869 bellard
        vnc_client_error(vs);
1240 24236869 bellard
        break;
1241 24236869 bellard
    }
1242 5fafdf24 ths
1243 24236869 bellard
    vnc_read_when(vs, protocol_client_msg, 1);
1244 24236869 bellard
    return 0;
1245 24236869 bellard
}
1246 24236869 bellard
1247 24236869 bellard
static int protocol_client_init(VncState *vs, char *data, size_t len)
1248 24236869 bellard
{
1249 24236869 bellard
    char pad[3] = { 0, 0, 0 };
1250 c35734b2 ths
    char buf[1024];
1251 c35734b2 ths
    int size;
1252 24236869 bellard
1253 24236869 bellard
    vs->width = vs->ds->width;
1254 24236869 bellard
    vs->height = vs->ds->height;
1255 24236869 bellard
    vnc_write_u16(vs, vs->ds->width);
1256 24236869 bellard
    vnc_write_u16(vs, vs->ds->height);
1257 24236869 bellard
1258 24236869 bellard
    vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1259 24236869 bellard
    vnc_write_u8(vs, vs->depth * 8); /* depth */
1260 3512779a bellard
#ifdef WORDS_BIGENDIAN
1261 3512779a bellard
    vnc_write_u8(vs, 1);             /* big-endian-flag */
1262 3512779a bellard
#else
1263 24236869 bellard
    vnc_write_u8(vs, 0);             /* big-endian-flag */
1264 3512779a bellard
#endif
1265 24236869 bellard
    vnc_write_u8(vs, 1);             /* true-color-flag */
1266 24236869 bellard
    if (vs->depth == 4) {
1267 24236869 bellard
        vnc_write_u16(vs, 0xFF);     /* red-max */
1268 24236869 bellard
        vnc_write_u16(vs, 0xFF);     /* green-max */
1269 24236869 bellard
        vnc_write_u16(vs, 0xFF);     /* blue-max */
1270 24236869 bellard
        vnc_write_u8(vs, 16);        /* red-shift */
1271 24236869 bellard
        vnc_write_u8(vs, 8);         /* green-shift */
1272 24236869 bellard
        vnc_write_u8(vs, 0);         /* blue-shift */
1273 3512779a bellard
        vs->send_hextile_tile = send_hextile_tile_32;
1274 24236869 bellard
    } else if (vs->depth == 2) {
1275 24236869 bellard
        vnc_write_u16(vs, 31);       /* red-max */
1276 24236869 bellard
        vnc_write_u16(vs, 63);       /* green-max */
1277 24236869 bellard
        vnc_write_u16(vs, 31);       /* blue-max */
1278 24236869 bellard
        vnc_write_u8(vs, 11);        /* red-shift */
1279 24236869 bellard
        vnc_write_u8(vs, 5);         /* green-shift */
1280 24236869 bellard
        vnc_write_u8(vs, 0);         /* blue-shift */
1281 3512779a bellard
        vs->send_hextile_tile = send_hextile_tile_16;
1282 24236869 bellard
    } else if (vs->depth == 1) {
1283 3512779a bellard
        /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1284 3512779a bellard
        vnc_write_u16(vs, 7);        /* red-max */
1285 24236869 bellard
        vnc_write_u16(vs, 7);        /* green-max */
1286 24236869 bellard
        vnc_write_u16(vs, 3);        /* blue-max */
1287 24236869 bellard
        vnc_write_u8(vs, 5);         /* red-shift */
1288 24236869 bellard
        vnc_write_u8(vs, 2);         /* green-shift */
1289 24236869 bellard
        vnc_write_u8(vs, 0);         /* blue-shift */
1290 3512779a bellard
        vs->send_hextile_tile = send_hextile_tile_8;
1291 24236869 bellard
    }
1292 3512779a bellard
    vs->write_pixels = vnc_write_pixels_copy;
1293 5fafdf24 ths
1294 24236869 bellard
    vnc_write(vs, pad, 3);           /* padding */
1295 24236869 bellard
1296 c35734b2 ths
    if (qemu_name)
1297 c35734b2 ths
        size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1298 c35734b2 ths
    else
1299 c35734b2 ths
        size = snprintf(buf, sizeof(buf), "QEMU");
1300 c35734b2 ths
1301 c35734b2 ths
    vnc_write_u32(vs, size);
1302 c35734b2 ths
    vnc_write(vs, buf, size);
1303 24236869 bellard
    vnc_flush(vs);
1304 24236869 bellard
1305 24236869 bellard
    vnc_read_when(vs, protocol_client_msg, 1);
1306 24236869 bellard
1307 24236869 bellard
    return 0;
1308 24236869 bellard
}
1309 24236869 bellard
1310 70848515 ths
static void make_challenge(VncState *vs)
1311 70848515 ths
{
1312 70848515 ths
    int i;
1313 70848515 ths
1314 70848515 ths
    srand(time(NULL)+getpid()+getpid()*987654+rand());
1315 70848515 ths
1316 70848515 ths
    for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1317 70848515 ths
        vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1318 70848515 ths
}
1319 70848515 ths
1320 70848515 ths
static int protocol_client_auth_vnc(VncState *vs, char *data, size_t len)
1321 70848515 ths
{
1322 70848515 ths
    char response[VNC_AUTH_CHALLENGE_SIZE];
1323 70848515 ths
    int i, j, pwlen;
1324 70848515 ths
    char key[8];
1325 70848515 ths
1326 70848515 ths
    if (!vs->password || !vs->password[0]) {
1327 70848515 ths
        VNC_DEBUG("No password configured on server");
1328 70848515 ths
        vnc_write_u32(vs, 1); /* Reject auth */
1329 70848515 ths
        if (vs->minor >= 8) {
1330 70848515 ths
            static const char err[] = "Authentication failed";
1331 70848515 ths
            vnc_write_u32(vs, sizeof(err));
1332 70848515 ths
            vnc_write(vs, err, sizeof(err));
1333 70848515 ths
        }
1334 70848515 ths
        vnc_flush(vs);
1335 70848515 ths
        vnc_client_error(vs);
1336 70848515 ths
        return 0;
1337 70848515 ths
    }
1338 70848515 ths
1339 70848515 ths
    memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1340 70848515 ths
1341 70848515 ths
    /* Calculate the expected challenge response */
1342 70848515 ths
    pwlen = strlen(vs->password);
1343 70848515 ths
    for (i=0; i<sizeof(key); i++)
1344 70848515 ths
        key[i] = i<pwlen ? vs->password[i] : 0;
1345 70848515 ths
    deskey(key, EN0);
1346 70848515 ths
    for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1347 70848515 ths
        des(response+j, response+j);
1348 70848515 ths
1349 70848515 ths
    /* Compare expected vs actual challenge response */
1350 70848515 ths
    if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1351 70848515 ths
        VNC_DEBUG("Client challenge reponse did not match\n");
1352 70848515 ths
        vnc_write_u32(vs, 1); /* Reject auth */
1353 70848515 ths
        if (vs->minor >= 8) {
1354 70848515 ths
            static const char err[] = "Authentication failed";
1355 70848515 ths
            vnc_write_u32(vs, sizeof(err));
1356 70848515 ths
            vnc_write(vs, err, sizeof(err));
1357 70848515 ths
        }
1358 70848515 ths
        vnc_flush(vs);
1359 70848515 ths
        vnc_client_error(vs);
1360 70848515 ths
    } else {
1361 70848515 ths
        VNC_DEBUG("Accepting VNC challenge response\n");
1362 70848515 ths
        vnc_write_u32(vs, 0); /* Accept auth */
1363 70848515 ths
        vnc_flush(vs);
1364 70848515 ths
1365 70848515 ths
        vnc_read_when(vs, protocol_client_init, 1);
1366 70848515 ths
    }
1367 70848515 ths
    return 0;
1368 70848515 ths
}
1369 70848515 ths
1370 70848515 ths
static int start_auth_vnc(VncState *vs)
1371 70848515 ths
{
1372 70848515 ths
    make_challenge(vs);
1373 70848515 ths
    /* Send client a 'random' challenge */
1374 70848515 ths
    vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1375 70848515 ths
    vnc_flush(vs);
1376 70848515 ths
1377 70848515 ths
    vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1378 70848515 ths
    return 0;
1379 70848515 ths
}
1380 70848515 ths
1381 8d5d2d4c ths
1382 8d5d2d4c ths
#if CONFIG_VNC_TLS
1383 8d5d2d4c ths
#define DH_BITS 1024
1384 8d5d2d4c ths
static gnutls_dh_params_t dh_params;
1385 8d5d2d4c ths
1386 8d5d2d4c ths
static int vnc_tls_initialize(void)
1387 8d5d2d4c ths
{
1388 8d5d2d4c ths
    static int tlsinitialized = 0;
1389 8d5d2d4c ths
1390 8d5d2d4c ths
    if (tlsinitialized)
1391 8d5d2d4c ths
        return 1;
1392 8d5d2d4c ths
1393 8d5d2d4c ths
    if (gnutls_global_init () < 0)
1394 8d5d2d4c ths
        return 0;
1395 8d5d2d4c ths
1396 8d5d2d4c ths
    /* XXX ought to re-generate diffie-hellmen params periodically */
1397 8d5d2d4c ths
    if (gnutls_dh_params_init (&dh_params) < 0)
1398 8d5d2d4c ths
        return 0;
1399 8d5d2d4c ths
    if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1400 8d5d2d4c ths
        return 0;
1401 8d5d2d4c ths
1402 8d5d2d4c ths
#if _VNC_DEBUG == 2
1403 8d5d2d4c ths
    gnutls_global_set_log_level(10);
1404 8d5d2d4c ths
    gnutls_global_set_log_function(vnc_debug_gnutls_log);
1405 8d5d2d4c ths
#endif
1406 8d5d2d4c ths
1407 8d5d2d4c ths
    tlsinitialized = 1;
1408 8d5d2d4c ths
1409 8d5d2d4c ths
    return 1;
1410 8d5d2d4c ths
}
1411 8d5d2d4c ths
1412 8d5d2d4c ths
static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1413 8d5d2d4c ths
{
1414 8d5d2d4c ths
    gnutls_anon_server_credentials anon_cred;
1415 8d5d2d4c ths
    int ret;
1416 8d5d2d4c ths
1417 8d5d2d4c ths
    if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1418 8d5d2d4c ths
        VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1419 8d5d2d4c ths
        return NULL;
1420 8d5d2d4c ths
    }
1421 8d5d2d4c ths
1422 8d5d2d4c ths
    gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1423 8d5d2d4c ths
1424 8d5d2d4c ths
    return anon_cred;
1425 8d5d2d4c ths
}
1426 8d5d2d4c ths
1427 8d5d2d4c ths
1428 6f43024c ths
static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1429 3a702699 ths
{
1430 3a702699 ths
    gnutls_certificate_credentials_t x509_cred;
1431 3a702699 ths
    int ret;
1432 6f43024c ths
1433 6f43024c ths
    if (!vs->x509cacert) {
1434 6f43024c ths
        VNC_DEBUG("No CA x509 certificate specified\n");
1435 6f43024c ths
        return NULL;
1436 6f43024c ths
    }
1437 6f43024c ths
    if (!vs->x509cert) {
1438 6f43024c ths
        VNC_DEBUG("No server x509 certificate specified\n");
1439 6f43024c ths
        return NULL;
1440 6f43024c ths
    }
1441 6f43024c ths
    if (!vs->x509key) {
1442 6f43024c ths
        VNC_DEBUG("No server private key specified\n");
1443 6f43024c ths
        return NULL;
1444 6f43024c ths
    }
1445 3a702699 ths
1446 3a702699 ths
    if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1447 3a702699 ths
        VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1448 3a702699 ths
        return NULL;
1449 3a702699 ths
    }
1450 6f43024c ths
    if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1451 6f43024c ths
                                                      vs->x509cacert,
1452 6f43024c ths
                                                      GNUTLS_X509_FMT_PEM)) < 0) {
1453 3a702699 ths
        VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1454 3a702699 ths
        gnutls_certificate_free_credentials(x509_cred);
1455 3a702699 ths
        return NULL;
1456 3a702699 ths
    }
1457 3a702699 ths
1458 6f43024c ths
    if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1459 6f43024c ths
                                                     vs->x509cert,
1460 6f43024c ths
                                                     vs->x509key,
1461 3a702699 ths
                                                     GNUTLS_X509_FMT_PEM)) < 0) {
1462 3a702699 ths
        VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1463 3a702699 ths
        gnutls_certificate_free_credentials(x509_cred);
1464 3a702699 ths
        return NULL;
1465 3a702699 ths
    }
1466 3a702699 ths
1467 6f43024c ths
    if (vs->x509cacrl) {
1468 6f43024c ths
        if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1469 6f43024c ths
                                                        vs->x509cacrl,
1470 6f43024c ths
                                                        GNUTLS_X509_FMT_PEM)) < 0) {
1471 3a702699 ths
            VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1472 3a702699 ths
            gnutls_certificate_free_credentials(x509_cred);
1473 3a702699 ths
            return NULL;
1474 3a702699 ths
        }
1475 3a702699 ths
    }
1476 3a702699 ths
1477 3a702699 ths
    gnutls_certificate_set_dh_params (x509_cred, dh_params);
1478 3a702699 ths
1479 3a702699 ths
    return x509_cred;
1480 3a702699 ths
}
1481 3a702699 ths
1482 469b15c6 ths
static int vnc_validate_certificate(struct VncState *vs)
1483 469b15c6 ths
{
1484 469b15c6 ths
    int ret;
1485 469b15c6 ths
    unsigned int status;
1486 469b15c6 ths
    const gnutls_datum_t *certs;
1487 469b15c6 ths
    unsigned int nCerts, i;
1488 469b15c6 ths
    time_t now;
1489 469b15c6 ths
1490 469b15c6 ths
    VNC_DEBUG("Validating client certificate\n");
1491 469b15c6 ths
    if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1492 469b15c6 ths
        VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1493 469b15c6 ths
        return -1;
1494 469b15c6 ths
    }
1495 469b15c6 ths
1496 469b15c6 ths
    if ((now = time(NULL)) == ((time_t)-1)) {
1497 469b15c6 ths
        return -1;
1498 469b15c6 ths
    }
1499 469b15c6 ths
1500 469b15c6 ths
    if (status != 0) {
1501 469b15c6 ths
        if (status & GNUTLS_CERT_INVALID)
1502 469b15c6 ths
            VNC_DEBUG("The certificate is not trusted.\n");
1503 469b15c6 ths
1504 469b15c6 ths
        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1505 469b15c6 ths
            VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1506 469b15c6 ths
1507 469b15c6 ths
        if (status & GNUTLS_CERT_REVOKED)
1508 469b15c6 ths
            VNC_DEBUG("The certificate has been revoked.\n");
1509 469b15c6 ths
1510 469b15c6 ths
        if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1511 469b15c6 ths
            VNC_DEBUG("The certificate uses an insecure algorithm\n");
1512 469b15c6 ths
1513 469b15c6 ths
        return -1;
1514 469b15c6 ths
    } else {
1515 469b15c6 ths
        VNC_DEBUG("Certificate is valid!\n");
1516 469b15c6 ths
    }
1517 469b15c6 ths
1518 469b15c6 ths
    /* Only support x509 for now */
1519 469b15c6 ths
    if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1520 469b15c6 ths
        return -1;
1521 469b15c6 ths
1522 469b15c6 ths
    if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1523 469b15c6 ths
        return -1;
1524 469b15c6 ths
1525 469b15c6 ths
    for (i = 0 ; i < nCerts ; i++) {
1526 469b15c6 ths
        gnutls_x509_crt_t cert;
1527 469b15c6 ths
        VNC_DEBUG ("Checking certificate chain %d\n", i);
1528 469b15c6 ths
        if (gnutls_x509_crt_init (&cert) < 0)
1529 469b15c6 ths
            return -1;
1530 469b15c6 ths
1531 469b15c6 ths
        if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1532 469b15c6 ths
            gnutls_x509_crt_deinit (cert);
1533 469b15c6 ths
            return -1;
1534 469b15c6 ths
        }
1535 469b15c6 ths
1536 469b15c6 ths
        if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1537 469b15c6 ths
            VNC_DEBUG("The certificate has expired\n");
1538 469b15c6 ths
            gnutls_x509_crt_deinit (cert);
1539 469b15c6 ths
            return -1;
1540 469b15c6 ths
        }
1541 469b15c6 ths
1542 469b15c6 ths
        if (gnutls_x509_crt_get_activation_time (cert) > now) {
1543 469b15c6 ths
            VNC_DEBUG("The certificate is not yet activated\n");
1544 469b15c6 ths
            gnutls_x509_crt_deinit (cert);
1545 469b15c6 ths
            return -1;
1546 469b15c6 ths
        }
1547 469b15c6 ths
1548 469b15c6 ths
        if (gnutls_x509_crt_get_activation_time (cert) > now) {
1549 469b15c6 ths
            VNC_DEBUG("The certificate is not yet activated\n");
1550 469b15c6 ths
            gnutls_x509_crt_deinit (cert);
1551 469b15c6 ths
            return -1;
1552 469b15c6 ths
        }
1553 469b15c6 ths
1554 469b15c6 ths
        gnutls_x509_crt_deinit (cert);
1555 469b15c6 ths
    }
1556 469b15c6 ths
1557 469b15c6 ths
    return 0;
1558 469b15c6 ths
}
1559 469b15c6 ths
1560 469b15c6 ths
1561 8d5d2d4c ths
static int start_auth_vencrypt_subauth(VncState *vs)
1562 8d5d2d4c ths
{
1563 8d5d2d4c ths
    switch (vs->subauth) {
1564 8d5d2d4c ths
    case VNC_AUTH_VENCRYPT_TLSNONE:
1565 3a702699 ths
    case VNC_AUTH_VENCRYPT_X509NONE:
1566 8d5d2d4c ths
       VNC_DEBUG("Accept TLS auth none\n");
1567 8d5d2d4c ths
       vnc_write_u32(vs, 0); /* Accept auth completion */
1568 8d5d2d4c ths
       vnc_read_when(vs, protocol_client_init, 1);
1569 8d5d2d4c ths
       break;
1570 8d5d2d4c ths
1571 8d5d2d4c ths
    case VNC_AUTH_VENCRYPT_TLSVNC:
1572 3a702699 ths
    case VNC_AUTH_VENCRYPT_X509VNC:
1573 8d5d2d4c ths
       VNC_DEBUG("Start TLS auth VNC\n");
1574 8d5d2d4c ths
       return start_auth_vnc(vs);
1575 8d5d2d4c ths
1576 8d5d2d4c ths
    default: /* Should not be possible, but just in case */
1577 8d5d2d4c ths
       VNC_DEBUG("Reject auth %d\n", vs->auth);
1578 8d5d2d4c ths
       vnc_write_u8(vs, 1);
1579 8d5d2d4c ths
       if (vs->minor >= 8) {
1580 8d5d2d4c ths
           static const char err[] = "Unsupported authentication type";
1581 8d5d2d4c ths
           vnc_write_u32(vs, sizeof(err));
1582 8d5d2d4c ths
           vnc_write(vs, err, sizeof(err));
1583 8d5d2d4c ths
       }
1584 8d5d2d4c ths
       vnc_client_error(vs);
1585 8d5d2d4c ths
    }
1586 8d5d2d4c ths
1587 8d5d2d4c ths
    return 0;
1588 8d5d2d4c ths
}
1589 8d5d2d4c ths
1590 8d5d2d4c ths
static void vnc_handshake_io(void *opaque);
1591 8d5d2d4c ths
1592 8d5d2d4c ths
static int vnc_continue_handshake(struct VncState *vs) {
1593 8d5d2d4c ths
    int ret;
1594 8d5d2d4c ths
1595 8d5d2d4c ths
    if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1596 8d5d2d4c ths
       if (!gnutls_error_is_fatal(ret)) {
1597 8d5d2d4c ths
           VNC_DEBUG("Handshake interrupted (blocking)\n");
1598 8d5d2d4c ths
           if (!gnutls_record_get_direction(vs->tls_session))
1599 8d5d2d4c ths
               qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1600 8d5d2d4c ths
           else
1601 8d5d2d4c ths
               qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1602 8d5d2d4c ths
           return 0;
1603 8d5d2d4c ths
       }
1604 8d5d2d4c ths
       VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1605 8d5d2d4c ths
       vnc_client_error(vs);
1606 8d5d2d4c ths
       return -1;
1607 8d5d2d4c ths
    }
1608 8d5d2d4c ths
1609 469b15c6 ths
    if (vs->x509verify) {
1610 469b15c6 ths
        if (vnc_validate_certificate(vs) < 0) {
1611 469b15c6 ths
            VNC_DEBUG("Client verification failed\n");
1612 469b15c6 ths
            vnc_client_error(vs);
1613 469b15c6 ths
            return -1;
1614 469b15c6 ths
        } else {
1615 469b15c6 ths
            VNC_DEBUG("Client verification passed\n");
1616 469b15c6 ths
        }
1617 469b15c6 ths
    }
1618 469b15c6 ths
1619 8d5d2d4c ths
    VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1620 8d5d2d4c ths
    vs->wiremode = VNC_WIREMODE_TLS;
1621 8d5d2d4c ths
    qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1622 8d5d2d4c ths
1623 8d5d2d4c ths
    return start_auth_vencrypt_subauth(vs);
1624 8d5d2d4c ths
}
1625 8d5d2d4c ths
1626 8d5d2d4c ths
static void vnc_handshake_io(void *opaque) {
1627 8d5d2d4c ths
    struct VncState *vs = (struct VncState *)opaque;
1628 8d5d2d4c ths
1629 8d5d2d4c ths
    VNC_DEBUG("Handshake IO continue\n");
1630 8d5d2d4c ths
    vnc_continue_handshake(vs);
1631 8d5d2d4c ths
}
1632 8d5d2d4c ths
1633 3a702699 ths
#define NEED_X509_AUTH(vs)                              \
1634 3a702699 ths
    ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
1635 3a702699 ths
     (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
1636 3a702699 ths
     (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1637 3a702699 ths
1638 3a702699 ths
1639 8d5d2d4c ths
static int vnc_start_tls(struct VncState *vs) {
1640 8d5d2d4c ths
    static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1641 8d5d2d4c ths
    static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1642 8d5d2d4c ths
    static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1643 3a702699 ths
    static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1644 8d5d2d4c ths
1645 8d5d2d4c ths
    VNC_DEBUG("Do TLS setup\n");
1646 8d5d2d4c ths
    if (vnc_tls_initialize() < 0) {
1647 8d5d2d4c ths
        VNC_DEBUG("Failed to init TLS\n");
1648 8d5d2d4c ths
        vnc_client_error(vs);
1649 8d5d2d4c ths
        return -1;
1650 8d5d2d4c ths
    }
1651 8d5d2d4c ths
    if (vs->tls_session == NULL) {
1652 8d5d2d4c ths
        if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1653 8d5d2d4c ths
            vnc_client_error(vs);
1654 8d5d2d4c ths
            return -1;
1655 8d5d2d4c ths
        }
1656 8d5d2d4c ths
1657 8d5d2d4c ths
        if (gnutls_set_default_priority(vs->tls_session) < 0) {
1658 8d5d2d4c ths
            gnutls_deinit(vs->tls_session);
1659 8d5d2d4c ths
            vs->tls_session = NULL;
1660 8d5d2d4c ths
            vnc_client_error(vs);
1661 8d5d2d4c ths
            return -1;
1662 8d5d2d4c ths
        }
1663 8d5d2d4c ths
1664 3a702699 ths
        if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1665 8d5d2d4c ths
            gnutls_deinit(vs->tls_session);
1666 8d5d2d4c ths
            vs->tls_session = NULL;
1667 8d5d2d4c ths
            vnc_client_error(vs);
1668 8d5d2d4c ths
            return -1;
1669 8d5d2d4c ths
        }
1670 8d5d2d4c ths
1671 8d5d2d4c ths
        if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1672 8d5d2d4c ths
            gnutls_deinit(vs->tls_session);
1673 8d5d2d4c ths
            vs->tls_session = NULL;
1674 8d5d2d4c ths
            vnc_client_error(vs);
1675 8d5d2d4c ths
            return -1;
1676 8d5d2d4c ths
        }
1677 8d5d2d4c ths
1678 8d5d2d4c ths
        if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1679 8d5d2d4c ths
            gnutls_deinit(vs->tls_session);
1680 8d5d2d4c ths
            vs->tls_session = NULL;
1681 8d5d2d4c ths
            vnc_client_error(vs);
1682 8d5d2d4c ths
            return -1;
1683 8d5d2d4c ths
        }
1684 8d5d2d4c ths
1685 3a702699 ths
        if (NEED_X509_AUTH(vs)) {
1686 6f43024c ths
            gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1687 3a702699 ths
            if (!x509_cred) {
1688 3a702699 ths
                gnutls_deinit(vs->tls_session);
1689 3a702699 ths
                vs->tls_session = NULL;
1690 3a702699 ths
                vnc_client_error(vs);
1691 3a702699 ths
                return -1;
1692 3a702699 ths
            }
1693 3a702699 ths
            if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1694 3a702699 ths
                gnutls_deinit(vs->tls_session);
1695 3a702699 ths
                vs->tls_session = NULL;
1696 3a702699 ths
                gnutls_certificate_free_credentials(x509_cred);
1697 3a702699 ths
                vnc_client_error(vs);
1698 3a702699 ths
                return -1;
1699 3a702699 ths
            }
1700 469b15c6 ths
            if (vs->x509verify) {
1701 469b15c6 ths
                VNC_DEBUG("Requesting a client certificate\n");
1702 469b15c6 ths
                gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1703 469b15c6 ths
            }
1704 469b15c6 ths
1705 3a702699 ths
        } else {
1706 3a702699 ths
            gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1707 3a702699 ths
            if (!anon_cred) {
1708 3a702699 ths
                gnutls_deinit(vs->tls_session);
1709 3a702699 ths
                vs->tls_session = NULL;
1710 3a702699 ths
                vnc_client_error(vs);
1711 3a702699 ths
                return -1;
1712 3a702699 ths
            }
1713 3a702699 ths
            if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1714 3a702699 ths
                gnutls_deinit(vs->tls_session);
1715 3a702699 ths
                vs->tls_session = NULL;
1716 3a702699 ths
                gnutls_anon_free_server_credentials(anon_cred);
1717 3a702699 ths
                vnc_client_error(vs);
1718 3a702699 ths
                return -1;
1719 3a702699 ths
            }
1720 8d5d2d4c ths
        }
1721 8d5d2d4c ths
1722 8d5d2d4c ths
        gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1723 8d5d2d4c ths
        gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1724 8d5d2d4c ths
        gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1725 8d5d2d4c ths
    }
1726 8d5d2d4c ths
1727 8d5d2d4c ths
    VNC_DEBUG("Start TLS handshake process\n");
1728 8d5d2d4c ths
    return vnc_continue_handshake(vs);
1729 8d5d2d4c ths
}
1730 8d5d2d4c ths
1731 8d5d2d4c ths
static int protocol_client_vencrypt_auth(VncState *vs, char *data, size_t len)
1732 8d5d2d4c ths
{
1733 8d5d2d4c ths
    int auth = read_u32(data, 0);
1734 8d5d2d4c ths
1735 8d5d2d4c ths
    if (auth != vs->subauth) {
1736 8d5d2d4c ths
        VNC_DEBUG("Rejecting auth %d\n", auth);
1737 8d5d2d4c ths
        vnc_write_u8(vs, 0); /* Reject auth */
1738 8d5d2d4c ths
        vnc_flush(vs);
1739 8d5d2d4c ths
        vnc_client_error(vs);
1740 8d5d2d4c ths
    } else {
1741 8d5d2d4c ths
        VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1742 8d5d2d4c ths
        vnc_write_u8(vs, 1); /* Accept auth */
1743 8d5d2d4c ths
        vnc_flush(vs);
1744 8d5d2d4c ths
1745 8d5d2d4c ths
        if (vnc_start_tls(vs) < 0) {
1746 8d5d2d4c ths
            VNC_DEBUG("Failed to complete TLS\n");
1747 8d5d2d4c ths
            return 0;
1748 8d5d2d4c ths
        }
1749 8d5d2d4c ths
1750 8d5d2d4c ths
        if (vs->wiremode == VNC_WIREMODE_TLS) {
1751 8d5d2d4c ths
            VNC_DEBUG("Starting VeNCrypt subauth\n");
1752 8d5d2d4c ths
            return start_auth_vencrypt_subauth(vs);
1753 8d5d2d4c ths
        } else {
1754 8d5d2d4c ths
            VNC_DEBUG("TLS handshake blocked\n");
1755 8d5d2d4c ths
            return 0;
1756 8d5d2d4c ths
        }
1757 8d5d2d4c ths
    }
1758 8d5d2d4c ths
    return 0;
1759 8d5d2d4c ths
}
1760 8d5d2d4c ths
1761 8d5d2d4c ths
static int protocol_client_vencrypt_init(VncState *vs, char *data, size_t len)
1762 8d5d2d4c ths
{
1763 8d5d2d4c ths
    if (data[0] != 0 ||
1764 8d5d2d4c ths
        data[1] != 2) {
1765 8d5d2d4c ths
        VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1766 8d5d2d4c ths
        vnc_write_u8(vs, 1); /* Reject version */
1767 8d5d2d4c ths
        vnc_flush(vs);
1768 8d5d2d4c ths
        vnc_client_error(vs);
1769 8d5d2d4c ths
    } else {
1770 8d5d2d4c ths
        VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1771 8d5d2d4c ths
        vnc_write_u8(vs, 0); /* Accept version */
1772 8d5d2d4c ths
        vnc_write_u8(vs, 1); /* Number of sub-auths */
1773 8d5d2d4c ths
        vnc_write_u32(vs, vs->subauth); /* The supported auth */
1774 8d5d2d4c ths
        vnc_flush(vs);
1775 8d5d2d4c ths
        vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1776 8d5d2d4c ths
    }
1777 8d5d2d4c ths
    return 0;
1778 8d5d2d4c ths
}
1779 8d5d2d4c ths
1780 8d5d2d4c ths
static int start_auth_vencrypt(VncState *vs)
1781 8d5d2d4c ths
{
1782 8d5d2d4c ths
    /* Send VeNCrypt version 0.2 */
1783 8d5d2d4c ths
    vnc_write_u8(vs, 0);
1784 8d5d2d4c ths
    vnc_write_u8(vs, 2);
1785 8d5d2d4c ths
1786 8d5d2d4c ths
    vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1787 8d5d2d4c ths
    return 0;
1788 8d5d2d4c ths
}
1789 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
1790 8d5d2d4c ths
1791 70848515 ths
static int protocol_client_auth(VncState *vs, char *data, size_t len)
1792 70848515 ths
{
1793 70848515 ths
    /* We only advertise 1 auth scheme at a time, so client
1794 70848515 ths
     * must pick the one we sent. Verify this */
1795 70848515 ths
    if (data[0] != vs->auth) { /* Reject auth */
1796 70848515 ths
       VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1797 70848515 ths
       vnc_write_u32(vs, 1);
1798 70848515 ths
       if (vs->minor >= 8) {
1799 70848515 ths
           static const char err[] = "Authentication failed";
1800 70848515 ths
           vnc_write_u32(vs, sizeof(err));
1801 70848515 ths
           vnc_write(vs, err, sizeof(err));
1802 70848515 ths
       }
1803 70848515 ths
       vnc_client_error(vs);
1804 70848515 ths
    } else { /* Accept requested auth */
1805 70848515 ths
       VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1806 70848515 ths
       switch (vs->auth) {
1807 70848515 ths
       case VNC_AUTH_NONE:
1808 70848515 ths
           VNC_DEBUG("Accept auth none\n");
1809 a26c97ad balrog
           if (vs->minor >= 8) {
1810 a26c97ad balrog
               vnc_write_u32(vs, 0); /* Accept auth completion */
1811 a26c97ad balrog
               vnc_flush(vs);
1812 a26c97ad balrog
           }
1813 70848515 ths
           vnc_read_when(vs, protocol_client_init, 1);
1814 70848515 ths
           break;
1815 70848515 ths
1816 70848515 ths
       case VNC_AUTH_VNC:
1817 70848515 ths
           VNC_DEBUG("Start VNC auth\n");
1818 70848515 ths
           return start_auth_vnc(vs);
1819 70848515 ths
1820 8d5d2d4c ths
#if CONFIG_VNC_TLS
1821 8d5d2d4c ths
       case VNC_AUTH_VENCRYPT:
1822 8d5d2d4c ths
           VNC_DEBUG("Accept VeNCrypt auth\n");;
1823 8d5d2d4c ths
           return start_auth_vencrypt(vs);
1824 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
1825 8d5d2d4c ths
1826 70848515 ths
       default: /* Should not be possible, but just in case */
1827 70848515 ths
           VNC_DEBUG("Reject auth %d\n", vs->auth);
1828 70848515 ths
           vnc_write_u8(vs, 1);
1829 70848515 ths
           if (vs->minor >= 8) {
1830 70848515 ths
               static const char err[] = "Authentication failed";
1831 70848515 ths
               vnc_write_u32(vs, sizeof(err));
1832 70848515 ths
               vnc_write(vs, err, sizeof(err));
1833 70848515 ths
           }
1834 70848515 ths
           vnc_client_error(vs);
1835 70848515 ths
       }
1836 70848515 ths
    }
1837 70848515 ths
    return 0;
1838 70848515 ths
}
1839 70848515 ths
1840 24236869 bellard
static int protocol_version(VncState *vs, char *version, size_t len)
1841 24236869 bellard
{
1842 24236869 bellard
    char local[13];
1843 24236869 bellard
1844 24236869 bellard
    memcpy(local, version, 12);
1845 24236869 bellard
    local[12] = 0;
1846 24236869 bellard
1847 70848515 ths
    if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1848 70848515 ths
        VNC_DEBUG("Malformed protocol version %s\n", local);
1849 24236869 bellard
        vnc_client_error(vs);
1850 24236869 bellard
        return 0;
1851 24236869 bellard
    }
1852 70848515 ths
    VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1853 70848515 ths
    if (vs->major != 3 ||
1854 70848515 ths
        (vs->minor != 3 &&
1855 b0566f4f ths
         vs->minor != 4 &&
1856 70848515 ths
         vs->minor != 5 &&
1857 70848515 ths
         vs->minor != 7 &&
1858 70848515 ths
         vs->minor != 8)) {
1859 70848515 ths
        VNC_DEBUG("Unsupported client version\n");
1860 70848515 ths
        vnc_write_u32(vs, VNC_AUTH_INVALID);
1861 70848515 ths
        vnc_flush(vs);
1862 70848515 ths
        vnc_client_error(vs);
1863 70848515 ths
        return 0;
1864 70848515 ths
    }
1865 b0566f4f ths
    /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1866 70848515 ths
     * as equivalent to v3.3 by servers
1867 70848515 ths
     */
1868 b0566f4f ths
    if (vs->minor == 4 || vs->minor == 5)
1869 70848515 ths
        vs->minor = 3;
1870 70848515 ths
1871 70848515 ths
    if (vs->minor == 3) {
1872 70848515 ths
        if (vs->auth == VNC_AUTH_NONE) {
1873 70848515 ths
            VNC_DEBUG("Tell client auth none\n");
1874 70848515 ths
            vnc_write_u32(vs, vs->auth);
1875 70848515 ths
            vnc_flush(vs);
1876 70848515 ths
            vnc_read_when(vs, protocol_client_init, 1);
1877 70848515 ths
       } else if (vs->auth == VNC_AUTH_VNC) {
1878 70848515 ths
            VNC_DEBUG("Tell client VNC auth\n");
1879 70848515 ths
            vnc_write_u32(vs, vs->auth);
1880 70848515 ths
            vnc_flush(vs);
1881 70848515 ths
            start_auth_vnc(vs);
1882 70848515 ths
       } else {
1883 70848515 ths
            VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1884 70848515 ths
            vnc_write_u32(vs, VNC_AUTH_INVALID);
1885 70848515 ths
            vnc_flush(vs);
1886 70848515 ths
            vnc_client_error(vs);
1887 70848515 ths
       }
1888 70848515 ths
    } else {
1889 70848515 ths
        VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1890 70848515 ths
        vnc_write_u8(vs, 1); /* num auth */
1891 70848515 ths
        vnc_write_u8(vs, vs->auth);
1892 70848515 ths
        vnc_read_when(vs, protocol_client_auth, 1);
1893 70848515 ths
        vnc_flush(vs);
1894 70848515 ths
    }
1895 24236869 bellard
1896 24236869 bellard
    return 0;
1897 24236869 bellard
}
1898 24236869 bellard
1899 24236869 bellard
static void vnc_listen_read(void *opaque)
1900 24236869 bellard
{
1901 24236869 bellard
    VncState *vs = opaque;
1902 24236869 bellard
    struct sockaddr_in addr;
1903 24236869 bellard
    socklen_t addrlen = sizeof(addr);
1904 24236869 bellard
1905 24236869 bellard
    vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1906 24236869 bellard
    if (vs->csock != -1) {
1907 8d5d2d4c ths
        VNC_DEBUG("New client on socket %d\n", vs->csock);
1908 6ca957f0 bellard
        socket_set_nonblock(vs->csock);
1909 24236869 bellard
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
1910 70848515 ths
        vnc_write(vs, "RFB 003.008\n", 12);
1911 24236869 bellard
        vnc_flush(vs);
1912 24236869 bellard
        vnc_read_when(vs, protocol_version, 12);
1913 24236869 bellard
        memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1914 24236869 bellard
        memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1915 24236869 bellard
        vs->has_resize = 0;
1916 24236869 bellard
        vs->has_hextile = 0;
1917 24236869 bellard
        vs->ds->dpy_copy = NULL;
1918 24236869 bellard
    }
1919 24236869 bellard
}
1920 24236869 bellard
1921 73fc9742 ths
extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1922 73fc9742 ths
1923 71cab5ca ths
void vnc_display_init(DisplayState *ds)
1924 24236869 bellard
{
1925 24236869 bellard
    VncState *vs;
1926 24236869 bellard
1927 24236869 bellard
    vs = qemu_mallocz(sizeof(VncState));
1928 24236869 bellard
    if (!vs)
1929 24236869 bellard
        exit(1);
1930 24236869 bellard
1931 24236869 bellard
    ds->opaque = vs;
1932 a9ce8590 bellard
    vnc_state = vs;
1933 71cab5ca ths
    vs->display = NULL;
1934 70848515 ths
    vs->password = NULL;
1935 24236869 bellard
1936 24236869 bellard
    vs->lsock = -1;
1937 24236869 bellard
    vs->csock = -1;
1938 24236869 bellard
    vs->depth = 4;
1939 564c337e bellard
    vs->last_x = -1;
1940 564c337e bellard
    vs->last_y = -1;
1941 24236869 bellard
1942 24236869 bellard
    vs->ds = ds;
1943 24236869 bellard
1944 24236869 bellard
    if (!keyboard_layout)
1945 24236869 bellard
        keyboard_layout = "en-us";
1946 24236869 bellard
1947 24236869 bellard
    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1948 24236869 bellard
    if (!vs->kbd_layout)
1949 24236869 bellard
        exit(1);
1950 24236869 bellard
1951 73fc9742 ths
    vs->ds->data = NULL;
1952 73fc9742 ths
    vs->ds->dpy_update = vnc_dpy_update;
1953 73fc9742 ths
    vs->ds->dpy_resize = vnc_dpy_resize;
1954 73fc9742 ths
    vs->ds->dpy_refresh = vnc_dpy_refresh;
1955 73fc9742 ths
1956 73fc9742 ths
    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1957 24236869 bellard
1958 73fc9742 ths
    vnc_dpy_resize(vs->ds, 640, 400);
1959 71cab5ca ths
}
1960 71cab5ca ths
1961 6f43024c ths
#if CONFIG_VNC_TLS
1962 6f43024c ths
static int vnc_set_x509_credential(VncState *vs,
1963 6f43024c ths
                                   const char *certdir,
1964 6f43024c ths
                                   const char *filename,
1965 6f43024c ths
                                   char **cred,
1966 6f43024c ths
                                   int ignoreMissing)
1967 6f43024c ths
{
1968 6f43024c ths
    struct stat sb;
1969 6f43024c ths
1970 6f43024c ths
    if (*cred) {
1971 6f43024c ths
        qemu_free(*cred);
1972 6f43024c ths
        *cred = NULL;
1973 6f43024c ths
    }
1974 6f43024c ths
1975 6f43024c ths
    if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
1976 6f43024c ths
        return -1;
1977 6f43024c ths
1978 6f43024c ths
    strcpy(*cred, certdir);
1979 6f43024c ths
    strcat(*cred, "/");
1980 6f43024c ths
    strcat(*cred, filename);
1981 6f43024c ths
1982 6f43024c ths
    VNC_DEBUG("Check %s\n", *cred);
1983 6f43024c ths
    if (stat(*cred, &sb) < 0) {
1984 6f43024c ths
        qemu_free(*cred);
1985 6f43024c ths
        *cred = NULL;
1986 6f43024c ths
        if (ignoreMissing && errno == ENOENT)
1987 6f43024c ths
            return 0;
1988 6f43024c ths
        return -1;
1989 6f43024c ths
    }
1990 6f43024c ths
1991 6f43024c ths
    return 0;
1992 6f43024c ths
}
1993 6f43024c ths
1994 6f43024c ths
static int vnc_set_x509_credential_dir(VncState *vs,
1995 6f43024c ths
                                       const char *certdir)
1996 6f43024c ths
{
1997 6f43024c ths
    if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
1998 6f43024c ths
        goto cleanup;
1999 6f43024c ths
    if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2000 6f43024c ths
        goto cleanup;
2001 6f43024c ths
    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2002 6f43024c ths
        goto cleanup;
2003 6f43024c ths
    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2004 6f43024c ths
        goto cleanup;
2005 6f43024c ths
2006 6f43024c ths
    return 0;
2007 6f43024c ths
2008 6f43024c ths
 cleanup:
2009 6f43024c ths
    qemu_free(vs->x509cacert);
2010 6f43024c ths
    qemu_free(vs->x509cacrl);
2011 6f43024c ths
    qemu_free(vs->x509cert);
2012 6f43024c ths
    qemu_free(vs->x509key);
2013 6f43024c ths
    vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2014 6f43024c ths
    return -1;
2015 6f43024c ths
}
2016 6f43024c ths
#endif /* CONFIG_VNC_TLS */
2017 6f43024c ths
2018 71cab5ca ths
void vnc_display_close(DisplayState *ds)
2019 71cab5ca ths
{
2020 e25a5822 ths
    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2021 71cab5ca ths
2022 71cab5ca ths
    if (vs->display) {
2023 71cab5ca ths
        qemu_free(vs->display);
2024 71cab5ca ths
        vs->display = NULL;
2025 71cab5ca ths
    }
2026 71cab5ca ths
    if (vs->lsock != -1) {
2027 71cab5ca ths
        qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2028 71cab5ca ths
        close(vs->lsock);
2029 71cab5ca ths
        vs->lsock = -1;
2030 71cab5ca ths
    }
2031 71cab5ca ths
    if (vs->csock != -1) {
2032 71cab5ca ths
        qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2033 71cab5ca ths
        closesocket(vs->csock);
2034 71cab5ca ths
        vs->csock = -1;
2035 71cab5ca ths
        buffer_reset(&vs->input);
2036 71cab5ca ths
        buffer_reset(&vs->output);
2037 71cab5ca ths
        vs->need_update = 0;
2038 8d5d2d4c ths
#if CONFIG_VNC_TLS
2039 8d5d2d4c ths
        if (vs->tls_session) {
2040 8d5d2d4c ths
            gnutls_deinit(vs->tls_session);
2041 8d5d2d4c ths
            vs->tls_session = NULL;
2042 8d5d2d4c ths
        }
2043 8d5d2d4c ths
        vs->wiremode = VNC_WIREMODE_CLEAR;
2044 8d5d2d4c ths
#endif /* CONFIG_VNC_TLS */
2045 71cab5ca ths
    }
2046 70848515 ths
    vs->auth = VNC_AUTH_INVALID;
2047 8d5d2d4c ths
#if CONFIG_VNC_TLS
2048 8d5d2d4c ths
    vs->subauth = VNC_AUTH_INVALID;
2049 469b15c6 ths
    vs->x509verify = 0;
2050 8d5d2d4c ths
#endif
2051 70848515 ths
}
2052 70848515 ths
2053 70848515 ths
int vnc_display_password(DisplayState *ds, const char *password)
2054 70848515 ths
{
2055 70848515 ths
    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2056 70848515 ths
2057 70848515 ths
    if (vs->password) {
2058 70848515 ths
        qemu_free(vs->password);
2059 70848515 ths
        vs->password = NULL;
2060 70848515 ths
    }
2061 70848515 ths
    if (password && password[0]) {
2062 70848515 ths
        if (!(vs->password = qemu_strdup(password)))
2063 70848515 ths
            return -1;
2064 70848515 ths
    }
2065 70848515 ths
2066 70848515 ths
    return 0;
2067 71cab5ca ths
}
2068 71cab5ca ths
2069 70848515 ths
int vnc_display_open(DisplayState *ds, const char *display)
2070 71cab5ca ths
{
2071 71cab5ca ths
    struct sockaddr *addr;
2072 71cab5ca ths
    struct sockaddr_in iaddr;
2073 71cab5ca ths
#ifndef _WIN32
2074 71cab5ca ths
    struct sockaddr_un uaddr;
2075 71cab5ca ths
#endif
2076 71cab5ca ths
    int reuse_addr, ret;
2077 71cab5ca ths
    socklen_t addrlen;
2078 71cab5ca ths
    const char *p;
2079 e25a5822 ths
    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2080 70848515 ths
    const char *options;
2081 70848515 ths
    int password = 0;
2082 8d5d2d4c ths
#if CONFIG_VNC_TLS
2083 3a702699 ths
    int tls = 0, x509 = 0;
2084 8d5d2d4c ths
#endif
2085 71cab5ca ths
2086 71cab5ca ths
    vnc_display_close(ds);
2087 70848515 ths
    if (strcmp(display, "none") == 0)
2088 71cab5ca ths
        return 0;
2089 24236869 bellard
2090 70848515 ths
    if (!(vs->display = strdup(display)))
2091 71cab5ca ths
        return -1;
2092 70848515 ths
2093 70848515 ths
    options = display;
2094 70848515 ths
    while ((options = strchr(options, ','))) {
2095 70848515 ths
        options++;
2096 469b15c6 ths
        if (strncmp(options, "password", 8) == 0) {
2097 70848515 ths
            password = 1; /* Require password auth */
2098 8d5d2d4c ths
#if CONFIG_VNC_TLS
2099 469b15c6 ths
        } else if (strncmp(options, "tls", 3) == 0) {
2100 8d5d2d4c ths
            tls = 1; /* Require TLS */
2101 469b15c6 ths
        } else if (strncmp(options, "x509", 4) == 0) {
2102 6f43024c ths
            char *start, *end;
2103 3a702699 ths
            x509 = 1; /* Require x509 certificates */
2104 6f43024c ths
            if (strncmp(options, "x509verify", 10) == 0)
2105 6f43024c ths
                vs->x509verify = 1; /* ...and verify client certs */
2106 6f43024c ths
2107 6f43024c ths
            /* Now check for 'x509=/some/path' postfix
2108 6f43024c ths
             * and use that to setup x509 certificate/key paths */
2109 6f43024c ths
            start = strchr(options, '=');
2110 6f43024c ths
            end = strchr(options, ',');
2111 6f43024c ths
            if (start && (!end || (start < end))) {
2112 6f43024c ths
                int len = end ? end-(start+1) : strlen(start+1);
2113 6f43024c ths
                char *path = qemu_malloc(len+1);
2114 6f43024c ths
                strncpy(path, start+1, len);
2115 6f43024c ths
                path[len] = '\0';
2116 6f43024c ths
                VNC_DEBUG("Trying certificate path '%s'\n", path);
2117 6f43024c ths
                if (vnc_set_x509_credential_dir(vs, path) < 0) {
2118 6f43024c ths
                    fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2119 6f43024c ths
                    qemu_free(path);
2120 6f43024c ths
                    qemu_free(vs->display);
2121 6f43024c ths
                    vs->display = NULL;
2122 6f43024c ths
                    return -1;
2123 6f43024c ths
                }
2124 6f43024c ths
                qemu_free(path);
2125 6f43024c ths
            } else {
2126 6f43024c ths
                fprintf(stderr, "No certificate path provided\n");
2127 6f43024c ths
                qemu_free(vs->display);
2128 6f43024c ths
                vs->display = NULL;
2129 6f43024c ths
                return -1;
2130 6f43024c ths
            }
2131 8d5d2d4c ths
#endif
2132 469b15c6 ths
        }
2133 70848515 ths
    }
2134 70848515 ths
2135 70848515 ths
    if (password) {
2136 8d5d2d4c ths
#if CONFIG_VNC_TLS
2137 8d5d2d4c ths
        if (tls) {
2138 8d5d2d4c ths
            vs->auth = VNC_AUTH_VENCRYPT;
2139 3a702699 ths
            if (x509) {
2140 3a702699 ths
                VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2141 3a702699 ths
                vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2142 3a702699 ths
            } else {
2143 3a702699 ths
                VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2144 3a702699 ths
                vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2145 3a702699 ths
            }
2146 8d5d2d4c ths
        } else {
2147 8d5d2d4c ths
#endif
2148 8d5d2d4c ths
            VNC_DEBUG("Initializing VNC server with password auth\n");
2149 8d5d2d4c ths
            vs->auth = VNC_AUTH_VNC;
2150 8d5d2d4c ths
#if CONFIG_VNC_TLS
2151 8d5d2d4c ths
            vs->subauth = VNC_AUTH_INVALID;
2152 8d5d2d4c ths
        }
2153 8d5d2d4c ths
#endif
2154 70848515 ths
    } else {
2155 8d5d2d4c ths
#if CONFIG_VNC_TLS
2156 8d5d2d4c ths
        if (tls) {
2157 8d5d2d4c ths
            vs->auth = VNC_AUTH_VENCRYPT;
2158 3a702699 ths
            if (x509) {
2159 3a702699 ths
                VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2160 3a702699 ths
                vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2161 3a702699 ths
            } else {
2162 3a702699 ths
                VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2163 3a702699 ths
                vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2164 3a702699 ths
            }
2165 8d5d2d4c ths
        } else {
2166 8d5d2d4c ths
#endif
2167 8d5d2d4c ths
            VNC_DEBUG("Initializing VNC server with no auth\n");
2168 8d5d2d4c ths
            vs->auth = VNC_AUTH_NONE;
2169 8d5d2d4c ths
#if CONFIG_VNC_TLS
2170 8d5d2d4c ths
            vs->subauth = VNC_AUTH_INVALID;
2171 8d5d2d4c ths
        }
2172 8d5d2d4c ths
#endif
2173 70848515 ths
    }
2174 73fc9742 ths
#ifndef _WIN32
2175 70848515 ths
    if (strstart(display, "unix:", &p)) {
2176 73fc9742 ths
        addr = (struct sockaddr *)&uaddr;
2177 73fc9742 ths
        addrlen = sizeof(uaddr);
2178 73fc9742 ths
2179 73fc9742 ths
        vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2180 73fc9742 ths
        if (vs->lsock == -1) {
2181 73fc9742 ths
            fprintf(stderr, "Could not create socket\n");
2182 71cab5ca ths
            free(vs->display);
2183 71cab5ca ths
            vs->display = NULL;
2184 71cab5ca ths
            return -1;
2185 73fc9742 ths
        }
2186 73fc9742 ths
2187 73fc9742 ths
        uaddr.sun_family = AF_UNIX;
2188 73fc9742 ths
        memset(uaddr.sun_path, 0, 108);
2189 73fc9742 ths
        snprintf(uaddr.sun_path, 108, "%s", p);
2190 73fc9742 ths
2191 73fc9742 ths
        unlink(uaddr.sun_path);
2192 73fc9742 ths
    } else
2193 73fc9742 ths
#endif
2194 73fc9742 ths
    {
2195 73fc9742 ths
        addr = (struct sockaddr *)&iaddr;
2196 73fc9742 ths
        addrlen = sizeof(iaddr);
2197 73fc9742 ths
2198 70848515 ths
        if (parse_host_port(&iaddr, display) < 0) {
2199 73fc9742 ths
            fprintf(stderr, "Could not parse VNC address\n");
2200 71cab5ca ths
            free(vs->display);
2201 71cab5ca ths
            vs->display = NULL;
2202 71cab5ca ths
            return -1;
2203 73fc9742 ths
        }
2204 71cab5ca ths
2205 73fc9742 ths
        iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
2206 73fc9742 ths
2207 71cab5ca ths
        vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2208 71cab5ca ths
        if (vs->lsock == -1) {
2209 71cab5ca ths
            fprintf(stderr, "Could not create socket\n");
2210 71cab5ca ths
            free(vs->display);
2211 71cab5ca ths
            vs->display = NULL;
2212 71cab5ca ths
            return -1;
2213 71cab5ca ths
        }
2214 71cab5ca ths
2215 73fc9742 ths
        reuse_addr = 1;
2216 73fc9742 ths
        ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2217 73fc9742 ths
                         (const char *)&reuse_addr, sizeof(reuse_addr));
2218 73fc9742 ths
        if (ret == -1) {
2219 73fc9742 ths
            fprintf(stderr, "setsockopt() failed\n");
2220 71cab5ca ths
            close(vs->lsock);
2221 71cab5ca ths
            vs->lsock = -1;
2222 71cab5ca ths
            free(vs->display);
2223 71cab5ca ths
            vs->display = NULL;
2224 71cab5ca ths
            return -1;
2225 73fc9742 ths
        }
2226 24236869 bellard
    }
2227 24236869 bellard
2228 73fc9742 ths
    if (bind(vs->lsock, addr, addrlen) == -1) {
2229 24236869 bellard
        fprintf(stderr, "bind() failed\n");
2230 71cab5ca ths
        close(vs->lsock);
2231 71cab5ca ths
        vs->lsock = -1;
2232 71cab5ca ths
        free(vs->display);
2233 71cab5ca ths
        vs->display = NULL;
2234 71cab5ca ths
        return -1;
2235 24236869 bellard
    }
2236 24236869 bellard
2237 24236869 bellard
    if (listen(vs->lsock, 1) == -1) {
2238 24236869 bellard
        fprintf(stderr, "listen() failed\n");
2239 71cab5ca ths
        close(vs->lsock);
2240 71cab5ca ths
        vs->lsock = -1;
2241 71cab5ca ths
        free(vs->display);
2242 71cab5ca ths
        vs->display = NULL;
2243 71cab5ca ths
        return -1;
2244 24236869 bellard
    }
2245 24236869 bellard
2246 71cab5ca ths
    return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
2247 24236869 bellard
}