From 81e20603d9d7202cc0a4ade616134fb03fe32029 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Apr 25 2017 12:39:32 +0000 Subject: [PATCH 1/3] ssh tools: The ai structure is not an array, This structure is actually a linked list, so do not mislead readers by treating it as an array. Resolves: https://pagure.io/SSSD/sssd/issue/1498 Signed-off-by: Simo Sorce --- diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c index adb8228..310243c 100644 --- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c +++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c @@ -268,10 +268,10 @@ int main(int argc, const char **argv) DEBUG(SSSDBG_OP_FAILURE, "getaddrinfo() failed (%d): %s\n", ret, gai_strerror(ret)); } else { - host = ai[0].ai_canonname; + host = ai->ai_canonname; } } else { - ret = getnameinfo(ai[0].ai_addr, ai[0].ai_addrlen, + ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, canonhost, NI_MAXHOST, NULL, 0, NI_NAMEREQD); if (ret) { DEBUG(SSSDBG_OP_FAILURE, @@ -295,7 +295,7 @@ int main(int argc, const char **argv) if (pc_args) { ret = connect_proxy_command(discard_const(pc_args)); } else if (ai) { - ret = connect_socket(ai[0].ai_family, ai[0].ai_addr, ai[0].ai_addrlen); + ret = connect_socket(ai->ai_family, ai->ai_addr, ai->ai_addrlen); } else { ret = EFAULT; } From b42a1496b2d8e71e2a3353401a92681f847ffbaa Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Apr 25 2017 14:00:15 +0000 Subject: [PATCH 2/3] ssh tools: Fix issues with multiple IP addresses Cycle through all resolved address until one succeed or all fail. This is needed for dual stack systems where either IPv4 or IPv6 are improperly configured or selectively filtered at some point along the route. Resolves: https://pagure.io/SSSD/sssd/issue/1498 Signed-off-by: Simo Sorce --- diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c index 310243c..b7b0c3b 100644 --- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c +++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c @@ -295,7 +295,13 @@ int main(int argc, const char **argv) if (pc_args) { ret = connect_proxy_command(discard_const(pc_args)); } else if (ai) { - ret = connect_socket(ai->ai_family, ai->ai_addr, ai->ai_addrlen); + /* Try all IP addresses before giving up */ + for (struct addrinfo *ti = ai; ti != NULL; ti = ti->ai_next) { + ret = connect_socket(ti->ai_family, ti->ai_addr, ti->ai_addrlen); + if (ret == 0) { + break; + } + } } else { ret = EFAULT; } From 68bd21a2f5bcb38e4e8a064b2305864e3774b6e1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Apr 25 2017 19:19:13 +0000 Subject: [PATCH 3/3] ssh tools: Split connect and communication phases We can fallback after a connect error, but we cannot easily fall back once we star tsending data as we may have consumed part of the buffer so reconnecting and sending what's left would not make sense. Therefore we now fallback on connect errors, but we issue a hard fail if error happens after communication has been established. Resolves: https://pagure.io/SSSD/sssd/issue/1498 Signed-off-by: Simo Sorce --- diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c index b7b0c3b..976ba86 100644 --- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c +++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c @@ -40,14 +40,10 @@ /* connect to server using socket */ static int -connect_socket(int family, struct sockaddr *addr, size_t addr_len) +connect_socket(int family, struct sockaddr *addr, size_t addr_len, int *sd) { int flags; int sock = -1; - struct pollfd fds[2]; - char buffer[BUFFER_SIZE]; - int i; - ssize_t res; int ret; /* set O_NONBLOCK on standard input */ @@ -85,6 +81,22 @@ connect_socket(int family, struct sockaddr *addr, size_t addr_len) goto done; } + *sd = sock; + +done: + if (ret != 0 && sock >= 0) close(sock); + return ret; +} + +static int proxy_data(int sock) +{ + int flags; + struct pollfd fds[2]; + char buffer[BUFFER_SIZE]; + int i; + ssize_t res; + int ret; + /* set O_NONBLOCK on the socket */ flags = fcntl(sock, F_GETFL); if (flags == -1) { @@ -158,8 +170,7 @@ connect_socket(int family, struct sockaddr *addr, size_t addr_len) } done: - if (sock >= 0) close(sock); - + close(sock); return ret; } @@ -297,8 +308,11 @@ int main(int argc, const char **argv) } else if (ai) { /* Try all IP addresses before giving up */ for (struct addrinfo *ti = ai; ti != NULL; ti = ti->ai_next) { - ret = connect_socket(ti->ai_family, ti->ai_addr, ti->ai_addrlen); + int socket_descriptor = -1; + ret = connect_socket(ti->ai_family, ti->ai_addr, ti->ai_addrlen, + &socket_descriptor); if (ret == 0) { + ret = proxy_data(socket_descriptor); break; } }