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