]> git.proxmox.com Git - mirror_qemu.git/blame - vnc.c
Remove dead code
[mirror_qemu.git] / vnc.c
CommitLineData
7d510b8c
FB
1/*
2 * QEMU VNC display driver
5fafdf24 3 *
7d510b8c
FB
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
19a490bf 6 * Copyright (C) 2009 Red Hat, Inc
5fafdf24 7 *
7d510b8c
FB
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
19a490bf 27#include "vnc.h"
87ecb68b 28#include "sysemu.h"
6ca957f0 29#include "qemu_socket.h"
87ecb68b 30#include "qemu-timer.h"
76655d6d 31#include "acl.h"
24236869
FB
32
33#define VNC_REFRESH_INTERVAL (1000 / 30)
34
35#include "vnc_keysym.h"
70848515
TS
36#include "d3des.h"
37
90a1e3c0
AL
38#define count_bits(c, v) { \
39 for (c = 0; v; v >>= 1) \
40 { \
41 c += v & 1; \
42 } \
43}
8d5d2d4c 44
24236869 45
753b4053 46static VncDisplay *vnc_display; /* needed for info vnc */
7d957bd8 47static DisplayChangeListener *dcl;
a9ce8590 48
1ff7df1a
AL
49static char *addr_to_string(const char *format,
50 struct sockaddr_storage *sa,
51 socklen_t salen) {
52 char *addr;
53 char host[NI_MAXHOST];
54 char serv[NI_MAXSERV];
55 int err;
457772e6 56 size_t addrlen;
1ff7df1a
AL
57
58 if ((err = getnameinfo((struct sockaddr *)sa, salen,
59 host, sizeof(host),
60 serv, sizeof(serv),
61 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
62 VNC_DEBUG("Cannot resolve address %d: %s\n",
63 err, gai_strerror(err));
64 return NULL;
65 }
66
457772e6
AL
67 /* Enough for the existing format + the 2 vars we're
68 * subsituting in. */
69 addrlen = strlen(format) + strlen(host) + strlen(serv);
70 addr = qemu_malloc(addrlen + 1);
71 snprintf(addr, addrlen, format, host, serv);
72 addr[addrlen] = '\0';
1ff7df1a
AL
73
74 return addr;
75}
76
2f9606b3
AL
77
78char *vnc_socket_local_addr(const char *format, int fd) {
1ff7df1a
AL
79 struct sockaddr_storage sa;
80 socklen_t salen;
81
82 salen = sizeof(sa);
83 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
84 return NULL;
85
86 return addr_to_string(format, &sa, salen);
87}
88
2f9606b3
AL
89
90char *vnc_socket_remote_addr(const char *format, int fd) {
1ff7df1a
AL
91 struct sockaddr_storage sa;
92 socklen_t salen;
93
94 salen = sizeof(sa);
95 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
96 return NULL;
97
98 return addr_to_string(format, &sa, salen);
99}
100
101static const char *vnc_auth_name(VncDisplay *vd) {
102 switch (vd->auth) {
103 case VNC_AUTH_INVALID:
104 return "invalid";
105 case VNC_AUTH_NONE:
106 return "none";
107 case VNC_AUTH_VNC:
108 return "vnc";
109 case VNC_AUTH_RA2:
110 return "ra2";
111 case VNC_AUTH_RA2NE:
112 return "ra2ne";
113 case VNC_AUTH_TIGHT:
114 return "tight";
115 case VNC_AUTH_ULTRA:
116 return "ultra";
117 case VNC_AUTH_TLS:
118 return "tls";
119 case VNC_AUTH_VENCRYPT:
120#ifdef CONFIG_VNC_TLS
121 switch (vd->subauth) {
122 case VNC_AUTH_VENCRYPT_PLAIN:
123 return "vencrypt+plain";
124 case VNC_AUTH_VENCRYPT_TLSNONE:
125 return "vencrypt+tls+none";
126 case VNC_AUTH_VENCRYPT_TLSVNC:
127 return "vencrypt+tls+vnc";
128 case VNC_AUTH_VENCRYPT_TLSPLAIN:
129 return "vencrypt+tls+plain";
130 case VNC_AUTH_VENCRYPT_X509NONE:
131 return "vencrypt+x509+none";
132 case VNC_AUTH_VENCRYPT_X509VNC:
133 return "vencrypt+x509+vnc";
134 case VNC_AUTH_VENCRYPT_X509PLAIN:
135 return "vencrypt+x509+plain";
28a76be8
AL
136 case VNC_AUTH_VENCRYPT_TLSSASL:
137 return "vencrypt+tls+sasl";
138 case VNC_AUTH_VENCRYPT_X509SASL:
139 return "vencrypt+x509+sasl";
1ff7df1a
AL
140 default:
141 return "vencrypt";
142 }
143#else
144 return "vencrypt";
145#endif
2f9606b3 146 case VNC_AUTH_SASL:
28a76be8 147 return "sasl";
1ff7df1a
AL
148 }
149 return "unknown";
150}
151
1ff7df1a
AL
152static void do_info_vnc_client(Monitor *mon, VncState *client)
153{
154 char *clientAddr =
155 vnc_socket_remote_addr(" address: %s:%s\n",
156 client->csock);
157 if (!clientAddr)
158 return;
159
160 monitor_printf(mon, "Client:\n");
161 monitor_printf(mon, "%s", clientAddr);
162 free(clientAddr);
1263b7d6
AL
163
164#ifdef CONFIG_VNC_TLS
165 if (client->tls.session &&
28a76be8
AL
166 client->tls.dname)
167 monitor_printf(mon, " x509 dname: %s\n", client->tls.dname);
1263b7d6 168 else
28a76be8 169 monitor_printf(mon, " x509 dname: none\n");
1263b7d6
AL
170#endif
171#ifdef CONFIG_VNC_SASL
172 if (client->sasl.conn &&
28a76be8
AL
173 client->sasl.username)
174 monitor_printf(mon, " username: %s\n", client->sasl.username);
1263b7d6 175 else
28a76be8 176 monitor_printf(mon, " username: none\n");
1263b7d6 177#endif
1ff7df1a
AL
178}
179
376253ec 180void do_info_vnc(Monitor *mon)
a9ce8590 181{
1ff7df1a
AL
182 if (vnc_display == NULL || vnc_display->display == NULL) {
183 monitor_printf(mon, "Server: disabled\n");
184 } else {
185 char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n",
186 vnc_display->lsock);
187
188 if (!serverAddr)
189 return;
190
191 monitor_printf(mon, "Server:\n");
192 monitor_printf(mon, "%s", serverAddr);
193 free(serverAddr);
194 monitor_printf(mon, " auth: %s\n", vnc_auth_name(vnc_display));
195
196 if (vnc_display->clients) {
197 VncState *client = vnc_display->clients;
198 while (client) {
199 do_info_vnc_client(mon, client);
200 client = client->next;
201 }
202 } else {
203 monitor_printf(mon, "Client: none\n");
204 }
a9ce8590
FB
205 }
206}
207
29fa4ed9
AL
208static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
209 return (vs->features & (1 << feature));
210}
211
24236869
FB
212/* TODO
213 1) Get the queue working for IO.
214 2) there is some weirdness when using the -S option (the screen is grey
215 and not totally invalidated
216 3) resolutions > 1024
217*/
218
24236869 219static void vnc_update_client(void *opaque);
24236869 220
753b4053 221static void vnc_colordepth(VncState *vs);
7eac3a87 222
99589bdc
FB
223static inline void vnc_set_bit(uint32_t *d, int k)
224{
225 d[k >> 5] |= 1 << (k & 0x1f);
226}
227
228static inline void vnc_clear_bit(uint32_t *d, int k)
229{
230 d[k >> 5] &= ~(1 << (k & 0x1f));
231}
232
233static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
234{
235 int j;
236
237 j = 0;
238 while (n >= 32) {
239 d[j++] = -1;
240 n -= 32;
241 }
5fafdf24 242 if (n > 0)
99589bdc
FB
243 d[j++] = (1 << n) - 1;
244 while (j < nb_words)
245 d[j++] = 0;
246}
247
248static inline int vnc_get_bit(const uint32_t *d, int k)
249{
250 return (d[k >> 5] >> (k & 0x1f)) & 1;
251}
252
5fafdf24 253static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
99589bdc
FB
254 int nb_words)
255{
256 int i;
257 for(i = 0; i < nb_words; i++) {
258 if ((d1[i] & d2[i]) != 0)
259 return 1;
260 }
261 return 0;
262}
263
753b4053 264static void vnc_update(VncState *vs, int x, int y, int w, int h)
24236869 265{
24236869
FB
266 int i;
267
268 h += y;
269
0486e8a7
AZ
270 /* round x down to ensure the loop only spans one 16-pixel block per,
271 iteration. otherwise, if (x % 16) != 0, the last iteration may span
272 two 16-pixel blocks but we only mark the first as dirty
273 */
274 w += (x % 16);
275 x -= (x % 16);
276
6cec5487
AL
277 x = MIN(x, vs->serverds.width);
278 y = MIN(y, vs->serverds.height);
279 w = MIN(x + w, vs->serverds.width) - x;
280 h = MIN(h, vs->serverds.height);
788abf8e 281
24236869 282 for (; y < h; y++)
28a76be8
AL
283 for (i = 0; i < w; i += 16)
284 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
24236869
FB
285}
286
753b4053
AL
287static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
288{
289 VncDisplay *vd = ds->opaque;
290 VncState *vs = vd->clients;
291 while (vs != NULL) {
292 vnc_update(vs, x, y, w, h);
293 vs = vs->next;
294 }
295}
296
24236869 297static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
28a76be8 298 int32_t encoding)
24236869
FB
299{
300 vnc_write_u16(vs, x);
301 vnc_write_u16(vs, y);
302 vnc_write_u16(vs, w);
303 vnc_write_u16(vs, h);
304
305 vnc_write_s32(vs, encoding);
306}
307
2f9606b3 308void buffer_reserve(Buffer *buffer, size_t len)
89064286
AL
309{
310 if ((buffer->capacity - buffer->offset) < len) {
28a76be8
AL
311 buffer->capacity += (len + 1024);
312 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
313 if (buffer->buffer == NULL) {
314 fprintf(stderr, "vnc: out of memory\n");
315 exit(1);
316 }
89064286
AL
317 }
318}
319
2f9606b3 320int buffer_empty(Buffer *buffer)
89064286
AL
321{
322 return buffer->offset == 0;
323}
324
2f9606b3 325uint8_t *buffer_end(Buffer *buffer)
89064286
AL
326{
327 return buffer->buffer + buffer->offset;
328}
329
2f9606b3 330void buffer_reset(Buffer *buffer)
89064286 331{
28a76be8 332 buffer->offset = 0;
89064286
AL
333}
334
2f9606b3 335void buffer_append(Buffer *buffer, const void *data, size_t len)
89064286
AL
336{
337 memcpy(buffer->buffer + buffer->offset, data, len);
338 buffer->offset += len;
339}
340
753b4053 341static void vnc_resize(VncState *vs)
24236869 342{
753b4053
AL
343 DisplayState *ds = vs->ds;
344
73e14b62 345 int size_changed;
24236869 346
7d957bd8 347 vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
24236869 348
7d957bd8 349 if (vs->old_data == NULL) {
28a76be8
AL
350 fprintf(stderr, "vnc: memory allocation failed\n");
351 exit(1);
24236869
FB
352 }
353
6cec5487 354 if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
a528b80c 355 console_color_init(ds);
753b4053 356 vnc_colordepth(vs);
6cec5487
AL
357 size_changed = ds_get_width(ds) != vs->serverds.width ||
358 ds_get_height(ds) != vs->serverds.height;
359 vs->serverds = *(ds->surface);
b94eb43f 360 if (size_changed) {
29fa4ed9 361 if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
b94eb43f
AZ
362 vnc_write_u8(vs, 0); /* msg id */
363 vnc_write_u8(vs, 0);
364 vnc_write_u16(vs, 1); /* number of rects */
29fa4ed9
AL
365 vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
366 VNC_ENCODING_DESKTOPRESIZE);
b94eb43f
AZ
367 vnc_flush(vs);
368 }
24236869 369 }
8bba5c81
AZ
370
371 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
0e1f5a0c 372 memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
24236869
FB
373}
374
753b4053
AL
375static void vnc_dpy_resize(DisplayState *ds)
376{
377 VncDisplay *vd = ds->opaque;
378 VncState *vs = vd->clients;
379 while (vs != NULL) {
380 vnc_resize(vs);
381 vs = vs->next;
382 }
383}
384
3512779a
FB
385/* fastest code */
386static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
387{
388 vnc_write(vs, pixels, size);
389}
390
391/* slowest but generic code. */
392static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
393{
7eac3a87
AL
394 uint8_t r, g, b;
395
90a1e3c0
AL
396 r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) << vs->clientds.pf.rbits) >>
397 vs->serverds.pf.rbits);
398 g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) << vs->clientds.pf.gbits) >>
399 vs->serverds.pf.gbits);
400 b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) << vs->clientds.pf.bbits) >>
401 vs->serverds.pf.bbits);
6cec5487
AL
402 v = (r << vs->clientds.pf.rshift) |
403 (g << vs->clientds.pf.gshift) |
404 (b << vs->clientds.pf.bshift);
405 switch(vs->clientds.pf.bytes_per_pixel) {
3512779a
FB
406 case 1:
407 buf[0] = v;
408 break;
409 case 2:
6cec5487 410 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
3512779a
FB
411 buf[0] = v >> 8;
412 buf[1] = v;
413 } else {
414 buf[1] = v >> 8;
415 buf[0] = v;
416 }
417 break;
418 default:
419 case 4:
6cec5487 420 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
3512779a
FB
421 buf[0] = v >> 24;
422 buf[1] = v >> 16;
423 buf[2] = v >> 8;
424 buf[3] = v;
425 } else {
426 buf[3] = v >> 24;
427 buf[2] = v >> 16;
428 buf[1] = v >> 8;
429 buf[0] = v;
430 }
431 break;
432 }
433}
434
435static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
436{
3512779a 437 uint8_t buf[4];
3512779a 438
6cec5487 439 if (vs->serverds.pf.bytes_per_pixel == 4) {
7eac3a87
AL
440 uint32_t *pixels = pixels1;
441 int n, i;
442 n = size >> 2;
443 for(i = 0; i < n; i++) {
444 vnc_convert_pixel(vs, buf, pixels[i]);
6cec5487 445 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
7eac3a87 446 }
6cec5487 447 } else if (vs->serverds.pf.bytes_per_pixel == 2) {
7eac3a87
AL
448 uint16_t *pixels = pixels1;
449 int n, i;
450 n = size >> 1;
451 for(i = 0; i < n; i++) {
452 vnc_convert_pixel(vs, buf, pixels[i]);
6cec5487 453 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
7eac3a87 454 }
6cec5487 455 } else if (vs->serverds.pf.bytes_per_pixel == 1) {
7eac3a87
AL
456 uint8_t *pixels = pixels1;
457 int n, i;
458 n = size;
459 for(i = 0; i < n; i++) {
460 vnc_convert_pixel(vs, buf, pixels[i]);
6cec5487 461 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
7eac3a87
AL
462 }
463 } else {
464 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
3512779a
FB
465 }
466}
467
24236869
FB
468static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
469{
470 int i;
60fe76f3 471 uint8_t *row;
24236869 472
6cec5487 473 row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
24236869 474 for (i = 0; i < h; i++) {
28a76be8
AL
475 vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
476 row += ds_get_linesize(vs->ds);
24236869
FB
477 }
478}
479
480static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
481{
482 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
483 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
484}
485
486#define BPP 8
487#include "vnchextile.h"
488#undef BPP
489
490#define BPP 16
491#include "vnchextile.h"
492#undef BPP
493
494#define BPP 32
495#include "vnchextile.h"
496#undef BPP
497
7eac3a87
AL
498#define GENERIC
499#define BPP 8
500#include "vnchextile.h"
501#undef BPP
502#undef GENERIC
503
504#define GENERIC
505#define BPP 16
506#include "vnchextile.h"
507#undef BPP
508#undef GENERIC
509
3512779a
FB
510#define GENERIC
511#define BPP 32
512#include "vnchextile.h"
513#undef BPP
514#undef GENERIC
515
24236869
FB
516static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
517{
518 int i, j;
519 int has_fg, has_bg;
7eac3a87 520 uint8_t *last_fg, *last_bg;
24236869 521
1eec614b
AL
522 last_fg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
523 last_bg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
24236869
FB
524 has_fg = has_bg = 0;
525 for (j = y; j < (y + h); j += 16) {
28a76be8 526 for (i = x; i < (x + w); i += 16) {
5fafdf24 527 vs->send_hextile_tile(vs, i, j,
3512779a 528 MIN(16, x + w - i), MIN(16, y + h - j),
7eac3a87 529 last_bg, last_fg, &has_bg, &has_fg);
28a76be8 530 }
24236869 531 }
7eac3a87
AL
532 free(last_fg);
533 free(last_bg);
534
24236869
FB
535}
536
059cef40
AL
537static void vnc_zlib_init(VncState *vs)
538{
539 int i;
540 for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
541 vs->zlib_stream[i].opaque = NULL;
542}
543
544static void vnc_zlib_start(VncState *vs)
545{
546 buffer_reset(&vs->zlib);
547
548 // make the output buffer be the zlib buffer, so we can compress it later
549 vs->zlib_tmp = vs->output;
550 vs->output = vs->zlib;
551}
552
553static int vnc_zlib_stop(VncState *vs, int stream_id)
554{
555 z_streamp zstream = &vs->zlib_stream[stream_id];
556 int previous_out;
557
558 // switch back to normal output/zlib buffers
559 vs->zlib = vs->output;
560 vs->output = vs->zlib_tmp;
561
562 // compress the zlib buffer
563
564 // initialize the stream
565 // XXX need one stream per session
566 if (zstream->opaque != vs) {
567 int err;
568
569 VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
570 VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
571 zstream->zalloc = Z_NULL;
572 zstream->zfree = Z_NULL;
573
574 err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
575 MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
576
577 if (err != Z_OK) {
578 fprintf(stderr, "VNC: error initializing zlib\n");
579 return -1;
580 }
581
582 zstream->opaque = vs;
583 }
584
585 // XXX what to do if tight_compression changed in between?
586
587 // reserve memory in output buffer
588 buffer_reserve(&vs->output, vs->zlib.offset + 64);
589
590 // set pointers
591 zstream->next_in = vs->zlib.buffer;
592 zstream->avail_in = vs->zlib.offset;
593 zstream->next_out = vs->output.buffer + vs->output.offset;
594 zstream->avail_out = vs->output.capacity - vs->output.offset;
595 zstream->data_type = Z_BINARY;
596 previous_out = zstream->total_out;
597
598 // start encoding
599 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
600 fprintf(stderr, "VNC: error during zlib compression\n");
601 return -1;
602 }
603
604 vs->output.offset = vs->output.capacity - zstream->avail_out;
605 return zstream->total_out - previous_out;
606}
607
608static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
609{
610 int old_offset, new_offset, bytes_written;
611
612 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
613
614 // remember where we put in the follow-up size
615 old_offset = vs->output.offset;
616 vnc_write_s32(vs, 0);
617
618 // compress the stream
619 vnc_zlib_start(vs);
620 send_framebuffer_update_raw(vs, x, y, w, h);
621 bytes_written = vnc_zlib_stop(vs, 0);
622
623 if (bytes_written == -1)
624 return;
625
626 // hack in the size
627 new_offset = vs->output.offset;
628 vs->output.offset = old_offset;
629 vnc_write_u32(vs, bytes_written);
630 vs->output.offset = new_offset;
631}
632
24236869
FB
633static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
634{
fb437313 635 switch(vs->vnc_encoding) {
28a76be8
AL
636 case VNC_ENCODING_ZLIB:
637 send_framebuffer_update_zlib(vs, x, y, w, h);
638 break;
639 case VNC_ENCODING_HEXTILE:
640 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
641 send_framebuffer_update_hextile(vs, x, y, w, h);
642 break;
643 default:
644 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
645 send_framebuffer_update_raw(vs, x, y, w, h);
646 break;
fb437313 647 }
24236869
FB
648}
649
753b4053 650static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
24236869 651{
24236869
FB
652 vnc_update_client(vs);
653
24236869
FB
654 vnc_write_u8(vs, 0); /* msg id */
655 vnc_write_u8(vs, 0);
656 vnc_write_u16(vs, 1); /* number of rects */
29fa4ed9 657 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
24236869
FB
658 vnc_write_u16(vs, src_x);
659 vnc_write_u16(vs, src_y);
660 vnc_flush(vs);
661}
662
753b4053
AL
663static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
664{
665 VncDisplay *vd = ds->opaque;
666 VncState *vs = vd->clients;
667 while (vs != NULL) {
668 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
669 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
670 else /* TODO */
671 vnc_update(vs, dst_x, dst_y, w, h);
672 vs = vs->next;
673 }
674}
675
24236869
FB
676static int find_dirty_height(VncState *vs, int y, int last_x, int x)
677{
678 int h;
679
6cec5487 680 for (h = 1; h < (vs->serverds.height - y); h++) {
28a76be8
AL
681 int tmp_x;
682 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
683 break;
684 for (tmp_x = last_x; tmp_x < x; tmp_x++)
685 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
24236869
FB
686 }
687
688 return h;
689}
690
691static void vnc_update_client(void *opaque)
692{
693 VncState *vs = opaque;
24236869 694 if (vs->need_update && vs->csock != -1) {
28a76be8
AL
695 int y;
696 uint8_t *row;
697 char *old_row;
698 uint32_t width_mask[VNC_DIRTY_WORDS];
699 int n_rectangles;
700 int saved_offset;
701 int has_dirty = 0;
24236869 702
a0ecfb73
AZ
703 vga_hw_update();
704
6cec5487 705 vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
24236869 706
28a76be8
AL
707 /* Walk through the dirty map and eliminate tiles that
708 really aren't dirty */
709 row = ds_get_data(vs->ds);
710 old_row = vs->old_data;
711
712 for (y = 0; y < ds_get_height(vs->ds); y++) {
713 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
714 int x;
715 uint8_t *ptr;
716 char *old_ptr;
717
718 ptr = row;
719 old_ptr = (char*)old_row;
720
721 for (x = 0; x < ds_get_width(vs->ds); x += 16) {
722 if (memcmp(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)) == 0) {
723 vnc_clear_bit(vs->dirty_row[y], (x / 16));
724 } else {
725 has_dirty = 1;
726 memcpy(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds));
727 }
728
729 ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
730 old_ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
731 }
732 }
733
734 row += ds_get_linesize(vs->ds);
735 old_row += ds_get_linesize(vs->ds);
736 }
737
738 if (!has_dirty && !vs->audio_cap) {
739 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
740 return;
741 }
742
743 /* Count rectangles */
744 n_rectangles = 0;
745 vnc_write_u8(vs, 0); /* msg id */
746 vnc_write_u8(vs, 0);
747 saved_offset = vs->output.offset;
748 vnc_write_u16(vs, 0);
749
750 for (y = 0; y < vs->serverds.height; y++) {
751 int x;
752 int last_x = -1;
753 for (x = 0; x < vs->serverds.width / 16; x++) {
754 if (vnc_get_bit(vs->dirty_row[y], x)) {
755 if (last_x == -1) {
756 last_x = x;
757 }
758 vnc_clear_bit(vs->dirty_row[y], x);
759 } else {
760 if (last_x != -1) {
761 int h = find_dirty_height(vs, y, last_x, x);
762 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
763 n_rectangles++;
764 }
765 last_x = -1;
766 }
767 }
768 if (last_x != -1) {
769 int h = find_dirty_height(vs, y, last_x, x);
770 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
771 n_rectangles++;
772 }
773 }
774 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
775 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
776 vnc_flush(vs);
24236869
FB
777
778 }
24236869 779
a0ecfb73
AZ
780 if (vs->csock != -1) {
781 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
24236869 782 }
24236869 783
24236869
FB
784}
785
429a8ed3 786/* audio */
787static void audio_capture_notify(void *opaque, audcnotification_e cmd)
788{
789 VncState *vs = opaque;
790
791 switch (cmd) {
792 case AUD_CNOTIFY_DISABLE:
793 vnc_write_u8(vs, 255);
794 vnc_write_u8(vs, 1);
795 vnc_write_u16(vs, 0);
796 vnc_flush(vs);
797 break;
798
799 case AUD_CNOTIFY_ENABLE:
800 vnc_write_u8(vs, 255);
801 vnc_write_u8(vs, 1);
802 vnc_write_u16(vs, 1);
803 vnc_flush(vs);
804 break;
805 }
806}
807
808static void audio_capture_destroy(void *opaque)
809{
810}
811
812static void audio_capture(void *opaque, void *buf, int size)
813{
814 VncState *vs = opaque;
815
816 vnc_write_u8(vs, 255);
817 vnc_write_u8(vs, 1);
818 vnc_write_u16(vs, 2);
819 vnc_write_u32(vs, size);
820 vnc_write(vs, buf, size);
821 vnc_flush(vs);
822}
823
824static void audio_add(VncState *vs)
825{
376253ec 826 Monitor *mon = cur_mon;
429a8ed3 827 struct audio_capture_ops ops;
828
829 if (vs->audio_cap) {
376253ec 830 monitor_printf(mon, "audio already running\n");
429a8ed3 831 return;
832 }
833
834 ops.notify = audio_capture_notify;
835 ops.destroy = audio_capture_destroy;
836 ops.capture = audio_capture;
837
838 vs->audio_cap = AUD_add_capture(NULL, &vs->as, &ops, vs);
839 if (!vs->audio_cap) {
376253ec 840 monitor_printf(mon, "Failed to add audio capture\n");
429a8ed3 841 }
842}
843
844static void audio_del(VncState *vs)
845{
846 if (vs->audio_cap) {
847 AUD_del_capture(vs->audio_cap, vs);
848 vs->audio_cap = NULL;
849 }
850}
851
2f9606b3
AL
852
853int vnc_client_io_error(VncState *vs, int ret, int last_errno)
24236869
FB
854{
855 if (ret == 0 || ret == -1) {
ea01e5fd
AZ
856 if (ret == -1) {
857 switch (last_errno) {
858 case EINTR:
859 case EAGAIN:
860#ifdef _WIN32
861 case WSAEWOULDBLOCK:
862#endif
863 return 0;
864 default:
865 break;
866 }
867 }
24236869 868
28a76be8
AL
869 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
870 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
871 closesocket(vs->csock);
753b4053
AL
872 qemu_del_timer(vs->timer);
873 qemu_free_timer(vs->timer);
874 if (vs->input.buffer) qemu_free(vs->input.buffer);
875 if (vs->output.buffer) qemu_free(vs->output.buffer);
eb38c52c 876#ifdef CONFIG_VNC_TLS
28a76be8 877 vnc_tls_client_cleanup(vs);
8d5d2d4c 878#endif /* CONFIG_VNC_TLS */
2f9606b3
AL
879#ifdef CONFIG_VNC_SASL
880 vnc_sasl_client_cleanup(vs);
881#endif /* CONFIG_VNC_SASL */
429a8ed3 882 audio_del(vs);
753b4053
AL
883
884 VncState *p, *parent = NULL;
885 for (p = vs->vd->clients; p != NULL; p = p->next) {
886 if (p == vs) {
887 if (parent)
888 parent->next = p->next;
889 else
890 vs->vd->clients = p->next;
891 break;
892 }
893 parent = p;
894 }
895 if (!vs->vd->clients)
896 dcl->idle = 1;
897
898 qemu_free(vs->old_data);
899 qemu_free(vs);
900
28a76be8 901 return 0;
24236869
FB
902 }
903 return ret;
904}
905
5fb6c7a8
AL
906
907void vnc_client_error(VncState *vs)
24236869 908{
6ca957f0 909 vnc_client_io_error(vs, -1, EINVAL);
24236869
FB
910}
911
2f9606b3
AL
912
913/*
914 * Called to write a chunk of data to the client socket. The data may
915 * be the raw data, or may have already been encoded by SASL.
916 * The data will be written either straight onto the socket, or
917 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
918 *
919 * NB, it is theoretically possible to have 2 layers of encryption,
920 * both SASL, and this TLS layer. It is highly unlikely in practice
921 * though, since SASL encryption will typically be a no-op if TLS
922 * is active
923 *
924 * Returns the number of bytes written, which may be less than
925 * the requested 'datalen' if the socket would block. Returns
926 * -1 on error, and disconnects the client socket.
927 */
928long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
24236869 929{
ceb5caaf 930 long ret;
eb38c52c 931#ifdef CONFIG_VNC_TLS
5fb6c7a8 932 if (vs->tls.session) {
28a76be8
AL
933 ret = gnutls_write(vs->tls.session, data, datalen);
934 if (ret < 0) {
935 if (ret == GNUTLS_E_AGAIN)
936 errno = EAGAIN;
937 else
938 errno = EIO;
939 ret = -1;
940 }
8d5d2d4c
TS
941 } else
942#endif /* CONFIG_VNC_TLS */
28a76be8 943 ret = send(vs->csock, data, datalen, 0);
2f9606b3
AL
944 VNC_DEBUG("Wrote wire %p %d -> %ld\n", data, datalen, ret);
945 return vnc_client_io_error(vs, ret, socket_error());
946}
947
948
949/*
950 * Called to write buffered data to the client socket, when not
951 * using any SASL SSF encryption layers. Will write as much data
952 * as possible without blocking. If all buffered data is written,
953 * will switch the FD poll() handler back to read monitoring.
954 *
955 * Returns the number of bytes written, which may be less than
956 * the buffered output data if the socket would block. Returns
957 * -1 on error, and disconnects the client socket.
958 */
959static long vnc_client_write_plain(VncState *vs)
960{
961 long ret;
962
963#ifdef CONFIG_VNC_SASL
964 VNC_DEBUG("Write Plain: Pending output %p size %d offset %d. Wait SSF %d\n",
965 vs->output.buffer, vs->output.capacity, vs->output.offset,
966 vs->sasl.waitWriteSSF);
967
968 if (vs->sasl.conn &&
969 vs->sasl.runSSF &&
970 vs->sasl.waitWriteSSF) {
971 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
972 if (ret)
973 vs->sasl.waitWriteSSF -= ret;
974 } else
975#endif /* CONFIG_VNC_SASL */
976 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
24236869 977 if (!ret)
2f9606b3 978 return 0;
24236869
FB
979
980 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
981 vs->output.offset -= ret;
982
983 if (vs->output.offset == 0) {
28a76be8 984 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
24236869 985 }
2f9606b3
AL
986
987 return ret;
988}
989
990
991/*
992 * First function called whenever there is data to be written to
993 * the client socket. Will delegate actual work according to whether
994 * SASL SSF layers are enabled (thus requiring encryption calls)
995 */
996void vnc_client_write(void *opaque)
997{
998 long ret;
999 VncState *vs = opaque;
1000
1001#ifdef CONFIG_VNC_SASL
1002 if (vs->sasl.conn &&
1003 vs->sasl.runSSF &&
1004 !vs->sasl.waitWriteSSF)
1005 ret = vnc_client_write_sasl(vs);
1006 else
1007#endif /* CONFIG_VNC_SASL */
1008 ret = vnc_client_write_plain(vs);
24236869
FB
1009}
1010
5fb6c7a8 1011void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
24236869
FB
1012{
1013 vs->read_handler = func;
1014 vs->read_handler_expect = expecting;
1015}
1016
2f9606b3
AL
1017
1018/*
1019 * Called to read a chunk of data from the client socket. The data may
1020 * be the raw data, or may need to be further decoded by SASL.
1021 * The data will be read either straight from to the socket, or
1022 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1023 *
1024 * NB, it is theoretically possible to have 2 layers of encryption,
1025 * both SASL, and this TLS layer. It is highly unlikely in practice
1026 * though, since SASL encryption will typically be a no-op if TLS
1027 * is active
1028 *
1029 * Returns the number of bytes read, which may be less than
1030 * the requested 'datalen' if the socket would block. Returns
1031 * -1 on error, and disconnects the client socket.
1032 */
1033long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
24236869 1034{
ceb5caaf 1035 long ret;
eb38c52c 1036#ifdef CONFIG_VNC_TLS
5fb6c7a8 1037 if (vs->tls.session) {
28a76be8
AL
1038 ret = gnutls_read(vs->tls.session, data, datalen);
1039 if (ret < 0) {
1040 if (ret == GNUTLS_E_AGAIN)
1041 errno = EAGAIN;
1042 else
1043 errno = EIO;
1044 ret = -1;
1045 }
8d5d2d4c
TS
1046 } else
1047#endif /* CONFIG_VNC_TLS */
28a76be8 1048 ret = recv(vs->csock, data, datalen, 0);
2f9606b3
AL
1049 VNC_DEBUG("Read wire %p %d -> %ld\n", data, datalen, ret);
1050 return vnc_client_io_error(vs, ret, socket_error());
1051}
24236869 1052
2f9606b3
AL
1053
1054/*
1055 * Called to read data from the client socket to the input buffer,
1056 * when not using any SASL SSF encryption layers. Will read as much
1057 * data as possible without blocking.
1058 *
1059 * Returns the number of bytes read. Returns -1 on error, and
1060 * disconnects the client socket.
1061 */
1062static long vnc_client_read_plain(VncState *vs)
1063{
1064 int ret;
1065 VNC_DEBUG("Read plain %p size %d offset %d\n",
1066 vs->input.buffer, vs->input.capacity, vs->input.offset);
1067 buffer_reserve(&vs->input, 4096);
1068 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1069 if (!ret)
1070 return 0;
24236869 1071 vs->input.offset += ret;
2f9606b3
AL
1072 return ret;
1073}
1074
1075
1076/*
1077 * First function called whenever there is more data to be read from
1078 * the client socket. Will delegate actual work according to whether
1079 * SASL SSF layers are enabled (thus requiring decryption calls)
1080 */
1081void vnc_client_read(void *opaque)
1082{
1083 VncState *vs = opaque;
1084 long ret;
1085
1086#ifdef CONFIG_VNC_SASL
1087 if (vs->sasl.conn && vs->sasl.runSSF)
1088 ret = vnc_client_read_sasl(vs);
1089 else
1090#endif /* CONFIG_VNC_SASL */
1091 ret = vnc_client_read_plain(vs);
1092 if (!ret)
28a76be8 1093 return;
24236869
FB
1094
1095 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
28a76be8
AL
1096 size_t len = vs->read_handler_expect;
1097 int ret;
1098
1099 ret = vs->read_handler(vs, vs->input.buffer, len);
1100 if (vs->csock == -1)
1101 return;
1102
1103 if (!ret) {
1104 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
1105 vs->input.offset -= len;
1106 } else {
1107 vs->read_handler_expect = ret;
1108 }
24236869
FB
1109 }
1110}
1111
5fb6c7a8 1112void vnc_write(VncState *vs, const void *data, size_t len)
24236869
FB
1113{
1114 buffer_reserve(&vs->output, len);
1115
1116 if (buffer_empty(&vs->output)) {
28a76be8 1117 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
24236869
FB
1118 }
1119
1120 buffer_append(&vs->output, data, len);
1121}
1122
5fb6c7a8 1123void vnc_write_s32(VncState *vs, int32_t value)
24236869
FB
1124{
1125 vnc_write_u32(vs, *(uint32_t *)&value);
1126}
1127
5fb6c7a8 1128void vnc_write_u32(VncState *vs, uint32_t value)
24236869
FB
1129{
1130 uint8_t buf[4];
1131
1132 buf[0] = (value >> 24) & 0xFF;
1133 buf[1] = (value >> 16) & 0xFF;
1134 buf[2] = (value >> 8) & 0xFF;
1135 buf[3] = value & 0xFF;
1136
1137 vnc_write(vs, buf, 4);
1138}
1139
5fb6c7a8 1140void vnc_write_u16(VncState *vs, uint16_t value)
24236869 1141{
64f5a135 1142 uint8_t buf[2];
24236869
FB
1143
1144 buf[0] = (value >> 8) & 0xFF;
1145 buf[1] = value & 0xFF;
1146
1147 vnc_write(vs, buf, 2);
1148}
1149
5fb6c7a8 1150void vnc_write_u8(VncState *vs, uint8_t value)
24236869
FB
1151{
1152 vnc_write(vs, (char *)&value, 1);
1153}
1154
5fb6c7a8 1155void vnc_flush(VncState *vs)
24236869
FB
1156{
1157 if (vs->output.offset)
28a76be8 1158 vnc_client_write(vs);
24236869
FB
1159}
1160
5fb6c7a8 1161uint8_t read_u8(uint8_t *data, size_t offset)
24236869
FB
1162{
1163 return data[offset];
1164}
1165
5fb6c7a8 1166uint16_t read_u16(uint8_t *data, size_t offset)
24236869
FB
1167{
1168 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1169}
1170
5fb6c7a8 1171int32_t read_s32(uint8_t *data, size_t offset)
24236869
FB
1172{
1173 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1174 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1175}
1176
5fb6c7a8 1177uint32_t read_u32(uint8_t *data, size_t offset)
24236869
FB
1178{
1179 return ((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1180 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1181}
1182
60fe76f3 1183static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
24236869
FB
1184{
1185}
1186
564c337e
FB
1187static void check_pointer_type_change(VncState *vs, int absolute)
1188{
29fa4ed9 1189 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
28a76be8
AL
1190 vnc_write_u8(vs, 0);
1191 vnc_write_u8(vs, 0);
1192 vnc_write_u16(vs, 1);
1193 vnc_framebuffer_update(vs, absolute, 0,
1194 ds_get_width(vs->ds), ds_get_height(vs->ds),
29fa4ed9 1195 VNC_ENCODING_POINTER_TYPE_CHANGE);
28a76be8 1196 vnc_flush(vs);
564c337e
FB
1197 }
1198 vs->absolute = absolute;
1199}
1200
24236869
FB
1201static void pointer_event(VncState *vs, int button_mask, int x, int y)
1202{
1203 int buttons = 0;
1204 int dz = 0;
1205
1206 if (button_mask & 0x01)
28a76be8 1207 buttons |= MOUSE_EVENT_LBUTTON;
24236869 1208 if (button_mask & 0x02)
28a76be8 1209 buttons |= MOUSE_EVENT_MBUTTON;
24236869 1210 if (button_mask & 0x04)
28a76be8 1211 buttons |= MOUSE_EVENT_RBUTTON;
24236869 1212 if (button_mask & 0x08)
28a76be8 1213 dz = -1;
24236869 1214 if (button_mask & 0x10)
28a76be8 1215 dz = 1;
564c337e
FB
1216
1217 if (vs->absolute) {
28a76be8
AL
1218 kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
1219 y * 0x7FFF / (ds_get_height(vs->ds) - 1),
1220 dz, buttons);
29fa4ed9 1221 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
28a76be8
AL
1222 x -= 0x7FFF;
1223 y -= 0x7FFF;
24236869 1224
28a76be8 1225 kbd_mouse_event(x, y, dz, buttons);
564c337e 1226 } else {
28a76be8
AL
1227 if (vs->last_x != -1)
1228 kbd_mouse_event(x - vs->last_x,
1229 y - vs->last_y,
1230 dz, buttons);
1231 vs->last_x = x;
1232 vs->last_y = y;
24236869 1233 }
564c337e
FB
1234
1235 check_pointer_type_change(vs, kbd_mouse_is_absolute());
24236869
FB
1236}
1237
64f5a135
FB
1238static void reset_keys(VncState *vs)
1239{
1240 int i;
1241 for(i = 0; i < 256; i++) {
1242 if (vs->modifiers_state[i]) {
1243 if (i & 0x80)
1244 kbd_put_keycode(0xe0);
1245 kbd_put_keycode(i | 0x80);
1246 vs->modifiers_state[i] = 0;
1247 }
1248 }
1249}
1250
a528b80c
AZ
1251static void press_key(VncState *vs, int keysym)
1252{
753b4053
AL
1253 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
1254 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
a528b80c
AZ
1255}
1256
9ca313aa 1257static void do_key_event(VncState *vs, int down, int keycode, int sym)
24236869 1258{
64f5a135
FB
1259 /* QEMU console switch */
1260 switch(keycode) {
1261 case 0x2a: /* Left Shift */
1262 case 0x36: /* Right Shift */
1263 case 0x1d: /* Left CTRL */
1264 case 0x9d: /* Right CTRL */
1265 case 0x38: /* Left ALT */
1266 case 0xb8: /* Right ALT */
1267 if (down)
1268 vs->modifiers_state[keycode] = 1;
1269 else
1270 vs->modifiers_state[keycode] = 0;
1271 break;
5fafdf24 1272 case 0x02 ... 0x0a: /* '1' to '9' keys */
64f5a135
FB
1273 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1274 /* Reset the modifiers sent to the current console */
1275 reset_keys(vs);
1276 console_select(keycode - 0x02);
1277 return;
1278 }
1279 break;
28a76be8
AL
1280 case 0x3a: /* CapsLock */
1281 case 0x45: /* NumLock */
a528b80c
AZ
1282 if (!down)
1283 vs->modifiers_state[keycode] ^= 1;
1284 break;
1285 }
1286
753b4053 1287 if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
a528b80c
AZ
1288 /* If the numlock state needs to change then simulate an additional
1289 keypress before sending this one. This will happen if the user
1290 toggles numlock away from the VNC window.
1291 */
753b4053 1292 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
a528b80c
AZ
1293 if (!vs->modifiers_state[0x45]) {
1294 vs->modifiers_state[0x45] = 1;
1295 press_key(vs, 0xff7f);
1296 }
1297 } else {
1298 if (vs->modifiers_state[0x45]) {
1299 vs->modifiers_state[0x45] = 0;
1300 press_key(vs, 0xff7f);
1301 }
1302 }
64f5a135 1303 }
24236869 1304
64f5a135
FB
1305 if (is_graphic_console()) {
1306 if (keycode & 0x80)
1307 kbd_put_keycode(0xe0);
1308 if (down)
1309 kbd_put_keycode(keycode & 0x7f);
1310 else
1311 kbd_put_keycode(keycode | 0x80);
1312 } else {
1313 /* QEMU console emulation */
1314 if (down) {
1315 switch (keycode) {
1316 case 0x2a: /* Left Shift */
1317 case 0x36: /* Right Shift */
1318 case 0x1d: /* Left CTRL */
1319 case 0x9d: /* Right CTRL */
1320 case 0x38: /* Left ALT */
1321 case 0xb8: /* Right ALT */
1322 break;
1323 case 0xc8:
1324 kbd_put_keysym(QEMU_KEY_UP);
1325 break;
1326 case 0xd0:
1327 kbd_put_keysym(QEMU_KEY_DOWN);
1328 break;
1329 case 0xcb:
1330 kbd_put_keysym(QEMU_KEY_LEFT);
1331 break;
1332 case 0xcd:
1333 kbd_put_keysym(QEMU_KEY_RIGHT);
1334 break;
1335 case 0xd3:
1336 kbd_put_keysym(QEMU_KEY_DELETE);
1337 break;
1338 case 0xc7:
1339 kbd_put_keysym(QEMU_KEY_HOME);
1340 break;
1341 case 0xcf:
1342 kbd_put_keysym(QEMU_KEY_END);
1343 break;
1344 case 0xc9:
1345 kbd_put_keysym(QEMU_KEY_PAGEUP);
1346 break;
1347 case 0xd1:
1348 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1349 break;
1350 default:
1351 kbd_put_keysym(sym);
1352 break;
1353 }
1354 }
1355 }
24236869
FB
1356}
1357
bdbd7676
FB
1358static void key_event(VncState *vs, int down, uint32_t sym)
1359{
9ca313aa
AL
1360 int keycode;
1361
a528b80c 1362 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
28a76be8 1363 sym = sym - 'A' + 'a';
9ca313aa 1364
753b4053 1365 keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
9ca313aa
AL
1366 do_key_event(vs, down, keycode, sym);
1367}
1368
1369static void ext_key_event(VncState *vs, int down,
1370 uint32_t sym, uint16_t keycode)
1371{
1372 /* if the user specifies a keyboard layout, always use it */
1373 if (keyboard_layout)
1374 key_event(vs, down, sym);
1375 else
1376 do_key_event(vs, down, keycode, sym);
bdbd7676
FB
1377}
1378
24236869 1379static void framebuffer_update_request(VncState *vs, int incremental,
28a76be8
AL
1380 int x_position, int y_position,
1381 int w, int h)
24236869 1382{
0e1f5a0c
AL
1383 if (x_position > ds_get_width(vs->ds))
1384 x_position = ds_get_width(vs->ds);
1385 if (y_position > ds_get_height(vs->ds))
1386 y_position = ds_get_height(vs->ds);
1387 if (x_position + w >= ds_get_width(vs->ds))
1388 w = ds_get_width(vs->ds) - x_position;
1389 if (y_position + h >= ds_get_height(vs->ds))
1390 h = ds_get_height(vs->ds) - y_position;
cf2d385c 1391
24236869
FB
1392 int i;
1393 vs->need_update = 1;
1394 if (!incremental) {
28a76be8 1395 char *old_row = vs->old_data + y_position * ds_get_linesize(vs->ds);
24236869 1396
28a76be8 1397 for (i = 0; i < h; i++) {
5fafdf24 1398 vnc_set_bits(vs->dirty_row[y_position + i],
0e1f5a0c 1399 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
28a76be8
AL
1400 memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds));
1401 old_row += ds_get_linesize(vs->ds);
1402 }
24236869
FB
1403 }
1404}
1405
9ca313aa
AL
1406static void send_ext_key_event_ack(VncState *vs)
1407{
1408 vnc_write_u8(vs, 0);
1409 vnc_write_u8(vs, 0);
1410 vnc_write_u16(vs, 1);
29fa4ed9
AL
1411 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1412 VNC_ENCODING_EXT_KEY_EVENT);
9ca313aa
AL
1413 vnc_flush(vs);
1414}
1415
429a8ed3 1416static void send_ext_audio_ack(VncState *vs)
1417{
1418 vnc_write_u8(vs, 0);
1419 vnc_write_u8(vs, 0);
1420 vnc_write_u16(vs, 1);
29fa4ed9
AL
1421 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1422 VNC_ENCODING_AUDIO);
429a8ed3 1423 vnc_flush(vs);
1424}
1425
24236869
FB
1426static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1427{
1428 int i;
29fa4ed9 1429 unsigned int enc = 0;
24236869 1430
059cef40 1431 vnc_zlib_init(vs);
29fa4ed9 1432 vs->features = 0;
fb437313
AL
1433 vs->vnc_encoding = 0;
1434 vs->tight_compression = 9;
1435 vs->tight_quality = 9;
564c337e 1436 vs->absolute = -1;
24236869
FB
1437
1438 for (i = n_encodings - 1; i >= 0; i--) {
29fa4ed9
AL
1439 enc = encodings[i];
1440 switch (enc) {
1441 case VNC_ENCODING_RAW:
fb437313 1442 vs->vnc_encoding = enc;
29fa4ed9
AL
1443 break;
1444 case VNC_ENCODING_COPYRECT:
753b4053 1445 vs->features |= VNC_FEATURE_COPYRECT_MASK;
29fa4ed9
AL
1446 break;
1447 case VNC_ENCODING_HEXTILE:
1448 vs->features |= VNC_FEATURE_HEXTILE_MASK;
fb437313 1449 vs->vnc_encoding = enc;
29fa4ed9 1450 break;
059cef40
AL
1451 case VNC_ENCODING_ZLIB:
1452 vs->features |= VNC_FEATURE_ZLIB_MASK;
1453 vs->vnc_encoding = enc;
1454 break;
29fa4ed9
AL
1455 case VNC_ENCODING_DESKTOPRESIZE:
1456 vs->features |= VNC_FEATURE_RESIZE_MASK;
1457 break;
1458 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1459 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1460 break;
1461 case VNC_ENCODING_EXT_KEY_EVENT:
9ca313aa
AL
1462 send_ext_key_event_ack(vs);
1463 break;
29fa4ed9 1464 case VNC_ENCODING_AUDIO:
429a8ed3 1465 send_ext_audio_ack(vs);
1466 break;
29fa4ed9
AL
1467 case VNC_ENCODING_WMVi:
1468 vs->features |= VNC_FEATURE_WMVI_MASK;
ca4cca4d 1469 break;
fb437313
AL
1470 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1471 vs->tight_compression = (enc & 0x0F);
1472 break;
1473 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1474 vs->tight_quality = (enc & 0x0F);
1475 break;
29fa4ed9
AL
1476 default:
1477 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1478 break;
1479 }
24236869 1480 }
564c337e
FB
1481
1482 check_pointer_type_change(vs, kbd_mouse_is_absolute());
24236869
FB
1483}
1484
6cec5487
AL
1485static void set_pixel_conversion(VncState *vs)
1486{
1487 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1488 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1489 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1490 vs->write_pixels = vnc_write_pixels_copy;
1491 switch (vs->ds->surface->pf.bits_per_pixel) {
1492 case 8:
1493 vs->send_hextile_tile = send_hextile_tile_8;
1494 break;
1495 case 16:
1496 vs->send_hextile_tile = send_hextile_tile_16;
1497 break;
1498 case 32:
1499 vs->send_hextile_tile = send_hextile_tile_32;
1500 break;
1501 }
1502 } else {
1503 vs->write_pixels = vnc_write_pixels_generic;
1504 switch (vs->ds->surface->pf.bits_per_pixel) {
1505 case 8:
1506 vs->send_hextile_tile = send_hextile_tile_generic_8;
1507 break;
1508 case 16:
1509 vs->send_hextile_tile = send_hextile_tile_generic_16;
1510 break;
1511 case 32:
1512 vs->send_hextile_tile = send_hextile_tile_generic_32;
1513 break;
1514 }
1515 }
1516}
1517
24236869 1518static void set_pixel_format(VncState *vs,
28a76be8
AL
1519 int bits_per_pixel, int depth,
1520 int big_endian_flag, int true_color_flag,
1521 int red_max, int green_max, int blue_max,
1522 int red_shift, int green_shift, int blue_shift)
24236869 1523{
3512779a 1524 if (!true_color_flag) {
28a76be8 1525 vnc_client_error(vs);
3512779a
FB
1526 return;
1527 }
24236869 1528
6cec5487
AL
1529 vs->clientds = vs->serverds;
1530 vs->clientds.pf.rmax = red_max;
90a1e3c0 1531 count_bits(vs->clientds.pf.rbits, red_max);
6cec5487
AL
1532 vs->clientds.pf.rshift = red_shift;
1533 vs->clientds.pf.rmask = red_max << red_shift;
1534 vs->clientds.pf.gmax = green_max;
90a1e3c0 1535 count_bits(vs->clientds.pf.gbits, green_max);
6cec5487
AL
1536 vs->clientds.pf.gshift = green_shift;
1537 vs->clientds.pf.gmask = green_max << green_shift;
1538 vs->clientds.pf.bmax = blue_max;
90a1e3c0 1539 count_bits(vs->clientds.pf.bbits, blue_max);
6cec5487
AL
1540 vs->clientds.pf.bshift = blue_shift;
1541 vs->clientds.pf.bmask = blue_max << blue_shift;
1542 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1543 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1544 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1545 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1546
1547 set_pixel_conversion(vs);
24236869
FB
1548
1549 vga_hw_invalidate();
1550 vga_hw_update();
1551}
1552
ca4cca4d
AL
1553static void pixel_format_message (VncState *vs) {
1554 char pad[3] = { 0, 0, 0 };
1555
6cec5487
AL
1556 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1557 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
ca4cca4d
AL
1558
1559#ifdef WORDS_BIGENDIAN
1560 vnc_write_u8(vs, 1); /* big-endian-flag */
1561#else
1562 vnc_write_u8(vs, 0); /* big-endian-flag */
1563#endif
1564 vnc_write_u8(vs, 1); /* true-color-flag */
6cec5487
AL
1565 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1566 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1567 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1568 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1569 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1570 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
1571 if (vs->ds->surface->pf.bits_per_pixel == 32)
ca4cca4d 1572 vs->send_hextile_tile = send_hextile_tile_32;
6cec5487 1573 else if (vs->ds->surface->pf.bits_per_pixel == 16)
ca4cca4d 1574 vs->send_hextile_tile = send_hextile_tile_16;
6cec5487 1575 else if (vs->ds->surface->pf.bits_per_pixel == 8)
ca4cca4d 1576 vs->send_hextile_tile = send_hextile_tile_8;
6cec5487
AL
1577 vs->clientds = *(vs->ds->surface);
1578 vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
ca4cca4d
AL
1579 vs->write_pixels = vnc_write_pixels_copy;
1580
1581 vnc_write(vs, pad, 3); /* padding */
1582}
1583
7d957bd8
AL
1584static void vnc_dpy_setdata(DisplayState *ds)
1585{
1586 /* We don't have to do anything */
1587}
1588
753b4053 1589static void vnc_colordepth(VncState *vs)
7eac3a87 1590{
753b4053 1591 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
ca4cca4d
AL
1592 /* Sending a WMVi message to notify the client*/
1593 vnc_write_u8(vs, 0); /* msg id */
1594 vnc_write_u8(vs, 0);
1595 vnc_write_u16(vs, 1); /* number of rects */
753b4053
AL
1596 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1597 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
ca4cca4d
AL
1598 pixel_format_message(vs);
1599 vnc_flush(vs);
7eac3a87 1600 } else {
6cec5487 1601 set_pixel_conversion(vs);
7eac3a87
AL
1602 }
1603}
1604
60fe76f3 1605static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
1606{
1607 int i;
1608 uint16_t limit;
1609
1610 switch (data[0]) {
1611 case 0:
28a76be8
AL
1612 if (len == 1)
1613 return 20;
1614
1615 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1616 read_u8(data, 6), read_u8(data, 7),
1617 read_u16(data, 8), read_u16(data, 10),
1618 read_u16(data, 12), read_u8(data, 14),
1619 read_u8(data, 15), read_u8(data, 16));
1620 break;
24236869 1621 case 2:
28a76be8
AL
1622 if (len == 1)
1623 return 4;
24236869 1624
28a76be8 1625 if (len == 4) {
69dd5c9f
AL
1626 limit = read_u16(data, 2);
1627 if (limit > 0)
1628 return 4 + (limit * 4);
1629 } else
1630 limit = read_u16(data, 2);
24236869 1631
28a76be8
AL
1632 for (i = 0; i < limit; i++) {
1633 int32_t val = read_s32(data, 4 + (i * 4));
1634 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1635 }
24236869 1636
28a76be8
AL
1637 set_encodings(vs, (int32_t *)(data + 4), limit);
1638 break;
24236869 1639 case 3:
28a76be8
AL
1640 if (len == 1)
1641 return 10;
24236869 1642
28a76be8
AL
1643 framebuffer_update_request(vs,
1644 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1645 read_u16(data, 6), read_u16(data, 8));
1646 break;
24236869 1647 case 4:
28a76be8
AL
1648 if (len == 1)
1649 return 8;
24236869 1650
28a76be8
AL
1651 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1652 break;
24236869 1653 case 5:
28a76be8
AL
1654 if (len == 1)
1655 return 6;
24236869 1656
28a76be8
AL
1657 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1658 break;
24236869 1659 case 6:
28a76be8
AL
1660 if (len == 1)
1661 return 8;
24236869 1662
28a76be8 1663 if (len == 8) {
baa7666c
TS
1664 uint32_t dlen = read_u32(data, 4);
1665 if (dlen > 0)
1666 return 8 + dlen;
1667 }
24236869 1668
28a76be8
AL
1669 client_cut_text(vs, read_u32(data, 4), data + 8);
1670 break;
9ca313aa
AL
1671 case 255:
1672 if (len == 1)
1673 return 2;
1674
1675 switch (read_u8(data, 1)) {
1676 case 0:
1677 if (len == 2)
1678 return 12;
1679
1680 ext_key_event(vs, read_u16(data, 2),
1681 read_u32(data, 4), read_u32(data, 8));
1682 break;
429a8ed3 1683 case 1:
1684 if (len == 2)
1685 return 4;
1686
1687 switch (read_u16 (data, 2)) {
1688 case 0:
1689 audio_add(vs);
1690 break;
1691 case 1:
1692 audio_del(vs);
1693 break;
1694 case 2:
1695 if (len == 4)
1696 return 10;
1697 switch (read_u8(data, 4)) {
1698 case 0: vs->as.fmt = AUD_FMT_U8; break;
1699 case 1: vs->as.fmt = AUD_FMT_S8; break;
1700 case 2: vs->as.fmt = AUD_FMT_U16; break;
1701 case 3: vs->as.fmt = AUD_FMT_S16; break;
1702 case 4: vs->as.fmt = AUD_FMT_U32; break;
1703 case 5: vs->as.fmt = AUD_FMT_S32; break;
1704 default:
1705 printf("Invalid audio format %d\n", read_u8(data, 4));
1706 vnc_client_error(vs);
1707 break;
1708 }
1709 vs->as.nchannels = read_u8(data, 5);
1710 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1711 printf("Invalid audio channel coount %d\n",
1712 read_u8(data, 5));
1713 vnc_client_error(vs);
1714 break;
1715 }
1716 vs->as.freq = read_u32(data, 6);
1717 break;
1718 default:
1719 printf ("Invalid audio message %d\n", read_u8(data, 4));
1720 vnc_client_error(vs);
1721 break;
1722 }
1723 break;
1724
9ca313aa
AL
1725 default:
1726 printf("Msg: %d\n", read_u16(data, 0));
1727 vnc_client_error(vs);
1728 break;
1729 }
1730 break;
24236869 1731 default:
28a76be8
AL
1732 printf("Msg: %d\n", data[0]);
1733 vnc_client_error(vs);
1734 break;
24236869 1735 }
5fafdf24 1736
24236869
FB
1737 vnc_read_when(vs, protocol_client_msg, 1);
1738 return 0;
1739}
1740
60fe76f3 1741static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 1742{
c35734b2
TS
1743 char buf[1024];
1744 int size;
24236869 1745
0e1f5a0c
AL
1746 vnc_write_u16(vs, ds_get_width(vs->ds));
1747 vnc_write_u16(vs, ds_get_height(vs->ds));
24236869 1748
ca4cca4d 1749 pixel_format_message(vs);
24236869 1750
c35734b2
TS
1751 if (qemu_name)
1752 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1753 else
1754 size = snprintf(buf, sizeof(buf), "QEMU");
1755
1756 vnc_write_u32(vs, size);
1757 vnc_write(vs, buf, size);
24236869
FB
1758 vnc_flush(vs);
1759
1760 vnc_read_when(vs, protocol_client_msg, 1);
1761
1762 return 0;
1763}
1764
5fb6c7a8
AL
1765void start_client_init(VncState *vs)
1766{
1767 vnc_read_when(vs, protocol_client_init, 1);
1768}
1769
70848515
TS
1770static void make_challenge(VncState *vs)
1771{
1772 int i;
1773
1774 srand(time(NULL)+getpid()+getpid()*987654+rand());
1775
1776 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1777 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1778}
1779
60fe76f3 1780static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 1781{
60fe76f3 1782 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
70848515 1783 int i, j, pwlen;
60fe76f3 1784 unsigned char key[8];
70848515 1785
753b4053 1786 if (!vs->vd->password || !vs->vd->password[0]) {
28a76be8
AL
1787 VNC_DEBUG("No password configured on server");
1788 vnc_write_u32(vs, 1); /* Reject auth */
1789 if (vs->minor >= 8) {
1790 static const char err[] = "Authentication failed";
1791 vnc_write_u32(vs, sizeof(err));
1792 vnc_write(vs, err, sizeof(err));
1793 }
1794 vnc_flush(vs);
1795 vnc_client_error(vs);
1796 return 0;
70848515
TS
1797 }
1798
1799 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1800
1801 /* Calculate the expected challenge response */
753b4053 1802 pwlen = strlen(vs->vd->password);
70848515 1803 for (i=0; i<sizeof(key); i++)
753b4053 1804 key[i] = i<pwlen ? vs->vd->password[i] : 0;
70848515
TS
1805 deskey(key, EN0);
1806 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1807 des(response+j, response+j);
1808
1809 /* Compare expected vs actual challenge response */
1810 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
28a76be8
AL
1811 VNC_DEBUG("Client challenge reponse did not match\n");
1812 vnc_write_u32(vs, 1); /* Reject auth */
1813 if (vs->minor >= 8) {
1814 static const char err[] = "Authentication failed";
1815 vnc_write_u32(vs, sizeof(err));
1816 vnc_write(vs, err, sizeof(err));
1817 }
1818 vnc_flush(vs);
1819 vnc_client_error(vs);
70848515 1820 } else {
28a76be8
AL
1821 VNC_DEBUG("Accepting VNC challenge response\n");
1822 vnc_write_u32(vs, 0); /* Accept auth */
1823 vnc_flush(vs);
70848515 1824
5fb6c7a8 1825 start_client_init(vs);
70848515
TS
1826 }
1827 return 0;
1828}
1829
5fb6c7a8 1830void start_auth_vnc(VncState *vs)
70848515
TS
1831{
1832 make_challenge(vs);
1833 /* Send client a 'random' challenge */
1834 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1835 vnc_flush(vs);
1836
1837 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
469b15c6
TS
1838}
1839
1840
60fe76f3 1841static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
1842{
1843 /* We only advertise 1 auth scheme at a time, so client
1844 * must pick the one we sent. Verify this */
753b4053 1845 if (data[0] != vs->vd->auth) { /* Reject auth */
1263b7d6 1846 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
70848515
TS
1847 vnc_write_u32(vs, 1);
1848 if (vs->minor >= 8) {
1849 static const char err[] = "Authentication failed";
1850 vnc_write_u32(vs, sizeof(err));
1851 vnc_write(vs, err, sizeof(err));
1852 }
1853 vnc_client_error(vs);
1854 } else { /* Accept requested auth */
1855 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
753b4053 1856 switch (vs->vd->auth) {
70848515
TS
1857 case VNC_AUTH_NONE:
1858 VNC_DEBUG("Accept auth none\n");
a26c97ad
AZ
1859 if (vs->minor >= 8) {
1860 vnc_write_u32(vs, 0); /* Accept auth completion */
1861 vnc_flush(vs);
1862 }
5fb6c7a8 1863 start_client_init(vs);
70848515
TS
1864 break;
1865
1866 case VNC_AUTH_VNC:
1867 VNC_DEBUG("Start VNC auth\n");
5fb6c7a8
AL
1868 start_auth_vnc(vs);
1869 break;
70848515 1870
eb38c52c 1871#ifdef CONFIG_VNC_TLS
8d5d2d4c
TS
1872 case VNC_AUTH_VENCRYPT:
1873 VNC_DEBUG("Accept VeNCrypt auth\n");;
5fb6c7a8
AL
1874 start_auth_vencrypt(vs);
1875 break;
8d5d2d4c
TS
1876#endif /* CONFIG_VNC_TLS */
1877
2f9606b3
AL
1878#ifdef CONFIG_VNC_SASL
1879 case VNC_AUTH_SASL:
1880 VNC_DEBUG("Accept SASL auth\n");
1881 start_auth_sasl(vs);
1882 break;
1883#endif /* CONFIG_VNC_SASL */
1884
70848515 1885 default: /* Should not be possible, but just in case */
1263b7d6 1886 VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
70848515
TS
1887 vnc_write_u8(vs, 1);
1888 if (vs->minor >= 8) {
1889 static const char err[] = "Authentication failed";
1890 vnc_write_u32(vs, sizeof(err));
1891 vnc_write(vs, err, sizeof(err));
1892 }
1893 vnc_client_error(vs);
1894 }
1895 }
1896 return 0;
1897}
1898
60fe76f3 1899static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
1900{
1901 char local[13];
24236869
FB
1902
1903 memcpy(local, version, 12);
1904 local[12] = 0;
1905
70848515 1906 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
28a76be8
AL
1907 VNC_DEBUG("Malformed protocol version %s\n", local);
1908 vnc_client_error(vs);
1909 return 0;
24236869 1910 }
70848515
TS
1911 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1912 if (vs->major != 3 ||
28a76be8
AL
1913 (vs->minor != 3 &&
1914 vs->minor != 4 &&
1915 vs->minor != 5 &&
1916 vs->minor != 7 &&
1917 vs->minor != 8)) {
1918 VNC_DEBUG("Unsupported client version\n");
1919 vnc_write_u32(vs, VNC_AUTH_INVALID);
1920 vnc_flush(vs);
1921 vnc_client_error(vs);
1922 return 0;
70848515 1923 }
b0566f4f 1924 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
1925 * as equivalent to v3.3 by servers
1926 */
b0566f4f 1927 if (vs->minor == 4 || vs->minor == 5)
28a76be8 1928 vs->minor = 3;
70848515
TS
1929
1930 if (vs->minor == 3) {
28a76be8 1931 if (vs->vd->auth == VNC_AUTH_NONE) {
70848515 1932 VNC_DEBUG("Tell client auth none\n");
753b4053 1933 vnc_write_u32(vs, vs->vd->auth);
70848515 1934 vnc_flush(vs);
28a76be8 1935 start_client_init(vs);
753b4053 1936 } else if (vs->vd->auth == VNC_AUTH_VNC) {
70848515 1937 VNC_DEBUG("Tell client VNC auth\n");
753b4053 1938 vnc_write_u32(vs, vs->vd->auth);
70848515
TS
1939 vnc_flush(vs);
1940 start_auth_vnc(vs);
1941 } else {
753b4053 1942 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
70848515
TS
1943 vnc_write_u32(vs, VNC_AUTH_INVALID);
1944 vnc_flush(vs);
1945 vnc_client_error(vs);
1946 }
1947 } else {
28a76be8
AL
1948 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
1949 vnc_write_u8(vs, 1); /* num auth */
1950 vnc_write_u8(vs, vs->vd->auth);
1951 vnc_read_when(vs, protocol_client_auth, 1);
1952 vnc_flush(vs);
70848515 1953 }
24236869
FB
1954
1955 return 0;
1956}
1957
753b4053 1958static void vnc_connect(VncDisplay *vd, int csock)
3aa3eea3 1959{
753b4053
AL
1960 VncState *vs = qemu_mallocz(sizeof(VncState));
1961 vs->csock = csock;
1962
1963 VNC_DEBUG("New client on socket %d\n", csock);
7d957bd8 1964 dcl->idle = 0;
3aa3eea3
AZ
1965 socket_set_nonblock(vs->csock);
1966 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
753b4053
AL
1967
1968 vs->vd = vd;
1969 vs->ds = vd->ds;
1970 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
1971 vs->last_x = -1;
1972 vs->last_y = -1;
1973
1974 vs->as.freq = 44100;
1975 vs->as.nchannels = 2;
1976 vs->as.fmt = AUD_FMT_S16;
1977 vs->as.endianness = 0;
1978
1979 vnc_resize(vs);
3aa3eea3
AZ
1980 vnc_write(vs, "RFB 003.008\n", 12);
1981 vnc_flush(vs);
1982 vnc_read_when(vs, protocol_version, 12);
0e1f5a0c 1983 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
3aa3eea3 1984 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
3aa3eea3 1985 vnc_update_client(vs);
53762ddb 1986 reset_keys(vs);
753b4053
AL
1987
1988 vs->next = vd->clients;
1989 vd->clients = vs;
3aa3eea3
AZ
1990}
1991
24236869
FB
1992static void vnc_listen_read(void *opaque)
1993{
753b4053 1994 VncDisplay *vs = opaque;
24236869
FB
1995 struct sockaddr_in addr;
1996 socklen_t addrlen = sizeof(addr);
1997
9f60ad50
AZ
1998 /* Catch-up */
1999 vga_hw_update();
2000
753b4053
AL
2001 int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2002 if (csock != -1) {
2003 vnc_connect(vs, csock);
24236869
FB
2004 }
2005}
2006
71cab5ca 2007void vnc_display_init(DisplayState *ds)
24236869 2008{
753b4053 2009 VncDisplay *vs;
24236869
FB
2010
2011 vs = qemu_mallocz(sizeof(VncState));
7d957bd8 2012 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
24236869
FB
2013
2014 ds->opaque = vs;
7d957bd8 2015 dcl->idle = 1;
753b4053 2016 vnc_display = vs;
24236869
FB
2017
2018 vs->lsock = -1;
24236869
FB
2019
2020 vs->ds = ds;
2021
9ca313aa 2022 if (keyboard_layout)
0483755a 2023 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
9ca313aa 2024 else
0483755a 2025 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
24236869 2026
24236869 2027 if (!vs->kbd_layout)
28a76be8 2028 exit(1);
24236869 2029
753b4053 2030 dcl->dpy_copy = vnc_dpy_copy;
7d957bd8
AL
2031 dcl->dpy_update = vnc_dpy_update;
2032 dcl->dpy_resize = vnc_dpy_resize;
2033 dcl->dpy_setdata = vnc_dpy_setdata;
7d957bd8 2034 register_displaychangelistener(ds, dcl);
71cab5ca
TS
2035}
2036
6f43024c 2037
71cab5ca
TS
2038void vnc_display_close(DisplayState *ds)
2039{
753b4053 2040 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
71cab5ca 2041
452b4d88
AL
2042 if (!vs)
2043 return;
71cab5ca 2044 if (vs->display) {
28a76be8
AL
2045 qemu_free(vs->display);
2046 vs->display = NULL;
71cab5ca
TS
2047 }
2048 if (vs->lsock != -1) {
28a76be8
AL
2049 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2050 close(vs->lsock);
2051 vs->lsock = -1;
71cab5ca 2052 }
70848515 2053 vs->auth = VNC_AUTH_INVALID;
eb38c52c 2054#ifdef CONFIG_VNC_TLS
8d5d2d4c 2055 vs->subauth = VNC_AUTH_INVALID;
5fb6c7a8 2056 vs->tls.x509verify = 0;
8d5d2d4c 2057#endif
70848515
TS
2058}
2059
2060int vnc_display_password(DisplayState *ds, const char *password)
2061{
753b4053 2062 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
70848515
TS
2063
2064 if (vs->password) {
28a76be8
AL
2065 qemu_free(vs->password);
2066 vs->password = NULL;
70848515
TS
2067 }
2068 if (password && password[0]) {
28a76be8
AL
2069 if (!(vs->password = qemu_strdup(password)))
2070 return -1;
70848515
TS
2071 }
2072
2073 return 0;
71cab5ca
TS
2074}
2075
70848515 2076int vnc_display_open(DisplayState *ds, const char *display)
71cab5ca 2077{
753b4053 2078 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
70848515
TS
2079 const char *options;
2080 int password = 0;
3aa3eea3 2081 int reverse = 0;
9712ecaf 2082 int to_port = 0;
eb38c52c 2083#ifdef CONFIG_VNC_TLS
3a702699 2084 int tls = 0, x509 = 0;
8d5d2d4c 2085#endif
2f9606b3
AL
2086#ifdef CONFIG_VNC_SASL
2087 int sasl = 0;
2088 int saslErr;
2089#endif
76655d6d 2090 int acl = 0;
71cab5ca 2091
753b4053 2092 if (!vnc_display)
452b4d88 2093 return -1;
71cab5ca 2094 vnc_display_close(ds);
70848515 2095 if (strcmp(display, "none") == 0)
28a76be8 2096 return 0;
24236869 2097
70848515 2098 if (!(vs->display = strdup(display)))
28a76be8 2099 return -1;
70848515
TS
2100
2101 options = display;
2102 while ((options = strchr(options, ','))) {
28a76be8
AL
2103 options++;
2104 if (strncmp(options, "password", 8) == 0) {
2105 password = 1; /* Require password auth */
2106 } else if (strncmp(options, "reverse", 7) == 0) {
2107 reverse = 1;
2108 } else if (strncmp(options, "to=", 3) == 0) {
9712ecaf 2109 to_port = atoi(options+3) + 5900;
2f9606b3 2110#ifdef CONFIG_VNC_SASL
28a76be8
AL
2111 } else if (strncmp(options, "sasl", 4) == 0) {
2112 sasl = 1; /* Require SASL auth */
2f9606b3 2113#endif
eb38c52c 2114#ifdef CONFIG_VNC_TLS
28a76be8
AL
2115 } else if (strncmp(options, "tls", 3) == 0) {
2116 tls = 1; /* Require TLS */
2117 } else if (strncmp(options, "x509", 4) == 0) {
2118 char *start, *end;
2119 x509 = 1; /* Require x509 certificates */
2120 if (strncmp(options, "x509verify", 10) == 0)
2121 vs->tls.x509verify = 1; /* ...and verify client certs */
2122
2123 /* Now check for 'x509=/some/path' postfix
2124 * and use that to setup x509 certificate/key paths */
2125 start = strchr(options, '=');
2126 end = strchr(options, ',');
2127 if (start && (!end || (start < end))) {
2128 int len = end ? end-(start+1) : strlen(start+1);
2129 char *path = qemu_strndup(start + 1, len);
2130
2131 VNC_DEBUG("Trying certificate path '%s'\n", path);
2132 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2133 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2134 qemu_free(path);
2135 qemu_free(vs->display);
2136 vs->display = NULL;
2137 return -1;
2138 }
2139 qemu_free(path);
2140 } else {
2141 fprintf(stderr, "No certificate path provided\n");
2142 qemu_free(vs->display);
2143 vs->display = NULL;
2144 return -1;
2145 }
8d5d2d4c 2146#endif
28a76be8
AL
2147 } else if (strncmp(options, "acl", 3) == 0) {
2148 acl = 1;
2149 }
70848515
TS
2150 }
2151
76655d6d
AL
2152#ifdef CONFIG_VNC_TLS
2153 if (acl && x509 && vs->tls.x509verify) {
28a76be8
AL
2154 if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
2155 fprintf(stderr, "Failed to create x509 dname ACL\n");
2156 exit(1);
2157 }
76655d6d
AL
2158 }
2159#endif
2160#ifdef CONFIG_VNC_SASL
2161 if (acl && sasl) {
28a76be8
AL
2162 if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
2163 fprintf(stderr, "Failed to create username ACL\n");
2164 exit(1);
2165 }
76655d6d
AL
2166 }
2167#endif
2168
2f9606b3
AL
2169 /*
2170 * Combinations we support here:
2171 *
2172 * - no-auth (clear text, no auth)
2173 * - password (clear text, weak auth)
2174 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
2175 * - tls (encrypt, weak anonymous creds, no auth)
2176 * - tls + password (encrypt, weak anonymous creds, weak auth)
2177 * - tls + sasl (encrypt, weak anonymous creds, good auth)
2178 * - tls + x509 (encrypt, good x509 creds, no auth)
2179 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
2180 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
2181 *
2182 * NB1. TLS is a stackable auth scheme.
2183 * NB2. the x509 schemes have option to validate a client cert dname
2184 */
70848515 2185 if (password) {
eb38c52c 2186#ifdef CONFIG_VNC_TLS
28a76be8
AL
2187 if (tls) {
2188 vs->auth = VNC_AUTH_VENCRYPT;
2189 if (x509) {
2190 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2191 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2192 } else {
2193 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2194 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2195 }
2196 } else {
2f9606b3 2197#endif /* CONFIG_VNC_TLS */
28a76be8
AL
2198 VNC_DEBUG("Initializing VNC server with password auth\n");
2199 vs->auth = VNC_AUTH_VNC;
eb38c52c 2200#ifdef CONFIG_VNC_TLS
28a76be8
AL
2201 vs->subauth = VNC_AUTH_INVALID;
2202 }
2f9606b3
AL
2203#endif /* CONFIG_VNC_TLS */
2204#ifdef CONFIG_VNC_SASL
2205 } else if (sasl) {
2206#ifdef CONFIG_VNC_TLS
2207 if (tls) {
2208 vs->auth = VNC_AUTH_VENCRYPT;
2209 if (x509) {
28a76be8 2210 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
2f9606b3
AL
2211 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
2212 } else {
28a76be8 2213 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
2f9606b3
AL
2214 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
2215 }
2216 } else {
2217#endif /* CONFIG_VNC_TLS */
28a76be8 2218 VNC_DEBUG("Initializing VNC server with SASL auth\n");
2f9606b3
AL
2219 vs->auth = VNC_AUTH_SASL;
2220#ifdef CONFIG_VNC_TLS
2221 vs->subauth = VNC_AUTH_INVALID;
2222 }
2223#endif /* CONFIG_VNC_TLS */
2224#endif /* CONFIG_VNC_SASL */
70848515 2225 } else {
eb38c52c 2226#ifdef CONFIG_VNC_TLS
28a76be8
AL
2227 if (tls) {
2228 vs->auth = VNC_AUTH_VENCRYPT;
2229 if (x509) {
2230 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2231 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2232 } else {
2233 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2234 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2235 }
2236 } else {
8d5d2d4c 2237#endif
28a76be8
AL
2238 VNC_DEBUG("Initializing VNC server with no auth\n");
2239 vs->auth = VNC_AUTH_NONE;
eb38c52c 2240#ifdef CONFIG_VNC_TLS
28a76be8
AL
2241 vs->subauth = VNC_AUTH_INVALID;
2242 }
8d5d2d4c 2243#endif
70848515 2244 }
24236869 2245
2f9606b3
AL
2246#ifdef CONFIG_VNC_SASL
2247 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2248 fprintf(stderr, "Failed to initialize SASL auth %s",
2249 sasl_errstring(saslErr, NULL, NULL));
2250 free(vs->display);
2251 vs->display = NULL;
2252 return -1;
2253 }
2254#endif
2255
3aa3eea3 2256 if (reverse) {
9712ecaf
AL
2257 /* connect to viewer */
2258 if (strncmp(display, "unix:", 5) == 0)
2259 vs->lsock = unix_connect(display+5);
2260 else
2261 vs->lsock = inet_connect(display, SOCK_STREAM);
2262 if (-1 == vs->lsock) {
3aa3eea3
AZ
2263 free(vs->display);
2264 vs->display = NULL;
2265 return -1;
2266 } else {
753b4053 2267 int csock = vs->lsock;
3aa3eea3 2268 vs->lsock = -1;
753b4053 2269 vnc_connect(vs, csock);
3aa3eea3 2270 }
9712ecaf 2271 return 0;
24236869 2272
9712ecaf
AL
2273 } else {
2274 /* listen for connects */
2275 char *dpy;
2276 dpy = qemu_malloc(256);
2277 if (strncmp(display, "unix:", 5) == 0) {
bc575e95 2278 pstrcpy(dpy, 256, "unix:");
4a55bfdf 2279 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
9712ecaf
AL
2280 } else {
2281 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2282 }
2283 if (-1 == vs->lsock) {
2284 free(dpy);
d0513623 2285 return -1;
9712ecaf
AL
2286 } else {
2287 free(vs->display);
2288 vs->display = dpy;
2289 }
24236869 2290 }
753b4053 2291 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);
24236869 2292}