Statistics
| Branch: | Revision:

root / vnc.c @ 5fafdf24

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