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