version 1.240, 2013/09/19 01:26:29 |
version 1.241, 2013/10/16 02:31:46 |
|
|
{ |
{ |
char *tmp, *ret, strport[NI_MAXSERV]; |
char *tmp, *ret, strport[NI_MAXSERV]; |
|
|
snprintf(strport, sizeof strport, "%hu", port); |
snprintf(strport, sizeof strport, "%d", port); |
xasprintf(&tmp, "exec %s", proxy_command); |
xasprintf(&tmp, "exec %s", proxy_command); |
ret = percent_expand(tmp, "h", host, "p", strport, |
ret = percent_expand(tmp, "h", host, "p", strport, |
"r", options.user, (char *)NULL); |
"r", options.user, (char *)NULL); |
|
|
|
|
/* Set the connection file descriptors. */ |
/* Set the connection file descriptors. */ |
packet_set_connection(sock, sock); |
packet_set_connection(sock, sock); |
packet_set_timeout(options.server_alive_interval, |
|
options.server_alive_count_max); |
|
|
|
return 0; |
return 0; |
} |
} |
|
|
pid_t pid; |
pid_t pid; |
char *shell; |
char *shell; |
|
|
if (!strcmp(proxy_command, "-")) { |
|
packet_set_connection(STDIN_FILENO, STDOUT_FILENO); |
|
packet_set_timeout(options.server_alive_interval, |
|
options.server_alive_count_max); |
|
return 0; |
|
} |
|
|
|
if (options.proxy_use_fdpass) |
|
return ssh_proxy_fdpass_connect(host, port, proxy_command); |
|
|
|
if ((shell = getenv("SHELL")) == NULL || *shell == '\0') |
if ((shell = getenv("SHELL")) == NULL || *shell == '\0') |
shell = _PATH_BSHELL; |
shell = _PATH_BSHELL; |
|
|
|
|
|
|
/* Set the connection file descriptors. */ |
/* Set the connection file descriptors. */ |
packet_set_connection(pout[0], pin[1]); |
packet_set_connection(pout[0], pin[1]); |
packet_set_timeout(options.server_alive_interval, |
|
options.server_alive_count_max); |
|
|
|
/* Indicate OK return */ |
/* Indicate OK return */ |
return 0; |
return 0; |
|
|
* and %p substituted for host and port, respectively) to use to contact |
* and %p substituted for host and port, respectively) to use to contact |
* the daemon. |
* the daemon. |
*/ |
*/ |
int |
static int |
ssh_connect(const char *host, struct sockaddr_storage * hostaddr, |
ssh_connect_direct(const char *host, struct addrinfo *aitop, |
u_short port, int family, int connection_attempts, int *timeout_ms, |
struct sockaddr_storage *hostaddr, u_short port, int family, |
int want_keepalive, int needpriv, const char *proxy_command) |
int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) |
{ |
{ |
int gaierr; |
|
int on = 1; |
int on = 1; |
int sock = -1, attempt; |
int sock = -1, attempt; |
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
struct addrinfo hints, *ai, *aitop; |
struct addrinfo *ai; |
|
|
debug2("ssh_connect: needpriv %d", needpriv); |
debug2("ssh_connect: needpriv %d", needpriv); |
|
|
/* If a proxy command is given, connect using it. */ |
|
if (proxy_command != NULL) |
|
return ssh_proxy_connect(host, port, proxy_command); |
|
|
|
/* No proxy command. */ |
|
|
|
memset(&hints, 0, sizeof(hints)); |
|
hints.ai_family = family; |
|
hints.ai_socktype = SOCK_STREAM; |
|
snprintf(strport, sizeof strport, "%u", port); |
|
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) |
|
fatal("%s: Could not resolve hostname %.100s: %s", __progname, |
|
host, ssh_gai_strerror(gaierr)); |
|
|
|
for (attempt = 0; attempt < connection_attempts; attempt++) { |
for (attempt = 0; attempt < connection_attempts; attempt++) { |
if (attempt > 0) { |
if (attempt > 0) { |
/* Sleep a moment before retrying. */ |
/* Sleep a moment before retrying. */ |
|
|
* sequence until the connection succeeds. |
* sequence until the connection succeeds. |
*/ |
*/ |
for (ai = aitop; ai; ai = ai->ai_next) { |
for (ai = aitop; ai; ai = ai->ai_next) { |
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) |
if (ai->ai_family != AF_INET && |
|
ai->ai_family != AF_INET6) |
continue; |
continue; |
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, |
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, |
ntop, sizeof(ntop), strport, sizeof(strport), |
ntop, sizeof(ntop), strport, sizeof(strport), |
|
|
break; /* Successful connection. */ |
break; /* Successful connection. */ |
} |
} |
|
|
freeaddrinfo(aitop); |
|
|
|
/* Return failure if we didn't get a successful connection. */ |
/* Return failure if we didn't get a successful connection. */ |
if (sock == -1) { |
if (sock == -1) { |
error("ssh: connect to host %s port %s: %s", |
error("ssh: connect to host %s port %s: %s", |
|
|
|
|
/* Set the connection. */ |
/* Set the connection. */ |
packet_set_connection(sock, sock); |
packet_set_connection(sock, sock); |
packet_set_timeout(options.server_alive_interval, |
|
options.server_alive_count_max); |
|
|
|
return 0; |
return 0; |
} |
} |
|
|
|
int |
|
ssh_connect(const char *host, struct addrinfo *addrs, |
|
struct sockaddr_storage *hostaddr, u_short port, int family, |
|
int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) |
|
{ |
|
if (options.proxy_command == NULL) { |
|
return ssh_connect_direct(host, addrs, hostaddr, port, family, |
|
connection_attempts, timeout_ms, want_keepalive, needpriv); |
|
} else if (strcmp(options.proxy_command, "-") == 0) { |
|
packet_set_connection(STDIN_FILENO, STDOUT_FILENO); |
|
return 0; /* Always succeeds */ |
|
} else if (options.proxy_use_fdpass) { |
|
return ssh_proxy_fdpass_connect(host, port, |
|
options.proxy_command); |
|
} |
|
return ssh_proxy_connect(host, port, options.proxy_command); |
|
} |
|
|
static void |
static void |
send_client_banner(int connection_out, int minor1) |
send_client_banner(int connection_out, int minor1) |
{ |
{ |
|
|
ssh_login(Sensitive *sensitive, const char *orighost, |
ssh_login(Sensitive *sensitive, const char *orighost, |
struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) |
struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) |
{ |
{ |
char *host, *cp; |
char *host; |
char *server_user, *local_user; |
char *server_user, *local_user; |
|
|
local_user = xstrdup(pw->pw_name); |
local_user = xstrdup(pw->pw_name); |
|
|
|
|
/* Convert the user-supplied hostname into all lowercase. */ |
/* Convert the user-supplied hostname into all lowercase. */ |
host = xstrdup(orighost); |
host = xstrdup(orighost); |
for (cp = host; *cp; cp++) |
lowercase(host); |
if (isupper(*cp)) |
|
*cp = (char)tolower(*cp); |
|
|
|
/* Exchange protocol version identification strings with the server. */ |
/* Exchange protocol version identification strings with the server. */ |
ssh_exchange_identification(timeout_ms); |
ssh_exchange_identification(timeout_ms); |