From 19a4130c7173342d7a18b9ef32f23cf4f848c361 Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 23 Jan 2005 14:31:08 +0000 Subject: [PATCH] When checking if a connection comes from localhost, don't assume it's an IPv4 connection. Instead, correctly check IPv4 and IPv6 connections, assume that AF_LOCAL is always local, and anything else is always remote. This makes trivial local-to-remote forwarding work on my system. git-svn-id: svn://svn.tartarus.org/sgt/putty@5180 cda61777-01e9-0310-a592-d414129be87e --- unix/uxnet.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/unix/uxnet.c b/unix/uxnet.c index 357fc862..9cd01f68 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -948,6 +948,29 @@ static int sk_tcp_write_oob(Socket sock, const char *buf, int len) return s->sending_oob; } +static int sockaddr_is_loopback(struct sockaddr *sa) +{ + struct sockaddr_in *sin; +#ifndef NO_IPV6 + struct sockaddr_in6 *sin6; +#endif + + switch (sa->sa_family) { + case AF_INET: + sin = (struct sockaddr_in *)sa; + return ipv4_is_loopback(sin->sin_addr); +#ifndef NO_IPV6 + case AF_INET6: + sin6 = (struct sockaddr_in6 *)sa; + return IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr); +#endif + case AF_LOCAL: + return TRUE; + default: + return FALSE; + } +} + static int net_select_result(int fd, int event) { int ret; @@ -1009,17 +1032,22 @@ static int net_select_result(int fd, int event) * On a listening socket, the readability event means a * connection is ready to be accepted. */ - struct sockaddr_in isa; - int addrlen = sizeof(struct sockaddr_in); +#ifdef NO_IPV6 + struct sockaddr_in ss; +#else + struct sockaddr_storage ss; +#endif + socklen_t addrlen = sizeof(ss); int t; /* socket of connection */ - memset(&isa, 0, sizeof(struct sockaddr_in)); - t = accept(s->s,(struct sockaddr *)&isa,(socklen_t *) &addrlen); + memset(&ss, 0, addrlen); + t = accept(s->s, (struct sockaddr *)&ss, &addrlen); if (t < 0) { break; } - if (s->localhost_only && !ipv4_is_loopback(isa.sin_addr)) { + if (s->localhost_only && + !sockaddr_is_loopback((struct sockaddr *)&ss)) { close(t); /* someone let nonlocal through?! */ } else if (plug_accepting(s->plug, t)) { close(t); /* denied or error */ -- 2.11.0