From d0a8981bce0c462bcd4b5db2900c0f29a40a41f0 Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Wed, 14 Mar 2012 08:02:36 -0400 Subject: SSH: Canonicalize host name and do reverse DNS lookup in sss_ssh_knownhostsproxy https://fedorahosted.org/sssd/ticket/1245 --- src/sss_client/ssh/sss_ssh_knownhostsproxy.c | 64 +++++++++++++++++----------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c index 19206c3c..c6b0bd86 100644 --- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c +++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c @@ -40,11 +40,8 @@ /* connect to server using socket */ static int -connect_socket(const char *host, - const char *port) +connect_socket(int family, struct sockaddr *addr, size_t addr_len) { - struct addrinfo ai_hint; - struct addrinfo *ai = NULL; int flags; int sock = -1; struct pollfd fds[2]; @@ -53,21 +50,6 @@ connect_socket(const char *host, ssize_t res; int ret; - /* get IP addresses of the host */ - memset(&ai_hint, 0, sizeof(struct addrinfo)); - ai_hint.ai_family = AF_UNSPEC; - ai_hint.ai_socktype = SOCK_STREAM; - ai_hint.ai_protocol = IPPROTO_TCP; - ai_hint.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; - - ret = getaddrinfo(host, port, &ai_hint, &ai); - if (ret) { - DEBUG(SSSDBG_CRIT_FAILURE, - ("getaddrinfo() failed (%d): %s\n", ret, gai_strerror(ret))); - ret = ENOENT; - goto done; - } - /* set O_NONBLOCK on standard input */ flags = fcntl(0, F_GETFL); if (flags == -1) { @@ -86,7 +68,7 @@ connect_socket(const char *host, } /* create socket */ - sock = socket(ai[0].ai_family, SOCK_STREAM, IPPROTO_TCP); + sock = socket(family, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, ("socket() failed (%d): %s\n", @@ -96,7 +78,7 @@ connect_socket(const char *host, } /* connect to the server */ - ret = connect(sock, ai[0].ai_addr, ai[0].ai_addrlen); + ret = connect(sock, addr, addr_len); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, ("connect() failed (%d): %s\n", @@ -175,7 +157,6 @@ connect_socket(const char *host, DEBUG(SSSDBG_TRACE_FUNC, ("Connection closed\n")); done: - if (ai) freeaddrinfo(ai); if (sock >= 0) close(sock); return ret; @@ -216,6 +197,9 @@ int main(int argc, const char **argv) POPT_TABLEEND }; poptContext pc = NULL; + struct addrinfo ai_hint; + struct addrinfo *ai = NULL; + char canonhost[NI_MAXHOST]; const char *host; struct sss_ssh_ent *ent; int ret; @@ -262,21 +246,48 @@ int main(int argc, const char **argv) ret, fini); } + /* get IP addresses of the host */ + memset(&ai_hint, 0, sizeof(struct addrinfo)); + ai_hint.ai_family = AF_UNSPEC; + ai_hint.ai_socktype = SOCK_STREAM; + ai_hint.ai_protocol = IPPROTO_TCP; + ai_hint.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; + + ret = getaddrinfo(pc_host, pc_port, &ai_hint, &ai); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("getaddrinfo() failed (%d): %s\n", ret, gai_strerror(ret))); + ERROR("Host name cannot be resolved\n"); + ret = EXIT_FAILURE; + goto fini; + } + + /* canonicalize hostname */ + ret = getnameinfo(ai[0].ai_addr, ai[0].ai_addrlen, + canonhost, NI_MAXHOST, NULL, 0, NI_NAMEREQD); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("getaddrinfo() failed (%d): %s\n", ret, gai_strerror(ret))); + ERROR("Reverse lookup failed\n"); + ret = EXIT_FAILURE; + goto fini; + } + /* append domain to hostname if domain is specified */ if (pc_domain) { - host = talloc_asprintf(mem_ctx, "%s@%s", pc_host, pc_domain); + host = talloc_asprintf(mem_ctx, "%s@%s", canonhost, pc_domain); if (!host) { ERROR("Not enough memory\n"); ret = EXIT_FAILURE; goto fini; } } else { - host = pc_host; + host = canonhost; } /* look up public keys */ ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, - host, NULL, &ent); + host, pc_host, &ent); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret))); @@ -287,12 +298,13 @@ int main(int argc, const char **argv) if (pc_args) { ret = connect_proxy_command(discard_const(pc_args)); } else { - ret = connect_socket(pc_host, pc_port); + ret = connect_socket(ai[0].ai_family, ai[0].ai_addr, ai[0].ai_addrlen); } ret = (ret == EOK) ? EXIT_SUCCESS : EXIT_FAILURE; fini: poptFreeContext(pc); + if (ai) freeaddrinfo(ai); talloc_free(mem_ctx); return ret; -- cgit