From e2c3d29b4295c3eec18294bc34f0c99a7b9ae413 Mon Sep 17 00:00:00 2001 From: Tommi Virtanen Date: Fri, 25 Mar 2011 16:40:48 -0700 Subject: [PATCH] libceph: Get secret from the kernel keys api when mounting with key=NAME. Signed-off-by: Tommi Virtanen Signed-off-by: Sage Weil --- net/ceph/Kconfig | 1 + net/ceph/ceph_common.c | 58 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig index ad424049b0cf..be683f2d401f 100644 --- a/net/ceph/Kconfig +++ b/net/ceph/Kconfig @@ -4,6 +4,7 @@ config CEPH_LIB select LIBCRC32C select CRYPTO_AES select CRYPTO + select KEYS default n help Choose Y or M here to include cephlib, which provides the diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 02e084f29d24..c92bc8d50597 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -197,6 +199,7 @@ enum { Opt_fsid, Opt_name, Opt_secret, + Opt_key, Opt_ip, Opt_last_string, /* string args above */ @@ -213,6 +216,7 @@ static match_table_t opt_tokens = { {Opt_fsid, "fsid=%s"}, {Opt_name, "name=%s"}, {Opt_secret, "secret=%s"}, + {Opt_key, "key=%s"}, {Opt_ip, "ip=%s"}, /* string args above */ {Opt_noshare, "noshare"}, @@ -232,6 +236,50 @@ void ceph_destroy_options(struct ceph_options *opt) } EXPORT_SYMBOL(ceph_destroy_options); +/* get secret from key store */ +static int get_secret(struct ceph_crypto_key *dst, const char *name) { + struct key *ukey; + int key_err; + int err = 0; + struct user_key_payload *payload; + void *p; + + ukey = request_key(&key_type_user, name, NULL); + if (!ukey || IS_ERR(ukey)) { + /* request_key errors don't map nicely to mount(2) + errors; don't even try, but still printk */ + key_err = PTR_ERR(ukey); + switch (key_err) { + case -ENOKEY: + pr_warning("ceph: Mount failed due to key not found: %s\n", name); + break; + case -EKEYEXPIRED: + pr_warning("ceph: Mount failed due to expired key: %s\n", name); + break; + case -EKEYREVOKED: + pr_warning("ceph: Mount failed due to revoked key: %s\n", name); + break; + default: + pr_warning("ceph: Mount failed due to unknown key error" + " %d: %s\n", key_err, name); + } + err = -EPERM; + goto out; + } + + payload = ukey->payload.data; + p = payload->data; + err = ceph_crypto_key_decode(dst, &p, p + payload->datalen); + if (err) + goto out_key; + /* pass through, err is 0 */ + +out_key: + key_put(ukey); +out: + return err; +} + int ceph_parse_options(struct ceph_options **popt, char *options, const char *dev_name, const char *dev_name_end, int (*parse_extra_token)(char *c, void *private), @@ -328,6 +376,16 @@ int ceph_parse_options(struct ceph_options **popt, char *options, if (err < 0) goto out; break; + case Opt_key: + opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); + if (!opt->key) { + err = -ENOMEM; + goto out; + } + err = get_secret(opt->key, argstr[0].from); + if (err < 0) + goto out; + break; /* misc */ case Opt_osdtimeout: