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