• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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