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