freebsd-ports/security/ssh/files/patch-al
Munechika SUMIKAWA b734a81d1c - re-enable TCP_NODELAY
Submitted by:	Arjan.deVet@adv.iae.nl (Arjan de Vet)

- do not exit in failure to connect using IPv6 and try to IPv4
  when connecting to dualstack hosts.

Approved by:	torstenb
2000-02-24 14:11:58 +00:00

409 lines
13 KiB
Plaintext

*** sshconnect.c.orig Wed May 12 20:19:29 1999
--- sshconnect.c Thu Feb 24 22:34:47 2000
***************
*** 337,343 ****
/* Creates a (possibly privileged) socket for use as the ssh connection. */
! int ssh_create_socket(uid_t original_real_uid, int privileged)
{
int sock;
--- 337,343 ----
/* Creates a (possibly privileged) socket for use as the ssh connection. */
! int ssh_create_socket(uid_t original_real_uid, int privileged, int family)
{
int sock;
***************
*** 345,379 ****
bind our own socket to a privileged port. */
if (privileged)
{
! struct sockaddr_in sin;
int p;
for (p = 1023; p > 512; p--)
{
! sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
! fatal("socket: %.100s", strerror(errno));
! /* Initialize the desired sockaddr_in structure. */
! memset(&sin, 0, sizeof(sin));
! sin.sin_family = AF_INET;
! sin.sin_addr.s_addr = INADDR_ANY;
! sin.sin_port = htons(p);
/* Try to bind the socket to the privileged port. */
#if defined(SOCKS)
! if (Rbind(sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
break; /* Success. */
#else /* SOCKS */
! if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
break; /* Success. */
#endif /* SOCKS */
if (errno == EADDRINUSE)
{
close(sock);
continue;
}
! fatal("bind: %.100s", strerror(errno));
}
debug("Allocated local port %d.", p);
}
else
--- 345,404 ----
bind our own socket to a privileged port. */
if (privileged)
{
! struct addrinfo hints, *ai = NULL;
! int errgai;
! char strport[PORTSTRLEN];
int p;
+ #if (defined(__OpenBSD__) || defined(__FreeBSD__)) && !defined(SOCKS)
+ p = 1023; /* Compat with old FreeBSD */
+ #if __FreeBSD__ >= 400014
+ sock = rresvport_af(&p, family);
+ if (sock < 0)
+ error("rresvport_af: %.100s", strerror(errno));
+ #else
+ sock = rresvport(&p);
+ if (sock < 0)
+ error("rresvport: %.100s", strerror(errno));
+ #endif
+ #else
for (p = 1023; p > 512; p--)
{
! sock = socket(family, SOCK_STREAM, 0);
if (sock < 0)
! error("socket: %.100s", strerror(errno));
! /* Initialize the desired addrinfo structure. */
! memset(&hints, 0, sizeof(hints));
! hints.ai_family = family;
! hints.ai_flags = AI_PASSIVE;
! hints.ai_socktype = SOCK_STREAM;
! sprintf(strport, "%d", p);
! #if defined(SOCKS)
! if ((errgai = Rgetaddrinfo(NULL, strport, &hints, &ai)) != 0)
! fatal("getaddrinfo: %.100s", gai_strerror(errgai));
! #else /* SOCKS */
! if ((errgai = getaddrinfo(NULL, strport, &hints, &ai)) != 0)
! fatal("getaddrinfo: %.100s", gai_strerror(errgai));
! #endif /* SOCKS */
/* Try to bind the socket to the privileged port. */
#if defined(SOCKS)
! if (Rbind(sock, ai->ai_addr, ai->ai_addrlen) >= 0)
break; /* Success. */
#else /* SOCKS */
! if (bind(sock, ai->ai_addr, ai->ai_addrlen) >= 0)
break; /* Success. */
#endif /* SOCKS */
if (errno == EADDRINUSE)
{
close(sock);
+ freeaddrinfo(ai);
continue;
}
! error("bind: %.100s", strerror(errno));
}
+ freeaddrinfo(ai);
+ #endif
debug("Allocated local port %d.", p);
}
else
***************
*** 396,409 ****
the daemon. */
int ssh_connect(const char *host, int port, int connection_attempts,
int anonymous, uid_t original_real_uid,
const char *proxy_command, RandomState *random_state)
{
int sock = -1, attempt, i;
int on = 1;
struct servent *sp;
! struct hostent *hp;
! struct sockaddr_in hostaddr;
#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
struct linger linger;
#endif /* SO_LINGER */
--- 421,439 ----
the daemon. */
int ssh_connect(const char *host, int port, int connection_attempts,
+ #ifdef ENABLE_ANOTHER_PORT_TRY
+ int another_port,
+ #endif /* ENABLE_ANOTHER_PORT_TRY */
int anonymous, uid_t original_real_uid,
const char *proxy_command, RandomState *random_state)
{
int sock = -1, attempt, i;
int on = 1;
struct servent *sp;
! struct addrinfo hints, *ai, *aitop, *aitmp;
! struct sockaddr_storage hostaddr;
! char ntop[ADDRSTRLEN], strport[PORTSTRLEN];
! int gaierr;
#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
struct linger linger;
#endif /* SO_LINGER */
***************
*** 421,430 ****
port = SSH_DEFAULT_PORT;
}
- /* Map localhost to ip-address locally */
- if (strcmp(host, "localhost") == 0)
- host = "127.0.0.1";
-
/* If a proxy command is given, connect using it. */
if (proxy_command != NULL && *proxy_command)
return ssh_proxy_connect(host, port, original_real_uid, proxy_command,
--- 451,456 ----
***************
*** 432,440 ****
/* No proxy command. */
! /* No host lookup made yet. */
! hp = NULL;
!
/* Try to connect several times. On some machines, the first time will
sometimes fail. In general socket code appears to behave quite
magically on many machines. */
--- 458,495 ----
/* No proxy command. */
! memset(&hints, 0, sizeof(hints));
! hints.ai_family = IPv4or6;
! hints.ai_socktype = SOCK_STREAM;
! sprintf(strport, "%d", port);
! #if defined(SOCKS)
! if ((gaierr = Rgetaddrinfo(host, strport, &hints, &aitop)) != 0)
! fatal("Bad host name: %.100s (%s)", host, gai_strerror(gaierr));
! #else /* SOCKS */
! if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
! fatal("Bad host name: %.100s (%s)", host, gai_strerror(gaierr));
! #endif /* SOCKS */
!
! #ifdef ENABLE_ANOTHER_PORT_TRY
! if (another_port)
! {
! aitmp = aitop;
! memset(&hints, 0, sizeof(hints));
! hints.ai_family = IPv4or6;
! hints.ai_socktype = SOCK_STREAM;
! sprintf(strport, "%d", another_port);
! #if defined(SOCKS)
! if ((gaierr = Rgetaddrinfo(host, strport, &hints, &aitop)) != 0)
! fatal("Bad host name: %.100s (%s)", host, gai_strerror(gaierr));
! #else /* SOCKS */
! if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
! fatal("Bad host name: %.100s (%s)", host, gai_strerror(gaierr));
! #endif /* SOCKS */
! for (ai = aitop; ai->ai_next; ai = ai->ai_next);
! ai->ai_next = aitmp;
! }
! #endif /* ENABLE_ANOTHER_PORT_TRY */
!
/* Try to connect several times. On some machines, the first time will
sometimes fail. In general socket code appears to behave quite
magically on many machines. */
***************
*** 443,545 ****
if (attempt > 0)
debug("Trying again...");
- /* Try to parse the host name as a numeric inet address. */
- memset(&hostaddr, 0, sizeof(hostaddr));
- hostaddr.sin_family = AF_INET;
- hostaddr.sin_port = htons(port);
- #ifdef BROKEN_INET_ADDR
- hostaddr.sin_addr.s_addr = inet_network(host);
- #else /* BROKEN_INET_ADDR */
- hostaddr.sin_addr.s_addr = inet_addr(host);
- #endif /* BROKEN_INET_ADDR */
- if ((hostaddr.sin_addr.s_addr & 0xffffffff) != 0xffffffff)
- {
- /* Create a socket. */
- sock = ssh_create_socket(original_real_uid,
- !anonymous && geteuid() == UID_ROOT);
-
- /* Valid numeric IP address */
- debug("Connecting to %.100s port %d.",
- inet_ntoa(hostaddr.sin_addr), port);
-
- /* Connect to the host. */
- #if defined(SOCKS)
- if (Rconnect(sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr))
- #else /* SOCKS */
- if (connect(sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr))
- #endif /* SOCKS */
- >= 0)
- {
- /* Successful connect. */
- break;
- }
- debug("connect: %.100s", strerror(errno));
-
- /* Destroy the failed socket. */
- shutdown(sock, 2);
- close(sock);
- }
- else
- {
- /* Not a valid numeric inet address. */
- /* Map host name to an address. */
- if (!hp)
- {
- struct hostent *hp_static;
-
- #if defined(SOCKS5)
- hp_static = Rgethostbyname(host);
- #else
- hp_static = gethostbyname(host);
- #endif
- if (hp_static)
- {
- hp = xmalloc(sizeof(struct hostent));
- memcpy(hp, hp_static, sizeof(struct hostent));
-
- /* Copy list of addresses, not just pointers.
- We don't use h_name & h_aliases so leave them as is */
- for (i = 0; hp_static->h_addr_list[i]; i++)
- ; /* count them */
- hp->h_addr_list = xmalloc((i + 1) *
- sizeof(hp_static->h_addr_list[0]));
- for (i = 0; hp_static->h_addr_list[i]; i++)
- {
- hp->h_addr_list[i] = xmalloc(hp->h_length);
- memcpy(hp->h_addr_list[i], hp_static->h_addr_list[i],
- hp->h_length);
- }
- hp->h_addr_list[i] = NULL; /* last one */
- }
- }
- if (!hp)
- fatal("Bad host name: %.100s", host);
- if (!hp->h_addr_list[0])
- fatal("Host does not have an IP address: %.100s", host);
-
/* Loop through addresses for this host, and try each one in
sequence until the connection succeeds. */
! for (i = 0; hp->h_addr_list[i]; i++)
{
! /* Set the address to connect to. */
! hostaddr.sin_family = hp->h_addrtype;
! memcpy(&hostaddr.sin_addr, hp->h_addr_list[i],
! sizeof(hostaddr.sin_addr));
! debug("Connecting to %.200s [%.100s] port %d.",
! host, inet_ntoa(hostaddr.sin_addr), port);
/* Create a socket for connecting. */
sock = ssh_create_socket(original_real_uid,
! !anonymous && geteuid() == UID_ROOT);
/* Connect to the host. */
#if defined(SOCKS)
! if (Rconnect(sock, (struct sockaddr *)&hostaddr,
! sizeof(hostaddr)) >= 0)
#else /* SOCKS */
! if (connect(sock, (struct sockaddr *)&hostaddr,
! sizeof(hostaddr)) >= 0)
#endif /* SOCKS */
{
/* Successful connection. */
--- 498,526 ----
if (attempt > 0)
debug("Trying again...");
/* Loop through addresses for this host, and try each one in
sequence until the connection succeeds. */
! 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);
! debug("Connecting to %.200s [%.100s] port %s.",
! host, ntop, strport);
/* Create a socket for connecting. */
sock = ssh_create_socket(original_real_uid,
! !anonymous && geteuid() == UID_ROOT,
! ai->ai_family);
! if (sock < 0)
! continue;
/* Connect to the host. */
#if defined(SOCKS)
! if (Rconnect(sock, ai->ai_addr, ai->ai_addrlen) >= 0)
#else /* SOCKS */
! if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0)
#endif /* SOCKS */
{
/* Successful connection. */
***************
*** 552,573 ****
returned an error. */
shutdown(sock, 2);
close(sock);
! }
! if (hp->h_addr_list[i])
break; /* Successful connection. */
- }
/* Sleep a moment before retrying. */
sleep(1);
}
! if (hp)
! {
! for (i = 0; hp->h_addr_list[i]; i++)
! xfree(hp->h_addr_list[i]);
! xfree(hp->h_addr_list);
! xfree(hp);
! }
/* Return failure if we didn't get a successful connection. */
if (attempt >= connection_attempts)
--- 533,547 ----
returned an error. */
shutdown(sock, 2);
close(sock);
! } /* for (ai = aitop; ai; ai = ai->ai_next) */
! if (ai)
break; /* Successful connection. */
/* Sleep a moment before retrying. */
sleep(1);
}
! freeaddrinfo(aitop);
/* Return failure if we didn't get a successful connection. */
if (attempt >= connection_attempts)
***************
*** 946,952 ****
int ap_opts, ret_stat = 0;
krb5_keyblock *session_key = 0;
krb5_ap_rep_enc_part *repl = 0;
! struct sockaddr_in local, foreign;
memset(&auth, 0 , sizeof(auth));
remotehost = (char *) get_canonical_hostname();
--- 920,926 ----
int ap_opts, ret_stat = 0;
krb5_keyblock *session_key = 0;
krb5_ap_rep_enc_part *repl = 0;
! struct sockaddr_storage local, foreign;
memset(&auth, 0 , sizeof(auth));
remotehost = (char *) get_canonical_hostname();