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