Additionally, don't drop the connection when the sss_ssh_knownhostsproxy
process receives a signal.
https://fedorahosted.org/sssd/ticket/1179
https://fedorahosted.org/sssd/ticket/1184
Honza
--
Jan Cholasta
>From 1638b90baf391ee1db9b88eb9ba96f5125be3d59 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <[email protected]>
Date: Mon, 13 Feb 2012 09:07:14 -0500
Subject: [PATCH] SSH: Continue connecting to SSH server even when SSSD is not
running in sss_ssh_knownhostsproxy
Additionally, don't drop the connection when the
sss_ssh_knownhostsproxy process receives a signal.
https://fedorahosted.org/sssd/ticket/1179
https://fedorahosted.org/sssd/ticket/1184
---
src/sss_client/ssh/sss_ssh_knownhostsproxy.c | 182 ++++++++++++++------------
1 files changed, 97 insertions(+), 85 deletions(-)
diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
index b95dbe8..686c65e 100644
--- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
+++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
@@ -41,26 +41,67 @@
#define BUFFER_SIZE 8192
-/* run proxy command */
-static int run_proxy(char **args)
+static void
+update_known_hosts(TALLOC_CTX *mem_ctx,
+ const char *file,
+ const char *req_host,
+ const char *host)
{
+ struct sss_ssh_pubkey *pubkeys;
+ size_t num_pubkeys, i;
+ FILE *f;
+ char *repr;
int ret;
- execv(args[0], (char * const *)args);
+ /* look up public keys */
+ ret = sss_ssh_get_pubkeys(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, host,
+ &pubkeys, &num_pubkeys);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("sss_ssh_get_pubkeys failed() (%d): %s\n", ret, strerror(ret)));
+ ERROR("Error looking up public keys\n");
+ goto done;
+ }
- ret = errno;
- DEBUG(SSSDBG_OP_FAILURE, ("execv() failed (%d): %s\n",
- ret, strerror(ret)));
- ERROR("Failed to execute proxy command\n");
+ /* write known_hosts file */
+ /* FIXME: Do not overwrite the file, handle concurrent access */
+ f = fopen(file, "w");
+ if (!f) {
+ ret = errno;
+ DEBUG(SSSDBG_OP_FAILURE, ("fopen() failed (%d): %s\n",
+ ret, strerror(ret)));
+ ERROR("Can't open known hosts file\n");
+ goto done;
+ }
+
+ fprintf(f,
+ "# Generated by sss_ssh_knownhostsproxy. Please do not modify.\n");
- return EXIT_FAILURE;
+ for (i = 0; i < num_pubkeys; i++) {
+ ret = sss_ssh_format_pubkey(mem_ctx, &pubkeys[i],
+ SSS_SSH_FORMAT_OPENSSH, &repr);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("sss_ssh_format_pubkey() failed (%d): %s\n",
+ ret, strerror(ret)));
+ continue;
+ }
+
+ fprintf(f, "%s %s\n", req_host, repr);
+ }
+
+done:
+ if (f) fclose(f);
}
-/* connect to server */
-static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
+/* connect to server using socket */
+static int
+connect_socket(int af,
+ struct sockaddr *addr,
+ size_t addr_len)
{
int flags;
- int sock;
+ int sock = -1;
fd_set fds;
char buffer[BUFFER_SIZE];
ssize_t rd_len, wr_len, wr_offs;
@@ -72,7 +113,7 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
ret, strerror(ret)));
- return EXIT_FAILURE;
+ goto done;
}
ret = fcntl(0, F_SETFL, flags | O_NONBLOCK);
@@ -80,7 +121,7 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
ret, strerror(ret)));
- return EXIT_FAILURE;
+ goto done;
}
/* create socket */
@@ -90,7 +131,7 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
DEBUG(SSSDBG_OP_FAILURE, ("socket() failed (%d): %s\n",
ret, strerror(ret)));
ERROR("Failed to open a socket\n");
- return EXIT_FAILURE;
+ goto done;
}
/* connect to the server */
@@ -100,8 +141,7 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
DEBUG(SSSDBG_OP_FAILURE, ("connect() failed (%d): %s\n",
ret, strerror(ret)));
ERROR("Failed to connect to the server\n");
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
/* set O_NONBLOCK on the socket */
@@ -110,8 +150,7 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
ret, strerror(ret)));
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
@@ -119,8 +158,7 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("fcntl() failed (%d): %s\n",
ret, strerror(ret)));
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
while (1) {
@@ -136,43 +174,40 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("select() failed (%d): %s\n",
ret, strerror(ret)));
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
/* read from standard input & write to socket */
if (FD_ISSET(0, &fds)) {
rd_len = read(0, buffer, BUFFER_SIZE);
if (rd_len == -1) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EINTR) {
continue;
}
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("read() failed (%d): %s\n",
ret, strerror(ret)));
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
wr_offs = 0;
do {
wr_len = send(sock, buffer+wr_offs, rd_len-wr_offs, 0);
if (wr_len == -1) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EINTR) {
continue;
}
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("send() failed (%d): %s\n",
ret, strerror(ret)));
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
if (wr_len == 0) {
- close(sock);
- return EXIT_SUCCESS;
+ ret = EOK;
+ goto done;
}
wr_offs += wr_len;
@@ -183,41 +218,60 @@ static int run_connect(int af, struct sockaddr *addr, size_t addr_len)
if (FD_ISSET(sock, &fds)) {
rd_len = recv(sock, buffer, BUFFER_SIZE, 0);
if (rd_len == -1) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EINTR) {
continue;
}
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("recv() failed (%d): %s\n",
ret, strerror(ret)));
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
if (rd_len == 0) {
- close(sock);
- return EXIT_SUCCESS;
+ ret = EOK;
+ goto done;
}
wr_offs = 0;
do {
wr_len = write(1, buffer+wr_offs, rd_len-wr_offs);
if (wr_len == -1) {
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EINTR) {
continue;
}
ret = errno;
DEBUG(SSSDBG_OP_FAILURE, ("write() failed (%d): %s\n",
ret, strerror(ret)));
- close(sock);
- return EXIT_FAILURE;
+ goto done;
}
wr_offs += wr_len;
} while(wr_offs < rd_len);
}
}
+
+done:
+ if (sock >= 0) close(sock);
+
+ return ret;
+}
+
+/* connect to server using proxy command */
+static int
+connect_proxy_command(char **args)
+{
+ int ret;
+
+ execv(args[0], (char * const *)args);
+
+ ret = errno;
+ DEBUG(SSSDBG_OP_FAILURE, ("execv() failed (%d): %s\n",
+ ret, strerror(ret)));
+ ERROR("Failed to execute proxy command\n");
+
+ return ret;
}
int main(int argc, const char **argv)
@@ -245,11 +299,7 @@ int main(int argc, const char **argv)
const char *file;
struct passwd *pwd;
const char *host;
- FILE *f;
struct addrinfo ai_hint, *ai = NULL;
- struct sss_ssh_pubkey *pubkeys;
- size_t num_pubkeys, i;
- char *repr;
int ret;
debug_prg_name = argv[0];
@@ -344,52 +394,14 @@ int main(int argc, const char **argv)
host = ai[0].ai_canonname;
}
- /* look up public keys */
- ret = sss_ssh_get_pubkeys(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, host,
- &pubkeys, &num_pubkeys);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- ("sss_ssh_get_pubkeys failed() (%d): %s\n", ret, strerror(ret)));
- ERROR("Error looking up public keys\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* write known_hosts file */
- /* FIXME: Do not overwrite the file, handle concurrent access */
- f = fopen(file, "w");
- if (!f) {
- ret = errno;
- DEBUG(SSSDBG_OP_FAILURE, ("fopen() failed (%d): %s\n",
- ret, strerror(ret)));
- ERROR("Can't open known hosts file\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- fprintf(f,
- "# Generated by sss_ssh_knownhostsproxy. Please do not modify.\n");
-
- for (i = 0; i < num_pubkeys; i++) {
- ret = sss_ssh_format_pubkey(mem_ctx, &pubkeys[i],
- SSS_SSH_FORMAT_OPENSSH, &repr);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- ("sss_ssh_format_pubkey() failed (%d): %s\n",
- ret, strerror(ret)));
- continue;
- }
-
- fprintf(f, "%s %s\n", pc_host, repr);
- }
-
- fclose(f);
+ /* update the known_hosts file */
+ update_known_hosts(mem_ctx, file, pc_host, host);
/* connect to server */
if (pc_args) {
- ret = run_proxy(discard_const(pc_args));
+ ret = connect_proxy_command(discard_const(pc_args));
} else {
- ret = run_connect(ai->ai_family, ai->ai_addr, ai->ai_addrlen);
+ ret = connect_socket(ai->ai_family, ai->ai_addr, ai->ai_addrlen);
}
fini:
@@ -397,5 +409,5 @@ fini:
talloc_free(mem_ctx);
if (ai) freeaddrinfo(ai);
- return ret;
+ return (ret == EOK) ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.7.6.5
_______________________________________________
sssd-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/sssd-devel