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