summaryrefslogtreecommitdiff
path: root/security/ssh6/patches/patch-aq
diff options
context:
space:
mode:
Diffstat (limited to 'security/ssh6/patches/patch-aq')
-rw-r--r--security/ssh6/patches/patch-aq462
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));
+