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