mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
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. [originally from svn r5180]
This commit is contained in:
parent
11bc6185ec
commit
15e7d71f39
38
unix/uxnet.c
38
unix/uxnet.c
@ -948,6 +948,29 @@ static int sk_tcp_write_oob(Socket sock, const char *buf, int len)
|
|||||||
return s->sending_oob;
|
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)
|
static int net_select_result(int fd, int event)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -1009,17 +1032,22 @@ static int net_select_result(int fd, int event)
|
|||||||
* On a listening socket, the readability event means a
|
* On a listening socket, the readability event means a
|
||||||
* connection is ready to be accepted.
|
* connection is ready to be accepted.
|
||||||
*/
|
*/
|
||||||
struct sockaddr_in isa;
|
#ifdef NO_IPV6
|
||||||
int addrlen = sizeof(struct sockaddr_in);
|
struct sockaddr_in ss;
|
||||||
|
#else
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
#endif
|
||||||
|
socklen_t addrlen = sizeof(ss);
|
||||||
int t; /* socket of connection */
|
int t; /* socket of connection */
|
||||||
|
|
||||||
memset(&isa, 0, sizeof(struct sockaddr_in));
|
memset(&ss, 0, addrlen);
|
||||||
t = accept(s->s,(struct sockaddr *)&isa,(socklen_t *) &addrlen);
|
t = accept(s->s, (struct sockaddr *)&ss, &addrlen);
|
||||||
if (t < 0) {
|
if (t < 0) {
|
||||||
break;
|
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?! */
|
close(t); /* someone let nonlocal through?! */
|
||||||
} else if (plug_accepting(s->plug, t)) {
|
} else if (plug_accepting(s->plug, t)) {
|
||||||
close(t); /* denied or error */
|
close(t); /* denied or error */
|
||||||
|
Loading…
Reference in New Issue
Block a user