1/*
2 *  Copyright (C) 2011-2012 Christian Beier <dontmind@freeshell.org>
3 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
4 *
5 *  This is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This software is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this software; if not, write to the Free Software
17 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
18 *  USA.
19 */
20
21/*
22 * sockets.c - functions to deal with sockets.
23 */
24
25#ifdef __STRICT_ANSI__
26#define _BSD_SOURCE
27#ifdef __linux__
28/* Setting this on other systems hides definitions such as INADDR_LOOPBACK.
29 * The check should be for __GLIBC__ in fact. */
30# define _POSIX_SOURCE
31#endif
32#endif
33#include <unistd.h>
34#include <errno.h>
35#include <fcntl.h>
36#include <assert.h>
37#include <rfb/rfbclient.h>
38#ifdef WIN32
39#undef SOCKET
40#include <winsock2.h>
41#ifdef MINGW32
42#define EWOULDBLOCK WSAEWOULDBLOCK
43#endif
44#define close closesocket
45#define read(sock,buf,len) recv(sock,buf,len,0)
46#define write(sock,buf,len) send(sock,buf,len,0)
47#define socklen_t int
48#ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H
49#undef socklen_t
50#include <ws2tcpip.h>
51#endif
52#else
53#include <sys/socket.h>
54#include <netinet/in.h>
55#include <sys/un.h>
56#include <netinet/tcp.h>
57#include <arpa/inet.h>
58#include <netdb.h>
59#endif
60#include "tls.h"
61
62#ifdef _MSC_VER
63#  define snprintf _snprintf
64#endif
65
66void PrintInHex(char *buf, int len);
67
68rfbBool errorMessageOnReadFailure = TRUE;
69
70/*
71 * ReadFromRFBServer is called whenever we want to read some data from the RFB
72 * server.  It is non-trivial for two reasons:
73 *
74 * 1. For efficiency it performs some intelligent buffering, avoiding invoking
75 *    the read() system call too often.  For small chunks of data, it simply
76 *    copies the data out of an internal buffer.  For large amounts of data it
77 *    reads directly into the buffer provided by the caller.
78 *
79 * 2. Whenever read() would block, it invokes the Xt event dispatching
80 *    mechanism to process X events.  In fact, this is the only place these
81 *    events are processed, as there is no XtAppMainLoop in the program.
82 */
83
84rfbBool
85ReadFromRFBServer(rfbClient* client, char *out, unsigned int n)
86{
87#undef DEBUG_READ_EXACT
88#ifdef DEBUG_READ_EXACT
89	char* oout=out;
90	int nn=n;
91	rfbClientLog("ReadFromRFBServer %d bytes\n",n);
92#endif
93
94  /* Handle attempts to write to NULL out buffer that might occur
95     when an outside malloc() fails. For instance, memcpy() to NULL
96     results in undefined behaviour and probably memory corruption.*/
97  if(!out)
98    return FALSE;
99
100  if (client->serverPort==-1) {
101    /* vncrec playing */
102    rfbVNCRec* rec = client->vncRec;
103    struct timeval tv;
104
105    if (rec->readTimestamp) {
106      rec->readTimestamp = FALSE;
107      if (!fread(&tv,sizeof(struct timeval),1,rec->file))
108        return FALSE;
109
110      tv.tv_sec = rfbClientSwap32IfLE (tv.tv_sec);
111      tv.tv_usec = rfbClientSwap32IfLE (tv.tv_usec);
112
113      if (rec->tv.tv_sec!=0 && !rec->doNotSleep) {
114        struct timeval diff;
115        diff.tv_sec = tv.tv_sec - rec->tv.tv_sec;
116        diff.tv_usec = tv.tv_usec - rec->tv.tv_usec;
117        if(diff.tv_usec<0) {
118	  diff.tv_sec--;
119	  diff.tv_usec+=1000000;
120        }
121#ifndef WIN32
122        sleep (diff.tv_sec);
123        usleep (diff.tv_usec);
124#else
125	Sleep (diff.tv_sec * 1000 + diff.tv_usec/1000);
126#endif
127      }
128
129      rec->tv=tv;
130    }
131
132    return (fread(out,1,n,rec->file) != n ? FALSE : TRUE);
133  }
134
135  if (n <= client->buffered) {
136    memcpy(out, client->bufoutptr, n);
137    client->bufoutptr += n;
138    client->buffered -= n;
139#ifdef DEBUG_READ_EXACT
140    goto hexdump;
141#endif
142    return TRUE;
143  }
144
145  memcpy(out, client->bufoutptr, client->buffered);
146
147  out += client->buffered;
148  n -= client->buffered;
149
150  client->bufoutptr = client->buf;
151  client->buffered = 0;
152
153  if (n <= RFB_BUF_SIZE) {
154
155    while (client->buffered < n) {
156      int i;
157      if (client->tlsSession) {
158        i = ReadFromTLS(client, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
159      } else {
160        i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
161      }
162      if (i <= 0) {
163	if (i < 0) {
164#ifdef WIN32
165	  errno=WSAGetLastError();
166#endif
167	  if (errno == EWOULDBLOCK || errno == EAGAIN) {
168	    /* TODO:
169	       ProcessXtEvents();
170	    */
171	    WaitForMessage(client, 100000);
172	    i = 0;
173	  } else {
174	    rfbClientErr("read (%d: %s)\n",errno,strerror(errno));
175	    return FALSE;
176	  }
177	} else {
178	  if (errorMessageOnReadFailure) {
179	    rfbClientLog("VNC server closed connection\n");
180	  }
181	  return FALSE;
182	}
183      }
184      client->buffered += i;
185    }
186
187    memcpy(out, client->bufoutptr, n);
188    client->bufoutptr += n;
189    client->buffered -= n;
190
191  } else {
192
193    while (n > 0) {
194      int i;
195      if (client->tlsSession) {
196        i = ReadFromTLS(client, out, n);
197      } else {
198        i = read(client->sock, out, n);
199      }
200
201      if (i <= 0) {
202	if (i < 0) {
203#ifdef WIN32
204	  errno=WSAGetLastError();
205#endif
206	  if (errno == EWOULDBLOCK || errno == EAGAIN) {
207	    /* TODO:
208	       ProcessXtEvents();
209	    */
210	    WaitForMessage(client, 100000);
211	    i = 0;
212	  } else {
213	    rfbClientErr("read (%s)\n",strerror(errno));
214	    return FALSE;
215	  }
216	} else {
217	  if (errorMessageOnReadFailure) {
218	    rfbClientLog("VNC server closed connection\n");
219	  }
220	  return FALSE;
221	}
222      }
223      out += i;
224      n -= i;
225    }
226  }
227
228#ifdef DEBUG_READ_EXACT
229hexdump:
230  { int ii;
231    for(ii=0;ii<nn;ii++)
232      fprintf(stderr,"%02x ",(unsigned char)oout[ii]);
233    fprintf(stderr,"\n");
234  }
235#endif
236
237  return TRUE;
238}
239
240
241/*
242 * Write an exact number of bytes, and don't return until you've sent them.
243 */
244
245rfbBool
246WriteToRFBServer(rfbClient* client, char *buf, int n)
247{
248  fd_set fds;
249  int i = 0;
250  int j;
251
252  if (client->serverPort==-1)
253    return TRUE; /* vncrec playing */
254
255  if (client->tlsSession) {
256    /* WriteToTLS() will guarantee either everything is written, or error/eof returns */
257    i = WriteToTLS(client, buf, n);
258    if (i <= 0) return FALSE;
259
260    return TRUE;
261  }
262
263  while (i < n) {
264    j = write(client->sock, buf + i, (n - i));
265    if (j <= 0) {
266      if (j < 0) {
267#ifdef WIN32
268	 errno=WSAGetLastError();
269#endif
270	if (errno == EWOULDBLOCK ||
271#ifdef LIBVNCSERVER_ENOENT_WORKAROUND
272		errno == ENOENT ||
273#endif
274		errno == EAGAIN) {
275	  FD_ZERO(&fds);
276	  FD_SET(client->sock,&fds);
277
278	  if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) {
279	    rfbClientErr("select\n");
280	    return FALSE;
281	  }
282	  j = 0;
283	} else {
284	  rfbClientErr("write\n");
285	  return FALSE;
286	}
287      } else {
288	rfbClientLog("write failed\n");
289	return FALSE;
290      }
291    }
292    i += j;
293  }
294  return TRUE;
295}
296
297
298
299static int initSockets() {
300#ifdef WIN32
301  WSADATA trash;
302  static rfbBool WSAinitted=FALSE;
303  if(!WSAinitted) {
304    int i=WSAStartup(MAKEWORD(2,0),&trash);
305    if(i!=0) {
306      rfbClientErr("Couldn't init Windows Sockets\n");
307      return 0;
308    }
309    WSAinitted=TRUE;
310  }
311#endif
312  return 1;
313}
314
315/*
316 * ConnectToTcpAddr connects to the given TCP port.
317 */
318
319int
320ConnectClientToTcpAddr(unsigned int host, int port)
321{
322  int sock;
323  struct sockaddr_in addr;
324  int one = 1;
325
326  if (!initSockets())
327	  return -1;
328
329  addr.sin_family = AF_INET;
330  addr.sin_port = htons(port);
331  addr.sin_addr.s_addr = host;
332
333  sock = socket(AF_INET, SOCK_STREAM, 0);
334  if (sock < 0) {
335#ifdef WIN32
336    errno=WSAGetLastError();
337#endif
338    rfbClientErr("ConnectToTcpAddr: socket (%s)\n",strerror(errno));
339    return -1;
340  }
341
342  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
343    rfbClientErr("ConnectToTcpAddr: connect\n");
344    close(sock);
345    return -1;
346  }
347
348  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
349		 (char *)&one, sizeof(one)) < 0) {
350    rfbClientErr("ConnectToTcpAddr: setsockopt\n");
351    close(sock);
352    return -1;
353  }
354
355  return sock;
356}
357
358int
359ConnectClientToTcpAddr6(const char *hostname, int port)
360{
361#ifdef LIBVNCSERVER_IPv6
362  int sock;
363  int n;
364  struct addrinfo hints, *res, *ressave;
365  char port_s[10];
366  int one = 1;
367
368  if (!initSockets())
369	  return -1;
370
371  snprintf(port_s, 10, "%d", port);
372  memset(&hints, 0, sizeof(struct addrinfo));
373  hints.ai_family = AF_UNSPEC;
374  hints.ai_socktype = SOCK_STREAM;
375  if ((n = getaddrinfo(hostname, port_s, &hints, &res)))
376  {
377    rfbClientErr("ConnectClientToTcpAddr6: getaddrinfo (%s)\n", gai_strerror(n));
378    return -1;
379  }
380
381  ressave = res;
382  sock = -1;
383  while (res)
384  {
385    sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
386    if (sock >= 0)
387    {
388      if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
389        break;
390      close(sock);
391      sock = -1;
392    }
393    res = res->ai_next;
394  }
395  freeaddrinfo(ressave);
396
397  if (sock == -1)
398  {
399    rfbClientErr("ConnectClientToTcpAddr6: connect\n");
400    return -1;
401  }
402
403  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
404		 (char *)&one, sizeof(one)) < 0) {
405    rfbClientErr("ConnectToTcpAddr: setsockopt\n");
406    close(sock);
407    return -1;
408  }
409
410  return sock;
411
412#else
413
414  rfbClientErr("ConnectClientToTcpAddr6: IPv6 disabled\n");
415  return -1;
416
417#endif
418}
419
420int
421ConnectClientToUnixSock(const char *sockFile)
422{
423#ifdef WIN32
424  rfbClientErr("Windows doesn't support UNIX sockets\n");
425  return -1;
426#else
427  int sock;
428  struct sockaddr_un addr;
429  addr.sun_family = AF_UNIX;
430  strcpy(addr.sun_path, sockFile);
431
432  sock = socket(AF_UNIX, SOCK_STREAM, 0);
433  if (sock < 0) {
434    rfbClientErr("ConnectToUnixSock: socket (%s)\n",strerror(errno));
435    return -1;
436  }
437
438  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr.sun_family) + strlen(addr.sun_path)) < 0) {
439    rfbClientErr("ConnectToUnixSock: connect\n");
440    close(sock);
441    return -1;
442  }
443
444  return sock;
445#endif
446}
447
448
449
450/*
451 * FindFreeTcpPort tries to find unused TCP port in the range
452 * (TUNNEL_PORT_OFFSET, TUNNEL_PORT_OFFSET + 99]. Returns 0 on failure.
453 */
454
455int
456FindFreeTcpPort(void)
457{
458  int sock, port;
459  struct sockaddr_in addr;
460
461  addr.sin_family = AF_INET;
462  addr.sin_addr.s_addr = htonl(INADDR_ANY);
463
464  if (!initSockets())
465    return -1;
466
467  sock = socket(AF_INET, SOCK_STREAM, 0);
468  if (sock < 0) {
469    rfbClientErr(": FindFreeTcpPort: socket\n");
470    return 0;
471  }
472
473  for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) {
474    addr.sin_port = htons((unsigned short)port);
475    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
476      close(sock);
477      return port;
478    }
479  }
480
481  close(sock);
482  return 0;
483}
484
485
486/*
487 * ListenAtTcpPort starts listening at the given TCP port.
488 */
489
490int
491ListenAtTcpPort(int port)
492{
493  return ListenAtTcpPortAndAddress(port, NULL);
494}
495
496
497
498/*
499 * ListenAtTcpPortAndAddress starts listening at the given TCP port on
500 * the given IP address
501 */
502
503int
504ListenAtTcpPortAndAddress(int port, const char *address)
505{
506  int sock;
507  int one = 1;
508#ifndef LIBVNCSERVER_IPv6
509  struct sockaddr_in addr;
510
511  addr.sin_family = AF_INET;
512  addr.sin_port = htons(port);
513  if (address) {
514    addr.sin_addr.s_addr = inet_addr(address);
515  } else {
516    addr.sin_addr.s_addr = htonl(INADDR_ANY);
517  }
518
519  if (!initSockets())
520    return -1;
521
522  sock = socket(AF_INET, SOCK_STREAM, 0);
523  if (sock < 0) {
524    rfbClientErr("ListenAtTcpPort: socket\n");
525    return -1;
526  }
527
528  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
529		 (const char *)&one, sizeof(one)) < 0) {
530    rfbClientErr("ListenAtTcpPort: setsockopt\n");
531    close(sock);
532    return -1;
533  }
534
535  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
536    rfbClientErr("ListenAtTcpPort: bind\n");
537    close(sock);
538    return -1;
539  }
540
541#else
542  int rv;
543  struct addrinfo hints, *servinfo, *p;
544  char port_str[8];
545
546  snprintf(port_str, 8, "%d", port);
547
548  memset(&hints, 0, sizeof(hints));
549  hints.ai_family = AF_UNSPEC;
550  hints.ai_socktype = SOCK_STREAM;
551  hints.ai_flags = AI_PASSIVE; /* fill in wildcard address if address == NULL */
552
553  if (!initSockets())
554    return -1;
555
556  if ((rv = getaddrinfo(address, port_str, &hints, &servinfo)) != 0) {
557    rfbClientErr("ListenAtTcpPortAndAddress: error in getaddrinfo: %s\n", gai_strerror(rv));
558    return -1;
559  }
560
561  /* loop through all the results and bind to the first we can */
562  for(p = servinfo; p != NULL; p = p->ai_next) {
563    if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
564      continue;
565    }
566
567#ifdef IPV6_V6ONLY
568    /* we have seperate IPv4 and IPv6 sockets since some OS's do not support dual binding */
569    if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
570      rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt IPV6_V6ONLY: %s\n", strerror(errno));
571      close(sock);
572      freeaddrinfo(servinfo);
573      return -1;
574    }
575#endif
576
577    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
578      rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt SO_REUSEADDR: %s\n", strerror(errno));
579      close(sock);
580      freeaddrinfo(servinfo);
581      return -1;
582    }
583
584    if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) {
585      close(sock);
586      continue;
587    }
588
589    break;
590  }
591
592  if (p == NULL)  {
593    rfbClientErr("ListenAtTcpPortAndAddress: error in bind: %s\n", strerror(errno));
594    return -1;
595  }
596
597  /* all done with this structure now */
598  freeaddrinfo(servinfo);
599#endif
600
601  if (listen(sock, 5) < 0) {
602    rfbClientErr("ListenAtTcpPort: listen\n");
603    close(sock);
604    return -1;
605  }
606
607  return sock;
608}
609
610
611/*
612 * AcceptTcpConnection accepts a TCP connection.
613 */
614
615int
616AcceptTcpConnection(int listenSock)
617{
618  int sock;
619  struct sockaddr_in addr;
620  socklen_t addrlen = sizeof(addr);
621  int one = 1;
622
623  sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen);
624  if (sock < 0) {
625    rfbClientErr("AcceptTcpConnection: accept\n");
626    return -1;
627  }
628
629  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
630		 (char *)&one, sizeof(one)) < 0) {
631    rfbClientErr("AcceptTcpConnection: setsockopt\n");
632    close(sock);
633    return -1;
634  }
635
636  return sock;
637}
638
639
640/*
641 * SetNonBlocking sets a socket into non-blocking mode.
642 */
643
644rfbBool
645SetNonBlocking(int sock)
646{
647#ifdef WIN32
648  unsigned long block=1;
649  if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) {
650    errno=WSAGetLastError();
651#else
652  int flags = fcntl(sock, F_GETFL);
653  if(flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
654#endif
655    rfbClientErr("Setting socket to non-blocking failed: %s\n",strerror(errno));
656    return FALSE;
657  }
658  return TRUE;
659}
660
661
662
663/*
664 * SetDSCP sets a socket's IP QoS parameters aka Differentiated Services Code Point field
665 */
666
667rfbBool
668SetDSCP(int sock, int dscp)
669{
670#ifdef WIN32
671  rfbClientErr("Setting of QoS IP DSCP not implemented for Windows\n");
672  return TRUE;
673#else
674  int level, cmd;
675  struct sockaddr addr;
676  socklen_t addrlen = sizeof(addr);
677
678  if(getsockname(sock, &addr, &addrlen) != 0) {
679    rfbClientErr("Setting socket QoS failed while getting socket address: %s\n",strerror(errno));
680    return FALSE;
681  }
682
683  switch(addr.sa_family)
684    {
685#if defined LIBVNCSERVER_IPv6 && defined IPV6_TCLASS
686    case AF_INET6:
687      level = IPPROTO_IPV6;
688      cmd = IPV6_TCLASS;
689      break;
690#endif
691    case AF_INET:
692      level = IPPROTO_IP;
693      cmd = IP_TOS;
694      break;
695    default:
696      rfbClientErr("Setting socket QoS failed: Not bound to IP address");
697      return FALSE;
698    }
699
700  if(setsockopt(sock, level, cmd, (void*)&dscp, sizeof(dscp)) != 0) {
701    rfbClientErr("Setting socket QoS failed: %s\n", strerror(errno));
702    return FALSE;
703  }
704
705  return TRUE;
706#endif
707}
708
709
710
711/*
712 * StringToIPAddr - convert a host string to an IP address.
713 */
714
715rfbBool
716StringToIPAddr(const char *str, unsigned int *addr)
717{
718  struct hostent *hp;
719
720  if (strcmp(str,"") == 0) {
721    *addr = htonl(INADDR_LOOPBACK); /* local */
722    return TRUE;
723  }
724
725  *addr = inet_addr(str);
726
727  if (*addr != -1)
728    return TRUE;
729
730  if (!initSockets())
731	  return -1;
732
733  hp = gethostbyname(str);
734
735  if (hp) {
736    *addr = *(unsigned int *)hp->h_addr;
737    return TRUE;
738  }
739
740  return FALSE;
741}
742
743
744/*
745 * Test if the other end of a socket is on the same machine.
746 */
747
748rfbBool
749SameMachine(int sock)
750{
751  struct sockaddr_in peeraddr, myaddr;
752  socklen_t addrlen = sizeof(struct sockaddr_in);
753
754  getpeername(sock, (struct sockaddr *)&peeraddr, &addrlen);
755  getsockname(sock, (struct sockaddr *)&myaddr, &addrlen);
756
757  return (peeraddr.sin_addr.s_addr == myaddr.sin_addr.s_addr);
758}
759
760
761/*
762 * Print out the contents of a packet for debugging.
763 */
764
765void
766PrintInHex(char *buf, int len)
767{
768  int i, j;
769  char c, str[17];
770
771  str[16] = 0;
772
773  rfbClientLog("ReadExact: ");
774
775  for (i = 0; i < len; i++)
776    {
777      if ((i % 16 == 0) && (i != 0)) {
778	rfbClientLog("           ");
779      }
780      c = buf[i];
781      str[i % 16] = (((c > 31) && (c < 127)) ? c : '.');
782      rfbClientLog("%02x ",(unsigned char)c);
783      if ((i % 4) == 3)
784	rfbClientLog(" ");
785      if ((i % 16) == 15)
786	{
787	  rfbClientLog("%s\n",str);
788	}
789    }
790  if ((i % 16) != 0)
791    {
792      for (j = i % 16; j < 16; j++)
793	{
794	  rfbClientLog("   ");
795	  if ((j % 4) == 3) rfbClientLog(" ");
796	}
797      str[i % 16] = 0;
798      rfbClientLog("%s\n",str);
799    }
800
801  fflush(stderr);
802}
803
804int WaitForMessage(rfbClient* client,unsigned int usecs)
805{
806  fd_set fds;
807  struct timeval timeout;
808  int num;
809
810  if (client->serverPort==-1)
811    /* playing back vncrec file */
812    return 1;
813
814  timeout.tv_sec=(usecs/1000000);
815  timeout.tv_usec=(usecs%1000000);
816
817  FD_ZERO(&fds);
818  FD_SET(client->sock,&fds);
819
820  num=select(client->sock+1, &fds, NULL, NULL, &timeout);
821  if(num<0) {
822#ifdef WIN32
823    errno=WSAGetLastError();
824#endif
825    rfbClientLog("Waiting for message failed: %d (%s)\n",errno,strerror(errno));
826  }
827
828  return num;
829}
830
831
832