Ejemplo n.º 1
0
static gint sock_connect_by_hostname(gint sock, const gchar *hostname,
				     gushort port)
{
	struct hostent *hp;
	struct sockaddr_in ad;

	resolver_init();

	memset(&ad, 0, sizeof(ad));
	ad.sin_family = AF_INET;
	ad.sin_port = htons(port);

	if (!my_inet_aton(hostname, &ad.sin_addr)) {
		if ((hp = my_gethostbyname(hostname)) == NULL) {
			fprintf(stderr, "%s: unknown host.\n", hostname);
			errno = 0;
			return -1;
		}

		if (hp->h_length != 4 && hp->h_length != 8) {
			fprintf(stderr, "illegal address length received for host %s\n", hostname);
			errno = 0;
			return -1;
		}

		memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
	}

	return sock_connect_with_timeout(sock, (struct sockaddr *)&ad,
					 sizeof(ad), io_timeout);
}
Ejemplo n.º 2
0
gint socks4_connect(SockInfo *sock, const gchar *hostname, gushort port)
{
	guchar socks_req[1024];
	struct hostent *hp;

	g_return_val_if_fail(sock != NULL, -1);
	g_return_val_if_fail(hostname != NULL, -1);

	debug_print("socks4_connect: connect to %s:%u\n", hostname, port);

	socks_req[0] = 4;
	socks_req[1] = 1;
	*((gushort *)(socks_req + 2)) = htons(port);

	/* lookup */
	if ((hp = my_gethostbyname(hostname)) == NULL) {
		g_warning("socks4_connect: cannot lookup host: %s", hostname);
		return -1;
	}
	if (hp->h_length != 4) {
		g_warning("socks4_connect: invalid address length for host: %s", hostname);
		return -1;
	}
	memcpy(socks_req + 4, (guchar *)hp->h_addr, 4);

	/* userid (empty) */
	socks_req[8] = 0;

	if (sock_write_all(sock, (gchar *)socks_req, 9) != 9) {
		g_warning("socks4_connect: SOCKS4 initial request write failed");
		return -1;
	}

	if (sock_read(sock, (gchar *)socks_req, 8) != 8) {
		g_warning("socks4_connect: SOCKS4 response read failed");
		return -1;
	}
	if (socks_req[0] != 0) {
		g_warning("socks4_connect: SOCKS4 response has invalid version");
		return -1;
	}
	if (socks_req[1] != 90) {
		g_warning("socks4_connect: SOCKS4 connection to %u.%u.%u.%u:%u failed. (%u)", socks_req[4], socks_req[5], socks_req[6], socks_req[7], ntohs(*(gushort *)(socks_req + 2)), socks_req[1]);
		return -1;
	}

	debug_print("socks4_connect: SOCKS4 connection to %s:%u successful.\n", hostname, port);

	return 0;
}
Ejemplo n.º 3
0
/* use sens functions for these, if found. */
struct hostent *ei_gethostbyname(const char *name)
{
  struct hostent *h = NULL;
  
  if (!sens_gethostbyname) {
    h = my_gethostbyname(name);
  }
  else {
    /* FIXME problem for threaded ? */
    static char buf[1024];
    h = sens_gethostbyname(name,buf,1024);
  }

  return h;
}
Ejemplo n.º 4
0
/*
 * Read bytes from the server
 */
bool VNCSockets::ReadFromRFBServer(char *out, uint32_t n)
{
    if (n <= buffered)
    {
        memcpy(out, bufoutptr, n);
        bufoutptr += n;
        buffered -= n;
        return true;
    }
    memcpy(out, bufoutptr, buffered);

    out += buffered;
    n -= buffered;
    bufoutptr = buf;
    buffered = 0;

    if (n <= sizeof(buf))
    {
        while (buffered < n)
        {

#ifdef _WIN32
            int i = recv(rfbsock, (char *)buf + buffered, sizeof(buf) - buffered, 0);
#else
            int i = read(rfbsock, buf + buffered, sizeof(buf) - buffered);
#endif
            if (i <= 0)
            {
                if (i < 0)
                {
#ifdef _WIN32
                    if (errno == EAGAIN || (errno == EINTR))
                    {
#else
                    if (errno == EWOULDBLOCK || errno == EAGAIN || (errno == EINTR))
                    {
#endif
                        i = 0;
                    }
                    else
                    {
                        fprintf(stderr, "VNCSockets::ReadFromRFBServer(): read\n");
                        return false;
                    }
                }
                else
                {
                    fprintf(stderr, "VNCSockets::ReadFromRFBServer(): VNC server closed connection\n");
                    return false;
                }
            }
            buffered += i;
        }
        memcpy(out, bufoutptr, n);
        bufoutptr += n;
        buffered -= n;
        return true;
    }
    else
    {
        while (n > 0)
        {
#ifdef _WIN32
            int i = recv(rfbsock, out, n, 0);
#else
            int i = read(rfbsock, out, n);
#endif
            if (i <= 0)
            {
                if (i < 0)
                {
#ifdef _WIN32
                    if (errno == EAGAIN || (errno == EINTR))
                    {
#else
                    if (errno == EWOULDBLOCK || errno == EAGAIN || (errno == EINTR))
                    {
#endif
                        i = 0;
                    }
                    else
                    {
                        fprintf(stderr, "VNCSockets::ReadFromRFBServer(): read\n");
                        return false;
                    }
                }
                else
                {
                    fprintf(stderr, "VNCSockets::ReadFromRFBServer(): VNC server closed connection\n");
                    return false;
                }
            }
            out += i;
            n -= i;
        }
        return true;
    }
}

/*
 * Write an exact number of bytes, and don't return until you've sent them.
 */
bool VNCSockets::WriteExact(char *buf, int n)
{
    for (int i = 0; i < n;)
    {
#ifdef _WIN32
        int j = send(rfbsock, buf + i, (n - i), 0);
#else
        int j = write(rfbsock, buf + i, (n - i));
#endif

        if (j <= 0)
        {
            if (j < 0)
            {
#ifdef _WIN32
                if (errno == EAGAIN || (errno == EINTR))
                {
#else
                if (errno == EWOULDBLOCK || errno == EAGAIN || (errno == EINTR))
                {
#endif
                    fd_set fds;
                    FD_ZERO(&fds);
                    FD_SET(rfbsock, &fds);
                    if (select(rfbsock + 1, NULL, &fds, NULL, NULL) <= 0)
                    {
                        fprintf(stderr, "VNCSockets::WriteExact(): select\n");
                        return false;
                    }
                    j = 0;
                }
                else
                {
                    fprintf(stderr, "VNCSockets::WriteExact(): write\n");
                    return false;
                }
            }
            else
            {
                fprintf(stderr, "VNCSockets::WriteExact() err: write failed\n");
                return false;
            }
        }
        i += j;
    }
    return true;
}

/*
 * ConnectToTcpAddr connects to the given TCP port.
 */
int VNCSockets::ConnectToTcpAddr()
{
    if ((rfbsock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        fprintf(stderr, "VNCSockets::ConnectToTcpAddr() err: socket\n");
        return -1;
    }

    struct sockaddr_in sa;

    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    sa.sin_addr.s_addr = htonl(ipaddr);

    fprintf(stderr, "VNCSockets::ConnectToTcpAddr(): connecting to %s:%i %x\n",
            ServerName, ntohs(sa.sin_port), ntohl(sa.sin_addr.s_addr));

    if (connect(rfbsock, (const struct sockaddr *)&sa, sizeof(sa)) < 0)
    {
        perror("VNC: connect");
        fprintf(stderr, "VNCSockets::ConnectToTcpAddr() err: %s (%d) sock=%d\n", strerror(errno), errno, rfbsock);
        closesocket(rfbsock);
        return -1;
    }
    if (setTcpNoDelay(rfbsock) < 0)
    {
        fprintf(stderr, "VNCSockets::ConnectToTcpAddr() err: TCP_NODELAY %s (%d)\n", strerror(errno), errno);
        //pd close(rfbsock);
        //pd return -1;
    }
    return rfbsock;
}

/*
 * SetNonBlocking sets a socket into non-blocking mode.
 */
bool VNCSockets::SetNonBlocking()
{
    if (setNoBlocking(rfbsock) < 0)
        return false;
    return true;
}

/*
 * StringToIPAddr - convert a host string to an IP address.
 */
bool VNCSockets::StringToIPAddr()
{
    struct hostent *hp;

    if ((hp = my_gethostbyname(ServerName, AF_INET)) != NULL)
    {
        memcpy(&ipaddr, hp->h_addr, hp->h_length);
        ipaddr = ntohl(ipaddr);
        fprintf(stderr, "VNCSockets::StringToIPAddr(): ServerName=%s (%x)\n", ServerName, ipaddr);
        return true;
    }
    return false;
}

/*
 * Test if the other end of a socket is on the same machine.
 */
bool VNCSockets::SameMachine()
{
    struct sockaddr_in peersa, mysa;
#ifdef WIN32
    int slen = sizeof(struct sockaddr_in);
#else
    socklen_t slen = sizeof(struct sockaddr_in);
#endif

    getpeername(rfbsock, (struct sockaddr *)&peersa, &slen);
    getsockname(rfbsock, (struct sockaddr *)&mysa, &slen);

    return (peersa.sin_addr.s_addr == mysa.sin_addr.s_addr);
}

#if 0 //unused
/*
 * Print out the contents of a packet for debugging.
 */
void VNCSockets::PrintInHex(char *buf, int len)
{
  int i;
  char c, str[17];

  str[16] = 0;

  trace(DBG_VNC, "ReadExact: ");

  for (i = 0; i < len; i++) {
    if ((i % 16 == 0) && (i != 0))
      fprintf(stderr, "           ");
    c = buf[i];
    str[i % 16] = (((c > 31) && (c < 127)) ? c : '.');
    fprintf(stderr,"%02x ", (uint8_t) c);
    if ((i % 4) == 3)
      fprintf(stderr, " ");
    if ((i % 16) == 15)
      fprintf(stderr,"%s\n", str);
  }
  if ((i % 16) != 0) {
    for (int j = i % 16; j < 16; j++) {
      fprintf(stderr, "   ");
      if ((j % 4) == 3) fprintf(stderr, " ");
    }
    str[i % 16] = 0;
    fprintf(stderr,"%s\n", str);
  }
  fflush(stderr);
}
#endif //unused

/*
 * Returns the socket used
 */
int VNCSockets::GetSock()
{
    return rfbsock;
}
Ejemplo n.º 5
0
static SockLookupData *sock_get_address_info_async(const gchar *hostname,
						   gushort port,
						   SockAddrFunc func,
						   gpointer data)
{
	SockLookupData *lookup_data = NULL;
	gint pipe_fds[2];
	pid_t pid;

	resolver_init();

	if (pipe(pipe_fds) < 0) {
		perror("pipe");
		func(NULL, data);
		return NULL;
	}

	if ((pid = fork()) < 0) {
		perror("fork");
		func(NULL, data);
		return NULL;
	}

	/* child process */
	if (pid == 0) {
#ifdef INET6
		gint gai_err;
		struct addrinfo hints, *res, *ai;
		gchar port_str[6];
#else /* !INET6 */
		struct hostent *hp;
		gchar **addr_list_p;
		struct sockaddr_in ad;
#endif /* INET6 */
		gint ai_member[4] = {AF_UNSPEC, 0, 0, 0};

		close(pipe_fds[0]);

#ifdef INET6
		memset(&hints, 0, sizeof(hints));
		/* hints.ai_flags = AI_CANONNAME; */
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_protocol = IPPROTO_TCP;

		g_snprintf(port_str, sizeof(port_str), "%d", port);

		gai_err = getaddrinfo(hostname, port_str, &hints, &res);
		if (gai_err != 0) {
			g_warning("getaddrinfo for %s:%s failed: %s\n",
				  hostname, port_str, gai_strerror(gai_err));
			fd_write_all(pipe_fds[1], (gchar *)ai_member,
				     sizeof(ai_member));
			close(pipe_fds[1]);
			_exit(1);
		}

		for (ai = res; ai != NULL; ai = ai->ai_next) {
			ai_member[0] = ai->ai_family;
			ai_member[1] = ai->ai_socktype;
			ai_member[2] = ai->ai_protocol;
			ai_member[3] = ai->ai_addrlen;

			fd_write_all(pipe_fds[1], (gchar *)ai_member,
				     sizeof(ai_member));
			fd_write_all(pipe_fds[1], (gchar *)ai->ai_addr,
				     ai->ai_addrlen);
		}

		if (res != NULL)
			freeaddrinfo(res);
#else /* !INET6 */
		hp = my_gethostbyname(hostname);
		if (hp == NULL || hp->h_addrtype != AF_INET) {
			fd_write_all(pipe_fds[1], (gchar *)ai_member,
				     sizeof(ai_member));
			close(pipe_fds[1]);
			_exit(1);
		}

		ai_member[0] = AF_INET;
		ai_member[1] = SOCK_STREAM;
		ai_member[2] = IPPROTO_TCP;
		ai_member[3] = sizeof(ad);

		memset(&ad, 0, sizeof(ad));
		ad.sin_family = AF_INET;
		ad.sin_port = htons(port);

		for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL;
		     addr_list_p++) {
			memcpy(&ad.sin_addr, *addr_list_p, hp->h_length);
			fd_write_all(pipe_fds[1], (gchar *)ai_member,
				     sizeof(ai_member));
			fd_write_all(pipe_fds[1], (gchar *)&ad, sizeof(ad));
		}
#endif /* INET6 */

		close(pipe_fds[1]);

		_exit(0);
	} else {
		close(pipe_fds[1]);

		lookup_data = g_new0(SockLookupData, 1);
		lookup_data->hostname = g_strdup(hostname);
		lookup_data->child_pid = pid;
		lookup_data->func = func;
		lookup_data->data = data;

		lookup_data->channel = g_io_channel_unix_new(pipe_fds[0]);
		lookup_data->io_tag = g_io_add_watch
			(lookup_data->channel, G_IO_IN,
			 sock_get_address_info_async_cb, lookup_data);
	}

	return lookup_data;
}
Ejemplo n.º 6
0
/* subset of getaddrinfo() */
static int my_getaddrinfo(const char *node, const char *service,
			  const struct addrinfo *hintp,
			  struct addrinfo **res)
{
	struct addrinfo *ai;
	struct sockaddr_in addr, *paddr;
	struct addrinfo hints;
	gint port = 0;

	if (win32_ipv6_supported())
		return getaddrinfo_func(node, service, hintp, res);

	if (!hintp) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_INET;
		hints.ai_socktype = SOCK_STREAM;
	} else
		memcpy(&hints, hintp, sizeof(hints));

	if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET)
		return EAI_FAMILY;
	if (hints.ai_socktype == 0)
		hints.ai_socktype = SOCK_STREAM;
	if (hints.ai_protocol == 0)
		hints.ai_protocol = IPPROTO_TCP;
	if (hints.ai_socktype != SOCK_STREAM)
		return EAI_SOCKTYPE;
	if (hints.ai_protocol != IPPROTO_TCP)
		return EAI_SOCKTYPE;
#if 0
	if (!node && !service)
		return EAI_NONAME;
#endif
	if (!node || !service)
		return EAI_NONAME;

	port = atoi(service);

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);

	if (!my_inet_aton(node, &addr.sin_addr)) {
		struct hostent *hp;

		if ((hp = my_gethostbyname(node)) == NULL) {
			fprintf(stderr, "%s: unknown host.\n", node);
			errno = 0;
			return EAI_NONAME;
		}
		if (hp->h_length != 4 && hp->h_length != 8) {
			fprintf(stderr, "illegal address length received for host %s\n", node);
			errno = 0;
			return EAI_FAIL;
		}

		memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
	}

	ai = g_malloc0(sizeof(struct addrinfo));
	paddr = g_malloc(sizeof(struct sockaddr_in));
	memcpy(paddr, &addr, sizeof(struct sockaddr_in));

	ai->ai_flags = 0;
	ai->ai_family = AF_INET;
	ai->ai_socktype = hints.ai_socktype;
	ai->ai_protocol = hints.ai_protocol;
	ai->ai_addrlen = sizeof(struct sockaddr_in);
	ai->ai_addr = (struct sockaddr *)paddr;
	ai->ai_canonname = NULL;
	ai->ai_next = NULL;

	*res = ai;

	return 0;
}
Ejemplo n.º 7
0
/* For better readability we use a separate function to implement the
   child code of sock_get_address_info_async.  Note, that under W32
   this is actually not a child but a thread and this is the reason
   why we pass only a void pointer. */
static void address_info_async_child(void *opaque)
{
        SockLookupData *parm = opaque;
#ifdef INET6
        gint gai_err;
        struct addrinfo hints, *res, *ai;
        gchar port_str[6];
#else /* !INET6 */
        struct hostent *hp;
        gchar **addr_list_p;
        struct sockaddr_in ad;
#endif /* INET6 */
        gint ai_member[4] = {AF_UNSPEC, 0, 0, 0};

#ifndef G_OS_WIN32
        close(parm->pipe_fds[0]);
        parm->pipe_fds[0] = -1;
#endif

#ifdef INET6
        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = AI_CANONNAME;
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;

        g_snprintf(port_str, sizeof(port_str), "%d", parm->port);

        gai_err = getaddrinfo(parm->hostname, port_str, &hints, &res);
        if (gai_err != 0) {
		gchar len = 0;
                g_warning("getaddrinfo for %s:%s failed: %s\n",
                          parm->hostname, port_str, gai_strerror(gai_err));
		log_error(LOG_PROTOCOL, _("%s:%s: host lookup failed (%s).\n"),
			  parm->hostname, port_str, gai_strerror(gai_err));
	        fd_write_all(parm->pipe_fds[1], &len,
                     sizeof(len));
                fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
                             sizeof(ai_member));
                close(parm->pipe_fds[1]);
                parm->pipe_fds[1] = -1;
#ifdef G_OS_WIN32
                _endthread();
#else
                _exit(1);
#endif
        }

	if (res != NULL) {
		if (res->ai_canonname && strlen(res->ai_canonname) < 255) {
			gchar len = strlen(res->ai_canonname);
	                fd_write_all(parm->pipe_fds[1], &len,
                             sizeof(len));
	                fd_write_all(parm->pipe_fds[1], res->ai_canonname,
                             len);			 
		} else {
			gchar len = 0;
	                fd_write_all(parm->pipe_fds[1], &len,
                             sizeof(len));
		}
	} else {
		gchar len = 0;
	        fd_write_all(parm->pipe_fds[1], &len,
                     sizeof(len));
	}

        for (ai = res; ai != NULL; ai = ai->ai_next) {
                ai_member[0] = ai->ai_family;
                ai_member[1] = ai->ai_socktype;
                ai_member[2] = ai->ai_protocol;
                ai_member[3] = ai->ai_addrlen;

                fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
                             sizeof(ai_member));
                fd_write_all(parm->pipe_fds[1], (gchar *)ai->ai_addr,
                             ai->ai_addrlen);
        }

        if (res != NULL)
                freeaddrinfo(res);
#else /* !INET6 */
        hp = my_gethostbyname(parm->hostname);
        if (hp == NULL || hp->h_addrtype != AF_INET) {
		gchar len = 0;
 	        fd_write_all(parm->pipe_fds[1], &len,
                     sizeof(len));
                fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
                             sizeof(ai_member));
               close(parm->pipe_fds[1]);
                parm->pipe_fds[1] = -1;
#ifdef G_OS_WIN32
                _endthread();
#else
                _exit(1);
#endif
        }

        ai_member[0] = AF_INET;
        ai_member[1] = SOCK_STREAM;
        ai_member[2] = IPPROTO_TCP;
        ai_member[3] = sizeof(ad);

        memset(&ad, 0, sizeof(ad));
        ad.sin_family = AF_INET;
        ad.sin_port = htons(parm->port);

	if (hp->h_name && strlen(hp->h_name) < 255) {
		gchar len = strlen(hp->h_name);
	        fd_write_all(parm->pipe_fds[1], &len,
                     sizeof(len));
	        fd_write_all(parm->pipe_fds[1], hp->h_name,
                     len);			 
	} else {
		gchar len = 0;
 	        fd_write_all(parm->pipe_fds[1], &len,
                     sizeof(len));
	}
        for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL;
             addr_list_p++) {
                memcpy(&ad.sin_addr, *addr_list_p, hp->h_length);
                fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
                             sizeof(ai_member));
                fd_write_all(parm->pipe_fds[1], (gchar *)&ad, sizeof(ad));
        }
#endif /* INET6 */

        close(parm->pipe_fds[1]);
        parm->pipe_fds[1] = -1;

#ifdef G_OS_WIN32
        _endthread();
#else
        _exit(0);
#endif
}