diff options
Diffstat (limited to 'security/ssh/files/patch-al')
-rw-r--r-- | security/ssh/files/patch-al | 409 |
1 files changed, 393 insertions, 16 deletions
diff --git a/security/ssh/files/patch-al b/security/ssh/files/patch-al index 839d1fe2b2bf..1bfbbb5f2542 100644 --- a/security/ssh/files/patch-al +++ b/security/ssh/files/patch-al @@ -1,27 +1,404 @@ -*** sshconnect.c.orig Wed May 12 20:19:29 1999 ---- sshconnect.c Sun Jun 6 02:39:02 1999 +*** sshconnect.c.orig Wed May 12 13:19:29 1999 +--- sshconnect.c Wed Jan 12 00:34:55 2000 *************** -*** 347,352 **** ---- 347,358 ---- +*** 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,385 **** + bind our own socket to a privileged port. */ + if (privileged) { - struct sockaddr_in sin; +! struct sockaddr_in sin; int p; -+ #if (defined(__OpenBSD__) || defined(__FreeBSD__)) && !defined(SOCKS) -+ p = 1023; /* Compat with old FreeBSD */ -+ sock = rresvport(&p); -+ if (sock < 0) -+ fatal("rresvport: %.100s", strerror(errno)); -+ #else for (p = 1023; p > 512; p--) { - sock = socket(AF_INET, SOCK_STREAM, 0); -*************** -*** 374,379 **** ---- 380,386 ---- +! 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 + { + /* Just create an ordinary socket on arbitrary port. */ +! sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + fatal("socket: %.100s", strerror(errno)); + } +--- 345,392 ---- + bind our own socket to a privileged port. */ + if (privileged) + { +! struct addrinfo hints, *ai = NULL; +! int errgai; +! char strport[PORTSTRLEN]; + int p; + for (p = 1023; p > 512; p--) + { +! sock = socket(family, SOCK_STREAM, 0); + if (sock < 0) + fatal("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 ((errgai = getaddrinfo(NULL, strport, &hints, &ai)) != 0) +! fatal("getaddrinfo: %.100s", gai_strerror(errgai)); + + /* 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; } fatal("bind: %.100s", strerror(errno)); } -+ #endif debug("Allocated local port %d.", p); ++ freeaddrinfo(ai); } else + { + /* Just create an ordinary socket on arbitrary port. */ +! sock = socket(family, SOCK_STREAM, 0); + if (sock < 0) + fatal("socket: %.100s", strerror(errno)); + } +*************** +*** 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 */ +--- 403,421 ---- + 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, +--- 433,438 ---- +*************** +*** 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. */ +--- 440,467 ---- + + /* No proxy command. */ + +! memset(&hints, 0, sizeof(hints)); +! hints.ai_family = IPv4or6; +! hints.ai_socktype = SOCK_STREAM; +! sprintf(strport, "%d", port); +! if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) +! fatal("Bad host name: %.100s (%s)", host, gai_strerror(gaierr)); +! +! #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 ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) +! fatal("Bad host name: %.100s (%s)", host, gai_strerror(gaierr)); +! 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. */ +--- 470,496 ---- + 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); + + /* 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) +--- 503,517 ---- + 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) +*************** +*** 578,586 **** +--- 522,532 ---- + /* Set socket options. We would like the socket to disappear as soon as + it has been closed for whatever reason. */ + /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ ++ #if 0 /* XXX */ + #if defined(TCP_NODELAY) && defined(ENABLE_TCP_NODELAY) + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)); + #endif /* TCP_NODELAY */ ++ #endif /* 0 */ + #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) + linger.l_onoff = 1; + linger.l_linger = 15; +*************** +*** 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(); +--- 892,898 ---- + 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(); |