diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sss_client/ssh/sss_ssh_authorizedkeys.c | 23 | ||||
-rw-r--r-- | src/sss_client/ssh/sss_ssh_client.c (renamed from src/sss_client/ssh/sss_ssh.c) | 165 | ||||
-rw-r--r-- | src/sss_client/ssh/sss_ssh_client.h | 39 | ||||
-rw-r--r-- | src/sss_client/ssh/sss_ssh_knownhostsproxy.c | 23 | ||||
-rw-r--r-- | src/util/sss_ssh.c | 174 | ||||
-rw-r--r-- | src/util/sss_ssh.h (renamed from src/sss_client/ssh/sss_ssh.h) | 36 |
6 files changed, 294 insertions, 166 deletions
diff --git a/src/sss_client/ssh/sss_ssh_authorizedkeys.c b/src/sss_client/ssh/sss_ssh_authorizedkeys.c index c8aa45c3..bc3cdf47 100644 --- a/src/sss_client/ssh/sss_ssh_authorizedkeys.c +++ b/src/sss_client/ssh/sss_ssh_authorizedkeys.c @@ -24,8 +24,9 @@ #include "util/util.h" #include "util/crypto/sss_crypto.h" +#include "util/sss_ssh.h" #include "sss_client/sss_cli.h" -#include "sss_client/ssh/sss_ssh.h" +#include "sss_client/ssh/sss_ssh_client.h" int main(int argc, const char **argv) { @@ -43,8 +44,8 @@ int main(int argc, const char **argv) }; poptContext pc = NULL; const char *user; - struct sss_ssh_pubkey *pubkeys; - size_t num_pubkeys, i; + struct sss_ssh_ent *ent; + size_t i; char *repr; int ret; @@ -96,24 +97,18 @@ int main(int argc, const char **argv) } /* look up public keys */ - ret = sss_ssh_get_pubkeys(mem_ctx, SSS_SSH_GET_USER_PUBKEYS, user, - &pubkeys, &num_pubkeys); + ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_USER_PUBKEYS, user, &ent); 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; } /* print results */ - 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))); + for (i = 0; i < ent->num_pubkeys; i++) { + repr = sss_ssh_format_pubkey(mem_ctx, ent, &ent->pubkeys[i], + SSS_SSH_FORMAT_OPENSSH); + if (!repr) { continue; } diff --git a/src/sss_client/ssh/sss_ssh.c b/src/sss_client/ssh/sss_ssh_client.c index bb76800a..82507787 100644 --- a/src/sss_client/ssh/sss_ssh.c +++ b/src/sss_client/ssh/sss_ssh_client.c @@ -23,7 +23,6 @@ #include <errno.h> #include <stdlib.h> #include <stdio.h> -#include <arpa/inet.h> #include <talloc.h> #include <popt.h> @@ -31,9 +30,11 @@ #include <libintl.h> #include <string.h> +#include "util/util.h" #include "util/crypto/sss_crypto.h" +#include "util/sss_ssh.h" #include "sss_client/sss_cli.h" -#include "sss_client/ssh/sss_ssh.h" +#include "sss_client/ssh/sss_ssh_client.h" /* FIXME - split from tools_util to create a common function */ void usage(poptContext pc, const char *error) @@ -69,9 +70,9 @@ int set_locale(void) /* SSH public key request: * - * 0..3: flags (unsigned int, must be 0) - * 4..7: name length (unsigned int) - * 8..$: name (null-terminated UTF-8 string) + * 0..3: flags (unsigned int, must be 0) + * 4..7: name length (unsigned int) + * 8..(X-1): name (null-terminated UTF-8 string) * * SSH public key reply: * @@ -85,14 +86,15 @@ int set_locale(void) * (X+4)..Y: key (public key blob as defined in RFC4253, section 6.6) */ errno_t -sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, - enum sss_cli_command command, - const char *name, - struct sss_ssh_pubkey **pubkeys, - size_t *pubkeys_len) +sss_ssh_get_ent(TALLOC_CTX *mem_ctx, + enum sss_cli_command command, + const char *name, + struct sss_ssh_ent **result) { TALLOC_CTX *tmp_ctx; - errno_t ret = EOK; + struct sss_ssh_ent *res = NULL; + errno_t ret; + uint32_t flags; uint32_t name_len; size_t req_len; uint8_t *req = NULL; @@ -102,7 +104,6 @@ sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, uint8_t *rep = NULL; size_t rep_len; uint32_t count, reserved, len, i; - struct sss_ssh_pubkey *result = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { @@ -110,6 +111,7 @@ sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, } /* build request */ + flags = 0; name_len = strlen(name)+1; req_len = 2*sizeof(uint32_t) + name_len; @@ -119,7 +121,7 @@ sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, goto done; } - SAFEALIGN_SET_UINT32(req+c, 0, &c); + SAFEALIGN_SET_UINT32(req+c, flags, &c); SAFEALIGN_SET_UINT32(req+c, name_len, &c); safealign_memcpy(req+c, name, name_len, &c); @@ -152,12 +154,20 @@ sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, goto done; } + res = talloc_zero(tmp_ctx, struct sss_ssh_ent); + if (!res) { + ret = ENOMEM; + goto done; + } + if (count > 0) { - result = talloc_zero_array(tmp_ctx, struct sss_ssh_pubkey, count); - if (!result) { + res->pubkeys = talloc_zero_array(res, struct sss_ssh_pubkey, count); + if (!res->pubkeys) { ret = ENOMEM; goto done; } + + res->num_pubkeys = count; } for (i = 0; i < count; i++) { @@ -166,8 +176,8 @@ sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, goto done; } - SAFEALIGN_COPY_UINT32(&result[i].flags, rep+c, &c); - if (result[i].flags != 0) { + SAFEALIGN_COPY_UINT32(&flags, rep+c, &c); + if (flags != 0) { ret = EINVAL; goto done; } @@ -179,16 +189,20 @@ sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, goto done; } - result[i].name = talloc_array(result, char, len); - if (!result[i].name) { - ret = ENOMEM; - goto done; - } - - safealign_memcpy(result[i].name, rep+c, len, &c); - if (strnlen(result[i].name, len) != len-1) { - ret = EINVAL; - goto done; + if (!res->name) { + res->name = talloc_array(res, char, len); + if (!res->name) { + ret = ENOMEM; + goto done; + } + + safealign_memcpy(res->name, rep+c, len, &c); + if (strnlen(res->name, len) != len-1) { + ret = EINVAL; + goto done; + } + } else { + c += len; } SAFEALIGN_COPY_UINT32(&len, rep+c, &c); @@ -198,103 +212,18 @@ sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, goto done; } - result[i].key = talloc_array(result, uint8_t, len); - if (!result[i].key) { + res->pubkeys[i].data = talloc_array(res, uint8_t, len); + if (!res->pubkeys[i].data) { ret = ENOMEM; goto done; } - safealign_memcpy(result[i].key, rep+c, len, &c); - result[i].key_len = len; - } - - *pubkeys = result ? talloc_steal(mem_ctx, result) : NULL; - *pubkeys_len = count; - -done: - talloc_free(tmp_ctx); - - return ret; -} - -char * -sss_ssh_get_pubkey_algorithm(TALLOC_CTX *mem_ctx, - struct sss_ssh_pubkey *pubkey) -{ - size_t c = 0; - uint32_t algo_len; - char *algo; - - SAFEALIGN_COPY_UINT32(&algo_len, pubkey->key, &c); - algo_len = ntohl(algo_len); - - algo = talloc_zero_array(mem_ctx, char, algo_len+1); - if (!algo) { - return NULL; - } - - memcpy(algo, pubkey->key+c, algo_len); - - return algo; -} - -errno_t -sss_ssh_format_pubkey(TALLOC_CTX *mem_ctx, - struct sss_ssh_pubkey *pubkey, - enum sss_ssh_pubkey_format format, - char **result) -{ - TALLOC_CTX *tmp_ctx; - errno_t ret = EOK; - char *pk; - char *algo; - char *out; - - if (!pubkey) { - return EINVAL; - } - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - pk = sss_base64_encode(tmp_ctx, pubkey->key, pubkey->key_len); - if (!pk) { - ret = ENOMEM; - goto done; - } - - switch (format) { - case SSS_SSH_FORMAT_RAW: - /* base64-encoded key blob */ - - out = talloc_steal(mem_ctx, pk); - - break; - - case SSS_SSH_FORMAT_OPENSSH: - /* OpenSSH authorized_keys/known_hosts format */ - - algo = sss_ssh_get_pubkey_algorithm(tmp_ctx, pubkey); - if (!algo) { - ret = ENOMEM; - goto done; - } - - out = talloc_asprintf(tmp_ctx, "%s %s %s", - algo, pk, pubkey->name); - if (!out) { - ret = ENOMEM; - goto done; - } - - talloc_steal(mem_ctx, out); - - break; + safealign_memcpy(res->pubkeys[i].data, rep+c, len, &c); + res->pubkeys[i].data_len = len; } - *result = out; + *result = talloc_steal(mem_ctx, res); + ret = EOK; done: talloc_free(tmp_ctx); diff --git a/src/sss_client/ssh/sss_ssh_client.h b/src/sss_client/ssh/sss_ssh_client.h new file mode 100644 index 00000000..1c8db1ff --- /dev/null +++ b/src/sss_client/ssh/sss_ssh_client.h @@ -0,0 +1,39 @@ +/* + Authors: + Jan Cholasta <jcholast@redhat.com> + + Copyright (C) 2012 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _SSS_SSH_CLIENT_H_ +#define _SSS_SSH_CLIENT_H_ + +void usage(poptContext pc, const char *error); +int set_locale(void); + +#define BAD_POPT_PARAMS(pc, msg, val, label) do { \ + usage(pc, msg); \ + val = EXIT_FAILURE; \ + goto label; \ +} while(0) + +errno_t +sss_ssh_get_ent(TALLOC_CTX *mem_ctx, + enum sss_cli_command command, + const char *name, + 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 b95dbe8e..fb93e4ad 100644 --- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c +++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c @@ -33,9 +33,10 @@ #include "util/util.h" #include "util/crypto/sss_crypto.h" +#include "util/sss_ssh.h" #include "tools/tools_util.h" #include "sss_client/sss_cli.h" -#include "sss_client/ssh/sss_ssh.h" +#include "sss_client/ssh/sss_ssh_client.h" #define DEFAULT_FILE ".ssh/sss_known_hosts" @@ -247,8 +248,8 @@ int main(int argc, const char **argv) const char *host; FILE *f; struct addrinfo ai_hint, *ai = NULL; - struct sss_ssh_pubkey *pubkeys; - size_t num_pubkeys, i; + struct sss_ssh_ent *ent; + size_t i; char *repr; int ret; @@ -345,11 +346,8 @@ int main(int argc, const char **argv) } /* look up public keys */ - ret = sss_ssh_get_pubkeys(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, host, - &pubkeys, &num_pubkeys); + ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, host, &ent); 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; @@ -370,13 +368,10 @@ int main(int argc, const char **argv) 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))); + for (i = 0; i < ent->num_pubkeys; i++) { + repr = sss_ssh_format_pubkey(mem_ctx, ent, &ent->pubkeys[i], + SSS_SSH_FORMAT_OPENSSH); + if (!repr) { continue; } diff --git a/src/util/sss_ssh.c b/src/util/sss_ssh.c new file mode 100644 index 00000000..83c1ec15 --- /dev/null +++ b/src/util/sss_ssh.c @@ -0,0 +1,174 @@ +/* + Authors: + Jan Cholasta <jcholast@redhat.com> + + Copyright (C) 2012 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <arpa/inet.h> + +#include "db/sysdb.h" +#include "util/util.h" +#include "util/crypto/sss_crypto.h" +#include "util/sss_ssh.h" + +errno_t +sss_ssh_make_ent(TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + struct sss_ssh_ent **result) +{ + TALLOC_CTX *tmp_ctx; + struct sss_ssh_ent *res = NULL; + errno_t ret; + const char *name; + struct ldb_message_element *el; + unsigned int i; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + if (!name) { + ret = EINVAL; + goto done; + } + + res = talloc_zero(tmp_ctx, struct sss_ssh_ent); + if (!res) { + ret = ENOMEM; + goto done; + } + + res->name = talloc_strdup(res, name); + if (!res->name) { + ret = ENOMEM; + goto done; + } + + el = ldb_msg_find_element(msg, SYSDB_SSH_PUBKEY); + if (el) { + res->num_pubkeys = el->num_values; + + res->pubkeys = talloc_array(res, struct sss_ssh_pubkey, + res->num_pubkeys); + if (!res->pubkeys) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < el->num_values; i++) { + res->pubkeys[i].data = sss_base64_decode(res->pubkeys, + (char *)el->values[i].data, &res->pubkeys[i].data_len); + if (!res->pubkeys[i].data) { + ret = ENOMEM; + goto done; + } + } + } + + el = ldb_msg_find_element(msg, SYSDB_NAME_ALIAS); + if (el) { + res->num_aliases = el->num_values; + + res->aliases = talloc_array(res, char *, res->num_aliases); + if (!res->aliases) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < el->num_values; i++) { + res->aliases[i] = talloc_strdup(res->aliases, + (char *)el->values[i].data); + if (!res->aliases[i]) { + ret = ENOMEM; + goto done; + } + } + } + + *result = talloc_steal(mem_ctx, res); + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +char * +sss_ssh_get_pubkey_algorithm(TALLOC_CTX *mem_ctx, + struct sss_ssh_pubkey *pubkey) +{ + size_t c = 0; + uint32_t algo_len; + char *algo; + + SAFEALIGN_COPY_UINT32(&algo_len, pubkey->data, &c); + algo_len = ntohl(algo_len); + + algo = talloc_zero_array(mem_ctx, char, algo_len+1); + if (!algo) { + return NULL; + } + + memcpy(algo, pubkey->data+c, algo_len); + + return algo; +} + +char * +sss_ssh_format_pubkey(TALLOC_CTX *mem_ctx, + struct sss_ssh_ent *ent, + struct sss_ssh_pubkey *pubkey, + enum sss_ssh_pubkey_format format) +{ + TALLOC_CTX *tmp_ctx; + char *blob; + char *algo; + char *result = NULL; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return NULL; + } + + blob = sss_base64_encode(tmp_ctx, pubkey->data, pubkey->data_len); + if (!blob) { + goto done; + } + + switch (format) { + case SSS_SSH_FORMAT_RAW: + /* base64-encoded key blob */ + result = talloc_steal(mem_ctx, blob); + + case SSS_SSH_FORMAT_OPENSSH: + /* OpenSSH authorized_keys/known_hosts format */ + algo = sss_ssh_get_pubkey_algorithm(tmp_ctx, pubkey); + if (!algo) { + goto done; + } + + result = talloc_asprintf(mem_ctx, "%s %s %s", algo, blob, ent->name); + } + +done: + talloc_free(tmp_ctx); + + return result; +} diff --git a/src/sss_client/ssh/sss_ssh.h b/src/util/sss_ssh.h index 633c3af7..a4ac7391 100644 --- a/src/sss_client/ssh/sss_ssh.h +++ b/src/util/sss_ssh.h @@ -21,29 +21,25 @@ #ifndef _SSS_SSH_H_ #define _SSS_SSH_H_ -void usage(poptContext pc, const char *error); -int set_locale(void); - -#define BAD_POPT_PARAMS(pc, msg, val, label) do { \ - usage(pc, msg); \ - val = EXIT_FAILURE; \ - goto label; \ -} while(0) - struct sss_ssh_pubkey { - uint32_t flags; + uint8_t *data; + size_t data_len; +}; + +struct sss_ssh_ent { char *name; - uint8_t *key; - size_t key_len; + struct sss_ssh_pubkey *pubkeys; + size_t num_pubkeys; + + char **aliases; + size_t num_aliases; }; errno_t -sss_ssh_get_pubkeys(TALLOC_CTX *mem_ctx, - enum sss_cli_command command, - const char *name, - struct sss_ssh_pubkey **pubkeys, - size_t *pubkeys_len); +sss_ssh_make_ent(TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + struct sss_ssh_ent **result); char * sss_ssh_get_pubkey_algorithm(TALLOC_CTX *mem_ctx, @@ -54,10 +50,10 @@ enum sss_ssh_pubkey_format { SSS_SSH_FORMAT_OPENSSH }; -errno_t +char * sss_ssh_format_pubkey(TALLOC_CTX *mem_ctx, + struct sss_ssh_ent *ent, struct sss_ssh_pubkey *pubkey, - enum sss_ssh_pubkey_format format, - char **result); + enum sss_ssh_pubkey_format format); #endif /* _SSS_SSH_H_ */ |