1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com> 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat All rights reserved. 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatThis file is part of x11vnc. 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is free software; you can redistribute it and/or modify 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatit under the terms of the GNU General Public License as published by 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe Free Software Foundation; either version 2 of the License, or (at 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatyour option) any later version. 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is distributed in the hope that it will be useful, 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatbut WITHOUT ANY WARRANTY; without even the implied warranty of 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatGNU General Public License for more details. 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatYou should have received a copy of the GNU General Public License 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatalong with x11vnc; if not, write to the Free Software 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehator see <http://www.gnu.org/licenses/>. 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatIn addition, as a special exception, Karl J. Runge 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatgives permission to link the code of its release of x11vnc with the 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatOpenSSL project's "OpenSSL" library (or with modified versions of it 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthat use the same license as the "OpenSSL" library), and distribute 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe linked executables. You must obey the GNU General Public License 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatin all respects for all of the code used other than "OpenSSL". If you 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatmodify this file, you may extend this exception to your version of the 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfile, but you are not obligated to do so. If you do not wish to do 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatso, delete this exception statement from your version. 31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat*/ 32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* -- inet.c -- */ 34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "x11vnc.h" 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "unixpw.h" 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "sslhelper.h" 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Simple utility to map host name to dotted IP address. Ignores aliases. 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Up to caller to free returned string. 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *host2ip(char *host); 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *raw2host(char *raw, int len); 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *raw2ip(char *raw); 46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ip2host(char *ip); 47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint ipv6_ip(char *host); 48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint dotted_ip(char *host, int partial); 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_remote_port(int sock); 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_local_port(int sock); 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *get_remote_host(int sock); 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *get_local_host(int sock); 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ident_username(rfbClientPtr client); 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint find_free_port(int start, int end); 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint find_free_port6(int start, int end); 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint have_ssh_env(void); 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen); 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ipv6_getipaddr(struct sockaddr *paddr, int addrlen); 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint listen6(int port); 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint listen_unix(char *file); 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint accept_unix(int s); 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint connect_tcp(char *host, int port); 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint listen_tcp(int port, in_addr_t iface, int try6); 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int get_port(int sock, int remote); 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char *get_host(int sock, int remote); 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *host2ip(char *host) { 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct hostent *hp; 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_in addr; 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! host_lookup) { 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hp = gethostbyname(host); 78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!hp) { 79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset(&addr, 0, sizeof(addr)); 82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat addr.sin_family = AF_INET; 83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr; 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = strdup(inet_ntoa(addr.sin_addr)); 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return str; 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *raw2host(char *raw, int len) { 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_NETDB_H && LIBVNCSERVER_HAVE_NETINET_IN_H 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct hostent *hp; 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! host_lookup) { 94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hp = gethostbyaddr(raw, len, AF_INET); 98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!hp) { 99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup(inet_ntoa(*((struct in_addr *)raw))); 100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = strdup(hp->h_name); 102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = strdup("unknown"); 104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return str; 106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *raw2ip(char *raw) { 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup(inet_ntoa(*((struct in_addr *)raw))); 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ip2host(char *ip) { 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_NETDB_H && LIBVNCSERVER_HAVE_NETINET_IN_H 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct hostent *hp; 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat in_addr_t iaddr; 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! host_lookup) { 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iaddr = inet_addr(ip); 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (iaddr == htonl(INADDR_NONE)) { 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hp = gethostbyaddr((char *)&iaddr, sizeof(in_addr_t), AF_INET); 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!hp) { 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = strdup(hp->h_name); 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = strdup("unknown"); 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return str; 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint ipv6_ip(char *host_in) { 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *p, *host, a[2]; 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ncol = 0, nhex = 0; 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (host_in[0] == '[') { 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat host = host_in + 1; 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat host = host_in; 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strstr(host, "::ffff:") == host || strstr(host, "::FFFF:") == host) { 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return dotted_ip(host + strlen("::ffff:"), 0); 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat a[1] = '\0'; 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = host; 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*p != '\0' && *p != '%' && *p != ']') { 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*p == ':') { 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ncol++; 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nhex++; 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat a[0] = *p; 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strpbrk(a, ":abcdef0123456789") == a) { 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p++; 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ncol < 2 || ncol > 8 || nhex == 0) { 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint dotted_ip(char *host, int partial) { 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int len, dots = 0; 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *p = host; 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!host) { 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!isdigit((unsigned char) host[0])) { 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat len = strlen(host); 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!partial && !isdigit((unsigned char) host[len-1])) { 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*p != '\0') { 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*p == '.') dots++; 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*p == '.' || isdigit((unsigned char) (*p))) { 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p++; 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!partial && dots != 3) { 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int get_port(int sock, int remote) { 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_in saddr; 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int saddr_len; 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int saddr_port; 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_len = sizeof(saddr); 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset(&saddr, 0, sizeof(saddr)); 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_port = -1; 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (remote) { 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!getpeername(sock, (struct sockaddr *)&saddr, &saddr_len)) { 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_port = ntohs(saddr.sin_port); 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!getsockname(sock, (struct sockaddr *)&saddr, &saddr_len)) { 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_port = ntohs(saddr.sin_port); 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return saddr_port; 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_remote_port(int sock) { 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return get_port(sock, 1); 228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_local_port(int sock) { 231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return get_port(sock, 0); 232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char *get_host(int sock, int remote) { 235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_in saddr; 236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int saddr_len; 237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int saddr_port; 238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *saddr_ip_str = NULL; 239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_len = sizeof(saddr); 241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset(&saddr, 0, sizeof(saddr)); 242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_port = -1; 243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_NETINET_IN_H 244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (remote) { 245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!getpeername(sock, (struct sockaddr *)&saddr, &saddr_len)) { 246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_ip_str = inet_ntoa(saddr.sin_addr); 247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!getsockname(sock, (struct sockaddr *)&saddr, &saddr_len)) { 250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_ip_str = inet_ntoa(saddr.sin_addr); 251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! saddr_ip_str) { 255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saddr_ip_str = "unknown"; 256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup(saddr_ip_str); 258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *get_remote_host(int sock) { 261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return get_host(sock, 1); 262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *get_local_host(int sock) { 265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return get_host(sock, 0); 266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ident_username(rfbClientPtr client) { 269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ClientData *cd = (ClientData *) client->clientData; 270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str, *newhost, *user = NULL, *newuser = NULL; 271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int len; 272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cd) { 274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat user = cd->username; 275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!user || *user == '\0') { 277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n, sock, ok = 0; 278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int block = 0; 279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int refused = 0; 280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * need to check to see if the operation will block for 283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * a long time: a firewall may just ignore our packets. 284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_FORK 286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { pid_t pid, pidw; 287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int rc; 288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((pid = fork()) > 0) { 289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat usleep(100 * 1000); /* 0.1 sec for quick success or refusal */ 290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pidw = waitpid(pid, &rc, WNOHANG); 291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (pidw <= 0) { 292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat usleep(1500 * 1000); /* 1.5 sec */ 293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pidw = waitpid(pid, &rc, WNOHANG); 294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (pidw <= 0) { 295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int rc2; 296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("ident_username: set block=1 (hung)\n"); 297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat block = 1; 298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kill(pid, SIGTERM); 299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat usleep(100 * 1000); 300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat waitpid(pid, &rc2, WNOHANG); 301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (pidw > 0 && !block) { 304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (WIFEXITED(rc) && WEXITSTATUS(rc) == 1) { 305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("ident_username: set refused=1 (exit)\n"); 306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat refused = 1; 307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (pid == -1) { 310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* child */ 313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat signal(SIGHUP, SIG_DFL); 314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat signal(SIGINT, SIG_DFL); 315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat signal(SIGQUIT, SIG_DFL); 316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat signal(SIGTERM, SIG_DFL); 317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((sock = connect_tcp(client->host, 113)) < 0) { 319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat exit(1); 320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat exit(0); 323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (block || refused) { 328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ((sock = connect_tcp(client->host, 113)) < 0) { 330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("ident_username: could not connect to ident: %s:%d\n", 331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->host, 113); 332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char msg[128]; 334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ret; 335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd_set rfds; 336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct timeval tv; 337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int rport = get_remote_port(client->sock); 338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int lport = get_local_port(client->sock); 339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(msg, "%d, %d\r\n", rport, lport); 341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = write(sock, msg, strlen(msg)); 342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_ZERO(&rfds); 344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_SET(sock, &rfds); 345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tv.tv_sec = 3; 346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tv.tv_usec = 0; 347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ret = select(sock+1, &rfds, NULL, NULL, &tv); 348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ret > 0) { 350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i; 351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *q, *p; 352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i < (int) sizeof(msg); i++) { 353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg[i] = '\0'; 354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat usleep(250*1000); 356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = read(sock, msg, 127); 357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n <= 0) goto badreply; 359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 32782 , 6000 : USERID : UNIX :runge */ 361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = strstr(msg, "USERID"); 362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!q) goto badreply; 363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = strstr(q, ":"); 364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!q) goto badreply; 365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q++; 366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = strstr(q, ":"); 367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!q) goto badreply; 368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q++; 369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = lblanks(q); 370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = q; 371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*p) { 372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*p == '\r' || *p == '\n') { 373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *p = '\0'; 374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p++; 376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ok = 1; 378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strlen(q) > 24) { 379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *(q+24) = '\0'; 380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newuser = strdup(q); 382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat badreply: 384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = 0; /* avoid syntax error */ 385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! ok || !newuser) { 390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newuser = strdup("unknown-user"); 391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cd) { 393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cd->username) { 394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(cd->username); 395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cd->username = newuser; 397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat user = newuser; 399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!strcmp(user, "unknown-user") && cd && cd->unixname[0] != '\0') { 401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat user = cd->unixname; 402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (unixpw && openssl_last_ip && strstr("UNIX:", user) != user) { 404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newhost = ip2host(openssl_last_ip); 405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newhost = ip2host(client->host); 407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat len = strlen(user) + 1 + strlen(newhost) + 1; 409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = (char *) malloc(len); 410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(str, "%s@%s", user, newhost); 411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(newhost); 412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return str; 413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint find_free_port(int start, int end) { 416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int port; 417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (start <= 0) { 418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat start = 1024; 419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (end <= 0) { 421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat end = 65530; 422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (port = start; port <= end; port++) { 424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock = listen_tcp(port, htonl(INADDR_ANY), 0); 425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sock >= 0) { 426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return port; 428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint find_free_port6(int start, int end) { 434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int port; 435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (start <= 0) { 436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat start = 1024; 437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (end <= 0) { 439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat end = 65530; 440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (port = start; port <= end; port++) { 442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock = listen6(port); 443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sock >= 0) { 444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return port; 446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint have_ssh_env(void) { 452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str, *p = getenv("SSH_CONNECTION"); 453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *rhost, *rport, *lhost, *lport; 454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! p) { 456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *q = getenv("SSH_CLIENT"); 457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! q) { 458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strstr(q, "127.0.0.1") != NULL) { 461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strstr(p, "127.0.0.1") != NULL) { 467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = strdup(p); 471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strtok(str, " "); 473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rhost = p; 474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strtok(NULL, " "); 476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! p) goto fail; 477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rport = p; 479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strtok(NULL, " "); 481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! p) goto fail; 482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lhost = p; 484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strtok(NULL, " "); 486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! p) goto fail; 487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lport = p; 489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (0) fprintf(stderr, "%d/%d - '%s' '%s'\n", atoi(rport), atoi(lport), rhost, lhost); 491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (atoi(rport) <= 16 || atoi(rport) > 65535) { 493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto fail; 494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (atoi(lport) <= 16 || atoi(lport) > 65535) { 496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto fail; 497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!strcmp(rhost, lhost)) { 500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto fail; 501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fail: 508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen) { 515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if X11VNC_IPV6 516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char name[200]; 517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (noipv6) { 518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, 0) == 0) { 521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup(name); 522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *ipv6_getipaddr(struct sockaddr *paddr, int addrlen) { 528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if X11VNC_IPV6 && defined(NI_NUMERICHOST) 529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char name[200]; 530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (noipv6) { 531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, NI_NUMERICHOST) == 0) { 534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup(name); 535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return strdup("unknown"); 538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint listen6(int port) { 541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if X11VNC_IPV6 542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_in6 sin; 543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int fd = -1, one = 1; 544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (noipv6) { 546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (port <= 0 || 65535 < port) { 549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* for us, invalid port means do not listen. */ 550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = socket(AF_INET6, SOCK_STREAM, 0); 554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd < 0) { 555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen6: socket"); 556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("(Ignore the above error if this system is IPv4-only.)\n"); 557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) { 561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen6: setsockopt SO_REUSEADDR"); 562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(fd); 563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) 567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) { 568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen6: setsockopt IPV6_V6ONLY"); 569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(fd); 570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset((char *)&sin, 0, sizeof(sin)); 575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sin.sin6_family = AF_INET6; 576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sin.sin6_port = htons(port); 577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sin.sin6_addr = in6addr_any; 578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (listen_str6) { 580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!strcmp(listen_str6, "localhost") || !strcmp(listen_str6, "::1")) { 581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sin.sin6_addr = in6addr_loopback; 582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int err; 584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct addrinfo *ai; 585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct addrinfo hints; 586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char service[32]; 587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset(&hints, 0, sizeof(hints)); 589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(service, "%d", port); 590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_family = AF_INET6; 592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_socktype = SOCK_STREAM; 593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef AI_ADDRCONFIG 594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_flags |= AI_ADDRCONFIG; 595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef AI_NUMERICHOST 597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(ipv6_ip(listen_str6)) { 598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_flags |= AI_NUMERICHOST; 599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef AI_NUMERICSERV 602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_flags |= AI_NUMERICSERV; 603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat err = getaddrinfo(listen_str6, service, &hints, &ai); 605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (err == 0) { 606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct addrinfo *ap = ai; 607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat err = 1; 608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (ap != NULL) { 609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen); 610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!s) s = strdup("unknown"); 611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("listen6: checking: %s family: %d\n", s, ap->ai_family); 613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ap->ai_family == AF_INET6) { 614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy((char *)&sin, ap->ai_addr, sizeof(sin)); 615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("listen6: using: %s scope_id: %d\n", s, sin.sin6_scope_id); 616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat err = 0; 617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(s); 618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(s); 621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ap = ap->ai_next; 622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat freeaddrinfo(ai); 624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (err != 0) { 627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Invalid or Unsupported -listen6 string: %s\n", listen_str6); 628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(fd); 629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (allow_list && !strcmp(allow_list, "127.0.0.1")) { 633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sin.sin6_addr = in6addr_loopback; 634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (listen_str) { 635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!strcmp(listen_str, "localhost")) { 636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sin.sin6_addr = in6addr_loopback; 637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { 641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen6: bind"); 642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(fd); 643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (listen(fd, 32) < 0) { 646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen6: listen"); 647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(fd); 648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return fd; 651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (port) {} 653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_SYS_SOCKET_H 658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/un.h> 659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint listen_unix(char *file) { 662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !defined(AF_UNIX) || !defined(LIBVNCSERVER_HAVE_SYS_SOCKET_H) 663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sock) {} 664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int s, len; 667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_un saun; 668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat s = socket(AF_UNIX, SOCK_STREAM, 0); 670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (s < 0) { 671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen_unix: socket"); 672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saun.sun_family = AF_UNIX; 675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcpy(saun.sun_path, file); 676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unlink(file); 677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat len = sizeof(saun.sun_family) + strlen(saun.sun_path); 679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (bind(s, (struct sockaddr *)&saun, len) < 0) { 681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen_unix: bind"); 682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(s); 683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (listen(s, 32) < 0) { 687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen_unix: listen"); 688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(s); 689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("listening on unix socket: %s fd=%d\n", file, s); 692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return s; 693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint accept_unix(int s) { 697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !defined(AF_UNIX) || !defined(LIBVNCSERVER_HAVE_SYS_SOCKET_H) 698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (s) {} 699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int fd, fromlen; 702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_un fsaun; 703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = accept(s, (struct sockaddr *)&fsaun, &fromlen); 705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd < 0) { 706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("accept_unix: accept"); 707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return fd; 710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint connect_tcp(char *host, int port) { 714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat double t0 = dnow(); 715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int fd = -1; 716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int fail4 = noipv4; 717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getenv("IPV4_FAILS")) { 718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fail4 = 2; 719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp: trying: %s %d\n", host, port); 722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fail4) { 724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fail4 > 1) { 725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("TESTING: IPV4_FAILS for connect_tcp.\n"); 726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = rfbConnectToTcpAddr(host, port); 729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd >= 0) { 732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return fd; 733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("connect_tcp: connection failed"); 735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (dnow() - t0 < 4.0) { 737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp: re-trying %s %d\n", host, port); 738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat usleep (100 * 1000); 739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!fail4) { 740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = rfbConnectToTcpAddr(host, port); 741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd < 0) { 743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("connect_tcp: connection failed"); 744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd < 0 && !noipv6) { 748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if X11VNC_IPV6 749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int err; 750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct addrinfo *ai; 751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct addrinfo hints; 752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char service[32], *host2, *q; 753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp: trying IPv6 %s %d\n", host, port); 755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset(&hints, 0, sizeof(hints)); 757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(service, "%d", port); 758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_family = AF_UNSPEC; 760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_socktype = SOCK_STREAM; 761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef AI_ADDRCONFIG 762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_flags |= AI_ADDRCONFIG; 763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(ipv6_ip(host)) { 765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef AI_NUMERICHOST 766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: setting AI_NUMERICHOST for %s\n", host); 767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_flags |= AI_NUMERICHOST; 768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef AI_NUMERICSERV 771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hints.ai_flags |= AI_NUMERICSERV; 772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!strcmp(host, "127.0.0.1")) { 775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat host2 = strdup("::1"); 776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (host[0] == '[') { 777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat host2 = strdup(host+1); 778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat host2 = strdup(host); 780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = strrchr(host2, ']'); 782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (q) { 783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *q = '\0'; 784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat err = getaddrinfo(host2, service, &hints, &ai); 787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (err != 0) { 788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: getaddrinfo[%d]: %s\n", err, gai_strerror(err)); 789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat usleep(100 * 1000); 790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat err = getaddrinfo(host2, service, &hints, &ai); 791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(host2); 793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (err != 0) { 795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: getaddrinfo[%d]: %s\n", err, gai_strerror(err)); 796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct addrinfo *ap = ai; 798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (ap != NULL) { 799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock; 800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fail4) { 802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_in6 *s6ptr; 803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ap->ai_family != AF_INET6) { 804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: skipping AF_INET address under -noipv4\n"); 805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ap = ap->ai_next; 806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef IN6_IS_ADDR_V4MAPPED 809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat s6ptr = (struct sockaddr_in6 *) ap->ai_addr; 810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (IN6_IS_ADDR_V4MAPPED(&(s6ptr->sin6_addr))) { 811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: skipping V4MAPPED address under -noipv4\n"); 812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ap = ap->ai_next; 813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol); 819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sock == -1) { 821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("connect_tcp[ipv6]: socket"); 822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (0) rfbLog("(Ignore the above error if this system is IPv4-only.)\n"); 823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int res = -1, dmsg = 0; 825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen); 826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!s) s = strdup("unknown"); 827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: trying sock=%d fam=%d proto=%d using %s\n", 829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sock, ap->ai_family, ap->ai_protocol, s); 830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat res = connect(sock, ap->ai_addr, ap->ai_addrlen); 831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) 832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (res != 0) { 833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int zero = 0; 834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("connect_tcp[ipv6]: connect"); 835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dmsg = 1; 836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) { 837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: trying again with IPV6_V6ONLY=0\n"); 838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat res = connect(sock, ap->ai_addr, ap->ai_addrlen); 839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dmsg = 0; 840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("connect_tcp[ipv6]: setsockopt IPV6_V6ONLY"); 842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (res == 0) { 846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv6]: connect OK\n"); 847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = sock; 848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!ipv6_client_ip_str) { 849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ipv6_client_ip_str = strdup(s); 850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(s); 852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!dmsg) rfbLogPerror("connect_tcp[ipv6]: connect"); 855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(s); 858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ap = ap->ai_next; 860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat freeaddrinfo(ai); 862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd < 0 && !fail4) { 866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* this is a kludge for IPv4-only machines getting v4mapped string. */ 867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *q, *host2; 868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (host[0] == '[') { 869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat host2 = strdup(host+1); 870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat host2 = strdup(host); 872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = strrchr(host2, ']'); 874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (q) { 875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *q = '\0'; 876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strstr(host2, "::ffff:") == host2 || strstr(host2, "::FFFF:") == host2) { 878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *host3 = host2 + strlen("::ffff:"); 879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (dotted_ip(host3, 0)) { 880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("connect_tcp[ipv4]: trying fallback to IPv4 for %s\n", host2); 881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = rfbConnectToTcpAddr(host3, port); 882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd < 0) { 883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("connect_tcp[ipv4]: connection failed"); 884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(host2); 888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return fd; 890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint listen_tcp(int port, in_addr_t iface, int try6) { 893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int fd = -1; 894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int fail4 = noipv4; 895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getenv("IPV4_FAILS")) { 896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fail4 = 2; 897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (port <= 0 || 65535 < port) { 900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* for us, invalid port means do not listen. */ 901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fail4) { 905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fail4 > 1) { 906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("TESTING: IPV4_FAILS for listen_tcp: port=%d try6=%d\n", port, try6); 907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = rfbListenOnTCPPort(port, iface); 910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd >= 0) { 913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return fd; 914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fail4 > 1) { 916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("listen_tcp: listen failed"); 917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fd < 0 && try6 && ipv6_listen && !noipv6) { 920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if X11VNC_IPV6 921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *save = listen_str6; 922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (iface == htonl(INADDR_LOOPBACK)) { 923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat listen_str6 = "localhost"; 924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("listen_tcp: retrying on IPv6 in6addr_loopback ...\n"); 925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = listen6(port); 926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (iface == htonl(INADDR_ANY)) { 927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat listen_str6 = NULL; 928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("listen_tcp: retrying on IPv6 in6addr_any ...\n"); 929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd = listen6(port); 930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat listen_str6 = save; 932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return fd; 935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 937