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