1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Copyright (C) 2000-2002 Constantin Kaplinsky.  All Rights Reserved.
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  This is free software; you can redistribute it and/or modify
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  it under the terms of the GNU General Public License as published by
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  the Free Software Foundation; either version 2 of the License, or
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  (at your option) any later version.
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  This software is distributed in the hope that it will be useful,
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  GNU General Public License for more details.
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  You should have received a copy of the GNU General Public License
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  along with this software; if not, write to the Free Software
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  USA.
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbproto.c - functions to deal with client side of RFB protocol.
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __STRICT_ANSI__
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _BSD_SOURCE
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _POSIX_SOURCE
291d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define _XOPEN_SOURCE 600
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef WIN32
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <unistd.h>
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/types.h>
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/stat.h>
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <pwd.h>
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <errno.h>
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfbclient.h>
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef WIN32
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef SOCKET
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef socklen_t
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <zlib.h>
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __CHECKER__
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef Z_NULL
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define Z_NULL NULL
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef _RPCNDR_H /* This Windows header typedefs 'boolean', jpeglib has to know */
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define HAVE_BOOLEAN
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <jpeglib.h>
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
561d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman
571d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifndef _MSC_VER
581d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman/* Strings.h is not available in MSVC */
591d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#include <strings.h>
601d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif
611d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdarg.h>
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <time.h>
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <gcrypt.h>
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "minilzo.h"
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "tls.h"
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
721d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef _MSC_VER
731d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#  define snprintf _snprintf /* MSVC went straight to the underscored syntax */
741d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif
751d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbClientLog prints a time-stamped message to the log file (stderr).
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbEnableClientLogging=TRUE;
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbDefaultClientLog(const char *format, ...)
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    va_list args;
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char buf[256];
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    time_t log_clock;
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(!rfbEnableClientLogging)
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return;
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    va_start(args, format);
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    time(&log_clock);
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock));
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    fprintf(stderr, "%s", buf);
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    vfprintf(stderr, format, args);
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    fflush(stderr);
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    va_end(args);
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientLogProc rfbClientLog=rfbDefaultClientLog;
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientLogProc rfbClientErr=rfbDefaultClientLog;
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* extensions */
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientProtocolExtension* rfbClientExtensions = NULL;
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbClientRegisterExtension(rfbClientProtocolExtension* e)
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	e->next = rfbClientExtensions;
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientExtensions = e;
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* client data */
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbClientSetClientData(rfbClient* client, void* tag, void* data)
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientData* clientData = client->clientData;
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while(clientData && clientData->tag != tag)
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clientData = clientData->next;
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(clientData == NULL) {
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clientData = calloc(sizeof(rfbClientData), 1);
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clientData->next = client->clientData;
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		client->clientData = clientData;
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clientData->tag = tag;
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	clientData->data = data;
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid* rfbClientGetClientData(rfbClient* client, void* tag)
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientData* clientData = client->clientData;
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while(clientData) {
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(clientData->tag == tag)
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return clientData->data;
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clientData = clientData->next;
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return NULL;
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* messages */
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i,j;
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define FILL_RECT(BPP) \
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      for(i=x;i<x+w;i++) \
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	((uint##BPP##_t*)client->frameBuffer)[j+i]=colour;
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  switch(client->format.bitsPerPixel) {
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case  8: FILL_RECT(8);  break;
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case 16: FILL_RECT(16); break;
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case 32: FILL_RECT(32); break;
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  default:
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int w, int h) {
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int j;
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1701d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman  if (client->frameBuffer == NULL) {
1711d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman      return;
1721d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman  }
1731d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define COPY_RECT(BPP) \
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  { \
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      memcpy(client->frameBuffer + j, buffer, rs); \
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      buffer += rs; \
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } \
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  switch(client->format.bitsPerPixel) {
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case  8: COPY_RECT(8);  break;
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case 16: COPY_RECT(16); break;
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case 32: COPY_RECT(32); break;
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  default:
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* TODO: test */
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i,j;
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define COPY_RECT_FROM_RECT(BPP) \
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  { \
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (dest_y < src_y) { \
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (dest_x < src_x) { \
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          for(i = dest_x; i < dest_x+w; i++) { \
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          } \
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else { \
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          for(i = dest_x+w-1; i >= dest_x; i--) { \
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          } \
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } \
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } \
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else { \
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (dest_x < src_x) { \
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          for(i = dest_x; i < dest_x+w; i++) { \
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          } \
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else { \
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          for(i = dest_x+w-1; i >= dest_x; i--) { \
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          } \
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } \
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } \
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } \
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  switch(client->format.bitsPerPixel) {
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case  8: COPY_RECT_FROM_RECT(8);  break;
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case 16: COPY_RECT_FROM_RECT(16); break;
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case 32: COPY_RECT_FROM_RECT(32); break;
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  default:
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleCoRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleCoRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleCoRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleHextile8(rfbClient* client, int rx, int ry, int rw, int rh);
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleHextile16(rfbClient* client, int rx, int ry, int rw, int rh);
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleHextile32(rfbClient* client, int rx, int ry, int rw, int rh);
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleUltra8(rfbClient* client, int rx, int ry, int rw, int rh);
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleUltra16(rfbClient* client, int rx, int ry, int rw, int rh);
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleUltra32(rfbClient* client, int rx, int ry, int rw, int rh);
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleUltraZip8(rfbClient* client, int rx, int ry, int rw, int rh);
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleUltraZip16(rfbClient* client, int rx, int ry, int rw, int rh);
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleUltraZip32(rfbClient* client, int rx, int ry, int rw, int rh);
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZlib8(rfbClient* client, int rx, int ry, int rw, int rh);
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZlib16(rfbClient* client, int rx, int ry, int rw, int rh);
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZlib32(rfbClient* client, int rx, int ry, int rw, int rh);
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleTight8(rfbClient* client, int rx, int ry, int rw, int rh);
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh);
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh);
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic long ReadCompactLen (rfbClient* client);
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void JpegInitSource(j_decompress_ptr cinfo);
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void JpegTermSource(j_decompress_ptr cinfo);
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData,
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                              int compressedLen);
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh);
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh);
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZRLE16(rfbClient* client, int rx, int ry, int rw, int rh);
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZRLE24(rfbClient* client, int rx, int ry, int rw, int rh);
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh);
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh);
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh);
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
2761d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef LIBVNCSERVER_CONFIG_LIBVA
2771d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartmanstatic rfbBool HandleH264 (rfbClient* client, int rx, int ry, int rw, int rh);
2781d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Server Capability Functions
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSupportsClient2Server(rfbClient* client, int messageType)
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return (client->supportedMessages.client2server[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSupportsServer2Client(rfbClient* client, int messageType)
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return (client->supportedMessages.server2client[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSetClient2Server(rfbClient* client, int messageType)
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->supportedMessages.client2server[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSetServer2Client(rfbClient* client, int messageType)
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->supportedMessages.server2client[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatClearClient2Server(rfbClient* client, int messageType)
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->supportedMessages.client2server[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatClearServer2Client(rfbClient* client, int messageType)
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->supportedMessages.server2client[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatDefaultSupportedMessages(rfbClient* client)
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    memset((char *)&client->supportedMessages,0,sizeof(client->supportedMessages));
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Default client supported messages (universal RFB 3.3 protocol) */
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbSetPixelFormat);
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* SetClient2Server(client, rfbFixColourMapEntries); Not currently supported */
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbSetEncodings);
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbFramebufferUpdateRequest);
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbKeyEvent);
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbPointerEvent);
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbClientCutText);
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* technically, we only care what we can *send* to the server
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     * but, we set Server2Client Just in case it ever becomes useful
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     */
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbFramebufferUpdate);
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbSetColourMapEntries);
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbBell);
339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbServerCutText);
340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatDefaultSupportedMessagesUltraVNC(rfbClient* client)
344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    DefaultSupportedMessages(client);
346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbFileTransfer);
347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbSetScale);
348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbSetServerInput);
349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbSetSW);
350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbTextChat);
351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbPalmVNCSetScaleFactor);
352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* technically, we only care what we can *send* to the server */
353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbResizeFrameBuffer);
354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbPalmVNCReSizeFrameBuffer);
355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbFileTransfer);
356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbTextChat);
357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatDefaultSupportedMessagesTightVNC(rfbClient* client)
362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    DefaultSupportedMessages(client);
364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbFileTransfer);
365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbSetServerInput);
366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbSetSW);
367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* SetClient2Server(client, rfbTextChat); */
368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* technically, we only care what we can *send* to the server */
369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbFileTransfer);
370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbTextChat);
371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef WIN32
374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool
375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatIsUnixSocket(const char *name)
376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  struct stat sb;
378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(stat(name, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK)
379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return TRUE;
380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return FALSE;
381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ConnectToRFBServer.
386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatConnectToRFBServer(rfbClient* client,const char *hostname, int port)
390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->serverPort==-1) {
392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* serverHost is a file recorded by vncrec. */
393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    const char* magic="vncLog0.0";
394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char buffer[10];
395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec));
396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->vncRec = rec;
397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rec->file = fopen(client->serverHost,"rb");
399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rec->tv.tv_sec = 0;
400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rec->readTimestamp = FALSE;
401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rec->doNotSleep = FALSE;
402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!rec->file) {
404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("Could not open %s.\n",client->serverHost);
405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    setbuf(rec->file,NULL);
4081d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman
4091d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman    if (fread(buffer,1,strlen(magic),rec->file) != strlen(magic) || strncmp(buffer,magic,strlen(magic))) {
410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost);
411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      fclose(rec->file);
412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->sock = -1;
415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return TRUE;
416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef WIN32
419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(IsUnixSocket(hostname))
420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* serverHost is a UNIX socket. */
421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->sock = ConnectClientToUnixSock(hostname);
422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  else
423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_IPv6
426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->sock = ConnectClientToTcpAddr6(hostname, port);
427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->sock == -1)
428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      unsigned int host;
431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* serverHost is a hostname */
433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!StringToIPAddr(hostname, &host)) {
434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("Couldn't convert '%s' to host address\n", hostname);
435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->sock = ConnectClientToTcpAddr(host, port);
438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->sock < 0) {
442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Unable to connect to VNC server\n");
443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(client->QoS_DSCP && !SetDSCP(client->sock, client->QoS_DSCP))
447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     return FALSE;
448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return SetNonBlocking(client->sock);
450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ConnectToRFBRepeater.
454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort)
457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbProtocolVersionMsg pv;
459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int major,minor;
460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  char tmphost[250];
461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_IPv6
463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->sock = ConnectClientToTcpAddr6(repeaterHost, repeaterPort);
464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->sock == -1)
465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    unsigned int host;
468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!StringToIPAddr(repeaterHost, &host)) {
469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost);
470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->sock = ConnectClientToTcpAddr(host, repeaterPort);
474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->sock < 0) {
477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Unable to connect to VNC repeater\n");
478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SetNonBlocking(client->sock))
482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg))
485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pv[sz_rfbProtocolVersionMsg] = 0;
487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* UltraVNC repeater always report version 000.000 to identify itself */
489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2 || major != 0 || minor != 0) {
490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Not a valid VNC repeater (%s)\n",pv);
491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor);
495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort);
497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, tmphost, sizeof(tmphost)))
498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatextern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatextern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key);
505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbHandleAuthResult(rfbClient* client)
508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint32_t authResult=0, reasonLen=0;
510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char *reason=NULL;
511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    authResult = rfbClientSwap32IfLE(authResult);
515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    switch (authResult) {
517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    case rfbVncAuthOK:
518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("VNC authentication succeeded\n");
519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return TRUE;
520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    case rfbVncAuthFailed:
522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (client->major==3 && client->minor>7)
523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* we have an error following */
525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        reasonLen = rfbClientSwap32IfLE(reasonLen);
527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        reason = malloc(reasonLen+1);
528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        reason[reasonLen]=0;
530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("VNC connection failed: %s\n",reason);
531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        free(reason);
532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("VNC authentication failed\n");
535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    case rfbVncAuthTooMany:
537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("VNC authentication failed - too many tries\n");
538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Unknown VNC authentication result: %d\n",
542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                 (int)authResult);
543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void
547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatReadReason(rfbClient* client)
548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint32_t reasonLen;
550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char *reason;
551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* we have an error following */
553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    reasonLen = rfbClientSwap32IfLE(reasonLen);
555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    reason = malloc(reasonLen+1);
556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    reason[reasonLen]=0;
558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("VNC connection failed: %s\n",reason);
559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(reason);
560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool
563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint8_t count=0;
566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint8_t loop=0;
567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint8_t flag=0;
568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint8_t tAuth[256];
569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char buf1[500],buf2[10];
570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint32_t authScheme;
571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (count==0)
575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("List of security types is ZERO, expecting an error to follow\n");
577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        ReadReason(client);
578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("We have %d security types to read\n", count);
582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    authScheme=0;
583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* now, we have a list of available security types to read ( uint8_t[] ) */
584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (loop=0;loop<count;loop++)
585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]);
588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (flag) continue;
589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth ||
5901d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#if defined(LIBVNCSERVER_HAVE_GNUTLS) || defined(LIBVNCSERVER_HAVE_LIBSSL)
5911d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman            tAuth[loop]==rfbVeNCrypt ||
5921d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif
593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            (tAuth[loop]==rfbARD && client->GetCredential) ||
594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            (!subAuth && (tAuth[loop]==rfbTLS || (tAuth[loop]==rfbVeNCrypt && client->GetCredential))))
595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        {
596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            if (!subAuth && client->clientAuthSchemes)
597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            {
598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                int i;
599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                for (i=0;client->clientAuthSchemes[i];i++)
600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                {
601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                    if (client->clientAuthSchemes[i]==(uint32_t)tAuth[loop])
602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                    {
603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                        flag++;
604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                        authScheme=tAuth[loop];
605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                        break;
606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                    }
607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                }
608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            }
609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            else
610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            {
611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                flag++;
612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                authScheme=tAuth[loop];
613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            }
614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            if (flag)
615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            {
616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                /* send back a single byte indicating which security type to use */
618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                if (!WriteToRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            }
620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (authScheme==0)
623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        memset(buf1, 0, sizeof(buf1));
625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        for (loop=0;loop<count;loop++)
626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        {
627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            if (strlen(buf1)>=sizeof(buf1)-1) break;
628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("Unknown authentication scheme from VNC server: %s\n",
632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat               buf1);
633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    *result = authScheme;
636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return TRUE;
637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool
640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatHandleVncAuth(rfbClient *client)
641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint8_t challenge[CHALLENGESIZE];
643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char *passwd=NULL;
644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int i;
645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->serverPort!=-1) { /* if not playing a vncrec file */
649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (client->GetPassword)
650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        passwd = client->GetPassword(client);
651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if ((!passwd) || (strlen(passwd) == 0)) {
653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("Reading password failed\n");
654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (strlen(passwd) > 8) {
657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        passwd[8] = '\0';
658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientEncryptBytes(challenge, passwd);
661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* Lose the password from memory */
663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      for (i = strlen(passwd); i >= 0; i--) {
664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        passwd[i] = '\0';
665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      free(passwd);
667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Handle the SecurityResult message */
672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!rfbHandleAuthResult(client)) return FALSE;
673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return TRUE;
675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void
678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatFreeUserCredential(rfbCredential *cred)
679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (cred->userCredential.username) free(cred->userCredential.username);
681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (cred->userCredential.password) free(cred->userCredential.password);
682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  free(cred);
683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool
686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatHandlePlainAuth(rfbClient *client)
687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint32_t ulen, ulensw;
689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint32_t plen, plensw;
690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbCredential *cred;
691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!client->GetCredential)
693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("GetCredential callback is not set.\n");
695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  cred = client->GetCredential(client, rfbCredentialTypeUser);
698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!cred)
699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Reading credential failed\n");
701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ulen = (cred->userCredential.username ? strlen(cred->userCredential.username) : 0);
705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ulensw = rfbClientSwap32IfLE(ulen);
706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  plen = (cred->userCredential.password ? strlen(cred->userCredential.password) : 0);
707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  plensw = rfbClientSwap32IfLE(plen);
708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, (char *)&ulensw, 4) ||
709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      !WriteToRFBServer(client, (char *)&plensw, 4))
710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    FreeUserCredential(cred);
712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (ulen > 0)
715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!WriteToRFBServer(client, cred->userCredential.username, ulen))
717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      FreeUserCredential(cred);
719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (plen > 0)
723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!WriteToRFBServer(client, cred->userCredential.password, plen))
725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      FreeUserCredential(cred);
727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  FreeUserCredential(cred);
732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Handle the SecurityResult message */
734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!rfbHandleAuthResult(client)) return FALSE;
735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* Simple 64bit big integer arithmetic implementation */
740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* (x + y) % m, works even if (x + y) > 64bit */
741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbAddM64(x,y,m) ((x+y)%m+(x+y<x?(((uint64_t)-1)%m+1)%m:0))
742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* (x * y) % m */
743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic uint64_t
744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbMulM64(uint64_t x, uint64_t y, uint64_t m)
745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint64_t r;
747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for(r=0;x>0;x>>=1)
748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (x&1) r=rfbAddM64(r,y,m);
750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    y=rfbAddM64(y,y,m);
751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return r;
753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* (x ^ y) % m */
755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic uint64_t
756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbPowM64(uint64_t b, uint64_t e, uint64_t m)
757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint64_t r;
759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for(r=1;e>0;e>>=1)
760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(e&1) r=rfbMulM64(r,b,m);
762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    b=rfbMulM64(b,b,m);
763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return r;
765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool
768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatHandleMSLogonAuth(rfbClient *client)
769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint64_t gen, mod, resp, priv, pub, key;
771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint8_t username[256], password[64];
772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbCredential *cred;
773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, (char *)&gen, 8)) return FALSE;
775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, (char *)&mod, 8)) return FALSE;
776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, (char *)&resp, 8)) return FALSE;
777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  gen = rfbClientSwap64IfLE(gen);
778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  mod = rfbClientSwap64IfLE(mod);
779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  resp = rfbClientSwap64IfLE(resp);
780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!client->GetCredential)
782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("GetCredential callback is not set.\n");
784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\
787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    "Use it only with SSH tunnel or trusted network.\n");
788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  cred = client->GetCredential(client, rfbCredentialTypeUser);
789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!cred)
790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Reading credential failed\n");
792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  memset(username, 0, sizeof(username));
796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  strncpy((char *)username, cred->userCredential.username, sizeof(username));
797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  memset(password, 0, sizeof(password));
798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  strncpy((char *)password, cred->userCredential.password, sizeof(password));
799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  FreeUserCredential(cred);
800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  srand(time(NULL));
802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  priv = ((uint64_t)rand())<<32;
803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  priv |= (uint64_t)rand();
804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pub = rfbPowM64(gen, priv, mod);
806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  key = rfbPowM64(resp, priv, mod);
807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pub = rfbClientSwap64IfLE(pub);
808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  key = rfbClientSwap64IfLE(key);
809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientEncryptBytes2(username, sizeof(username), (unsigned char *)&key);
811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientEncryptBytes2(password, sizeof(password), (unsigned char *)&key);
812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, (char *)&pub, 8)) return FALSE;
814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, (char *)username, sizeof(username))) return FALSE;
815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, (char *)password, sizeof(password))) return FALSE;
816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Handle the SecurityResult message */
818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!rfbHandleAuthResult(client)) return FALSE;
819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT
824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool
825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbMpiToBytes(const gcry_mpi_t value, uint8_t *result, size_t size)
826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  gcry_error_t error;
828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  size_t len;
829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i;
830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  error = gcry_mpi_print(GCRYMPI_FMT_USG, result, size, &len, value);
832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("gcry_mpi_print error: %s\n", gcry_strerror(error));
835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for (i=size-1;i>(int)size-1-(int)len;--i)
838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    result[i] = result[i-size+len];
839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for (;i>=0;--i)
840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    result[i] = 0;
841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool
845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatHandleARDAuth(rfbClient *client)
846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint8_t gen[2], len[2];
848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  size_t keylen;
849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint8_t *mod = NULL, *resp, *pub, *key, *shared;
850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  gcry_mpi_t genmpi = NULL, modmpi = NULL, respmpi = NULL;
851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  gcry_mpi_t privmpi = NULL, pubmpi = NULL, keympi = NULL;
852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  gcry_md_hd_t md5 = NULL;
853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  gcry_cipher_hd_t aes = NULL;
854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  gcry_error_t error;
855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint8_t userpass[128], ciphertext[128];
856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int passwordLen, usernameLen;
857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbCredential *cred = NULL;
858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbBool result = FALSE;
859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  while (1)
861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)gen, 2))
863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)len, 2))
865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!client->GetCredential)
868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("GetCredential callback is not set.\n");
870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    cred = client->GetCredential(client, rfbCredentialTypeUser);
873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!cred)
874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("Reading credential failed\n");
876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    keylen = 256*len[0]+len[1];
880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    mod = (uint8_t*)malloc(keylen*4);
881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!mod)
882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("malloc out of memory\n");
884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    resp = mod+keylen;
887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    pub = resp+keylen;
888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    key = pub+keylen;
889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)mod, keylen))
891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)resp, keylen))
893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_mpi_scan(&genmpi, GCRYMPI_FMT_USG, gen, 2, NULL);
896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_mpi_scan(&modmpi, GCRYMPI_FMT_USG, mod, keylen, NULL);
902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_mpi_scan(&respmpi, GCRYMPI_FMT_USG, resp, keylen, NULL);
908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    privmpi = gcry_mpi_new(keylen);
915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!privmpi)
916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_mpi_new out of memory\n");
918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_randomize(privmpi, (keylen/8)*8, GCRY_STRONG_RANDOM);
921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    pubmpi = gcry_mpi_new(keylen);
923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!pubmpi)
924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_mpi_new out of memory\n");
926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_powm(pubmpi, genmpi, privmpi, modmpi);
929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    keympi = gcry_mpi_new(keylen);
931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!keympi)
932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_mpi_new out of memory\n");
934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_powm(keympi, respmpi, privmpi, modmpi);
937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!rfbMpiToBytes(pubmpi, pub, keylen))
939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!rfbMpiToBytes(keympi, key, keylen))
941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_md_open(&md5, GCRY_MD_MD5, 0);
944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_md_open error: %s\n", gcry_strerror(error));
947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_md_write(md5, key, keylen);
950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_md_final(md5);
951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_md_final error: %s\n", gcry_strerror(error));
954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    shared = gcry_md_read(md5, GCRY_MD_MD5);
957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    passwordLen = strlen(cred->userCredential.password)+1;
959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    usernameLen = strlen(cred->userCredential.username)+1;
960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (passwordLen > sizeof(userpass)/2)
961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      passwordLen = sizeof(userpass)/2;
962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (usernameLen > sizeof(userpass)/2)
963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      usernameLen = sizeof(userpass)/2;
964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_randomize(userpass, sizeof(userpass), GCRY_STRONG_RANDOM);
966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    memcpy(userpass, cred->userCredential.username, usernameLen);
967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    memcpy(userpass+sizeof(userpass)/2, cred->userCredential.password, passwordLen);
968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_cipher_open(&aes, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0);
970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_cipher_open error: %s\n", gcry_strerror(error));
973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_cipher_setkey(aes, shared, 16);
976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_cipher_setkey error: %s\n", gcry_strerror(error));
979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    error = gcry_cipher_encrypt(aes, ciphertext, sizeof(ciphertext), userpass, sizeof(userpass));
982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("gcry_cipher_encrypt error: %s\n", gcry_strerror(error));
985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!WriteToRFBServer(client, (char *)ciphertext, sizeof(ciphertext)))
989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!WriteToRFBServer(client, (char *)pub, keylen))
991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Handle the SecurityResult message */
994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!rfbHandleAuthResult(client))
995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    result = TRUE;
998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (cred)
1002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    FreeUserCredential(cred);
1003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (mod)
1004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(mod);
1005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (genmpi)
1006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_release(genmpi);
1007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (modmpi)
1008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_release(modmpi);
1009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (respmpi)
1010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_release(respmpi);
1011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (privmpi)
1012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_release(privmpi);
1013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (pubmpi)
1014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_release(pubmpi);
1015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (keympi)
1016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_mpi_release(keympi);
1017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (md5)
1018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_md_close(md5);
1019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (aes)
1020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    gcry_cipher_close(aes);
1021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return result;
1022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SetClientAuthSchemes.
1027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
1030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size)
1031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i;
1033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->clientAuthSchemes)
1035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(client->clientAuthSchemes);
1037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->clientAuthSchemes = NULL;
1038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (authSchemes)
1040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (size<0)
1042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
1043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* If size<0 we assume the passed-in list is also 0-terminate, so we
1044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       * calculate the size here */
1045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      for (size=0;authSchemes[size];size++) ;
1046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->clientAuthSchemes = (uint32_t*)malloc(sizeof(uint32_t)*(size+1));
1048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (i=0;i<size;i++)
1049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->clientAuthSchemes[i] = authSchemes[i];
1050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->clientAuthSchemes[size] = 0;
1051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * InitialiseRFBConnection.
1056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatInitialiseRFBConnection(rfbClient* client)
1060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbProtocolVersionMsg pv;
1062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int major,minor;
1063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint32_t authScheme;
1064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint32_t subAuthScheme;
1065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientInitMsg ci;
1066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* if the connection is immediately closed, don't report anything, so
1068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       that pmw's monitor can make test connections */
1069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->listenSpecified)
1071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    errorMessageOnReadFailure = FALSE;
1072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
1074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pv[sz_rfbProtocolVersionMsg]=0;
1075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  errorMessageOnReadFailure = TRUE;
1077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pv[sz_rfbProtocolVersionMsg] = 0;
1079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
1081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Not a valid VNC server (%s)\n",pv);
1082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  DefaultSupportedMessages(client);
1087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->major = major;
1088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->minor = minor;
1089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* fall back to viewer supported version */
1091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if ((major==rfbProtocolMajorVersion) && (minor>rfbProtocolMinorVersion))
1092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->minor = rfbProtocolMinorVersion;
1093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* UltraVNC uses minor codes 4 and 6 for the server */
1095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (major==3 && (minor==4 || minor==6)) {
1096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv);
1097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      DefaultSupportedMessagesUltraVNC(client);
1098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* UltraVNC Single Click uses minor codes 14 and 16 for the server */
1101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (major==3 && (minor==14 || minor==16)) {
1102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     minor = minor - 10;
1103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     client->minor = minor;
1104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     rfbClientLog("UltraVNC Single Click server detected, enabling UltraVNC specific messages\n",pv);
1105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     DefaultSupportedMessagesUltraVNC(client);
1106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* TightVNC uses minor codes 5 for the server */
1109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (major==3 && minor==5) {
1110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv);
1111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      DefaultSupportedMessagesTightVNC(client);
1112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* we do not support > RFB3.8 */
1115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if ((major==3 && minor>8) || major>3)
1116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->major=3;
1118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->minor=8;
1119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n",
1122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
1123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor);
1125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
1127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* 3.7 and onwards sends a # of security types first */
1130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->major==3 && client->minor > 6)
1131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) return FALSE;
1133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  else
1135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE;
1137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    authScheme = rfbClientSwap32IfLE(authScheme);
1138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientLog("Selected Security Scheme %d\n", authScheme);
1141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->authScheme = authScheme;
1142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  switch (authScheme) {
1144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbConnFailed:
1146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    ReadReason(client);
1147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbNoAuth:
1150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("No authentication needed\n");
1151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* 3.8 and upwards sends a Security Result for rfbNoAuth */
1153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if ((client->major==3 && client->minor > 7) || client->major>3)
1154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!rfbHandleAuthResult(client)) return FALSE;
1155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
1157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbVncAuth:
1159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!HandleVncAuth(client)) return FALSE;
1160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
1161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbMSLogon:
1163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!HandleMSLogonAuth(client)) return FALSE;
1164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
1165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbARD:
1167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef LIBVNCSERVER_WITH_CLIENT_GCRYPT
1168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("GCrypt support was not compiled in\n");
1169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
1171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!HandleARDAuth(client)) return FALSE;
1172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
1174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbTLS:
1176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!HandleAnonTLSAuth(client)) return FALSE;
1177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* After the TLS session is established, sub auth types are expected.
1178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     * Note that all following reading/writing are through the TLS session from here.
1179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     */
1180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadSupportedSecurityType(client, &subAuthScheme, TRUE)) return FALSE;
1181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->subAuthScheme = subAuthScheme;
1182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    switch (subAuthScheme) {
1184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbConnFailed:
1186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        ReadReason(client);
1187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
1188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbNoAuth:
1190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("No sub authentication needed\n");
1191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* 3.8 and upwards sends a Security Result for rfbNoAuth */
1192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if ((client->major==3 && client->minor > 7) || client->major>3)
1193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            if (!rfbHandleAuthResult(client)) return FALSE;
1194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        break;
1195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbVncAuth:
1197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!HandleVncAuth(client)) return FALSE;
1198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        break;
1199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      default:
1201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n",
1202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            (int)subAuthScheme);
1203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
1204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
1207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbVeNCrypt:
1209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!HandleVeNCryptAuth(client)) return FALSE;
1210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    switch (client->subAuthScheme) {
1212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbVeNCryptTLSNone:
1214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbVeNCryptX509None:
1215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("No sub authentication needed\n");
1216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!rfbHandleAuthResult(client)) return FALSE;
1217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        break;
1218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbVeNCryptTLSVNC:
1220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbVeNCryptX509VNC:
1221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!HandleVncAuth(client)) return FALSE;
1222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        break;
1223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbVeNCryptTLSPlain:
1225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbVeNCryptX509Plain:
1226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!HandlePlainAuth(client)) return FALSE;
1227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        break;
1228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      default:
1230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n",
1231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            client->subAuthScheme);
1232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
1233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
1236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  default:
1238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Unknown authentication scheme from VNC server: %d\n",
1239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    (int)authScheme);
1240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ci.shared = (client->appData.shareDesktop ? 1 : 0);
1244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client,  (char *)&ci, sz_rfbClientInitMsg)) return FALSE;
1246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE;
1248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth);
1250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight);
1251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax);
1252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax);
1253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
1254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
1255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
12561d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman  /* To guard against integer wrap-around, si.nameLength is cast to 64 bit */
12571d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman  client->desktopName = malloc((uint64_t)client->si.nameLength + 1);
1258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!client->desktopName) {
1259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
1260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            (unsigned long)client->si.nameLength);
1261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE;
1265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  client->desktopName[client->si.nameLength] = 0;
1267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientLog("Desktop name \"%s\"\n",client->desktopName);
1269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientLog("Connected to VNC server, using protocol version %d.%d\n",
1271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  client->major, client->minor);
1272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientLog("VNC server default format:\n");
1274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  PrintPixelFormat(&client->si.format);
1275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
1277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SetFormatAndEncodings.
1282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSetFormatAndEncodings(rfbClient* client)
1286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbSetPixelFormatMsg spf;
1288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
1289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
1291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]);
1292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int len = 0;
1293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbBool requestCompressLevel = FALSE;
1294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbBool requestQualityLevel = FALSE;
1295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbBool requestLastRectEncoding = FALSE;
1296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientProtocolExtension* e;
1297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE;
1299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  spf.type = rfbSetPixelFormat;
13011d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman  spf.pad1 = 0;
13021d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman  spf.pad2 = 0;
1303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  spf.format = client->format;
1304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax);
1305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax);
1306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax);
1307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg))
1309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE;
1313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  se->type = rfbSetEncodings;
1315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  se->nEncodings = 0;
1316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->appData.encodingsString) {
1318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    const char *encStr = client->appData.encodingsString;
1319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int encStrLen;
1320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    do {
1321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      const char *nextEncStr = strchr(encStr, ' ');
1322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (nextEncStr) {
1323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encStrLen = nextEncStr - encStr;
1324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	nextEncStr++;
1325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else {
1326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encStrLen = strlen(encStr);
1327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (strncasecmp(encStr,"raw",encStrLen) == 0) {
1330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
1331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
1332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
1333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
1334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
1335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
1336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
1337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	requestLastRectEncoding = TRUE;
1338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
1339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  requestCompressLevel = TRUE;
1340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (client->appData.enableJPEG)
1341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  requestQualityLevel = TRUE;
1342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
1345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
1346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
1347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
1348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
1349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
1350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  requestCompressLevel = TRUE;
1351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) {
1352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex);
1353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
1354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  requestCompressLevel = TRUE;
1355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
1356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
1357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
1358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
1359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	requestQualityLevel = TRUE;
1360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) {
1362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* There are 2 encodings used in 'ultra' */
1363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
1364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
1365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
1366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
1367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
1368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
13691d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef LIBVNCSERVER_CONFIG_LIBVA
13701d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman      } else if (strncasecmp(encStr,"h264",encStrLen) == 0) {
13711d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingH264);
13721d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif
1373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else {
1374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr);
1375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encStr = nextEncStr;
1378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } while (encStr && se->nEncodings < MAX_ENCODINGS);
1379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
1381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
1382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					  rfbEncodingCompressLevel0);
1383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
1386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
1387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        client->appData.qualityLevel = 5;
1388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
1389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					  rfbEncodingQualityLevel0);
1390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  else {
1393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (SameMachine(client->sock)) {
1394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* TODO:
1395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!tunnelSpecified) {
1396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      */
1397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("Same machine: preferring raw encoding\n");
1398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
1399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /*
1400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else {
1401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog("Tunneling active: preferring tight encoding\n");
1402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      */
1404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
1407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
1408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
1409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
1410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    requestLastRectEncoding = TRUE;
1411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
1414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
1415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
1416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
1417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
1418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
1420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
1421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
1422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
1423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) {
1425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
1426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					  rfbEncodingCompressLevel0);
1427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else /* if (!tunnelSpecified) */ {
1428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* If -tunnel option was provided, we assume that server machine is
1429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 not in the local network so we use default compression level for
1430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 tight encoding instead of fast compression. Thus we are
1431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 requesting level 1 compression only if tunneling is not used. */
1432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1);
1433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->appData.enableJPEG) {
1436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
1437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->appData.qualityLevel = 5;
1438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
1439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					  rfbEncodingQualityLevel0);
1440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
14411d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef LIBVNCSERVER_CONFIG_LIBVA
14421d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingH264);
14431d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman    rfbClientLog("h264 encoding added\n");
14441d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif
1445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Remote Cursor Support (local to viewer) */
1450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->appData.useRemoteCursor) {
1451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (se->nEncodings < MAX_ENCODINGS)
1452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
1453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (se->nEncodings < MAX_ENCODINGS)
1454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor);
1455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (se->nEncodings < MAX_ENCODINGS)
1456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
1457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Keyboard State Encodings */
1460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (se->nEncodings < MAX_ENCODINGS)
1461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
1462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* New Frame Buffer Size */
1464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize)
1465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize);
1466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Last Rect */
1468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding)
1469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
1470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Server Capabilities */
1472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (se->nEncodings < MAX_ENCODINGS)
1473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages);
1474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (se->nEncodings < MAX_ENCODINGS)
1475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings);
1476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (se->nEncodings < MAX_ENCODINGS)
1477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity);
1478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* xvp */
1480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (se->nEncodings < MAX_ENCODINGS)
1481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXvp);
1482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* client extensions */
1484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for(e = rfbClientExtensions; e; e = e->next)
1485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(e->encodings) {
1486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      int* enc;
1487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      for(enc = e->encodings; *enc; enc++)
1488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
1489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
1492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
1494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, buf, len)) return FALSE;
1496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
1498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SendIncrementalFramebufferUpdateRequest.
1503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSendIncrementalFramebufferUpdateRequest(rfbClient* client)
1507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return SendFramebufferUpdateRequest(client,
1509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			client->updateRect.x, client->updateRect.y,
1510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			client->updateRect.w, client->updateRect.h, TRUE);
1511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SendFramebufferUpdateRequest.
1516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental)
1520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbFramebufferUpdateRequestMsg fur;
1522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE;
1524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  fur.type = rfbFramebufferUpdateRequest;
1526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  fur.incremental = incremental ? 1 : 0;
1527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  fur.x = rfbClientSwap16IfLE(x);
1528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  fur.y = rfbClientSwap16IfLE(y);
1529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  fur.w = rfbClientSwap16IfLE(w);
1530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  fur.h = rfbClientSwap16IfLE(h);
1531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
1533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
1536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SendScaleSetting.
1541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSendScaleSetting(rfbClient* client,int scaleSetting)
1544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbSetScaleMsg ssm;
1546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ssm.scale = scaleSetting;
1548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ssm.pad = 0;
1549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* favor UltraVNC SetScale if both are supported */
1551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (SupportsClient2Server(client, rfbSetScale)) {
1552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      ssm.type = rfbSetScale;
1553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
1554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          return FALSE;
1555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) {
1558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      ssm.type = rfbPalmVNCSetScaleFactor;
1559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
1560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          return FALSE;
1561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
1564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * TextChatFunctions (UltraVNC)
1568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Extremely bandwidth friendly method of communicating with a user
1569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (Think HelpDesk type applications)
1570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool TextChatSend(rfbClient* client, char *text)
1573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbTextChatMsg chat;
1575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int count = strlen(text);
1576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.type = rfbTextChat;
1579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad1 = 0;
1580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad2 = 0;
1581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.length = (uint32_t)count;
1582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.length = rfbClientSwap32IfLE(chat.length);
1583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg))
1585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
1586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (count>0) {
1588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (!WriteToRFBServer(client, text, count))
1589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return FALSE;
1590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return TRUE;
1592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool TextChatOpen(rfbClient* client)
1595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbTextChatMsg chat;
1597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.type = rfbTextChat;
1600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad1 = 0;
1601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad2 = 0;
1602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.length = rfbClientSwap32IfLE(rfbTextChatOpen);
1603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
1604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool TextChatClose(rfbClient* client)
1607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbTextChatMsg chat;
1609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.type = rfbTextChat;
1611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad1 = 0;
1612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad2 = 0;
1613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.length = rfbClientSwap32IfLE(rfbTextChatClose);
1614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
1615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool TextChatFinish(rfbClient* client)
1618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbTextChatMsg chat;
1620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.type = rfbTextChat;
1622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad1 = 0;
1623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.pad2 = 0;
1624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    chat.length = rfbClientSwap32IfLE(rfbTextChatFinished);
1625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
1626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * UltraVNC Server Input Disable
1630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Apparently, the remote client can *prevent* the local user from interacting with the display
1631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * I would think this is extremely helpful when used in a HelpDesk situation
1632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool PermitServerInput(rfbClient* client, int enabled)
1634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbSetServerInputMsg msg;
1636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE;
1638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* enabled==1, then server input from local keyboard is disabled */
1639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    msg.type = rfbSetServerInput;
1640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    msg.status = (enabled ? 1 : 0);
1641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    msg.pad = 0;
1642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return  (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE);
1643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * send xvp client message
1648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * A client supporting the xvp extension sends this to request that the server initiate
1649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * a clean shutdown, clean reboot or abrupt reset of the system whose framebuffer the
1650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * client is displaying.
1651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
1652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * only version 1 is defined in the protocol specs
1653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
1654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * possible values for code are:
1655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *   rfbXvp_Shutdown
1656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *   rfbXvp_Reboot
1657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *   rfbXvp_Reset
1658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool SendXvpMsg(rfbClient* client, uint8_t version, uint8_t code)
1661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbXvpMsg xvp;
1663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!SupportsClient2Server(client, rfbXvp)) return TRUE;
1665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    xvp.type = rfbXvp;
1666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    xvp.pad = 0;
1667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    xvp.version = version;
1668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    xvp.code = code;
1669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!WriteToRFBServer(client, (char *)&xvp, sz_rfbXvpMsg))
1671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
1672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return TRUE;
1674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SendPointerEvent.
1679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSendPointerEvent(rfbClient* client,int x, int y, int buttonMask)
1683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbPointerEventMsg pe;
1685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE;
1687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pe.type = rfbPointerEvent;
1689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pe.buttonMask = buttonMask;
1690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (x < 0) x = 0;
1691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (y < 0) y = 0;
1692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pe.x = rfbClientSwap16IfLE(x);
1694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  pe.y = rfbClientSwap16IfLE(y);
1695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg);
1696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SendKeyEvent.
1701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSendKeyEvent(rfbClient* client, uint32_t key, rfbBool down)
1705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbKeyEventMsg ke;
1707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE;
1709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ke.type = rfbKeyEvent;
1711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ke.down = down ? 1 : 0;
1712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  ke.key = rfbClientSwap32IfLE(key);
1713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg);
1714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * SendClientCutText.
1719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatSendClientCutText(rfbClient* client, char *str, int len)
1723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientCutTextMsg cct;
1725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE;
1727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  cct.type = rfbClientCutText;
1729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  cct.length = rfbClientSwap32IfLE(len);
1730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return  (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) &&
1731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   WriteToRFBServer(client, str, len));
1732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
1737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * HandleRFBServerMessage.
1738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
1739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatHandleRFBServerMessage(rfbClient* client)
1742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbServerToClientMsg msg;
1744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (client->serverPort==-1)
1746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->vncRec->readTimestamp = TRUE;
1747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (!ReadFromRFBServer(client, (char *)&msg, 1))
1748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return FALSE;
1749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  switch (msg.type) {
1751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbSetColourMapEntries:
1753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* TODO:
1755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int i;
1756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint16_t rgb[3];
1757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    XColor xc;
1758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			   sz_rfbSetColourMapEntriesMsg - 1))
1761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
1762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour);
1764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours);
1765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (i = 0; i < msg.scme.nColours; i++) {
1767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!ReadFromRFBServer(client, (char *)rgb, 6))
1768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return FALSE;
1769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      xc.pixel = msg.scme.firstColour + i;
1770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      xc.red = rfbClientSwap16IfLE(rgb[0]);
1771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      xc.green = rfbClientSwap16IfLE(rgb[1]);
1772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      xc.blue = rfbClientSwap16IfLE(rgb[2]);
1773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      xc.flags = DoRed|DoGreen|DoBlue;
1774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      XStoreColor(dpy, cmap, &xc);
1775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    */
1777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
1779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbFramebufferUpdate:
1782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbFramebufferUpdateRectHeader rect;
1784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int linesToRead;
1785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int bytesPerLine;
1786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int i;
1787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1,
1789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			   sz_rfbFramebufferUpdateMsg - 1))
1790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
1791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects);
1793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    for (i = 0; i < msg.fu.nRects; i++) {
1795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader))
1796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return FALSE;
1797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rect.encoding = rfbClientSwap32IfLE(rect.encoding);
1799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingLastRect)
1800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
1801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rect.r.x = rfbClientSwap16IfLE(rect.r.x);
1803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rect.r.y = rfbClientSwap16IfLE(rect.r.y);
1804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rect.r.w = rfbClientSwap16IfLE(rect.r.w);
1805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rect.r.h = rfbClientSwap16IfLE(rect.r.h);
1806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingXCursor ||
1809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  rect.encoding == rfbEncodingRichCursor) {
1810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!HandleCursorShape(client,
1812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			       rect.r.x, rect.r.y, rect.r.w, rect.r.h,
1813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			       rect.encoding)) {
1814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  return FALSE;
1815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	continue;
1817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingPointerPos) {
1820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) {
1821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  return FALSE;
1822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	continue;
1824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingKeyboardLedState) {
1827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* OK! We have received a keyboard state message!!! */
1828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          client->KeyboardLedStateEnabled = 1;
1829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (client->HandleKeyboardLedState!=NULL)
1830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              client->HandleKeyboardLedState(client, rect.r.x, 0);
1831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* stash it for the future */
1832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          client->CurrentKeyboardLedState = rect.r.x;
1833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          continue;
1834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingNewFBSize) {
1837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->width = rect.r.w;
1838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->height = rect.r.h;
1839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->updateRect.x = client->updateRect.y = 0;
1840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->updateRect.w = client->width;
1841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->updateRect.h = client->height;
18421d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman	if (!client->MallocFrameBuffer(client))
18431d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman	  return FALSE;
1844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE);
1845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h);
1846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	continue;
1847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* rect.r.w=byte count */
1850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingSupportedMessages) {
1851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          int loop;
1852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages))
1853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              return FALSE;
1854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */
1856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* currently ignored by this library */
1857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbClientLog("client2server supported messages (bit flags)\n");
1859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          for (loop=0;loop<32;loop+=8)
1860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.client2server[loop],   client->supportedMessages.client2server[loop+1],
1862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3],
1863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5],
1864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]);
1865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbClientLog("server2client supported messages (bit flags)\n");
1867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          for (loop=0;loop<32;loop+=8)
1868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.server2client[loop],   client->supportedMessages.server2client[loop+1],
1870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3],
1871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5],
1872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]);
1873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          continue;
1874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* rect.r.w=byte count, rect.r.h=# of encodings */
1877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingSupportedEncodings) {
1878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          char *buffer;
1879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          buffer = malloc(rect.r.w);
1880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!ReadFromRFBServer(client, buffer, rect.r.w))
1881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          {
1882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              free(buffer);
1883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              return FALSE;
1884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          }
1885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */
1887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* currently ignored by this library */
1888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          free(buffer);
1889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          continue;
1890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* rect.r.w=byte count */
1893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding == rfbEncodingServerIdentity) {
1894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          char *buffer;
1895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          buffer = malloc(rect.r.w+1);
1896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!ReadFromRFBServer(client, buffer, rect.r.w))
1897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          {
1898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              free(buffer);
1899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              return FALSE;
1900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          }
1901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          buffer[rect.r.w]=0; /* null terminate, just in case */
1902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbClientLog("Connected to Server \"%s\"\n", buffer);
1903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          free(buffer);
1904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          continue;
1905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* rfbEncodingUltraZip is a collection of subrects.   x = # of subrects, and h is always 0 */
1908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (rect.encoding != rfbEncodingUltraZip)
1909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
1910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if ((rect.r.x + rect.r.w > client->width) ||
1911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    (rect.r.y + rect.r.h > client->height))
1912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    {
1913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      rfbClientLog("Rect too large: %dx%d at (%d, %d)\n",
1914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  	  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      return FALSE;
1916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            }
1917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* UltraVNC with scaling, will send rectangles with a zero W or H
1919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat         *
1920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if ((rect.encoding != rfbEncodingTight) &&
1921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            (rect.r.h * rect.r.w == 0))
1922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        {
1923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  rfbClientLog("Zero size rect - ignoring (encoding=%d (0x%08x) %dx, %dy, %dw, %dh)\n", rect.encoding, rect.encoding, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  continue;
1925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
1926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        */
1927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* If RichCursor encoding is used, we should prevent collisions
1929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   between framebuffer updates and cursor drawing operations. */
1930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      switch (rect.encoding) {
1934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingRaw: {
1936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int y=rect.r.y, h=rect.r.h;
1937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8;
1939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	linesToRead = RFB_BUFFER_SIZE / bytesPerLine;
1940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (h > 0) {
1942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (linesToRead > h)
1943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    linesToRead = h;
1944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead))
1946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
1947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  CopyRectangle(client, (uint8_t *)client->buffer,
1949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			   rect.r.x, y, rect.r.w,linesToRead);
1950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  h -= linesToRead;
1952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  y += linesToRead;
1953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
1955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } break;
1956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingCopyRect:
1958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
1959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbCopyRect cr;
1960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect))
1962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  return FALSE;
1963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cr.srcX = rfbClientSwap16IfLE(cr.srcX);
1965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cr.srcY = rfbClientSwap16IfLE(cr.srcY);
1966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* If RichCursor encoding is used, we should extend our
1968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   "cursor lock area" (previously set to destination
1969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   rectangle) to the source rectangle as well. */
1970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->SoftCursorLockArea(client,
1971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				   cr.srcX, cr.srcY, rect.r.w, rect.r.h);
1972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (client->GotCopyRect != NULL) {
1974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              rect.r.x, rect.r.y);
1976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        } else
1977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		CopyRectangleFromRectangle(client,
1978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				   cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				   rect.r.x, rect.r.y);
1980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
1982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingRRE:
1985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
1986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	switch (client->format.bitsPerPixel) {
1987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 8:
1988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
1990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
1991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 16:
1992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
1994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
1995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 32:
1996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
1998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
1999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
2001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingCoRRE:
2004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
2005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	switch (client->format.bitsPerPixel) {
2006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 8:
2007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 16:
2011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 32:
2015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
2020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingHextile:
2023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
2024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	switch (client->format.bitsPerPixel) {
2025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 8:
2026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 16:
2030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 32:
2034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
2039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingUltra:
2042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
2043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        switch (client->format.bitsPerPixel) {
2044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 8:
2045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return FALSE;
2047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 16:
2049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return FALSE;
2051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 32:
2053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return FALSE;
2055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
2057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        break;
2058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingUltraZip:
2060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
2061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        switch (client->format.bitsPerPixel) {
2062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 8:
2063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return FALSE;
2065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 16:
2067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return FALSE;
2069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        case 32:
2071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return FALSE;
2073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
2075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        break;
2076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
2079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingZlib:
2080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
2081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	switch (client->format.bitsPerPixel) {
2082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 8:
2083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 16:
2087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 32:
2091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
2096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     }
2097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
2099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingTight:
2100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
2101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	switch (client->format.bitsPerPixel) {
2102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 8:
2103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 16:
2107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 32:
2111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
2116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
2118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingZRLE:
2119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Fail safe for ZYWRLE unsupport VNC server. */
2120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	client->appData.qualityLevel = 9;
2121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* fall through */
2122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbEncodingZYWRLE:
2123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      {
2124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	switch (client->format.bitsPerPixel) {
2125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 8:
2126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 16:
2130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if (client->si.format.greenMax > 0x1F) {
2131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      return FALSE;
2133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  } else {
2134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      return FALSE;
2136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  }
2137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	case 32:
2139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
2140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  uint32_t maxColor=(client->format.redMax<<client->format.redShift)|
2141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		(client->format.greenMax<<client->format.greenShift)|
2142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		(client->format.blueMax<<client->format.blueShift);
2143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if ((client->format.bigEndian && (maxColor&0xff)==0) ||
2144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      (!client->format.bigEndian && (maxColor&0xff000000)==0)) {
2145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      return FALSE;
2147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  } else if (!client->format.bigEndian && (maxColor&0xff)==0) {
2148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      return FALSE;
2150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  } else if (client->format.bigEndian && (maxColor&0xff000000)==0) {
2151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      return FALSE;
2153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    return FALSE;
2155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  break;
2156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
2158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	break;
2159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     }
2160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
21621d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef LIBVNCSERVER_CONFIG_LIBVA
21631d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman      case rfbEncodingH264:
21641d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman      {
21651d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman	if (!HandleH264(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h))
21661d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman	  return FALSE;
21671d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman	break;
21681d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman      }
21691d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif
2170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      default:
2172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 {
2173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   rfbBool handled = FALSE;
2174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   rfbClientProtocolExtension* e;
2175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   for(e = rfbClientExtensions; !handled && e; e = e->next)
2177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     if(e->handleEncoding && e->handleEncoding(client, &rect))
2178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	       handled = TRUE;
2179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   if(!handled) {
2181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     rfbClientLog("Unknown rect encoding %d\n",
2182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		 (int)rect.encoding);
2183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     return FALSE;
2184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   }
2185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 }
2186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      /* Now we may discard "soft cursor locks". */
2189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->SoftCursorUnlockScreen(client);
2190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
2192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
2193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!SendIncrementalFramebufferUpdateRequest(client))
2195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
2196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->FinishedFrameBufferUpdate)
2198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->FinishedFrameBufferUpdate(client);
2199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
2201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbBell:
2204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
2205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->Bell(client);
2206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
2208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbServerCutText:
2211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
2212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char *buffer;
2213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			   sz_rfbServerCutTextMsg - 1))
2216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
2217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
2219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    buffer = malloc(msg.sct.length+1);
2221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, buffer, msg.sct.length))
2223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
2224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    buffer[msg.sct.length] = 0;
2226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (client->GotXCutText)
2228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->GotXCutText(client, buffer, msg.sct.length);
2229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    free(buffer);
2231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
2233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbTextChat:
2236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
2237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      char *buffer=NULL;
2238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                             sz_rfbTextChatMsg- 1))
2240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        return FALSE;
2241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      msg.tc.length = rfbClientSwap32IfLE(msg.sct.length);
2242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      switch(msg.tc.length) {
2243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbTextChatOpen:
2244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbClientLog("Received TextChat Open\n");
2245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (client->HandleTextChat!=NULL)
2246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              client->HandleTextChat(client, (int)rfbTextChatOpen, NULL);
2247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbTextChatClose:
2249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbClientLog("Received TextChat Close\n");
2250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat         if (client->HandleTextChat!=NULL)
2251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              client->HandleTextChat(client, (int)rfbTextChatClose, NULL);
2252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      case rfbTextChatFinished:
2254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbClientLog("Received TextChat Finished\n");
2255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat         if (client->HandleTextChat!=NULL)
2256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              client->HandleTextChat(client, (int)rfbTextChatFinished, NULL);
2257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      default:
2259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          buffer=malloc(msg.tc.length+1);
2260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (!ReadFromRFBServer(client, buffer, msg.tc.length))
2261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          {
2262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              free(buffer);
2263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              return FALSE;
2264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          }
2265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* Null Terminate <just in case> */
2266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          buffer[msg.tc.length]=0;
2267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbClientLog("Received TextChat \"%s\"\n", buffer);
2268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if (client->HandleTextChat!=NULL)
2269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              client->HandleTextChat(client, (int)msg.tc.length, buffer);
2270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          free(buffer);
2271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          break;
2272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      break;
2274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbXvp:
2277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
2278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                           sz_rfbXvpMsg -1))
2280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
2281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetClient2Server(client, rfbXvp);
2283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* technically, we only care what we can *send* to the server
2284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     * but, we set Server2Client Just in case it ever becomes useful
2285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     */
2286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SetServer2Client(client, rfbXvp);
2287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(client->HandleXvpMsg)
2289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      client->HandleXvpMsg(client, msg.xvp.version, msg.xvp.code);
2290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
2292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbResizeFrameBuffer:
2295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
2296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                           sz_rfbResizeFrameBufferMsg -1))
2298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
2299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth);
2300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth);
2301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.x = client->updateRect.y = 0;
2302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.w = client->width;
2303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.h = client->height;
23041d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman    if (!client->MallocFrameBuffer(client))
23051d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman      return FALSE;
23061d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman
2307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
2308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
2309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
2310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  case rfbPalmVNCReSizeFrameBuffer:
2313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
2314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                           sz_rfbPalmVNCReSizeFrameBufferMsg -1))
2316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return FALSE;
2317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w);
2318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h);
2319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.x = client->updateRect.y = 0;
2320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.w = client->width;
2321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    client->updateRect.h = client->height;
23221d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman    if (!client->MallocFrameBuffer(client))
23231d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman      return FALSE;
2324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
2325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
2326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    break;
2327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  default:
2330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    {
2331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbBool handled = FALSE;
2332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientProtocolExtension* e;
2333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      for(e = rfbClientExtensions; !handled && e; e = e->next)
2335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(e->handleMessage && e->handleMessage(client, &msg))
2336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  handled = TRUE;
2337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if(!handled) {
2339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char buffer[256];
2340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
2341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	ReadFromRFBServer(client, buffer, 256);
2342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return FALSE;
2343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
2344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
2345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return TRUE;
2348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
2352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
2354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			       ((uint8_t*)&(pix))[1] = *(ptr)++)
2355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
2357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			       ((uint8_t*)&(pix))[1] = *(ptr)++, \
2358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			       ((uint8_t*)&(pix))[2] = *(ptr)++, \
2359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			       ((uint8_t*)&(pix))[3] = *(ptr)++)
2360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* CONCAT2 concatenates its two arguments.  CONCAT2E does the same but also
2362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   expands its arguments if they are macros */
2363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CONCAT2(a,b) a##b
2365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CONCAT2E(a,b) CONCAT2(a,b)
2366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CONCAT3(a,b,c) a##b##c
2367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CONCAT3E(a,b,c) CONCAT3(a,b,c)
2368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define BPP 8
2370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "rre.c"
2371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "corre.c"
2372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "hextile.c"
2373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "ultra.c"
2374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zlib.c"
2375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "tight.c"
2376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zrle.c"
2377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef BPP
2378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define BPP 16
2379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "rre.c"
2380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "corre.c"
2381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "hextile.c"
2382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "ultra.c"
2383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zlib.c"
2384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "tight.c"
2385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zrle.c"
2386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define REALBPP 15
2387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zrle.c"
2388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef BPP
2389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define BPP 32
2390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "rre.c"
2391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "corre.c"
2392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "hextile.c"
2393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "ultra.c"
2394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zlib.c"
2395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "tight.c"
2396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zrle.c"
2397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define REALBPP 24
2398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zrle.c"
2399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define REALBPP 24
2400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define UNCOMP 8
2401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zrle.c"
2402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define REALBPP 24
2403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define UNCOMP -8
2404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zrle.c"
2405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef BPP
24061d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#include "h264.c"
2407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * PrintPixelFormat.
2411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
2412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
2414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatPrintPixelFormat(rfbPixelFormat *format)
2415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
2416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (format->bitsPerPixel == 1) {
2417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("  Single bit per pixel.\n");
2418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog(
2419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    "  %s significant bit in each byte is leftmost on the screen.\n",
2420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    (format->bigEndian ? "Most" : "Least"));
2421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  } else {
2422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientLog("  %d bits per pixel.\n",format->bitsPerPixel);
2423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (format->bitsPerPixel != 8) {
2424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("  %s significant byte first in each pixel.\n",
2425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      (format->bigEndian ? "Most" : "Least"));
2426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
2427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (format->trueColour) {
2428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("  TRUE colour: max red %d green %d blue %d"
2429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		   ", shift red %d green %d blue %d\n",
2430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		   format->redMax, format->greenMax, format->blueMax,
2431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		   format->redShift, format->greenShift, format->blueShift);
2432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    } else {
2433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientLog("  Colour map (not true colour).\n");
2434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
2435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
2436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
2437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* avoid name clashes with LibVNCServer */
2439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbEncryptBytes rfbClientEncryptBytes
2441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbEncryptBytes2 rfbClientEncryptBytes2
2442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbDes rfbClientDes
2443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbDesKey rfbClientDesKey
2444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbUseKey rfbClientUseKey
2445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbCPKey rfbClientCPKey
2446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
2447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "vncauth.c"
2448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "d3des.c"
2449