Esempio n. 1
0
int
main (int argc, char **argv)
{
	struct sockaddr_in saddr;
	fd_set writefds, wfds;
	int n, s, high_s;
	unsigned int addr, i;

	inet_aton(argv[1] ? argv[1] : "127.0.0.0", &saddr.sin_addr);
	addr = saddr.sin_addr.s_addr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(5500);
	for (i = 1; i < 255; i++) {
		saddr.sin_addr.s_addr = htonl(ntohl(addr) | i);
		s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (s < 0) {
			perror("socket");
			exit(1);
		}
		fd_blocking(s, 0);
		if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr))) {
			if (errno != EINPROGRESS) {
				perror("connect");
				exit(1);
			}
		}
		FD_SET(s, &writefds);
	}
	high_s = s;
	for (;;) {
		wfds = writefds;
		n = select(high_s + 1, 0, &wfds, 0, 0);
		if (n < 0) {
			perror("select");
			exit(1);
		}
		for (s = 3; n && s <= high_s; s++) {
			if (FD_ISSET(s, &wfds)) {
				int siz = sizeof(saddr);
				if (!getpeername(s, &saddr, &siz)) {
					unsigned char magic[8];
					fd_blocking(s, 1);
					write(s, "TRTPHOTL\0\1\0\2", 12);
					if (read(s, magic, 8) == 8 && !memcmp(magic, "TRTP\0\0\0\0", 8)) {
						printf("%s\n", inet_ntoa(saddr.sin_addr));
						close(s);
						exit(0);
					}
				}
				close(s);
				FD_CLR(s, &writefds);
				n--;
			}
		}
	}

	return 0;
}
Esempio n. 2
0
static void
translate_write (int s)
{
	struct trans_conn *trans = (struct trans_conn *)hxd_files[s].conn.ptr;
	int r;

	if (!TRANS_CONNECTED(trans)) {
		int err = -1;
		socklen_t errlen = sizeof(int);

		getsockopt(s, SOL_SOCKET, SO_ERROR, (SETSOCKOPT_PTR_CAST_T)&err, &errlen);
		if (err != 0) {
			hx_printf_prefix(&hx_htlc, 0, INFOPREFIX, "translate: connect so_error %d\n", err);
			trans_close(trans);
			return;
		}
		TRANS_TOGGLE(trans, TRANS_FLAG_CONNECTED);
	}
	fd_blocking(s, 1);
	r = write(s, trans->text, strlen(trans->text));
	fd_blocking(s, 0);
	hxd_fd_clr(s, FDW);
	hxd_fd_set(s, FDR);
}
Esempio n. 3
0
void
translate_connect (struct trans_conn *trans)
{
	int s, r;
	struct SOCKADDR_IN saddr;

	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s < 0) {
		hx_printf_prefix(&hx_htlc, 0, INFOPREFIX, "translate: socket: %s\n", strerror(errno));
		return;
	}
	trans->s = s;
	fd_blocking(s, 0);
 	fd_closeonexec(s, 1);
	saddr.sin_port = htons(80);
	saddr.sin_family = AFINET;
	inet_aton(BABELFISH_IPADDRESS, &saddr.sin_addr);
	r = connect(s, (struct sockaddr *)&saddr, sizeof(saddr));
	if (r < 0) {
		switch (errno) {
			case EINPROGRESS:
				break;
			default:
				hx_printf_prefix(&hx_htlc, 0, INFOPREFIX, "translate: connect: %s\n", strerror(errno));
				trans_close(trans);
				return;
				break;
		}
	} else {
		TRANS_TOGGLE(trans, TRANS_FLAG_CONNECTED);
	}
	hxd_files[s].ready_read = translate_read;
	hxd_files[s].ready_write = translate_write;
	hxd_files[s].conn.ptr = (void *)trans;
	hxd_fd_add(s);
	hxd_fd_set(s, FDW);
}
Esempio n. 4
0
static void
listen_ready_read (int fd)
{
   int s;
   struct SOCKADDR_IN saddr;
   int siz = sizeof(saddr);
#ifdef CONFIG_IPV6
   char buf[HOSTLEN+1];
#else
   char buf[16];
#endif
   struct htlc_conn *htlc;

   s = accept(fd, (struct SOCKADDR *)&saddr, &siz);
   if (s < 0) {
      hxd_log("htls: accept: %s", strerror(errno));
      return;
   }
   if (s >= hxd_open_max) {
      hxd_log("%s:%d: %d >= hxd_open_max (%d)", __FILE__, __LINE__, s, hxd_open_max);
      close(s);
      return;
   }
   fd_closeonexec(s, 1);
   fd_blocking(s, 0);
#ifdef CONFIG_IPV6
   inet_ntop(AFINET, (char *)&saddr.SIN_ADDR, buf, sizeof(buf));
#else
   inet_ntoa_r(saddr.SIN_ADDR, buf, sizeof(buf));
#endif
   hxd_log("%s:%u -- htlc connection accepted", buf, ntohs(saddr.SIN_PORT));

   htlc = xmalloc(sizeof(struct htlc_conn));
   memset(htlc, 0, sizeof(struct htlc_conn));

   htlc->sockaddr = saddr;

   hxd_files[s].ready_read = htlc_read;
   hxd_files[s].ready_write = htlc_write;
   hxd_files[s].conn.htlc = htlc;

   htlc->fd = s;
   htlc->rcv = rcv_magic;
   htlc->trans = 1;
   htlc->chattrans = 1;
   htlc->put_limit = hxd_cfg.limits.individual_uploads > HTXF_PUT_MAX ? HTXF_PUT_MAX : hxd_cfg.limits.individual_uploads;
   htlc->get_limit = hxd_cfg.limits.individual_downloads > HTXF_GET_MAX ? HTXF_GET_MAX : hxd_cfg.limits.individual_downloads;
   htlc->limit_out_Bps = hxd_cfg.limits.out_Bps;
   INITLOCK_HTXF(htlc);

   if (high_fd < s)
      high_fd = s;

   htlc->flags.visible = 1;

   htlc->identfd = -1;
   if (check_banlist(htlc))
      return;
   htlc->access_extra.can_login = 1;
   timer_add_secs(14, login_timeout, htlc);

   if (hxd_cfg.options.ident) {
      start_ident(htlc);
   } else {
      qbuf_set(&htlc->in, 0, HTLC_MAGIC_LEN); 
      FD_SET(s, &hxd_rfds);
   }
}
Esempio n. 5
0
void
hx_connect (struct htlc_conn *htlc, const char *serverstr, u_int16_t port,
	    const char *name, u_int16_t icon, const char *login, const char *pass,
	    int secure)
{
	int s;
	struct SOCKADDR_IN saddr;
	char abuf[HOSTLEN+1];

#if !defined(__WIN32__)
	if (serverstr[0] == '|' && serverstr[1]) {
		int pfds[2];
		int r;

		if (htlc->fd)
			hx_htlc_close(htlc);
		r = fd_popen(pfds, serverstr+1);
		if (r < 0) {
			hx_printf_prefix(htlc, 0, INFOPREFIX, "fd_popen(%s): %s\n",
					serverstr+1, strerror(errno));
			return;
		}
		hx_printf_prefix(htlc, 0, INFOPREFIX, "connecting through pipe %s\n", serverstr+1);
		htlc->fd = pfds[0];
		htlc->wfd = pfds[1];
		s = htlc->fd;
		fd_blocking(s, 0);
		fd_closeonexec(s, 1);
		hxd_files[s].ready_write = 0;
		hxd_files[s].ready_read = htlc_read;
		hxd_files[s].conn.htlc = htlc;
		hxd_fd_add(s);
		hxd_fd_set(s, FDR);
		if (high_fd < s)
			high_fd = s;
		s = htlc->wfd;
		fd_blocking(s, 0);
		fd_closeonexec(s, 1);
		hxd_files[s].ready_read = 0;
		hxd_files[s].ready_write = htlc_write;
		hxd_files[s].conn.htlc = htlc;
		hxd_fd_add(s);
		hxd_fd_set(s, FDW);
		if (high_fd < s)
			high_fd = s;
		goto is_pipe;
	}
#endif
#if defined(CONFIG_UNIXSOCKETS)
	else if (serverstr[0] == '!' && serverstr[1]) {
		struct sockaddr_un usaddr;

		s = socket(AF_UNIX, SOCK_STREAM, 0);
		if (s < 0) {
			hx_printf_prefix(htlc, 0, INFOPREFIX, "socket: %s\n", strerror(errno));
			return;
		}
		usaddr.sun_family = AF_UNIX;
		snprintf(usaddr.sun_path, sizeof(usaddr.sun_path), "%s", serverstr+1);

		if (htlc->fd)
			hx_htlc_close(htlc);
		if (connect(s, (struct sockaddr *)&usaddr, sizeof(usaddr))) {
			switch (errno) {
				case EINPROGRESS:
					break;
				default:
					hx_printf_prefix(htlc, 0, INFOPREFIX, "connect: %s\n", strerror(errno));
					socket_close(s);
					return;
			}
		}
		htlc->usockaddr = usaddr;
		socket_blocking(s, 0);
		fd_closeonexec(s, 1);
		goto is_unix;
	}
#endif

	s = socket(AFINET, SOCK_STREAM, IPPROTO_TCP);
	if (s < 0) {
		hx_printf_prefix(htlc, 0, INFOPREFIX, "socket: %s\n", strerror(errno));
		return;
	}
	if (s >= hxd_open_max) {
		hx_printf_prefix(htlc, 0, INFOPREFIX, "%s:%d: %d >= hxd_open_max (%d)", __FILE__, __LINE__, s, hxd_open_max);
		close(s);
		return;
	}
	socket_blocking(s, 0);
	fd_closeonexec(s, 1);

	if (hx_hostname[0]) {
#ifdef CONFIG_IPV6
		if (!inet_pton(AFINET, hx_hostname, &saddr.SIN_ADDR)) {
#else
		if (!inet_aton(hx_hostname, &saddr.SIN_ADDR)) {
#endif
			struct hostent *he;

			if ((he = gethostbyname(hx_hostname))) {
				size_t len = (unsigned int)he->h_length > sizeof(struct IN_ADDR)
					     ? sizeof(struct IN_ADDR) : (unsigned int)he->h_length;
				memcpy(&saddr.SIN_ADDR, he->h_addr, len);
			} else {
#ifndef HAVE_HSTRERROR
				hx_printf_prefix(htlc, 0, INFOPREFIX, "DNS lookup for %s failed\n", hx_hostname);
#else
				hx_printf_prefix(htlc, 0, INFOPREFIX, "DNS lookup for %s failed: %s\n", hx_hostname, hstrerror(h_errno));
#endif
				socket_close(s);
				return;
			}
		}
		saddr.SIN_PORT = 0;
		saddr.SIN_FAMILY = AFINET;
		if (bind(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
			inaddr2str(abuf, &saddr);
			hx_printf_prefix(htlc, 0, INFOPREFIX, "bind %s (%s): %s\n", hx_hostname, abuf, strerror(errno));
			socket_close(s);
			return;
		}
	}

#ifdef CONFIG_IPV6
	if (!inet_pton(AFINET, serverstr, &saddr.SIN_ADDR)) {
#else
	if (!inet_aton(serverstr, &saddr.SIN_ADDR)) {
#endif
		struct hostent *he;

		if ((he = gethostbyname(serverstr))) {
			size_t len = (unsigned int)he->h_length > sizeof(struct IN_ADDR)
				     ? sizeof(struct IN_ADDR) : (unsigned int)he->h_length;
			memcpy(&saddr.SIN_ADDR, he->h_addr, len);
		} else {
#ifndef HAVE_HSTRERROR
			hx_printf_prefix(htlc, 0, INFOPREFIX, "DNS lookup for %s failed\n", serverstr);
#else
			hx_printf_prefix(htlc, 0, INFOPREFIX, "DNS lookup for %s failed: %s\n", serverstr, hstrerror(h_errno));
#endif
			socket_close(s);
			return;
		}
	}
	saddr.SIN_PORT = htons(port);
	saddr.SIN_FAMILY = AFINET;

	if (htlc->fd)
		hx_htlc_close(htlc);
	if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr))) {
#if !defined(__WIN32__)
		switch (errno) {
			case EINPROGRESS:
				break;
			default:
				hx_printf_prefix(htlc, 0, INFOPREFIX, "connect: %s\n", strerror(errno));
				socket_close(s);
				return;
		}
#else
		int wsaerr;
		wsaerr = WSAGetLastError();
		if (wsaerr != WSAEWOULDBLOCK) {
			hx_printf_prefix(htlc, 0, INFOPREFIX, "connect: WSA error %d\n", wsaerr);
			socket_close(s);
			return;
		}
#endif
	}
	htlc->sockaddr = saddr;
	inaddr2str(abuf, &saddr);
	hx_printf_prefix(htlc, 0, INFOPREFIX, "connecting to %s:%u\n", abuf, ntohs(saddr.SIN_PORT));

is_unix:
	hxd_files[s].ready_read = htlc_read;
	hxd_files[s].ready_write = htlc_write_connect;
	hxd_files[s].conn.htlc = htlc;
	hxd_fd_add(s);
	hxd_fd_set(s, FDR|FDW);
	htlc->fd = s;

is_pipe:
	hx_output.status();

	if (name)
		strlcpy(htlc->name, name, sizeof(htlc->name));
	if (icon)
		htlc->icon = icon;
	if (login)
		strlcpy(htlc->login, login, sizeof(htlc->login));
	if (pass)
		strlcpy(htlc->password, pass, sizeof(htlc->password));
	else
		htlc->password[0] = 0;
	htlc->secure = secure;
	htlc->flags.in_login = 1;
	htlc->rcv = hx_rcv_magic;
	htlc->trans = 1;
	memset(&htlc->in, 0, sizeof(struct qbuf));
	memset(&htlc->out, 0, sizeof(struct qbuf));
	qbuf_set(&htlc->in, 0, HTLS_MAGIC_LEN);
	qbuf_add(&htlc->out, HTLC_MAGIC, HTLC_MAGIC_LEN);
}

void
hx_connect_finish (struct htlc_conn *htlc)
{
	char enclogin[64], encpass[64];
	char abuf[HOSTLEN+1];
	u_int16_t icon16;
	u_int16_t llen, plen;
	int secure;
	u_int8_t *login, *pass;

	secure = htlc->secure;
	login = htlc->login;
	pass = htlc->password;
	inaddr2str(abuf, &htlc->sockaddr);
#ifdef CONFIG_HOPE
	if (secure) {
#ifdef CONFIG_CIPHER
		u_int8_t cipheralglist[64];
		u_int16_t cipheralglistlen;
		u_int8_t cipherlen;
#endif
#ifdef CONFIG_COMPRESS
		u_int8_t compressalglist[64];
		u_int16_t compressalglistlen;
		u_int8_t compresslen;
#endif
		u_int16_t hc;
		u_int8_t macalglist[64];
		u_int16_t macalglistlen;

		abuf[0] = 0;
		task_new(htlc, rcv_task_login, htlc, 0, "login");
		strcpy(htlc->macalg, "HMAC-SHA1");
		S16HTON(2, macalglist);
		macalglistlen = 2;
		macalglist[macalglistlen] = 9;
		macalglistlen++;
		memcpy(macalglist+macalglistlen, htlc->macalg, 9);
		macalglistlen += 9;
		macalglist[macalglistlen] = 8;
		macalglistlen++;
		memcpy(macalglist+macalglistlen, "HMAC-MD5", 8);
		macalglistlen += 8;

		hc = 4;
#ifdef CONFIG_COMPRESS
		if (htlc->compressalg[0]) {
			compresslen = strlen(htlc->compressalg);
			S16HTON(1, compressalglist);
			compressalglistlen = 2;
			compressalglist[compressalglistlen] = compresslen;
			compressalglistlen++;
			memcpy(compressalglist+compressalglistlen, htlc->compressalg, compresslen);
			compressalglistlen += compresslen;
			hc++;
		} else
			compressalglistlen = 0;
#endif
#ifdef CONFIG_CIPHER
		if (htlc->cipheralg[0]) {
			cipherlen = strlen(htlc->cipheralg);
			S16HTON(1, cipheralglist);
			cipheralglistlen = 2;
			cipheralglist[cipheralglistlen] = cipherlen;
			cipheralglistlen++;
			memcpy(cipheralglist+cipheralglistlen, htlc->cipheralg, cipherlen);
			cipheralglistlen += cipherlen;
			hc++;
		} else
			cipheralglistlen = 0;
#endif
		hlwrite(htlc, HTLC_HDR_LOGIN, 0, hc,
			HTLC_DATA_LOGIN, 1, abuf,
			HTLC_DATA_PASSWORD, 1, abuf,
			HTLC_DATA_MAC_ALG, macalglistlen, macalglist,
#ifdef CONFIG_CIPHER
			HTLC_DATA_CIPHER_ALG, cipheralglistlen, cipheralglist,
#endif
#ifdef CONFIG_COMPRESS
			HTLC_DATA_COMPRESS_ALG, compressalglistlen, compressalglist,
#endif
			HTLC_DATA_SESSIONKEY, 0, 0);
		return;
	}
#endif /* HOPE */

	task_new(htlc, rcv_task_login, 0, 0, "login");

	icon16 = htons(htlc->icon);
	if (login) {
		llen = strlen(login);
		if (llen > 32)
			llen = 32;
		hl_encode(enclogin, login, llen);
	} else
		llen = 0;
	htlc->clientversion = g_clientversion;
	if (htlc->clientversion >= 150) {
		if (pass) {
			u_int16_t cv = htons(185);
			plen = strlen(pass);
			if (plen > 32)
				plen = 32;
			hl_encode(encpass, pass, plen);
			hlwrite(htlc, HTLC_HDR_LOGIN, 0, 3,
				HTLC_DATA_LOGIN, llen, enclogin,
				HTLC_DATA_PASSWORD, plen, encpass,
				HTLC_DATA_CLIENTVERSION, 2, &cv);
		} else {
			u_int16_t cv = htons(185);
			hlwrite(htlc, HTLC_HDR_LOGIN, 0, 2,
				HTLC_DATA_LOGIN, llen, enclogin,
				HTLC_DATA_CLIENTVERSION, 2, &cv);
		}
	} else { /* 123 */
		if (pass) {
			plen = strlen(pass);
			if (plen > 32)
				plen = 32;
			hl_encode(encpass, pass, plen);
			hlwrite(htlc, HTLC_HDR_LOGIN, 0, 4,
				HTLC_DATA_ICON, 2, &icon16,
				HTLC_DATA_LOGIN, llen, enclogin,
				HTLC_DATA_PASSWORD, plen, encpass,
				HTLC_DATA_NAME, strlen(htlc->name), htlc->name);
		} else {
			hlwrite(htlc, HTLC_HDR_LOGIN, 0, 3,
				HTLC_DATA_ICON, 2, &icon16,
				HTLC_DATA_LOGIN, llen, enclogin,
				HTLC_DATA_NAME, strlen(htlc->name), htlc->name);
		}
	}
	memset(htlc->password, 0, sizeof(htlc->password));
}