summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2012-03-14 07:54:16 -0400
committerStephen Gallagher <sgallagh@redhat.com>2012-03-15 14:18:18 -0400
commit0a5a81f3820158641e6472497bb4c2d829ae4803 (patch)
tree584d33b185eb25b9a254a3780206e0e2a0175b14
parent2a30a449a87a2c400af5fea608269ef51dd4c1d1 (diff)
downloadsssd-0a5a81f3820158641e6472497bb4c2d829ae4803.tar.gz
sssd-0a5a81f3820158641e6472497bb4c2d829ae4803.tar.xz
sssd-0a5a81f3820158641e6472497bb4c2d829ae4803.zip
SSH: Allow clients to explicitly specify host alias
This change removes the need to canonicalize host names on the responder side - the relevant code was removed.
-rw-r--r--Makefile.am4
-rw-r--r--src/responder/ssh/sshsrv.c7
-rw-r--r--src/responder/ssh/sshsrv_cmd.c97
-rw-r--r--src/responder/ssh/sshsrv_private.h1
-rw-r--r--src/sss_client/ssh/sss_ssh_authorizedkeys.c9
-rw-r--r--src/sss_client/ssh/sss_ssh_client.c18
-rw-r--r--src/sss_client/ssh/sss_ssh_client.h1
-rw-r--r--src/sss_client/ssh/sss_ssh_knownhostsproxy.c3
8 files changed, 64 insertions, 76 deletions
diff --git a/Makefile.am b/Makefile.am
index 64f5c42e8..c2985561f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -534,11 +534,9 @@ if BUILD_SSH
sssd_ssh_SOURCES = \
src/responder/ssh/sshsrv.c \
src/responder/ssh/sshsrv_cmd.c \
- $(SSSD_RESPONDER_OBJ) \
- $(SSSD_RESOLV_OBJ)
+ $(SSSD_RESPONDER_OBJ)
sssd_ssh_LDADD = \
$(SSSD_LIBS) \
- $(CARES_LIBS) \
libsss_util.la
endif
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c
index 242704530..28a5e9c01 100644
--- a/src/responder/ssh/sshsrv.c
+++ b/src/responder/ssh/sshsrv.c
@@ -26,7 +26,6 @@
#include "responder/common/responder.h"
#include "responder/ssh/sshsrv_private.h"
#include "providers/data_provider.h"
-#include "resolv/async_resolv.h"
struct sbus_method monitor_ssh_methods[] = {
{ MON_CLI_METHOD_PING, monitor_common_pong },
@@ -129,12 +128,6 @@ int ssh_process_init(TALLOC_CTX *mem_ctx,
ssh_dp_reconnect_init, iter);
}
- ret = resolv_init(ssh_ctx, ev, RESOLV_DEFAULT_TIMEOUT, &ssh_ctx->resolv);
- if (ret != EOK) {
- DEBUG(SSSDBG_FATAL_FAILURE, ("Could not set up resolver context\n"));
- return ret;
- }
-
DEBUG(SSSDBG_TRACE_FUNC, ("SSH Initialization complete\n"));
return EOK;
diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c
index 9d5c584cf..cae0b87c0 100644
--- a/src/responder/ssh/sshsrv_cmd.c
+++ b/src/responder/ssh/sshsrv_cmd.c
@@ -33,7 +33,6 @@
#include "responder/common/responder.h"
#include "responder/common/responder_packet.h"
#include "responder/ssh/sshsrv_private.h"
-#include "resolv/async_resolv.h"
static errno_t
ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx);
@@ -85,16 +84,14 @@ done:
return ssh_cmd_done(cmd_ctx, ret);
}
-static void
-ssh_host_pubkeys_resolv_done(struct tevent_req *req);
+static errno_t
+ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx);
static int
sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx)
{
- struct ssh_ctx *ssh_ctx = cctx->rctx->pvt_ctx;
- struct ssh_cmd_ctx *cmd_ctx;
errno_t ret;
- struct tevent_req *req;
+ struct ssh_cmd_ctx *cmd_ctx;
cmd_ctx = talloc_zero(cctx, struct ssh_cmd_ctx);
if (!cmd_ctx) {
@@ -109,8 +106,9 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx)
}
DEBUG(SSSDBG_TRACE_FUNC,
- ("Requesting SSH host public keys for [%s] from [%s]\n",
- cmd_ctx->name, cmd_ctx->domname ? cmd_ctx->domname : "<ALL>"));
+ ("Requesting SSH host public keys for [%s][%s] from [%s]\n",
+ cmd_ctx->name, cmd_ctx->alias ? cmd_ctx->alias : "",
+ cmd_ctx->domname ? cmd_ctx->domname : "<ALL>"));
if (cmd_ctx->domname) {
cmd_ctx->domain = responder_get_domain(cctx->rctx->domains,
@@ -124,54 +122,12 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx)
cmd_ctx->check_next = true;
}
- /* canonicalize host name */
- req = resolv_gethostbyname_send(cmd_ctx, cctx->rctx->ev, ssh_ctx->resolv,
- cmd_ctx->name, IPV4_FIRST,
- default_host_dbs);
- if (!req) {
- ret = ENOMEM;
- DEBUG(SSSDBG_OP_FAILURE,
- ("Out of memory sending resolver request\n"));
- goto done;
- }
-
- tevent_req_set_callback(req, ssh_host_pubkeys_resolv_done, cmd_ctx);
- ret = EAGAIN;
+ ret = ssh_host_pubkeys_search(cmd_ctx);
done:
return ssh_cmd_done(cmd_ctx, ret);
}
-static errno_t
-ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx);
-
-static void
-ssh_host_pubkeys_resolv_done(struct tevent_req *req)
-{
- struct ssh_cmd_ctx *cmd_ctx = tevent_req_callback_data(req,
- struct ssh_cmd_ctx);
- errno_t ret;
- int resolv_status;
- struct resolv_hostent *hostent;
-
- ret = resolv_gethostbyname_recv(req, cmd_ctx,
- &resolv_status, NULL, &hostent);
- talloc_zfree(req);
- if (ret == EOK) {
- if (strcmp(cmd_ctx->name, hostent->name) != 0) {
- cmd_ctx->alias = cmd_ctx->name;
- cmd_ctx->name = hostent->name;
- }
- } else {
- DEBUG(SSSDBG_OP_FAILURE,
- ("Failed to resolve [%s]: %s\n", cmd_ctx->name,
- resolv_strerror(resolv_status)));
- }
-
- ret = ssh_host_pubkeys_search(cmd_ctx);
- ssh_cmd_done(cmd_ctx, ret);
-}
-
static void
ssh_dp_send_req_done(struct tevent_req *req)
{
@@ -603,28 +559,30 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
uint8_t *body;
size_t body_len;
size_t c = 0;
- uint32_t reserved;
+ uint32_t flags;
uint32_t name_len;
char *name;
+ uint32_t alias_len;
+ char *alias;
sss_packet_get_body(cctx->creq->in, &body, &body_len);
- SAFEALIGN_COPY_UINT32_CHECK(&reserved, body+c, body_len, &c);
- if (reserved != 0) {
+ SAFEALIGN_COPY_UINT32_CHECK(&flags, body+c, body_len, &c);
+ if (flags > 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid flags received [0x%x]\n", flags));
return EINVAL;
}
SAFEALIGN_COPY_UINT32_CHECK(&name_len, body+c, body_len, &c);
if (name_len == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Zero-length name is not valid\n"));
return EINVAL;
}
name = (char *)(body+c);
- if (!sss_utf8_check((const uint8_t *)name, name_len-1)) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Supplied data is not valid UTF-8 string\n"));
- return EINVAL;
- }
- if (strnlen(name, name_len) != name_len-1) {
+ if (!sss_utf8_check((const uint8_t *)name, name_len-1) ||
+ name[name_len-1] != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Name is not valid UTF-8 string\n"));
return EINVAL;
}
c += name_len;
@@ -636,6 +594,27 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
return ENOENT;
}
+ if (flags & 1) {
+ SAFEALIGN_COPY_UINT32_CHECK(&alias_len, body+c, body_len, &c);
+ if (alias_len == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Zero-length alias is not valid\n"));
+ return EINVAL;
+ }
+
+ alias = (char *)(body+c);
+ if (!sss_utf8_check((const uint8_t *)alias, alias_len-1) ||
+ alias[alias_len-1] != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Alias is not valid UTF-8 string\n"));
+ return EINVAL;
+ }
+ c += alias_len;
+
+ if (strcmp(cmd_ctx->name, alias) != 0) {
+ cmd_ctx->alias = talloc_strdup(cmd_ctx, alias);
+ if (!cmd_ctx->alias) return ENOMEM;
+ }
+ }
+
return EOK;
}
diff --git a/src/responder/ssh/sshsrv_private.h b/src/responder/ssh/sshsrv_private.h
index 315e4f294..ab9edf7c3 100644
--- a/src/responder/ssh/sshsrv_private.h
+++ b/src/responder/ssh/sshsrv_private.h
@@ -31,7 +31,6 @@
struct ssh_ctx {
struct resp_ctx *rctx;
- struct resolv_ctx *resolv;
};
struct ssh_cmd_ctx {
diff --git a/src/sss_client/ssh/sss_ssh_authorizedkeys.c b/src/sss_client/ssh/sss_ssh_authorizedkeys.c
index 174cb531e..b64bbc3d2 100644
--- a/src/sss_client/ssh/sss_ssh_authorizedkeys.c
+++ b/src/sss_client/ssh/sss_ssh_authorizedkeys.c
@@ -97,7 +97,8 @@ int main(int argc, const char **argv)
}
/* look up public keys */
- ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_USER_PUBKEYS, user, &ent);
+ ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_USER_PUBKEYS,
+ user, NULL, &ent);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret)));
@@ -111,9 +112,9 @@ int main(int argc, const char **argv)
repr = sss_ssh_format_pubkey(mem_ctx, ent, &ent->pubkeys[i],
SSS_SSH_FORMAT_OPENSSH);
if (!repr) {
- DEBUG(SSSDBG_OP_FAILURE,
- ("Out of memory formatting SSH public key\n"));
- continue;
+ ERROR("Not enough memory\n");
+ ret = EXIT_FAILURE;
+ goto fini;
}
printf("%s\n", repr);
diff --git a/src/sss_client/ssh/sss_ssh_client.c b/src/sss_client/ssh/sss_ssh_client.c
index 41b20e76c..8520cd1b1 100644
--- a/src/sss_client/ssh/sss_ssh_client.c
+++ b/src/sss_client/ssh/sss_ssh_client.c
@@ -70,9 +70,13 @@ int set_locale(void)
/* SSH public key request:
*
- * 0..3: flags (unsigned int, must be 0)
+ * 0..3: flags (unsigned int, must be 0 or 1)
* 4..7: name length (unsigned int)
* 8..(X-1): name (null-terminated UTF-8 string)
+ * if (flags & 1) {
+ * X..(X+3): alias length (unsigned int)
+ * (X+4)..Y: alias (null-terminated UTF-8 string)
+ * }
*
* SSH public key reply:
*
@@ -89,6 +93,7 @@ errno_t
sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
enum sss_cli_command command,
const char *name,
+ const char *alias,
struct sss_ssh_ent **result)
{
TALLOC_CTX *tmp_ctx;
@@ -96,6 +101,7 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
errno_t ret;
uint32_t flags;
uint32_t name_len;
+ uint32_t alias_len;
size_t req_len;
uint8_t *req = NULL;
size_t c = 0;
@@ -115,6 +121,12 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
name_len = strlen(name)+1;
req_len = 2*sizeof(uint32_t) + name_len;
+ if (alias) {
+ flags |= 1;
+ alias_len = strlen(alias)+1;
+ req_len += sizeof(uint32_t) + alias_len;
+ }
+
req = talloc_array(tmp_ctx, uint8_t, req_len);
if (!req) {
ret = ENOMEM;
@@ -124,6 +136,10 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
SAFEALIGN_SET_UINT32(req+c, flags, &c);
SAFEALIGN_SET_UINT32(req+c, name_len, &c);
safealign_memcpy(req+c, name, name_len, &c);
+ if (alias) {
+ SAFEALIGN_SET_UINT32(req+c, alias_len, &c);
+ safealign_memcpy(req+c, alias, alias_len, &c);
+ }
/* send request */
rd.data = req;
diff --git a/src/sss_client/ssh/sss_ssh_client.h b/src/sss_client/ssh/sss_ssh_client.h
index 1c8db1ff3..7ffc3983e 100644
--- a/src/sss_client/ssh/sss_ssh_client.h
+++ b/src/sss_client/ssh/sss_ssh_client.h
@@ -34,6 +34,7 @@ errno_t
sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
enum sss_cli_command command,
const char *name,
+ const char *alias,
struct sss_ssh_ent **result);
#endif /* _SSS_SSH_CLIENT_H_ */
diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
index 280532b6e..19206c3c3 100644
--- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
+++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
@@ -275,7 +275,8 @@ int main(int argc, const char **argv)
}
/* look up public keys */
- ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, host, &ent);
+ ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS,
+ host, NULL, &ent);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret)));