diff options
Diffstat (limited to 'security/ssh6/patches/patch-aq')
-rw-r--r-- | security/ssh6/patches/patch-aq | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/security/ssh6/patches/patch-aq b/security/ssh6/patches/patch-aq new file mode 100644 index 00000000000..0fa31c89a33 --- /dev/null +++ b/security/ssh6/patches/patch-aq @@ -0,0 +1,462 @@ +$NetBSD: patch-aq,v 1.1 2000/03/20 02:25:37 itojun Exp $ + +--- newchannels.c.orig Wed May 12 07:19:27 1999 ++++ newchannels.c Fri Dec 24 22:01:15 1999 +@@ -274,7 +274,7 @@ + #include "authfd.h" + #include "emulate.h" + #include "servconf.h" +-#ifdef LIBWRAP ++#if defined(LIBWRAP) && defined(LIBWRAP_FWD) + #include <tcpd.h> + #include <syslog.h> + #ifdef NEED_SYS_SYSLOG_H +@@ -922,6 +922,7 @@ + /* This is our fake X11 server socket. */ + if (FD_ISSET(ch->sock, readset)) + { ++ int on = 1; + debug("X11 connection requested."); + addrlen = sizeof(addr); + newsock = accept(ch->sock, &addr, &addrlen); +@@ -930,11 +931,12 @@ + error("accept: %.100s", strerror(errno)); + break; + } ++ setsockopt(newsock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); + remote_hostname = get_remote_hostname(newsock); + snprintf(buf, sizeof(buf), "X11 connection from %.200s port %d", + remote_hostname, get_peer_port(newsock)); + xfree(remote_hostname); +-#ifdef LIBWRAP ++#if defined(LIBWRAP) && defined(LIBWRAP_FWD) + { + struct request_info req; + struct servent *serv; +@@ -986,7 +988,7 @@ + ch->listening_port, remote_hostname, + get_peer_port(newsock)); + xfree(remote_hostname); +-#ifdef LIBWRAP ++#if defined(LIBWRAP) && defined(LIBWRAP_FWD) + { + struct request_info req; + struct servent *serv; +@@ -1405,13 +1407,29 @@ + int host_port, int gatewayports) + { + int ch, sock; +- struct sockaddr_in sin; ++ struct addrinfo hints, *ai, *aitop; ++ char ntop[ADDRSTRLEN], strport[PORTSTRLEN]; + + if (strlen(host) > sizeof(channels[0].path) - 1) + packet_disconnect("Forward host name too long."); + ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_family = IPv4or6; ++ hints.ai_flags = gatewayports ? AI_PASSIVE : 0; ++ hints.ai_socktype = SOCK_STREAM; ++ sprintf(strport, "%d", port); ++ if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) ++ packet_disconnect("getaddrinfo: fatal error"); ++ ++ for (ai = aitop; ai; ai = ai->ai_next) ++ { ++ ++ getnameinfo(ai->ai_addr, ai->ai_addrlen, ++ ntop, sizeof(ntop), strport, sizeof(strport), ++ NI_NUMERICHOST|NI_NUMERICSERV); ++ + /* Create a port to listen for the host. */ +- sock = socket(AF_INET, SOCK_STREAM, 0); ++ sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) + packet_disconnect("socket: %.100s", strerror(errno)); + +@@ -1421,21 +1439,10 @@ + (void)fcntl(sock, F_SETFL, O_NDELAY); + #endif /* O_NONBLOCK && !O_NONBLOCK_BROKEN */ + +- /* Initialize socket address. */ +- memset(&sin, 0, sizeof(sin)); +- sin.sin_family = AF_INET; +- if (gatewayports) +- sin.sin_addr.s_addr = INADDR_ANY; +- else +-#ifdef BROKEN_INET_ADDR +- sin.sin_addr.s_addr = inet_network("127.0.0.1"); +-#else /* BROKEN_INET_ADDR */ +- sin.sin_addr.s_addr = inet_addr("127.0.0.1"); +-#endif /* BROKEN_INET_ADDR */ +- sin.sin_port = htons(port); +- ++ debug("Listening on %s port %s.", ntop, strport); ++ + /* Bind the socket to the address. */ +- if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) ++ if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) + packet_disconnect("bind: %.100s", strerror(errno)); + + /* Start listening for connections on the socket. */ +@@ -1448,6 +1455,9 @@ + strcpy(channels[ch].path, host); /* note: host name stored here */ + channels[ch].host_port = host_port; /* port on host to connect to */ + channels[ch].listening_port = port; /* port being listened */ ++ ++ } /* for (ai = aitop; ai; ai = ai->ai_next) */ ++ freeaddrinfo(aitop); + } + + /* Initiate forwarding of connections to port "port" on remote host through +@@ -1636,9 +1646,10 @@ + void channel_input_port_open(void) + { + int remote_channel, sock, newch, host_port, i; +- struct sockaddr_in sin; + char *host, *originator_string; +- struct hostent *hp; ++ struct addrinfo hints, *ai, *aitop; ++ char ntop[ADDRSTRLEN], strport[PORTSTRLEN]; ++ int gaierr; + + /* Get remote channel number. */ + remote_channel = packet_get_int(); +@@ -1678,36 +1689,15 @@ + } + } + +- memset(&sin, 0, sizeof(sin)); +-#ifdef BROKEN_INET_ADDR +- sin.sin_addr.s_addr = inet_network(host); +-#else /* BROKEN_INET_ADDR */ +- sin.sin_addr.s_addr = inet_addr(host); +-#endif /* BROKEN_INET_ADDR */ +- if ((sin.sin_addr.s_addr & 0xffffffff) != 0xffffffff) ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_family = IPv4or6; ++ hints.ai_socktype = SOCK_STREAM; ++ sprintf(strport, "%d", host_port); ++ if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) + { +- /* It was a valid numeric host address. */ +- sin.sin_family = AF_INET; +- } +- else +- { +- /* Look up the host address from the name servers. */ +- hp = gethostbyname(host); +- if (!hp) +- { +- error("%.100s: unknown host.", host); +- goto fail; +- } +- if (!hp->h_addr_list[0]) +- { +- error("%.100s: host has no IP address.", host); +- goto fail; +- } +- sin.sin_family = hp->h_addrtype; +- memcpy(&sin.sin_addr, hp->h_addr_list[0], +- sizeof(sin.sin_addr)); ++ error("%.100s: unknown host (%s)", host, gai_strerror(gaierr)); ++ goto fail; + } +- sin.sin_port = htons(host_port); + + #ifdef F_SECURE_COMMERCIAL + +@@ -1744,8 +1734,15 @@ + + #endif /* F_SECURE_COMMERCIAL */ + ++ for (ai = aitop; ai; ai = ai->ai_next) ++ { ++ ++ getnameinfo(ai->ai_addr, ai->ai_addrlen, ++ ntop, sizeof(ntop), strport, sizeof(strport), ++ NI_NUMERICHOST|NI_NUMERICSERV); ++ + /* Create the socket. */ +- sock = socket(sin.sin_family, SOCK_STREAM, 0); ++ sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) + { + error("socket: %.100s", strerror(errno)); +@@ -1753,15 +1750,25 @@ + } + + /* Connect to the host/port. */ +- if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) ++ if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) + { +- error("connect %.100s:%d: %.100s", host, host_port, +- strerror(errno)); ++ debug("connect %.100s port %s: %.100s", ntop, strport, strerror(errno)); + close(sock); ++ continue; /* fail -- try next */ ++ } ++ break; /* success */ ++ ++ } /* for (ai = aitop; ai; ai = ai->ai_next) */ ++ freeaddrinfo(aitop); ++ ++ if (!ai) ++ { ++ error("connect %.100s:%d: failed.", host, host_port); + goto fail; + } + + /* Successful connection. */ ++ debug("Connecting to %.200s [%.100s] port %s.", host, ntop, strport); + + #if defined(O_NONBLOCK) && !defined(O_NONBLOCK_BROKEN) + (void)fcntl(sock, F_SETFL, O_NONBLOCK); +@@ -1803,7 +1810,10 @@ + { + extern ServerOptions options; + int display_number, port, sock; +- struct sockaddr_in sin; ++ struct addrinfo hints, *ai, *aitop; ++ char strport[PORTSTRLEN]; ++#define NUM_SOCKS 10 ++ int gaierr, n, nn, num_socks = 0, socks[NUM_SOCKS]; + char buf[512]; + #ifdef HAVE_GETHOSTNAME + char hostname[257]; +@@ -1817,12 +1827,21 @@ + for (display_number = options.x11_display_offset; display_number < MAX_DISPLAYS; display_number++) + { + port = 6000 + display_number; +- memset(&sin, 0, sizeof(sin)); +- sin.sin_family = AF_INET; +- sin.sin_addr.s_addr = INADDR_ANY; +- sin.sin_port = htons(port); ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_family = IPv4or6; ++ hints.ai_flags = AI_PASSIVE; ++ hints.ai_socktype = SOCK_STREAM; ++ sprintf(strport, "%d", port); ++ if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) ++ { ++ error("getaddrinfo: %.100s", gai_strerror(gaierr)); ++ return NULL; ++ } ++ ++ for (ai = aitop; ai; ai = ai->ai_next) ++ { + +- sock = socket(AF_INET, SOCK_STREAM, 0); ++ sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) + { + error("socket: %.100s", strerror(errno)); +@@ -1835,13 +1854,26 @@ + (void)fcntl(sock, F_SETFL, O_NDELAY); + #endif /* O_NONBLOCK && !O_NONBLOCK_BROKEN */ + +- if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) ++ if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) + { + debug("bind port %d: %.100s", port, strerror(errno)); + shutdown(sock, 2); + close(sock); +- continue; ++ for (n = 0; n < num_socks; n++) ++ { ++ shutdown(socks[n], 2); ++ close(socks[n]); ++ } ++ num_socks = 0; ++ break; + } ++ ++ socks[num_socks++] = sock; ++ if (num_socks == NUM_SOCKS) ++ break; ++ } /* for (ai = aitop; ai; ai = ai->ai_next) */ ++ ++ if (num_socks > 0) + break; + } + if (display_number >= MAX_DISPLAYS) +@@ -1851,13 +1883,22 @@ + } + + /* Start listening for connections on the socket. */ ++ for (n = 0; n < num_socks; n++) ++ { ++ sock = socks[n]; + if (listen(sock, 5) < 0) + { + error("listen: %.100s", strerror(errno)); + shutdown(sock, 2); + close(sock); ++ for (nn = 0; nn < n; nn++) ++ { ++ shutdown(socks[nn], 2); ++ close(socks[nn]); ++ } + return NULL; + } ++ } /* for (n = 0; n < num_socks; n++) */ + + /* Set up a suitable value for the DISPLAY variable. */ + #ifdef NONSTANDARD_IP_ADDRESS_X11_KLUDGE +@@ -1868,10 +1909,11 @@ + if (gethostname(hostname, sizeof(hostname)) < 0) + fatal("gethostname: %.100s", strerror(errno)); + { +- struct hostent *hp; +- struct in_addr addr; +- hp = gethostbyname(hostname); +- if (hp == NULL || !hp->h_addr_list[0]) ++ struct addrinfo hints, *ai; ++ char ntop[ADDRSTRLEN]; ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_family = IPv4or6; ++ if (getaddrinfo(hostname, NULL, &hints, &ai) != 0 || !ai) + { + error("Could not get server IP address for %.200s.", hostname); + packet_send_debug("Could not get server IP address for %.200s.", +@@ -1880,9 +1922,10 @@ + close(sock); + return NULL; + } +- memcpy(&addr, hp->h_addr_list[0], sizeof(addr)); ++ getnameinfo(ai->ai_addr, ai->ai_addrlen, ++ ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST); + snprintf(buf, sizeof(buf), +- "%.100s:%d.%d", inet_ntoa(addr), display_number, ++ "%.100s:%d.%d", ntop, display_number, + screen_number); + } + #else /* NONSTANDARD_IP_ADDRESS_X11_KLUDGE */ +@@ -1900,8 +1943,12 @@ + #endif /* NONSTANDARD_IP_ADDRESS_X11_KLUDGE */ + + /* Allocate a channel for the socket. */ ++ for (n = 0; n < num_socks; n++) ++ { ++ sock = socks[n]; + (void)channel_allocate(SSH_CHANNEL_X11_LISTENER, sock, + xstrdup("X11 inet listener")); ++ } /* for (n = 0; n < num_socks; n++) */ + + /* Return a suitable value for the DISPLAY environment variable. */ + return xstrdup(buf); +@@ -1916,9 +1963,10 @@ + int remote_channel, display_number, sock, newch; + const char *display; + struct sockaddr_un ssun; +- struct sockaddr_in sin; + char buf[255], *cp, *remote_host; +- struct hostent *hp; ++ struct addrinfo hints, *ai, *aitop; ++ char strport[PORTSTRLEN]; ++ int gaierr; + + /* Get remote channel number. */ + remote_channel = packet_get_int(); +@@ -2058,59 +2106,54 @@ + goto fail; + } + +- /* Try to parse the host name as a numeric IP address. */ +- memset(&sin, 0, sizeof(sin)); +-#ifdef BROKEN_INET_ADDR +- sin.sin_addr.s_addr = inet_network(buf); +-#else /* BROKEN_INET_ADDR */ +- sin.sin_addr.s_addr = inet_addr(buf); +-#endif /* BROKEN_INET_ADDR */ +- if ((sin.sin_addr.s_addr & 0xffffffff) != 0xffffffff) ++ /* Look up the host address */ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_family = IPv4or6; ++ hints.ai_socktype = SOCK_STREAM; ++ sprintf(strport, "%d", 6000 + display_number); ++ if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) + { +- /* It was a valid numeric host address. */ +- sin.sin_family = AF_INET; ++ error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); ++ goto fail; + } +- else ++ ++ for (ai = aitop; ai; ai = ai->ai_next) + { +- /* Not a numeric IP address. */ +- /* Look up the host address from the name servers. */ +- hp = gethostbyname(buf); +- if (!hp) +- { +- error("%.100s: unknown host.", buf); +- goto fail; +- } +- if (!hp->h_addr_list[0]) +- { +- error("%.100s: host has no IP address.", buf); +- goto fail; +- } +- sin.sin_family = hp->h_addrtype; +- memcpy(&sin.sin_addr, hp->h_addr_list[0], +- sizeof(sin.sin_addr)); +- } +- /* Set port number. */ +- sin.sin_port = htons(6000 + display_number); + + /* Create a socket. */ +- sock = socket(sin.sin_family, SOCK_STREAM, 0); ++ sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) + { +- error("socket: %.100s", strerror(errno)); +- goto fail; ++ debug("socket: %.100s", strerror(errno)); ++ continue; + } + /* Connect it to the display. */ +- if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) ++ if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) + { +- error("connect %.100s:%d: %.100s", buf, 6000 + display_number, ++ debug("connect %.100s:%d: %.100s", buf, 6000 + display_number, + strerror(errno)); + close(sock); ++ continue; ++ } ++ /* Success */ ++ break; ++ ++ } /* (ai = aitop, ai; ai = ai->ai_next) */ ++ freeaddrinfo(aitop); ++ if (!ai) ++ { ++ error("connect %.100s:%d: %.100s", buf, 6000 + display_number, ++ strerror(errno)); + goto fail; + } + + success: + /* We have successfully obtained a connection to the real X display. */ +- ++ { ++ int on = 1; ++ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); ++ } ++ + #if defined(O_NONBLOCK) && !defined(O_NONBLOCK_BROKEN) + (void)fcntl(sock, F_SETFL, O_NONBLOCK); + #else /* O_NONBLOCK && !O_NONBLOCK_BROKEN */ +@@ -2412,6 +2455,10 @@ + ssh-agent connections on your system */ + old_umask = umask(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + ++ /* Make sure the socket doesn't already exist, left over from a system ++ crash perhaps. */ ++ unlink(channel_forwarded_auth_socket_name); ++ + if (bind(sock, (struct sockaddr *)&sunaddr, AF_UNIX_SIZE(sunaddr)) < 0) + packet_disconnect("Agent socket bind failed: %.100s", strerror(errno)); + |